Merge branch 'master' into feature/budget_phases

This commit is contained in:
BertoCQ
2018-01-16 17:47:47 +01:00
committed by GitHub
26 changed files with 166 additions and 76 deletions

View File

@@ -26,6 +26,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Improve budget investment form https://github.com/consul/consul/pull/2280
- Prevent edition of investments if budget is in the final phase https://github.com/consul/consul/pull/2223
- Split 'routes.rb' file into multiple small files https://github.com/consul/consul/pull/1908
- Design Improvements https://github.com/consul/consul/pull/2327
### Deprecated
- Budget's `description_*` columns will be erased from database in next release. Please run rake task `budgets:phases:generate_missing` to migrate them. Details at Warning section of https://github.com/consul/consul/pull/2323

View File

@@ -20,7 +20,7 @@ gem 'devise_security_extension', '~> 0.10.0'
gem 'foundation-rails', '~> 6.2.4.0'
gem 'foundation_rails_helper', '~> 2.0.0'
gem 'graphiql-rails', '~> 1.4.1'
gem 'graphql', '~> 1.7.7'
gem 'graphql', '~> 1.7.8'
gem 'groupdate', '~> 3.2.0'
gem 'initialjs-rails', '~> 0.2.0.5'
gem 'invisible_captcha', '~> 0.10.0'
@@ -44,7 +44,7 @@ gem 'rollbar', '~> 2.15.5'
gem 'rubyzip', '~> 1.2.0'
gem 'sass-rails', '~> 5.0', '>= 5.0.4'
gem 'savon', '~> 2.11.1'
gem 'sitemap_generator', '~> 6.0.0'
gem 'sitemap_generator', '~> 6.0.1'
gem 'social-share-button', '~> 1.1'
gem 'sprockets', '~> 3.7.1'
gem 'turbolinks', '~> 2.5.3'
@@ -66,7 +66,7 @@ group :development, :test do
gem 'i18n-tasks', '~> 0.9.15'
gem 'knapsack_pro', '~> 0.53.0'
gem 'launchy', '~> 2.4.3'
gem 'letter_opener_web', '~> 1.3.1'
gem 'letter_opener_web', '~> 1.3.2'
gem 'quiet_assets', '~> 1.1.0'
gem 'spring', '~> 2.0.1'
gem 'spring-commands-rspec', '~> 1.0.4'

View File

@@ -522,7 +522,7 @@ DEPENDENCIES
foundation-rails (~> 6.2.4.0)
foundation_rails_helper (~> 2.0.0)
graphiql-rails (~> 1.4.1)
graphql (~> 1.7.7)
graphql (~> 1.7.8)
groupdate (~> 3.2.0)
i18n-tasks (~> 0.9.15)
initialjs-rails (~> 0.2.0.5)
@@ -533,7 +533,7 @@ DEPENDENCIES
kaminari (~> 1.1.1)
knapsack_pro (~> 0.53.0)
launchy (~> 2.4.3)
letter_opener_web (~> 1.3.1)
letter_opener_web (~> 1.3.2)
mdl (~> 0.4.0)
newrelic_rpm (~> 4.1.0.333)
omniauth (~> 1.8.1)
@@ -561,7 +561,7 @@ DEPENDENCIES
sass-rails (~> 5.0, >= 5.0.4)
savon (~> 2.11.1)
scss_lint (~> 0.54.0)
sitemap_generator (~> 6.0.0)
sitemap_generator (~> 6.0.1)
social-share-button (~> 1.1)
spring (~> 2.0.1)
spring-commands-rspec (~> 1.0.4)

View File

@@ -83,4 +83,4 @@ App.Map =
toogleMap: ->
$('.map').toggle()
$('.location-map-remove-marker-button').toggle()
$('.js-location-map-remove-marker').toggle()

View File

