diff --git a/decidim-budgets/app/packs/stylesheets/budgets.scss b/decidim-budgets/app/packs/stylesheets/budgets.scss index 2db3116ef42e7..a60c974fe03cb 100644 --- a/decidim-budgets/app/packs/stylesheets/budgets.scss +++ b/decidim-budgets/app/packs/stylesheets/budgets.scss @@ -4,12 +4,8 @@ } &-summary { - @apply bg-tertiary; - - box-shadow: 0 4px 6px 0 rgba(211, 211, 211, 0.25); - &__content { - @apply p-4 md:p-0; + @apply bg-tertiary p-4 md:h-full md:p-0; } &__container { @@ -21,7 +17,7 @@ } &__content__header { - @apply col-span-2 text-2xl mb-2; + @apply col-span-2 text-2xl pb-2 mb-2; .ql-editor { @apply inline-block text-2xl; @@ -37,24 +33,20 @@ } &__progressbar { - @apply my-4 relative; + @apply my-0 lg:my-4 relative; .budget-progress { - @apply bg-white rounded; + @apply bg-white rounded h-2; } &--minimum { - @apply absolute; - - .progress-meter--minimum-mark { - @apply h-[20px] ml-auto w-[2px] bg-black block; - } + @apply absolute h-2 bg-gray-3 rounded-s; } &--meter { background-color: var(--success); - @apply h-[20px] rounded; + @apply h-2 rounded-s absolute; } } @@ -71,11 +63,11 @@ } &__progressbar-legend { - @apply text-sm block; + @apply text-xs md:text-sm block; } &__progressbar-legend-strong { - @apply font-bold block; + @apply font-semibold block text-[10px] md:text-sm text-nowrap; } } @@ -231,7 +223,23 @@ } .budget-summary__button-modal { - @apply col-span-12 mb-4 pb-4; + @apply hidden lg:text-secondary lg:block lg:col-span-12 lg:mb-4 lg:pb-4; +} + +.budget-summary__button-dropdown { + @apply col-span-12 text-secondary lg:hidden; + + &_text { + @apply flex gap-4 justify-start; + + svg { + @apply w-5 h-5; + } + } + + p { + @apply text-gray-4 font-normal text-[13px]; + } } .progressbox-fixed-wrapper { @@ -262,7 +270,11 @@ } .budget-summary__button-modal { - @apply col-span-10 col-start-2 justify-start; + @apply hidden lg:text-secondary lg:block lg:col-span-10 lg:col-start-2 lg:justify-start; + } + + .budget-summary__button-dropdown { + @apply block text-secondary col-span-10 col-start-2 justify-start lg:hidden; } .progressbox-fixed-wrapper { diff --git a/decidim-budgets/app/views/decidim/budgets/projects/_order_progress_progressbar_marks_right.html.erb b/decidim-budgets/app/views/decidim/budgets/projects/_order_progress_progressbar_marks_right.html.erb index a76b9935f6da5..b8d9d1ba6f3f7 100644 --- a/decidim-budgets/app/views/decidim/budgets/projects/_order_progress_progressbar_marks_right.html.erb +++ b/decidim-budgets/app/views/decidim/budgets/projects/_order_progress_progressbar_marks_right.html.erb @@ -1,5 +1,4 @@ - <%= t("budget", scope: "decidim.budgets.projects.order_progress") %> <% if current_order.projects_rule? %> <%= current_order.maximum_projects %> @@ -7,4 +6,5 @@ <%= budget_to_currency(budget.total_budget) %> <% end %> + <%= t("budget", scope: "decidim.budgets.projects.order_progress") %> diff --git a/decidim-budgets/app/views/decidim/budgets/projects/_order_progress_summary_content.html.erb b/decidim-budgets/app/views/decidim/budgets/projects/_order_progress_summary_content.html.erb index fb2b429924651..34da1e815715a 100644 --- a/decidim-budgets/app/views/decidim/budgets/projects/_order_progress_summary_content.html.erb +++ b/decidim-budgets/app/views/decidim/budgets/projects/_order_progress_summary_content.html.erb @@ -22,30 +22,29 @@
" aria-valuenow="<%= current_order_budget_percent %>" aria-valuetext="<%= current_order_budget_percent %> %" aria-valuemin="0" aria-valuemax="100">
-
- <%= t("assigned", scope: "decidim.budgets.projects.order_progress") %> " class="budget-summary__progressbar-legend-strong"> <%= render partial: "decidim/budgets/projects/order_total_budget" %> + <%= t("assigned", scope: "decidim.budgets.projects.order_progress") %> <% if current_order.minimum_budget > 0 %> - <%= t("minimum", scope: "decidim.budgets.projects.order_progress") %> <%= budget_to_currency(current_order.minimum_budget) %> + <%= t("minimum", scope: "decidim.budgets.projects.order_progress") %> <% end %> <%= render partial: "decidim/budgets/projects/order_progress_progressbar_marks_right" %>
-
+
<% if !current_order_checked_out? && voting_open? %>
+ +
+ + +
diff --git a/decidim-budgets/config/locales/en.yml b/decidim-budgets/config/locales/en.yml index a8f174dfc4aba..ee8f2ac008192 100644 --- a/decidim-budgets/config/locales/en.yml +++ b/decidim-budgets/config/locales/en.yml @@ -172,7 +172,7 @@ en: back_to: Back to %{component_name} close_modal: Close modal continue: Continue - more_information: More information + more_information: More information about budget budgets_list: budgets: Budgets cancel_order: diff --git a/decidim-budgets/spec/system/orders_spec.rb b/decidim-budgets/spec/system/orders_spec.rb index be2575f3710f6..b0f288d89502f 100644 --- a/decidim-budgets/spec/system/orders_spec.rb +++ b/decidim-budgets/spec/system/orders_spec.rb @@ -109,7 +109,7 @@ it "displays total budget" do within ".budget-summary", match: :first do - expect(page).to have_content("Budget\n€0") + expect(page).to have_content("€0\nBudget") end end end @@ -129,7 +129,7 @@ expect(page).to have_css ".budget-list__data--added", count: 1 within ".budget-summary__progressbar-marks", match: :first do - expect(page).to have_content(/Assigned\s€25,000,000/) + expect(page).to have_content(/€25,000,000\sAssigned/) end within ".budget__list--header" do expect(page).to have_content(/Added\s1/) @@ -162,7 +162,7 @@ expect(page).to have_css ".budget-list__data--added", count: 1 within ".budget-summary__progressbar-marks", match: :first do - expect(page).to have_content(/Assigned\s€25,000,000/) + expect(page).to have_content(/€25,000,000\sAssigned/) end within ".budget__list--header" do expect(page).to have_content(/Added\s1/) @@ -278,7 +278,7 @@ visit_budget within ".budget-summary__progressbar-marks", match: :first do - expect(page).to have_content(/Assigned\s€25,000,000/) + expect(page).to have_content(/€25,000,000\sAssigned/) end within ".budget__list--header" do expect(page).to have_content(/Added\s1/) @@ -289,7 +289,7 @@ end within ".budget-summary__progressbar-marks", match: :first do - expect(page).to have_content(/Assigned\s€0/) + expect(page).to have_content(/€0\sAssigned/) end within ".budget__list--header" do expect(page).to have_content(/Added\s0/) diff --git a/decidim-core/app/cells/decidim/progress_bar/show.erb b/decidim-core/app/cells/decidim/progress_bar/show.erb index 91f460fec3c2c..2a099ae79b66e 100644 --- a/decidim-core/app/cells/decidim/progress_bar/show.erb +++ b/decidim-core/app/cells/decidim/progress_bar/show.erb @@ -4,11 +4,13 @@ <%= content_tag :span, total if total != 0 %> - <%= content_tag :div, units_name_text, class: "progress-bar__units" if units_name %> +
+ <%= content_tag :div, units_name_text, class: "progress-bar__units" if units_name %> - <% if total != 0 %> -
" aria-valuenow="<%= number_with_precision(percentage, separator: ".", precision: 2) %>" aria-valuemin="0" aria-valuemax="100" aria-valuetext="<%= number_to_percentage(percentage, precision: 2) %>"> -
-
- <% end %> + <% if total != 0 %> +
" aria-valuenow="<%= number_with_precision(percentage, separator: ".", precision: 2) %>" aria-valuemin="0" aria-valuemax="100" aria-valuetext="<%= number_to_percentage(percentage, precision: 2) %>"> +
+
+ <% end %> +
diff --git a/decidim-core/app/packs/src/decidim/sticky_header.js b/decidim-core/app/packs/src/decidim/sticky_header.js index 335ab1cd903e2..57459ed94d4ba 100644 --- a/decidim-core/app/packs/src/decidim/sticky_header.js +++ b/decidim-core/app/packs/src/decidim/sticky_header.js @@ -1,14 +1,37 @@ -// This script implements a sticky header that hides when participants scroll down and shows when they scroll up. -// Sticky headers allow users to quickly access the navigation, search, and utility-navigation elements without scrolling up to the top of the page. -// They increase the discoverability of the elements in the header. +// This script implements the sticky header and the sticky buttons. The sticky header hides when participants scroll down and shows when they scroll up. +// Sticky headers allow users to quickly access the navigation, search, and utility-navigation elements without scrolling up to the top of the page. They increase the discoverability of the elements in the header. +// The sticky buttons in the other hand, those are some of the main Call to Actions (CTAs) that remain accessible on the screen as the user scrolls through the detailed view of the Meetings, Proposals, Surveys, and Budgets components. + let prevScroll = window.scrollY; const stickyHeader = document.querySelector("[data-sticky-header]"); +const footer = document.querySelector("footer"); +const stickyButtons = document.querySelectorAll("[data-sticky-buttons]"); + +const isElementInViewport = (element) => { + const rect = element.getBoundingClientRect(); + return rect.top >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight); +}; + +const adjustCtasButtons = () => { + if (!stickyButtons || !stickyButtons.length) { + return; + } + + let visibleButtons = Array.from(stickyButtons).filter(isElementInViewport); + + if (visibleButtons.length > 0) { + const marginBottom = Math.max(...visibleButtons.map((ctasButton) => ctasButton.offsetHeight)); + footer.style.marginBottom = `${marginBottom}px`; + } else { + footer.style.marginBottom = 0; + } +}; if (stickyHeader) { document.addEventListener("scroll", () => { // if a subelement is not visible it has no offsetParent const header = document.getElementById("main-bar").offsetParent; - if (header) { + if (header && window.getComputedStyle(stickyHeader).position === "fixed") { let currentScroll = window.scrollY; let goingDown = prevScroll > currentScroll; let change = Math.abs(prevScroll - currentScroll); @@ -20,6 +43,12 @@ if (stickyHeader) { } prevScroll = currentScroll; } + + adjustCtasButtons(); } }); + + document.addEventListener("on:toggle", () => { + adjustCtasButtons(); + }); }; diff --git a/decidim-core/app/packs/stylesheets/decidim/_flash.scss b/decidim-core/app/packs/stylesheets/decidim/_flash.scss index be68d8d442071..1c02977fafbfa 100644 --- a/decidim-core/app/packs/stylesheets/decidim/_flash.scss +++ b/decidim-core/app/packs/stylesheets/decidim/_flash.scss @@ -12,7 +12,7 @@ } &__message { - @apply text-black font-medium text-md; + @apply text-black font-medium text-md flex-col; a { @apply underline text-secondary; diff --git a/decidim-core/app/packs/stylesheets/decidim/_layout.scss b/decidim-core/app/packs/stylesheets/decidim/_layout.scss index d268b413691ea..7dbdf4614ff76 100644 --- a/decidim-core/app/packs/stylesheets/decidim/_layout.scss +++ b/decidim-core/app/packs/stylesheets/decidim/_layout.scss @@ -105,3 +105,16 @@ .layout-main__buttons { @apply flex gap-x-1 items-center; } + +.layout-aside__ctas-buttons { + @apply fixed md:relative inset-x-0 bottom-0 z-30 md:z-0 flex flex-row-reverse md:flex-col items-center md:items-stretch last:[&>button]:font-semibold first:[&>button]:text-lg justify-around bg-white md:bg-transparent gap-4 md:gap-0 p-4 md:p-0 shadow-inner md:shadow-none first:[&>*]:grow md:first:[&>*]:grow-0 last:[&>*]:w-1/2 md:last:[&>*]:w-auto h-20 md:h-fit first:[&>button]:py-3; + + .meeting__aside-progress, + .proposals__aside-progress { + @apply flex flex-col-reverse md:flex-col md:w-auto; + } +} + +.survey-section-buttons { + @apply flex-row last:[&>button]:font-semibold md:[&>button]:font-normal last:[&>button]:text-lg md:last:[&>button]:text-sm md:first:[&>button]:text-sm last:[&>button]:py-3 md:last:[&>button]:py-1.5 md:first:[&>button]:py-1.5; +} diff --git a/decidim-core/app/views/layouts/decidim/header/_main_links_mobile_search.html.erb b/decidim-core/app/views/layouts/decidim/header/_main_links_mobile_search.html.erb new file mode 100644 index 0000000000000..4902b66b3150d --- /dev/null +++ b/decidim-core/app/views/layouts/decidim/header/_main_links_mobile_search.html.erb @@ -0,0 +1,13 @@ + diff --git a/decidim-forms/app/cells/decidim/forms/step_navigation/show.erb b/decidim-forms/app/cells/decidim/forms/step_navigation/show.erb index 46697b90616f8..d70e33dffddc8 100644 --- a/decidim-forms/app/cells/decidim/forms/step_navigation/show.erb +++ b/decidim-forms/app/cells/decidim/forms/step_navigation/show.erb @@ -1,6 +1,6 @@ -
+
<% if !first_step? %> - @@ -14,7 +14,7 @@ **confirm_data ) %> <% else %> - diff --git a/decidim-forms/app/cells/decidim/forms/step_navigation_cell.rb b/decidim-forms/app/cells/decidim/forms/step_navigation_cell.rb index ea56612047b5d..324bb684ee05b 100644 --- a/decidim-forms/app/cells/decidim/forms/step_navigation_cell.rb +++ b/decidim-forms/app/cells/decidim/forms/step_navigation_cell.rb @@ -43,7 +43,8 @@ def current_step_dom_id def confirm_data { data: { confirm: t("decidim.forms.step_navigation.show.are_you_sure"), - disable: true + disable: true, + data: "survey-buttons" } } end end diff --git a/decidim-meetings/app/cells/decidim/meetings/join_meeting_button/remaining_slots.erb b/decidim-meetings/app/cells/decidim/meetings/join_meeting_button/remaining_slots.erb index 8eb54a7eac221..5f481154a7b24 100644 --- a/decidim-meetings/app/cells/decidim/meetings/join_meeting_button/remaining_slots.erb +++ b/decidim-meetings/app/cells/decidim/meetings/join_meeting_button/remaining_slots.erb @@ -1,4 +1,5 @@
<%= t("remaining_slots", scope: "decidim.meetings.meetings.show", count: model.remaining_slots) %> + <%= model.remaining_slots %> / <%= model.available_slots %>
diff --git a/decidim-meetings/app/packs/stylesheets/decidim/meetings/_item.scss b/decidim-meetings/app/packs/stylesheets/decidim/meetings/_item.scss index d975028f66976..b2009e1c1f254 100644 --- a/decidim-meetings/app/packs/stylesheets/decidim/meetings/_item.scss +++ b/decidim-meetings/app/packs/stylesheets/decidim/meetings/_item.scss @@ -125,13 +125,17 @@ } &::-webkit-progress-bar { - @apply bg-white; + @apply bg-gray lg:bg-white; } &::-moz-progress-bar { @apply bg-success; } } + + &-label { + @apply text-sm font-bold lg:hidden; + } } &-block { diff --git a/decidim-meetings/app/views/decidim/meetings/meetings/_meeting_aside.html.erb b/decidim-meetings/app/views/decidim/meetings/meetings/_meeting_aside.html.erb index d081974690962..8e9a2c828d07c 100644 --- a/decidim-meetings/app/views/decidim/meetings/meetings/_meeting_aside.html.erb +++ b/decidim-meetings/app/views/decidim/meetings/meetings/_meeting_aside.html.erb @@ -1,7 +1,7 @@ <%= render partial: "meeting_poll_actions" %> <% if meeting.can_be_joined_by?(current_user) || meeting.on_different_platform? %> -
+
<%= cell "decidim/meetings/join_meeting_button", meeting, show_remaining_slots: true %>
<% end %> diff --git a/decidim-proposals/app/packs/stylesheets/decidim/proposals/proposals.scss b/decidim-proposals/app/packs/stylesheets/decidim/proposals/proposals.scss index 8d27a9a3a8f1e..01eb0e88cfe87 100644 --- a/decidim-proposals/app/packs/stylesheets/decidim/proposals/proposals.scss +++ b/decidim-proposals/app/packs/stylesheets/decidim/proposals/proposals.scss @@ -24,7 +24,7 @@ &__aside { &-vote { - @apply flex flex-row-reverse md:flex-col gap-4 items-center md:items-stretch justify-between first:[&>*]:grow last:[&>*]:w-1/4 md:last:[&>*]:w-auto; + @apply flex flex-row-reverse md:flex-col gap-4 items-center md:items-stretch justify-around md:last:[&>*]:w-auto; } } diff --git a/decidim-proposals/app/views/decidim/proposals/proposals/_proposal_aside.html.erb b/decidim-proposals/app/views/decidim/proposals/proposals/_proposal_aside.html.erb index 9ae3dfc11e4d3..edabd6b229d0f 100644 --- a/decidim-proposals/app/views/decidim/proposals/proposals/_proposal_aside.html.erb +++ b/decidim-proposals/app/views/decidim/proposals/proposals/_proposal_aside.html.erb @@ -1,6 +1,6 @@ <% if current_settings.votes_enabled? && (show_endorsements_card? || current_user) %>
-
+
<%= render partial: "vote_button", locals: { proposal: @proposal, from_proposals_list: false } unless @proposal.withdrawn? %> <%= render partial: "votes_count", locals: { proposal: @proposal, from_proposals_list: false } %>
diff --git a/decidim-templates/spec/commands/decidim/templates/admin/copy_proposal_answer_template_spec.rb b/decidim-templates/spec/commands/decidim/templates/admin/copy_proposal_answer_template_spec.rb index 92f5cf954b1bd..c062a8557e898 100644 --- a/decidim-templates/spec/commands/decidim/templates/admin/copy_proposal_answer_template_spec.rb +++ b/decidim-templates/spec/commands/decidim/templates/admin/copy_proposal_answer_template_spec.rb @@ -21,10 +21,11 @@ module Admin end describe "when the template is valid" do - let(:destination_template) do - events = described_class.call(template, user) + let(:events) { described_class.call(template, user) } + let(:destination_template) { events[:ok] } + + it "returns an event with :ok key" do expect(events).to have_key(:ok) - events[:ok] end it "applies template attributes to the questionnaire" do diff --git a/decidim-templates/spec/commands/decidim/templates/admin/copy_questionnaire_template_spec.rb b/decidim-templates/spec/commands/decidim/templates/admin/copy_questionnaire_template_spec.rb index 63504fdb84d1a..560bbf3dcf3b4 100644 --- a/decidim-templates/spec/commands/decidim/templates/admin/copy_questionnaire_template_spec.rb +++ b/decidim-templates/spec/commands/decidim/templates/admin/copy_questionnaire_template_spec.rb @@ -22,11 +22,15 @@ module Admin end describe "when the template is valid" do - let(:destination_questionnaire) do - events = described_class.call(template, user) - # events => { :ok => copied_template } + let(:events) { described_class.call(template, user) } + let(:destination_questionnaire) { events[:ok].templatable } + + it "returns an event with :ok key" do expect(events).to have_key(:ok) - events[:ok].templatable + end + + it "assigns the correct templatable to destination_questionnaire" do + expect(destination_questionnaire).to eq(events[:ok].templatable) end it "applies template attributes to the questionnaire" do diff --git a/decidim-templates/spec/commands/decidim/templates/admin/copy_template_spec.rb b/decidim-templates/spec/commands/decidim/templates/admin/copy_template_spec.rb index 20bf7b136f1f2..424855a3560c6 100644 --- a/decidim-templates/spec/commands/decidim/templates/admin/copy_template_spec.rb +++ b/decidim-templates/spec/commands/decidim/templates/admin/copy_template_spec.rb @@ -22,10 +22,15 @@ module Admin end describe "when the template is valid" do - let(:destination_questionnaire) do - events = described_class.call(template, user) + let(:events) { described_class.call(template, user) } + let(:destination_questionnaire) { events[:ok].templatable } + + it "returns an event with :ok key" do expect(events).to have_key(:ok) - events[:ok].templatable + end + + it "assigns the correct templatable to destination_questionnaire" do + expect(destination_questionnaire).to eq(events[:ok].templatable) end it "applies template attributes to the questionnaire" do