Merge pull request #5764 from consuldemocracy/use_flex_in_executions
Use flex instead of data-equalizer in executions
This commit is contained in:
20
app/assets/stylesheets/budgets/executions/heading.scss
Normal file
20
app/assets/stylesheets/budgets/executions/heading.scss
Normal file
@@ -0,0 +1,20 @@
|
||||
.budgets-executions-heading {
|
||||
.budgets-executions-heading-investments {
|
||||
$spacing: rem-calc(map-get($grid-column-gutter, medium));
|
||||
|
||||
@include flex-with-gap($spacing);
|
||||
flex-wrap: wrap;
|
||||
|
||||
> * {
|
||||
margin-bottom: $line-height;
|
||||
|
||||
@include breakpoint(medium) {
|
||||
width: calc(100% / 2 - #{$spacing});
|
||||
}
|
||||
|
||||
@include breakpoint(large) {
|
||||
width: calc(100% / 3 - #{$spacing});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
54
app/assets/stylesheets/budgets/executions/investment.scss
Normal file
54
app/assets/stylesheets/budgets/executions/investment.scss
Normal file
@@ -0,0 +1,54 @@
|
||||
.budget-executions-investment {
|
||||
@include card;
|
||||
border: 1px solid $border;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
display: block;
|
||||
|
||||
img {
|
||||
height: $line-height * 9;
|
||||
max-width: none;
|
||||
min-width: 100%;
|
||||
transition-duration: 0.3s;
|
||||
transition-property: transform;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
|
||||
img {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: $base-font-size;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.budget-execution-info {
|
||||
padding: calc(#{$line-height} / 2);
|
||||
}
|
||||
|
||||
.author {
|
||||
color: $text-medium;
|
||||
font-size: $small-font-size;
|
||||
}
|
||||
|
||||
.budget-execution-content {
|
||||
min-height: $line-height * 3;
|
||||
}
|
||||
|
||||
.price {
|
||||
color: $budget;
|
||||
font-size: rem-calc(24);
|
||||
}
|
||||
|
||||
&:hover:not(:focus-within) {
|
||||
box-shadow: 0 0 12px 0 rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
}
|
||||
@@ -1290,61 +1290,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.budget-execution {
|
||||
@include card;
|
||||
border: 1px solid $border;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
display: block;
|
||||
|
||||
img {
|
||||
height: $line-height * 9;
|
||||
max-width: none;
|
||||
min-width: 100%;
|
||||
transition-duration: 0.3s;
|
||||
transition-property: transform;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
|
||||
img {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: $base-font-size;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.budget-execution-info {
|
||||
padding: calc(#{$line-height} / 2);
|
||||
}
|
||||
|
||||
.author {
|
||||
color: $text-medium;
|
||||
font-size: $small-font-size;
|
||||
}
|
||||
|
||||
.budget-execution-content {
|
||||
min-height: $line-height * 3;
|
||||
}
|
||||
|
||||
.price {
|
||||
color: $budget;
|
||||
font-size: rem-calc(24);
|
||||
}
|
||||
|
||||
&:hover:not(:focus-within) {
|
||||
box-shadow: 0 0 12px 0 rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
// 07. Proposals successful
|
||||
// -------------------------
|
||||
|
||||
|
||||
11
app/components/budgets/executions/heading_component.html.erb
Normal file
11
app/components/budgets/executions/heading_component.html.erb
Normal file
@@ -0,0 +1,11 @@
|
||||
<div class="budgets-executions-heading">
|
||||
<h4 id="<%= heading.name.parameterize %>">
|
||||
<%= heading.name %> (<%= investments.count %>)
|
||||
</h4>
|
||||
|
||||
<div class="budgets-executions-heading-investments">
|
||||
<% investments.each do |investment| %>
|
||||
<%= render Budgets::Executions::InvestmentComponent.new(investment) %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
8
app/components/budgets/executions/heading_component.rb
Normal file
8
app/components/budgets/executions/heading_component.rb
Normal file
@@ -0,0 +1,8 @@
|
||||
class Budgets::Executions::HeadingComponent < ApplicationComponent
|
||||
attr_reader :heading, :investments
|
||||
|
||||
def initialize(heading, investments)
|
||||
@heading = heading
|
||||
@investments = investments
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,15 @@
|
||||
<div class="budget-executions-investment">
|
||||
<%= render Budgets::Executions::ImageComponent.new(investment) %>
|
||||
<div class="budget-execution-info">
|
||||
<div class="budget-execution-content">
|
||||
<h5>
|
||||
<%= link_to investment.title,
|
||||
polymorphic_path(investment, anchor: "tab-milestones") %>
|
||||
</h5>
|
||||
<span class="author"><%= investment.author.name %></span>
|
||||
</div>
|
||||
<p class="price margin-top text-center">
|
||||
<strong><%= investment.formatted_price %></strong>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,7 @@
|
||||
class Budgets::Executions::InvestmentComponent < ApplicationComponent
|
||||
attr_reader :investment
|
||||
|
||||
def initialize(investment)
|
||||
@investment = investment
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,3 @@
|
||||
<% investments_by_heading.each do |heading, investments| %>
|
||||
<%= render Budgets::Executions::HeadingComponent.new(heading, investments) %>
|
||||
<% end %>
|
||||
@@ -0,0 +1,7 @@
|
||||
class Budgets::Executions::InvestmentsComponent < ApplicationComponent
|
||||
attr_reader :investments_by_heading
|
||||
|
||||
def initialize(investments_by_heading)
|
||||
@investments_by_heading = investments_by_heading
|
||||
end
|
||||
end
|
||||
@@ -1,26 +0,0 @@
|
||||
<% @investments_by_heading.each do |heading, investments| %>
|
||||
<h4 id="<%= heading.name.parameterize %>">
|
||||
<%= heading.name %> (<%= investments.count %>)
|
||||
</h4>
|
||||
<div class="row" data-equalizer-on="medium" data-equalizer>
|
||||
<% investments.each do |investment| %>
|
||||
<div class="small-12 medium-6 large-4 column end margin-bottom">
|
||||
<div class="budget-execution" data-equalizer-watch>
|
||||
<%= render Budgets::Executions::ImageComponent.new(investment) %>
|
||||
<div class="budget-execution-info">
|
||||
<div class="budget-execution-content">
|
||||
<h5>
|
||||
<%= link_to investment.title,
|
||||
budget_investment_path(@budget, investment, anchor: "tab-milestones") %>
|
||||
</h5>
|
||||
<span class="author"><%= investment.author.name %></span>
|
||||
</div>
|
||||
<p class="price margin-top text-center">
|
||||
<strong><%= investment.formatted_price %></strong>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
@@ -45,7 +45,7 @@
|
||||
<%= render Budgets::Executions::FiltersComponent.new(@budget, @statuses) %>
|
||||
|
||||
<% if @investments_by_heading.any? %>
|
||||
<%= render "budgets/executions/investments" %>
|
||||
<%= render Budgets::Executions::InvestmentsComponent.new(@investments_by_heading) %>
|
||||
<% else %>
|
||||
<div class="callout primary clear">
|
||||
<%= t("budgets.executions.no_winner_investments") %>
|
||||
|
||||
@@ -1,13 +1,50 @@
|
||||
require "rails_helper"
|
||||
|
||||
describe Budgets::Executions::ImageComponent do
|
||||
let(:component) { Budgets::Executions::ImageComponent.new(investment) }
|
||||
|
||||
context "investment with image" do
|
||||
let(:investment) { create(:budget_investment, :with_image) }
|
||||
|
||||
it "shows a milestone image if available" do
|
||||
create(:milestone, :with_image, image_title: "Building in progress", milestoneable: investment)
|
||||
|
||||
render_inline component
|
||||
|
||||
expect(page).to have_css "img[alt='Building in progress']"
|
||||
expect(page).not_to have_css "img[alt='#{investment.image.title}']"
|
||||
end
|
||||
|
||||
it "shows the investment image if no milestone image is available" do
|
||||
create(:milestone, :with_image, image_title: "Not related", milestoneable: create(:budget_investment))
|
||||
|
||||
render_inline component
|
||||
|
||||
expect(page).to have_css "img[alt='#{investment.image.title}']"
|
||||
expect(page).not_to have_css "img[alt='Not related']"
|
||||
end
|
||||
|
||||
it "shows the last milestone's image if the investment has multiple milestones with images associated" do
|
||||
create(:milestone, milestoneable: investment)
|
||||
create(:milestone, :with_image, image_title: "First image", milestoneable: investment)
|
||||
create(:milestone, :with_image, image_title: "Second image", milestoneable: investment)
|
||||
create(:milestone, milestoneable: investment)
|
||||
|
||||
render_inline component
|
||||
|
||||
expect(page).to have_css "img[alt='Second image']"
|
||||
expect(page).not_to have_css "img[alt='First image']"
|
||||
expect(page).not_to have_css "img[alt='#{investment.image.title}']"
|
||||
end
|
||||
end
|
||||
|
||||
context "investment and milestone without image" do
|
||||
let(:component) { Budgets::Executions::ImageComponent.new(Budget::Investment.new) }
|
||||
let(:investment) { Budget::Investment.new(title: "New and empty") }
|
||||
|
||||
it "shows the default image" do
|
||||
render_inline component
|
||||
|
||||
expect(page).to have_css "img[src*='budget_execution_no_image']"
|
||||
expect(page).to have_css "img[src*='budget_execution_no_image'][alt='New and empty']"
|
||||
end
|
||||
|
||||
it "shows a custom default image when available" do
|
||||
@@ -18,7 +55,7 @@ describe Budgets::Executions::ImageComponent do
|
||||
|
||||
render_inline component
|
||||
|
||||
expect(page).to have_css "img[src$='logo_header-260x80.png']"
|
||||
expect(page).to have_css "img[src$='logo_header-260x80.png'][alt='New and empty']"
|
||||
expect(page).not_to have_css "img[src*='budget_execution_no_image']"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -83,31 +83,6 @@ describe "Executions" do
|
||||
end
|
||||
|
||||
context "Images" do
|
||||
scenario "renders milestone image if available" do
|
||||
milestone1 = create(:milestone, :with_image, milestoneable: investment1)
|
||||
|
||||
visit budget_path(budget)
|
||||
|
||||
click_link "See results"
|
||||
click_link "Milestones"
|
||||
|
||||
expect(page).to have_content(investment1.title)
|
||||
expect(page).to have_css("img[alt='#{milestone1.image.title}']")
|
||||
end
|
||||
|
||||
scenario "renders investment image if no milestone image is available" do
|
||||
create(:milestone, milestoneable: investment2)
|
||||
create(:image, imageable: investment2)
|
||||
|
||||
visit budget_path(budget)
|
||||
|
||||
click_link "See results"
|
||||
click_link "Milestones"
|
||||
|
||||
expect(page).to have_content(investment2.title)
|
||||
expect(page).to have_css("img[alt='#{investment2.image.title}']")
|
||||
end
|
||||
|
||||
scenario "renders default image if no milestone nor investment images are available" do
|
||||
create(:milestone, milestoneable: investment4)
|
||||
|
||||
@@ -116,23 +91,8 @@ describe "Executions" do
|
||||
click_link "See results"
|
||||
click_link "Milestones"
|
||||
|
||||
expect(page).to have_content(investment4.title)
|
||||
expect(page).to have_css("img[alt='#{investment4.title}']")
|
||||
end
|
||||
|
||||
scenario "renders last milestone's image if investment has multiple milestones with images associated" do
|
||||
create(:milestone, milestoneable: investment1)
|
||||
create(:milestone, :with_image, image_title: "First image", milestoneable: investment1)
|
||||
create(:milestone, :with_image, image_title: "Second image", milestoneable: investment1)
|
||||
create(:milestone, milestoneable: investment1)
|
||||
|
||||
visit budget_path(budget)
|
||||
|
||||
click_link "See results"
|
||||
click_link "Milestones"
|
||||
|
||||
expect(page).to have_content(investment1.title)
|
||||
expect(page).to have_css("img[alt='Second image']")
|
||||
expect(page).to have_content investment4.title
|
||||
expect(page).to have_css "img[alt='#{investment4.title}']"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -294,7 +254,7 @@ describe "Executions" do
|
||||
|
||||
visit budget_executions_path(budget)
|
||||
|
||||
expect(page).to have_css(".budget-execution", count: 3)
|
||||
expect(page).to have_css(".budget-executions-investment", count: 3)
|
||||
expect(a_heading.name).to appear_before(m_heading.name)
|
||||
expect(m_heading.name).to appear_before(z_heading.name)
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user