diff --git a/app/cells/decidim/proposals/proposal_m_cell.rb b/app/cells/decidim/proposals/proposal_m_cell.rb new file mode 100644 index 00000000..46516461 --- /dev/null +++ b/app/cells/decidim/proposals/proposal_m_cell.rb @@ -0,0 +1,155 @@ +# frozen_string_literal: true + +require "cell/partial" + +module Decidim + module Proposals + # This cell renders a proposal with its M-size card. + class ProposalMCell < Decidim::CardMCell + include ProposalCellsHelper + + delegate :current_locale, to: :controller + + def badge + render if has_badge? + end + + private + + def preview? + options[:preview] + end + + def title + present(model).title(html_escape: true) + end + + def body + decidim_sanitize_editor(present(model).body) + end + + def has_state? + model.published? + end + + def has_badge? + published_state? || withdrawn? + end + + def has_link_to_resource? + model.published? + end + + def has_footer? + return false if model.emendation? + + true + end + + def description + strip_tags(body).truncate(100, separator: /\s/) + end + + def badge_classes + return super unless options[:full_badge] + + state_classes.concat(["label", "proposal-status"]).join(" ") + end + + def base_statuses + @base_statuses ||= begin + if endorsements_visible? + [:endorsements_count, :comments_count] + else + [:comments_count] + end + end + end + + def statuses + return [] if preview? + return base_statuses if model.draft? + return [:creation_date] + base_statuses if !has_link_to_resource? || !can_be_followed? + + [:creation_date, :follow] + base_statuses + end + + def creation_date_status + explanation = tag.strong(t("activemodel.attributes.common.created_at")) + "#{explanation}
#{l(model.published_at.to_date, format: :decidim_short)}" + end + + def endorsements_count_status + return endorsements_count unless has_link_to_resource? + + link_to resource_path, "aria-label" => "#{t("decidim.endorsable.endorsements_count")}: #{model.endorsements_count}", title: t("decidim.endorsable.endorsements_count") do + endorsements_count + end + end + + def endorsements_count + with_tooltip t("decidim.endorsable.endorsements") do + "#{icon("bullhorn", class: "icon--small")} #{model.endorsements_count}" + end + end + + def progress_bar_progress + model.proposal_votes_count || 0 + end + + def progress_bar_total + model.maximum_votes || 0 + end + + def progress_bar_subtitle_text + if progress_bar_progress >= progress_bar_total + t("decidim.proposals.proposals.votes_count.most_popular_proposal") + else + t("decidim.proposals.proposals.votes_count.need_more_votes") + end + end + + def can_be_followed? + !model.withdrawn? + end + + def endorsements_visible? + model.component.current_settings.endorsements_enabled? + end + + def has_image? + @has_image ||= model.attachments.map(&:image?).any? + end + + def resource_image_path + @resource_image_path ||= has_image? ? model.attachments.find_by("content_type like '%image%'").thumbnail_url : nil + end + + def cache_hash + hash = [] + hash << "decidim/proposals/proposal_m" + hash << I18n.locale.to_s + hash << I18n.t(state, scope: "decidim.proposals.answers", default: :not_answered) + hash << model.cache_key_with_version + hash << model.proposal_votes_count + hash << model.endorsements_count + hash << model.comments_count + hash << Digest::MD5.hexdigest(model.component.cache_key_with_version) + hash << Digest::MD5.hexdigest(resource_image_path) if resource_image_path + hash << render_space? ? 1 : 0 + if current_user + hash << current_user.cache_key_with_version + hash << current_user.follows?(model) ? 1 : 0 + end + hash << model.follows_count + hash << Digest::MD5.hexdigest(model.authors.map(&:cache_key_with_version).to_s) + hash << (model.must_render_translation?(model.organization) ? 1 : 0) if model.respond_to?(:must_render_translation?) + hash << model.component.participatory_space.active_step.id if model.component.participatory_space.try(:active_step) + hash << has_footer? + hash << has_actions? + + hash.join(Decidim.cache_key_separator) + end + end + end +end diff --git a/spec/lib/tasks/decidim_app/k8s/dump_db_tasks_spec.rb b/spec/lib/tasks/decidim_app/k8s/dump_db_tasks_spec.rb index d4a47338..8e54062f 100644 --- a/spec/lib/tasks/decidim_app/k8s/dump_db_tasks_spec.rb +++ b/spec/lib/tasks/decidim_app/k8s/dump_db_tasks_spec.rb @@ -8,7 +8,7 @@ end it "invokes the configuration exporter" do - expect(DecidimApp::K8s::ConfigurationExporter).to receive(:dump_db).and_return(true) + expect(DecidimApp::K8s::ConfigurationExporter).to receive(:dump_db).at_least(:once).and_return(true) task.execute end diff --git a/spec/lib/tasks/decidim_app/k8s/export_configuration_tasks_spec.rb b/spec/lib/tasks/decidim_app/k8s/export_configuration_tasks_spec.rb index 02126459..c4012f6d 100644 --- a/spec/lib/tasks/decidim_app/k8s/export_configuration_tasks_spec.rb +++ b/spec/lib/tasks/decidim_app/k8s/export_configuration_tasks_spec.rb @@ -11,7 +11,7 @@ it "invokes the configuration exporter" do with_modified_env IMAGE: image do - expect(DecidimApp::K8s::ConfigurationExporter).to receive(:export!).with(image).and_return(true) + expect(DecidimApp::K8s::ConfigurationExporter).to receive(:export!).with(image).at_least(:once).and_return(true) task.execute end diff --git a/spec/lib/tasks/decidim_app/k8s/external_install_or_reload_task_spec.rb b/spec/lib/tasks/decidim_app/k8s/external_install_or_reload_task_spec.rb index 6f6b58ff..1806cde3 100644 --- a/spec/lib/tasks/decidim_app/k8s/external_install_or_reload_task_spec.rb +++ b/spec/lib/tasks/decidim_app/k8s/external_install_or_reload_task_spec.rb @@ -11,7 +11,7 @@ it "calls the manager service" do with_modified_env path: path.to_s do - expect(DecidimApp::K8s::Manager).to receive(:run).with(path.to_s) + expect(DecidimApp::K8s::Manager).to receive(:run).at_least(:once).with(path.to_s) task.execute end diff --git a/spec/lib/tasks/decidim_app/k8s/upgrade_task_spec.rb b/spec/lib/tasks/decidim_app/k8s/upgrade_task_spec.rb index 6489f678..13818324 100644 --- a/spec/lib/tasks/decidim_app/k8s/upgrade_task_spec.rb +++ b/spec/lib/tasks/decidim_app/k8s/upgrade_task_spec.rb @@ -8,7 +8,7 @@ end it "calls db:migrate" do - expect(Rake::Task["db:migrate"]).to receive(:invoke) + expect(Rake::Task["db:migrate"]).to receive(:invoke).at_least(:once).and_return(true) task.execute end diff --git a/spec/lib/tasks/scaleway/storage/migrate_from_local_task_spec.rb b/spec/lib/tasks/scaleway/storage/migrate_from_local_task_spec.rb index 786b7f5f..480fc2b1 100644 --- a/spec/lib/tasks/scaleway/storage/migrate_from_local_task_spec.rb +++ b/spec/lib/tasks/scaleway/storage/migrate_from_local_task_spec.rb @@ -8,7 +8,7 @@ end it "invokes the migrator" do - expect(ActiveStorage::Migrator).to receive(:migrate!).with(:local, :scaleway).and_return(true) + expect(ActiveStorage::Migrator).to receive(:migrate!).with(:local, :scaleway).at_least(:once).and_return(true) task.execute end