@@ -22,6 +22,7 @@
// 20. Documents
// 21. Related content
// 22. Images
// 23. Maps
//
// 01. Global styles
@@ -2427,10 +2428,6 @@ table {
margin-bottom: 0 !important;
padding: $line-height / 2;
&:first-child {
border-top: 1px solid $border;
}
@include breakpoint(medium) {
.score-actions {
@@ -2439,6 +2436,10 @@ table {
}
}
&:first-child {
border-top: 1px solid $border;
}
&:hover {
background: #f9f9f9;
@@ -2478,8 +2479,8 @@ table {
position: relative;
text-decoration: none;
&.score-positive:before,
&.score-negative:before {
&.score-positive::before,
&.score-negative::before {
font-family: 'icons';
left: 0;
position: absolute;
@@ -2488,7 +2489,7 @@ table {
&.score-positive {
color: $color-success;
&:before {
&::before {
color: $color-success;
content: '\6c';
}
@@ -2497,7 +2498,7 @@ table {
&.score-negative {
color: $color-alert;
&:before {
&::before {
color: $color-alert;
content: '\76';
}
@@ -2511,3 +2512,28 @@ table {
.images .button {
margin-top: $line-height / 2;
}
// 23. Maps
// -----------------
.location-map-remove-marker {
border-bottom: 1px dotted #cf2a0e;
color: $delete;
display: inline-block;
margin-top: $line-height / 2;
&:hover,
&:active,
&:focus {
border-bottom: 1px solid #cf2a0e;
color: #cf2a0e;
text-decoration: none;
}
}
.leaflet-bar a {
&.leaflet-disabled {
color: #525252 !important;
}
}

View File

@@ -339,6 +339,7 @@
.topic-show,
.milestone-content {
h1,
p {
word-wrap: break-word;
}

View File

@@ -2,7 +2,7 @@ class Admin::BudgetsController < Admin::BaseController
include FeatureFlags
feature_flag :budgets
has_filters %w{current finished}, only: :index
has_filters %w{open finished}, only: :index
load_and_authorize_resource

View File

@@ -25,6 +25,7 @@ class ApplicationController < ActionController::Base
layout :set_layout
respond_to :html
helper_method :current_budget
private
@@ -120,4 +121,8 @@ class ApplicationController < ActionController::Base
params[:filter] ||= "selected"
end
end
def current_budget
Budget.current
end
end

View File

@@ -19,7 +19,7 @@ class Management::BudgetsController < Management::BaseController
end
def print_investments
@budgets = Budget.current.order(created_at: :desc).page(params[:page])
@budget = Budget.current
end
private

View File

@@ -5,10 +5,10 @@ class Valuation::BudgetsController < Valuation::BaseController
load_and_authorize_resource
def index
@budgets = @budgets.current.order(created_at: :desc).page(params[:page])
@investments_with_valuation_open = {}
@budgets.each do |b|
@investments_with_valuation_open[b.id] = b.investments
@budget = Budget.current
if @budget.present?
@investments_with_valuation_open = {}
@investments_with_valuation_open = @budget.investments
.by_valuator(current_user.valuator.try(:id))
.valuation_open
.count

View File

@@ -34,11 +34,11 @@ module MapLocationsHelper
end
def map_location_remove_marker(map_location, text)
content_tag :div, class: "text-right" do
content_tag :div, class: "margin-bottom" do
content_tag :a,
id: map_location_remove_marker_link_id(map_location),
href: "#",
class: "location-map-remove-marker-button delete" do
class: "js-location-map-remove-marker location-map-remove-marker" do
text
end
end

View File

@@ -29,7 +29,12 @@ class Budget < ActiveRecord::Base
scope :balloting, -> { where(phase: "balloting") }
scope :reviewing_ballots, -> { where(phase: "reviewing_ballots") }
scope :finished, -> { where(phase: "finished") }
scope :current, -> { where.not(phase: "finished") }
scope :open, -> { where.not(phase: "finished") }
def self.current
where.not(phase: "drafting").last
end
def current_phase
phases.send(phase)
@@ -99,10 +104,6 @@ class Budget < ActiveRecord::Base
balloting_process? || finished?
end
def current?
!finished?
end
def heading_price(heading)
heading_ids.include?(heading.id) ? heading.price : -1
end

View File

@@ -4,7 +4,7 @@
<% if @investments.any? %>
<h3 class="inline-block"><%= page_entries_info @investments %></h3>
<table>
<table class="table-for-mobile">
<thead>
<tr>
<th><%= t("admin.budget_investments.index.table_id") %></th>

View File

@@ -1,12 +1,10 @@
<table>
<% @budgets.each do |budget| %>
<tr id="<%= dom_id(budget) %>">
<td><%= budget.name %></td>
<td><%= budget.translated_phase %></td>
<tr id="<%= dom_id(@budget) %>">
<td><%= @budget.name %></td>
<td><%= @budget.translated_phase %></td>
<td align="right">
<%= link_to t("management.budgets.print_investments"),
print_management_budget_investments_path(budget) %>
print_management_budget_investments_path(@budget) %>
</td>
</tr>
<% end %>
</table>

View File

@@ -1,7 +1,5 @@
<h2 class="inline-block"><%= t("valuation.budgets.index.title") %></h2>
<h3><%= page_entries_info @budgets %></h3>
<table>
<thead>
<tr>
@@ -12,25 +10,21 @@
</tr>
</thead>
<tbody>
<% @budgets.each do |budget| %>
<tr id="<%= dom_id(budget) %>" class="budget">
<td>
<%= budget.name %>
</td>
<td>
<%= t("budgets.phase.#{budget.phase}") %>
</td>
<td>
<%= @investments_with_valuation_open[budget.id] %>
</td>
<td>
<%= link_to t("valuation.budgets.index.evaluate"),
valuation_budget_budget_investments_path(budget_id: budget.id),
class: "button hollow expanded" %>
</td>
</tr>
<% end %>
<tr id="<%= dom_id(@budget) %>" class="budget">
<td>
<%= @budget.name %>
</td>
<td>
<%= t("budgets.phase.#{@budget.phase}") %>
</td>
<td>
<%= @investments_with_valuation_open %>
</td>
<td>
<%= link_to t("valuation.budgets.index.evaluate"),
valuation_budget_budget_investments_path(budget_id: @budget.id),
class: "button hollow expanded" %>
</td>
</tr>
</tbody>
</table>
<%= paginate @budgets %>

View File

@@ -117,8 +117,8 @@ en:
external_url: "Link to additional documentation"
heading_id: "Heading"
title: "Title"
location: "Location"
organization_name: "If you are proposing in the name of a collective/organization, write its name"
location: "Location (optional)"
organization_name: "If you are proposing in the name of a collective/organization, or on behalf of more people, write its name"
image: "Proposal descriptive image"
image_title: "Image title"
budget/investment/milestone:

View File

@@ -104,7 +104,7 @@ en:
unfeasibility_explanation: Unfeasibility explanation
code_html: 'Investment project code: <strong>%{code}</strong>'
location_html: 'Location: <strong>%{location}</strong>'
organization_name_html: 'Organization: <strong>%{name}</strong>'
organization_name_html: 'Proposed on behalf of: <strong>%{name}</strong>'
share: Share
title: Investment project
supports: Supports

View File

@@ -113,7 +113,7 @@ es:
external_url: "Enlace a documentación adicional"
location: "Ubicación"
administrator_id: "Administrador"
organization_name: "Si estás proponiendo en nombre de una organización o colectivo, escribe su nombre"
organization_name: "Si estás proponiendo en nombre de una organización o colectivo, o en nombre de más gente, escribe su nombre"
image: "Imagen descriptiva de la propuesta de inversión"
image_title: "Título de la imagen"
budget/heading:

View File

@@ -59,7 +59,7 @@ es:
tags_placeholder: "Escribe las etiquetas que desees separadas por una coma (',')"
map_location: "Ubicación en el mapa"
map_location_instructions: "Navega por el mapa hasta la ubicación y coloca el marcador."
map_remove_marker: "Eliminar el marcador"
map_remove_marker: "Eliminar marcador en el mapa"
location: "Información adicional de la ubicación"
index:
title: Presupuestos participativos
@@ -104,7 +104,7 @@ es:
unfeasibility_explanation: Informe de inviabilidad
code_html: 'Código propuesta de gasto: <strong>%{code}</strong>'
location_html: 'Ubicación: <strong>%{location}</strong>'
organization_name_html: 'Organización: <strong>%{name}</strong>'
organization_name_html: 'Propuesto en nombre de: <strong>%{name}</strong>'
share: Compartir
title: Proyecto de inversión
supports: Apoyos

View File

@@ -338,7 +338,7 @@ es:
tags_placeholder: "Escribe las etiquetas que desees separadas por una coma (',')"
map_location: "Ubicación en el mapa"
map_location_instructions: "Navega por el mapa hasta la ubicación y coloca el marcador."
map_remove_marker: "Eliminar el marcador"
map_remove_marker: "Eliminar marcador en el mapa"
map_skip_checkbox: "Esta propuesta no tiene una ubicación concreta o no la conozco."
index:
featured_proposals: Destacadas

View File

@@ -17,11 +17,11 @@ apis: &apis
http_basic_auth: &http_basic_auth
http_basic_auth: true
development:
http_basic_username: "dev"
http_basic_password: "pass"
<<: *default
<<: *maps
test:
<<: *default

View File

@@ -0,0 +1,19 @@
require 'rails_helper'
describe ApplicationController do
describe "#current_budget" do
it "returns the last budget that is not in draft phase" do
old_budget = create(:budget, phase: "finished", created_at: 2.years.ago)
previous_budget = create(:budget, phase: "accepting", created_at: 1.year.ago)
current_budget = create(:budget, phase: "accepting", created_at: 1.month.ago)
next_budget = create(:budget, phase: "drafting", created_at: 1.week.ago)
budget = subject.instance_eval{ current_budget }
expect(budget).to eq(current_budget)
end
end
end

View File

@@ -259,9 +259,10 @@ feature 'Budget Investments' do
context "Printing" do
scenario 'Printing budget investments' do
16.times { create(:budget_investment, budget: @budget) }
16.times { create(:budget_investment, budget: @budget, heading: @heading) }
click_link "Print Budget Investments"
expect(page).to have_content(@budget.name)
within "#budget_#{@budget.id}" do
click_link "Print Budget Investments"
@@ -273,15 +274,17 @@ feature 'Budget Investments' do
scenario "Filtering budget investments by heading to be printed", :js do
district_9 = create(:budget_heading, group: @group, name: "District Nine")
another_heading = create(:budget_heading, group: @group)
low_investment = create(:budget_investment, budget: @budget, title: 'Nuke district 9', heading: district_9, cached_votes_up: 1)
mid_investment = create(:budget_investment, budget: @budget, title: 'Change district 9', heading: district_9, cached_votes_up: 10)
top_investment = create(:budget_investment, budget: @budget, title: 'Destroy district 9', heading: district_9, cached_votes_up: 100)
unvoted_investment = create(:budget_investment, budget: @budget, title: 'Add new districts to the city')
unvoted_investment = create(:budget_investment, budget: @budget, heading: another_heading, title: 'Add new districts to the city')
user = create(:user, :level_two)
login_managed_user(user)
click_link "Print Budget Investments"
expect(page).to have_content(@budget.name)
within "#budget_#{@budget.id}" do
click_link "Print Budget Investments"

View File

@@ -24,18 +24,15 @@ feature 'Valuation budgets' do
end
scenario 'Filters by phase' do
budget1 = create(:budget)
budget2 = create(:budget, :accepting)
budget3 = create(:budget, :selecting)
budget4 = create(:budget, :balloting)
budget5 = create(:budget, :finished)
budget1 = create(:budget, :finished)
budget2 = create(:budget, :finished)
budget3 = create(:budget, :accepting)
visit valuation_budgets_path
expect(page).to have_content(budget1.name)
expect(page).to have_content(budget2.name)
expect(page).to_not have_content(budget1.name)
expect(page).to_not have_content(budget2.name)
expect(page).to have_content(budget3.name)
expect(page).to have_content(budget4.name)
expect(page).not_to have_content(budget5.name)
end
end

View File

@@ -66,6 +66,8 @@ feature 'Valuation' do
scenario 'Access as a valuator is authorized' do
create(:valuator, user: user)
create(:budget)
login_as(user)
visit root_path
@@ -78,6 +80,8 @@ feature 'Valuation' do
scenario 'Access as an administrator is authorized' do
create(:administrator, user: user)
create(:budget)
login_as(user)
visit root_path
@@ -90,6 +94,8 @@ feature 'Valuation' do
scenario "Valuation access links" do
create(:valuator, user: user)
create(:budget)
login_as(user)
visit root_path
@@ -100,6 +106,8 @@ feature 'Valuation' do
scenario 'Valuation dashboard' do
create(:valuator, user: user)
create(:budget)
login_as(user)
visit root_path

View File

@@ -118,6 +118,43 @@ describe Budget do
end
end
describe "#current" do
it "returns nil if there is only one budget and it is still in drafting phase" do
budget = create(:budget, phase: "drafting")
expect(Budget.current).to eq(nil)
end
it "returns the budget if there is only one and not in drafting phase" do
budget = create(:budget, phase: "accepting")
expect(Budget.current).to eq(budget)
end
it "returns the last budget created that is not in drafting phase" do
old_budget = create(:budget, phase: "finished", created_at: 2.years.ago)
previous_budget = create(:budget, phase: "accepting", created_at: 1.year.ago)
current_budget = create(:budget, phase: "accepting", created_at: 1.month.ago)
next_budget = create(:budget, phase: "drafting", created_at: 1.week.ago)
expect(Budget.current).to eq(current_budget)
end
end
describe "#open" do
it "returns all budgets that are not in the finished phase" do
phases = Budget::PHASES - ["finished"]
phases.each do |phase|
budget = create(:budget, phase: phase)
expect(Budget.open).to include(budget)
end
end
end
describe "heading_price" do
let(:group) { create(:budget_group, budget: budget) }