fixes conflicts with master
This commit is contained in:
@@ -168,7 +168,7 @@ body.admin {
|
||||
clear: both;
|
||||
|
||||
.checkbox {
|
||||
font-size: rem-calc(12);
|
||||
font-size: $small-font-size;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -378,39 +378,59 @@ header {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
color: white;
|
||||
display: inline-block;
|
||||
line-height: rem-calc(46);
|
||||
position: relative;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
|
||||
@media (min-width: $small-breakpoint) {
|
||||
color: $text;
|
||||
font-weight: bold;
|
||||
margin-right: $line-height*1.5;
|
||||
margin-right: 12px\9;
|
||||
width: auto;
|
||||
|
||||
&:hover {
|
||||
color: $link;
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: white;
|
||||
ul {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
|
||||
li {
|
||||
@media (min-width: $small-breakpoint) {
|
||||
border-bottom: 2px solid $brand;
|
||||
color: $brand;
|
||||
display: inline-block;
|
||||
margin-right: rem-calc(36);
|
||||
}
|
||||
|
||||
a {
|
||||
color: white;
|
||||
display: inline-block;
|
||||
line-height: $line-height*2;
|
||||
position: relative;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
|
||||
@media (min-width: $small-breakpoint) {
|
||||
color: $text;
|
||||
display: block;
|
||||
font-weight: bold;
|
||||
margin-left: 18px\9;
|
||||
margin-right: 18px\9;
|
||||
width: auto;
|
||||
|
||||
&:hover {
|
||||
color: $link;
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: white;
|
||||
|
||||
@media (min-width: $small-breakpoint) {
|
||||
border-bottom: 2px solid $brand;
|
||||
color: $brand;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
color: $border;
|
||||
}
|
||||
|
||||
.input-group {
|
||||
margin-bottom: 0;
|
||||
padding-top: $line-height/4;
|
||||
|
||||
@media (min-width: $small-breakpoint) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.input-group-field {
|
||||
@@ -606,6 +626,12 @@ form.locale-form {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
|
||||
label {
|
||||
color: white;
|
||||
font-size: $small-font-size;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
select {
|
||||
background-image: image-url("language_select.png");
|
||||
background-origin: border-box;
|
||||
@@ -628,6 +654,7 @@ form.locale-form {
|
||||
outline: none;
|
||||
padding-left: rem-calc(3);
|
||||
padding-right: $line-height;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -641,6 +668,10 @@ form {
|
||||
line-height: $line-height;
|
||||
}
|
||||
|
||||
fieldset legend {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
input, textarea {
|
||||
height: 48px\9;
|
||||
line-height: 48px\9;
|
||||
@@ -648,13 +679,28 @@ form {
|
||||
width: 100%\9;
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
input[type="checkbox"],
|
||||
input[type="radio"] {
|
||||
height: auto\9;
|
||||
line-height: inherit\9;
|
||||
width: auto\9;
|
||||
}
|
||||
|
||||
input[type]:not([type=submit]):not([type=file]):not([type=checkbox]) {
|
||||
input[type="radio"] {
|
||||
height: $line-height !important;
|
||||
vertical-align: top;
|
||||
width: 18px\9;
|
||||
|
||||
+ label {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
&:checked + label {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
input[type]:not([type=submit]):not([type=file]):not([type=checkbox]):not([type=radio]) {
|
||||
background: $input-bg;
|
||||
height: $line-height*2;
|
||||
margin-bottom: rem-calc(16);
|
||||
@@ -1035,10 +1081,15 @@ img.avatar, img.admin-avatar, img.moderator-avatar, img.initialjs-avatar {
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
table {
|
||||
border: $border;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
width: 100%;
|
||||
|
||||
th {
|
||||
background: #f8f9fb;
|
||||
}
|
||||
|
||||
tr {
|
||||
|
||||
td {
|
||||
@@ -1047,7 +1098,11 @@ table {
|
||||
}
|
||||
|
||||
&:nth-child(odd) {
|
||||
background: #F0F2F6;
|
||||
background: white;
|
||||
}
|
||||
|
||||
&:nth-child(even) {
|
||||
background: #fafcfb;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
15
app/controllers/valuation/base_controller.rb
Normal file
15
app/controllers/valuation/base_controller.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
class Valuation::BaseController < ApplicationController
|
||||
layout 'admin'
|
||||
|
||||
before_action :authenticate_user!
|
||||
before_action :verify_valuator
|
||||
|
||||
skip_authorization_check
|
||||
|
||||
private
|
||||
|
||||
def verify_valuator
|
||||
raise CanCan::AccessDenied unless current_user.try(:valuator?) || current_user.try(:administrator?)
|
||||
end
|
||||
|
||||
end
|
||||
38
app/controllers/valuation/spending_proposals_controller.rb
Normal file
38
app/controllers/valuation/spending_proposals_controller.rb
Normal file
@@ -0,0 +1,38 @@
|
||||
class Valuation::SpendingProposalsController < Valuation::BaseController
|
||||
include FeatureFlags
|
||||
feature_flag :spending_proposals
|
||||
|
||||
before_action :restrict_access_to_assigned_items, only: [:show, :edit, :valuate]
|
||||
|
||||
has_filters %w{valuating valuation_finished}, only: :index
|
||||
|
||||
load_and_authorize_resource
|
||||
|
||||
def index
|
||||
if current_user.valuator?
|
||||
@spending_proposals = SpendingProposal.search(params_for_current_valuator, @current_filter).order(created_at: :desc).page(params[:page])
|
||||
else
|
||||
@spending_proposals = SpendingProposal.none.page(params[:page])
|
||||
end
|
||||
end
|
||||
|
||||
def valuate
|
||||
@spending_proposal.update_attributes(valuation_params)
|
||||
redirect_to valuation_spending_proposal_path(@spending_proposal), notice: t('valuation.spending_proposals.notice.valuate')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def valuation_params
|
||||
params.require(:spending_proposal).permit(:price, :price_first_year, :price_explanation, :feasible, :feasible_explanation, :time_scope, :valuation_finished, :internal_comments)
|
||||
end
|
||||
|
||||
def params_for_current_valuator
|
||||
params.merge({valuator_id: current_user.valuator.id})
|
||||
end
|
||||
|
||||
def restrict_access_to_assigned_items
|
||||
raise ActionController::RoutingError.new('Not Found') unless current_user.administrator? || ValuationAssignment.exists?(spending_proposal_id: params[:id], valuator_id: current_user.valuator.id)
|
||||
end
|
||||
|
||||
end
|
||||
@@ -11,4 +11,8 @@ module TextWithLinksHelper
|
||||
Rinku.auto_link(html, :all, 'target="_blank" rel="nofollow"').html_safe
|
||||
end
|
||||
|
||||
def simple_format_no_tags_no_sanitize(html)
|
||||
simple_format(html, {}, sanitize: false)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
30
app/helpers/valuation_helper.rb
Normal file
30
app/helpers/valuation_helper.rb
Normal file
@@ -0,0 +1,30 @@
|
||||
module ValuationHelper
|
||||
|
||||
def valuator_select_options(valuator=nil)
|
||||
if valuator.present?
|
||||
Valuator.where.not(id: valuator.id).order('users.username asc').includes(:user).collect { |v| [ v.name, v.id ] }.prepend([valuator.name, valuator.id])
|
||||
else
|
||||
Valuator.all.order('users.username asc').includes(:user).collect { |v| [ v.name, v.id ] }
|
||||
end
|
||||
end
|
||||
|
||||
def assigned_valuators_info(valuators)
|
||||
case valuators.size
|
||||
when 0
|
||||
t("valuation.spending_proposals.index.no_valuators_assigned")
|
||||
when 1
|
||||
"<span title=\"#{t('valuation.spending_proposals.index.valuators_assigned', count: 1)}\">".html_safe +
|
||||
valuators.first.name +
|
||||
"</span>".html_safe
|
||||
else
|
||||
"<span title=\"".html_safe + valuators.map(&:name).join(', ') + "\">".html_safe +
|
||||
t('valuation.spending_proposals.index.valuators_assigned', count: valuators.size) +
|
||||
"</span>".html_safe
|
||||
end
|
||||
end
|
||||
|
||||
def explanation_field(field)
|
||||
simple_format_no_tags_no_sanitize(safe_html_with_links(field.html_safe)) if field.present?
|
||||
end
|
||||
|
||||
end
|
||||
@@ -4,6 +4,7 @@ module Abilities
|
||||
|
||||
def initialize(user)
|
||||
self.merge Abilities::Moderation.new(user)
|
||||
self.merge Abilities::Valuator.new(user)
|
||||
|
||||
can :restore, Comment
|
||||
cannot :restore, Comment, hidden_at: nil
|
||||
|
||||
@@ -36,6 +36,7 @@ class SpendingProposal < ActiveRecord::Base
|
||||
results = results.by_geozone(params[:geozone_id]) if params[:geozone_id].present?
|
||||
results = results.by_administrator(params[:administrator_id]) if params[:administrator_id].present?
|
||||
results = results.by_tag(params[:tag_name]) if params[:tag_name].present?
|
||||
results = results.by_valuator(params[:valuator_id]) if params[:valuator_id].present?
|
||||
results = results.send(current_filter) if current_filter.present?
|
||||
results.for_render
|
||||
end
|
||||
@@ -52,10 +53,15 @@ class SpendingProposal < ActiveRecord::Base
|
||||
where(administrator_id: administrator.presence)
|
||||
end
|
||||
|
||||
|
||||
def self.by_tag(tag_name)
|
||||
tagged_with(tag_name)
|
||||
end
|
||||
|
||||
def self.by_valuator(valuator)
|
||||
joins(:valuation_assignments).includes(:valuators).where("valuation_assignments.valuator_id = ?", valuator.presence)
|
||||
end
|
||||
|
||||
def feasibility
|
||||
case feasible
|
||||
when true
|
||||
|
||||
@@ -76,6 +76,10 @@
|
||||
<p><strong><%= t("admin.spending_proposals.show.price") %> (<%= t("admin.spending_proposals.show.currency") %>):</strong>
|
||||
<%= @spending_proposal.price.present? ? @spending_proposal.price : t("admin.spending_proposals.show.undefined") %>
|
||||
</p>
|
||||
<p><strong><%= t("admin.spending_proposals.show.price_first_year") %> (<%= t("admin.spending_proposals.show.currency") %>):</strong>
|
||||
<%= @spending_proposal.price_first_year.present? ? @spending_proposal.price_first_year : t("admin.spending_proposals.show.undefined") %>
|
||||
</p>
|
||||
|
||||
<%= simple_format(safe_html_with_links(@spending_proposal.price_explanation.html_safe), {}, sanitize: false) if @spending_proposal.price_explanation.present? %>
|
||||
|
||||
<p><strong><%= t("admin.spending_proposals.show.feasibility") %>:</strong>
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
<div class="small-12 medium-3 column">
|
||||
|
||||
<aside class="margin-bottom" role="complementary">
|
||||
<aside class="margin-bottom">
|
||||
<%= link_to t("debates.index.start_debate"), new_debate_path, class: 'button expanded' %>
|
||||
<%= render "shared/tag_cloud", taggable: 'debate' %>
|
||||
</aside>
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
<% if user_signed_in? %>
|
||||
<li>
|
||||
<%= link_to notifications_path, class: "notifications" do %>
|
||||
<%= link_to notifications_path, class: "notifications", accesskey: "n" do %>
|
||||
<% if current_user.notifications_count > 0 %>
|
||||
<i class="icon-circle"></i>
|
||||
<i class="icon-notification" title="<%= t('layouts.header.new_notifications', count: current_user.notifications_count).html_safe %>">
|
||||
<i class="icon-circle" aria-hidden="true"></i>
|
||||
<i class="icon-notification" aria-hidden="true" title="<%= t('layouts.header.new_notifications', count: current_user.notifications_count).html_safe %>">
|
||||
</i>
|
||||
<% else %>
|
||||
<i class="icon-no-notification" title="<%= t('layouts.header.no_notifications') %>"></i>
|
||||
<i class="icon-no-notification" aria-hidden="true" title="<%= t('layouts.header.no_notifications') %>"></i>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</li>
|
||||
<li>
|
||||
<%= link_to(t("layouts.header.my_activity_link"), user_path(current_user)) %>
|
||||
<%= link_to(t("layouts.header.my_activity_link"), user_path(current_user), accesskey: "a") %>
|
||||
</li>
|
||||
<li>
|
||||
<%= link_to(t("layouts.header.my_account_link"), account_path) %>
|
||||
<%= link_to(t("layouts.header.my_account_link"), account_path, accesskey: "m") %>
|
||||
</li>
|
||||
<li>
|
||||
<%= link_to(t("devise_views.menu.login_items.logout"), destroy_user_session_path, method: :delete) %>
|
||||
|
||||
@@ -1,82 +1,91 @@
|
||||
<footer>
|
||||
<div class="row-full">
|
||||
<div class="row">
|
||||
<div class="row">
|
||||
<div class="small-12 large-4 column">
|
||||
<h1 class="logo">
|
||||
<%= link_to t("layouts.header.open_gov", open: "#{t('layouts.header.open')}").html_safe %>
|
||||
</h1>
|
||||
|
||||
<div class="small-12 large-4 column">
|
||||
<h1 class="logo">
|
||||
<%= link_to t("layouts.header.open_gov", open: "#{t('layouts.header.open')}").html_safe %>
|
||||
</h1>
|
||||
|
||||
<p class="info">
|
||||
<%= t("layouts.footer.description",
|
||||
open_source: link_to(t("layouts.footer.open_source"), t("layouts.footer.open_source_url"), target: "blank"),
|
||||
consul: link_to(t("layouts.footer.consul"), t("layouts.footer.consul_url"), target: "blank")).html_safe
|
||||
%>
|
||||
<%= t("layouts.footer.contact_us") %>
|
||||
<%= link_to t("layouts.footer.faq"), page_path('faq') %>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="footer-sections small-12 large-8 column">
|
||||
<div class="small-12 medium-4 column">
|
||||
<h2>
|
||||
<%= link_to t("layouts.footer.participation_title"), root_path %>
|
||||
</h2>
|
||||
<p><%= t("layouts.footer.participation_text") %></p>
|
||||
</div>
|
||||
|
||||
<div class="small-12 medium-4 column">
|
||||
<h2>
|
||||
<%= link_to t("layouts.footer.transparency_title"), t("layouts.footer.transparency_url") %>
|
||||
</h2>
|
||||
<p><%= t("layouts.footer.transparency_text") %></p>
|
||||
</div>
|
||||
|
||||
<div class="small-12 medium-4 column">
|
||||
<h2>
|
||||
<%= link_to t("layouts.footer.open_data_title"), "/opendata" %>
|
||||
</h2>
|
||||
<p><%= t("layouts.footer.open_data_text") %></p>
|
||||
</div>
|
||||
</div>
|
||||
<p class="info">
|
||||
<%= t("layouts.footer.description",
|
||||
open_source: link_to(t("layouts.footer.open_source"), t("layouts.footer.open_source_url"), target: "blank"),
|
||||
consul: link_to(t("layouts.footer.consul"), t("layouts.footer.consul_url"), target: "blank")).html_safe
|
||||
%>
|
||||
<%= t("layouts.footer.contact_us") %>
|
||||
<%= link_to t("layouts.footer.faq"), page_path('faq') %>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="subfooter row">
|
||||
<div class="small-12 medium-9 column">
|
||||
<p>
|
||||
<%= t("layouts.footer.copyright", year: Time.now.year) %> |
|
||||
<%= link_to t("layouts.footer.more_info"), page_path('more_information') %> |
|
||||
<%= link_to t("layouts.footer.privacy"), page_path('privacy') %> |
|
||||
<%= link_to t("layouts.footer.conditions"), page_path('conditions') %> |
|
||||
<%= link_to t("layouts.footer.accessibility"), page_path('accessibility') %>
|
||||
</p>
|
||||
<div class="footer-sections small-12 large-8 column">
|
||||
<div class="small-12 medium-4 column">
|
||||
<h2>
|
||||
<%= link_to t("layouts.footer.participation_title"), root_path %>
|
||||
</h2>
|
||||
<p><%= t("layouts.footer.participation_text") %></p>
|
||||
</div>
|
||||
|
||||
<div class="small-12 medium-3 column social">
|
||||
<% if setting['twitter_handle'] %>
|
||||
<%= link_to "https://twitter.com/#{setting['twitter_handle']}", target: "_blank", title: t("social.twitter") do %>
|
||||
<span class="sr-only"><%= t("social.twitter") %></span>
|
||||
<i class="icon-twitter"></i>
|
||||
<div class="small-12 medium-4 column">
|
||||
<h2>
|
||||
<%= link_to t("layouts.footer.transparency_title"), t("layouts.footer.transparency_url") %>
|
||||
</h2>
|
||||
<p><%= t("layouts.footer.transparency_text") %></p>
|
||||
</div>
|
||||
|
||||
<div class="small-12 medium-4 column">
|
||||
<h2>
|
||||
<%= link_to t("layouts.footer.open_data_title"), "/opendata" %>
|
||||
</h2>
|
||||
<p><%= t("layouts.footer.open_data_text") %></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="subfooter row">
|
||||
<div class="small-12 medium-8 column">
|
||||
<p>
|
||||
<%= t("layouts.footer.copyright", year: Time.now.year) %> |
|
||||
<%= link_to t("layouts.footer.more_info"), page_path('more_information') %> |
|
||||
<%= link_to t("layouts.footer.privacy"), page_path('privacy') %> |
|
||||
<%= link_to t("layouts.footer.conditions"), page_path('conditions') %> |
|
||||
<%= link_to t("layouts.footer.accessibility"), page_path('accessibility') %>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="small-12 medium-4 column social">
|
||||
<div class="text-right">
|
||||
<ul>
|
||||
<% if setting['twitter_handle'] %>
|
||||
<li class="inline-block">
|
||||
<%= link_to "https://twitter.com/#{setting['twitter_handle']}", target: "_blank", title: t("social.twitter") do %>
|
||||
<span class="sr-only"><%= t("social.twitter") %></span>
|
||||
<i class="icon-twitter" aria-hidden="true"></i>
|
||||
<% end %>
|
||||
</li>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% if setting['facebook_handle'] %>
|
||||
<%= link_to "https://www.facebook.com/#{setting['facebook_handle']}/", target: "_blank", title: t("social.facebook") do %>
|
||||
<span class="sr-only"><%= t("social.facebook") %></span>
|
||||
<i class="icon-facebook"></i>
|
||||
<% if setting['facebook_handle'] %>
|
||||
<li class="inline-block">
|
||||
<%= link_to "https://www.facebook.com/#{setting['facebook_handle']}/", target: "_blank", title: t("social.facebook") do %>
|
||||
<span class="sr-only"><%= t("social.facebook") %></span>
|
||||
<i class="icon-facebook" aria-hidden="true"></i>
|
||||
<% end %>
|
||||
</li>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% if setting['blog_url'] %>
|
||||
<%= link_to setting['blog_url'], target: "_blank", title: t("social.blog") do %>
|
||||
<span class="sr-only"><%= t("social.blog") %></span>
|
||||
<i class="icon-blog"></i>
|
||||
<% if setting['blog_url'] %>
|
||||
<li class="inline-block">
|
||||
<%= link_to setting['blog_url'], target: "_blank", title: t("social.blog") do %>
|
||||
<span class="sr-only"><%= t("social.blog") %></span>
|
||||
<i class="icon-blog" aria-hidden="true"></i>
|
||||
<% end %>
|
||||
</li>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% if setting['youtube_handle'] %>
|
||||
<%= link_to "https://www.youtube.com/#{setting['youtube_handle']}", target: "_blank", title: t("social.youtube") do %>
|
||||
<span class="sr-only"><%= t("social.youtube") %></span>
|
||||
<i class="icon-youtube"></i>
|
||||
<% if setting['youtube_handle'] %>
|
||||
<li class="inline-block">
|
||||
<%= link_to "https://www.youtube.com/#{setting['youtube_handle']}", target: "_blank", title: t("social.youtube") do %>
|
||||
<span class="sr-only"><%= t("social.youtube") %></span>
|
||||
<i class="icon-youtube" aria-hidden="true"></i>
|
||||
<% end %>
|
||||
</li>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
<div id="responsive-menu">
|
||||
<div class="top-bar-title">
|
||||
<%= link_to root_path, class: "hide-for-small-only" do %>
|
||||
<%= link_to root_path, class: "hide-for-small-only", accesskey: "/" do %>
|
||||
<%= image_tag('header_logo_madrid.png', class: 'hide-for-small-only float-left', size: '80x80', alt: t("layouts.header.logo")) %>
|
||||
<% if opendata_page? %>
|
||||
<%= t("layouts.header.open_gov", open: "#{t('layouts.header.open')}") %> <span>|</span>
|
||||
@@ -34,6 +34,9 @@
|
||||
<div class="show-for-small-only">
|
||||
<div class="subnavigation row">
|
||||
<%= render "shared/subnavigation" %>
|
||||
<div class="small-12 medium-3 column">
|
||||
<%= yield :header_addon %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -45,9 +48,9 @@
|
||||
<div class="row">
|
||||
<div class="hide-for-small-only">
|
||||
<%= render "shared/subnavigation" %>
|
||||
</div>
|
||||
<div class="small-12 medium-3 column">
|
||||
<%= yield :header_addon %>
|
||||
<div class="small-12 medium-3 column">
|
||||
<%= yield :header_addon %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div class="row">
|
||||
<div class="small-12 column">
|
||||
|
||||
<h1 class="float-left margin-top"><%= t("notifications.index.title") %></h1>
|
||||
<h1 class="float-left"><%= t("notifications.index.title") %></h1>
|
||||
|
||||
<% if @notifications.empty? %>
|
||||
<div data-alert class="callout primary margin-top clear">
|
||||
|
||||
@@ -1,18 +1,148 @@
|
||||
<% provide :title do %><%= t('pages.titles.accessibility') %><% end %>
|
||||
<div class="page row-full">
|
||||
<div class="row">
|
||||
<div class="text small-12 column">
|
||||
<h1>Accesibilidad</h1>
|
||||
<p>La accesibilidad web se refiere a la posibilidad de acceso a la web y a sus contenidos por todas las personas, independientemente de las discapacidades (físicas, intelectuales o técnicas) que puedan presentar o de las que se deriven del contexto de uso (tecnológicas o ambientales).</p>
|
||||
<div class="row">
|
||||
<div class="small-12 column">
|
||||
<h1>Accesibilidad</h1>
|
||||
<p>La accesibilidad web se refiere a la posibilidad de acceso a la web y a sus contenidos por todas las personas, independientemente de las discapacidades (físicas, intelectuales o técnicas) que puedan presentar o de las que se deriven del contexto de uso (tecnológicas o ambientales).</p>
|
||||
|
||||
<p>Cuando los sitios web están diseñados pensando en la accesibilidad, todos los usuarios pueden acceder en condiciones de igualdad a los contenidos, por ejemplo:</p>
|
||||
<p>Cuando los sitios web están diseñados pensando en la accesibilidad, todos los usuarios pueden acceder en condiciones de igualdad a los contenidos, por ejemplo:</p>
|
||||
|
||||
<ul>
|
||||
<li>Proporcionando un texto alternativo a las imágenes, los usuarios invidentes o con problemas de visión pueden utilizar lectores especiales para acceder a la información. </li>
|
||||
<li>Cuando los vídeos disponen de subtítulos, los usuarios con dificultades auditivas pueden entenderlos plenamente. </li>
|
||||
<li>Si los contenidos están escritos en un lenguaje sencillo e ilustrados, los usuarios con problemas de aprendizaje están en mejores condiciones de entenderlos.</li>
|
||||
<li>Si el usuario tiene problemas de movilidad y le cuesta usar el ratón, las alternativas con el teclado le ayudan en la navegación.</li>
|
||||
</ul>
|
||||
|
||||
<h2>"Atajos" de teclado</h2>
|
||||
|
||||
<p>Para poder navegar por este sitio web de forma accesible, se han programado un grupo de teclas de acceso rápido que recogen las principales secciones de interés general en los que está organizado el sitio.</p>
|
||||
|
||||
<div class="small-12 medium-6">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center">Tecla</th>
|
||||
<th>Página</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="text-center">/</td>
|
||||
<td>Inicio</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-center">D</td>
|
||||
<td>Debates</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-center">P</td>
|
||||
<td>Propuestas</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-center">S</td>
|
||||
<td>Presupuestos ciudadanos</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-center">I</td>
|
||||
<td>Más información</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-center">N</td>
|
||||
<td>Notificaciones</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-center">A</td>
|
||||
<td>Mi actividad</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-center">M</td>
|
||||
<td>Mi cuenta</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<p>Dependiendo del sistema operativo y del navegador que se utilice, la combinación de teclas será la siguiente:</p>
|
||||
|
||||
<div class="small-12 medium-6">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Navegador</th>
|
||||
<th>Combinación de teclas</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Explorer</td>
|
||||
<td>ALT + atajo y luego ENTER</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Firefox</td>
|
||||
<td>ALT + MAYÚSCULAS + atajo</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Chrome</td>
|
||||
<td>ALT + atajo (si es un MAC, CTRL + ALT + atajo)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Safari</td>
|
||||
<td>ALT + atajo (si es un MAC, CMD + atajo)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Opera</td>
|
||||
<td>MAYÚSCULAS + ESC + atajo</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h2>Tamaño del texto</h2>
|
||||
<p>El diseño accesible de este sitio web permite que el usuario pueda elegir el tamaño del texto que le convenga. Esta acción puede llevarse a cabo de diferentes maneras según el navegador que se utilice.</p>
|
||||
|
||||
<div class="small-12 medium-6">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Navegador</th>
|
||||
<th>Acción a realizar </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Explorer</td>
|
||||
<td>Ver > Tamaño del texto</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Firefox</td>
|
||||
<td>Ver > Tamaño</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Chrome</td>
|
||||
<td>Ajustes (icono) > Opciones > Avanzada > Contenido web > Tamaño fuente</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Safari</td>
|
||||
<td>Visualización > ampliar/reducir</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Opera</td>
|
||||
<td>Ver > escala</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<p>Otra forma de modificar el tamaño de texto es utilizar los atajos de teclado definidos en los navegadores, en particular la combinación de teclas:</p>
|
||||
|
||||
<ul>
|
||||
<li><code>CTRL y + (CMD y + en MAC)</code> para aumentar el tamaño del texto</li>
|
||||
<li><code> CTRL y - (CMD y - en MAC)</code> para reducir el tamaño del texto</li>
|
||||
</ul>
|
||||
|
||||
<h2>Compatibilidad con estándares y diseño visual</h2>
|
||||
|
||||
<p>Todas las páginas de este sitio web cumplen con las <strong>Pautas de Accesibilidad</strong> o Principios Generales de Diseño Accesible establecidas por el Grupo de Trabajo <abbr title="Web Accessibility Initiative" lang="en">WAI</abbr> perteneciente al W3C.</p>
|
||||
|
||||
<ul>
|
||||
<li>Proporcionando un texto alternativo a las imágenes, los usuarios invidentes o con problemas de visión pueden utilizar lectores especiales para acceder a la información. </li>
|
||||
<li>Cuando los vídeos disponen de subtítulos, los usuarios con dificultades auditivas pueden entenderlos plenamente. </li>
|
||||
<li>Si los contenidos están escritos en un lenguaje sencillo e ilustrados, los usuarios con problemas de aprendizaje están en mejores condiciones de entenderlos.</li>
|
||||
<li>Si el usuario tiene problemas de movilidad y le cuesta usar el ratón, las alternativas con el teclado le ayudan en la navegación.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,73 +1,71 @@
|
||||
<% provide :title do %><%= t('pages.titles.more_information') %><% end %>
|
||||
<div class="page row-full">
|
||||
<div class="row">
|
||||
<div class="more-information margin-top small-12 medium-7 column">
|
||||
<h1><%= t('pages.titles.more_information') %></h1>
|
||||
<ul class="no-bullet">
|
||||
<li>
|
||||
<%= link_to page_path('how_it_works') do %>
|
||||
<%= t('pages.more_information.titles.how_it_works') %>
|
||||
<br>
|
||||
<span><%= t('pages.more_information.description.how_it_works') %></span>
|
||||
<% end %>
|
||||
</li>
|
||||
<li>
|
||||
<%= link_to page_path('how_to_use') do %>
|
||||
<%= t('pages.more_information.titles.how_to_use') %>
|
||||
<br>
|
||||
<span><%= t('pages.more_information.description.how_to_use') %></span>
|
||||
<div class="row">
|
||||
<div class="more-information small-12 medium-7 column">
|
||||
<h1><%= t('pages.titles.more_information') %></h1>
|
||||
<ul class="no-bullet">
|
||||
<li>
|
||||
<%= link_to page_path('how_it_works') do %>
|
||||
<%= t('pages.more_information.titles.how_it_works') %>
|
||||
<br>
|
||||
<span><%= t('pages.more_information.description.how_it_works') %></span>
|
||||
<% end %>
|
||||
</li>
|
||||
<li>
|
||||
<%= link_to page_path('participation') do %>
|
||||
<%= t('pages.more_information.titles.participation') %>
|
||||
<br>
|
||||
<span><%= t('pages.more_information.description.participation') %></span>
|
||||
<% end %>
|
||||
</li>
|
||||
<li>
|
||||
<%= link_to page_path('proposals_info') do %>
|
||||
<%= t('pages.more_information.titles.proposals_info') %>
|
||||
<br>
|
||||
<span><%= t('pages.more_information.description.proposals_info') %></span>
|
||||
<% end %>
|
||||
</li>
|
||||
<li>
|
||||
<%= link_to page_path('spending_proposals_info') do %>
|
||||
<%= t('pages.more_information.titles.spending_proposals_info') %>
|
||||
<br>
|
||||
<span><%= t('pages.more_information.description.spending_proposals_info') %></span>
|
||||
<% end %>
|
||||
</li>
|
||||
<li>
|
||||
<%= link_to page_path('participation_world') do %>
|
||||
<%= t('pages.more_information.titles.participation_world') %>
|
||||
<br>
|
||||
<span><%= t('pages.more_information.description.participation_world') %></span>
|
||||
<% end %>
|
||||
</li>
|
||||
<li>
|
||||
<%= link_to page_path('participation_facts') do %>
|
||||
<%= t('pages.more_information.titles.participation_facts') %>
|
||||
<br>
|
||||
<span><%= t('pages.more_information.description.participation_facts') %></span>
|
||||
<% end %>
|
||||
</li>
|
||||
<li>
|
||||
<%= link_to page_path('faq') do %>
|
||||
<%= t('pages.more_information.titles.faq') %>
|
||||
<br>
|
||||
<span><%= t('pages.more_information.description.faq') %></span>
|
||||
<% end %>
|
||||
</li>
|
||||
<li>
|
||||
<%= link_to page_path('proposals_info', :anchor => "iii") do %>
|
||||
<%= t('pages.more_information.titles.signature_sheet') %>
|
||||
<br>
|
||||
<span><%= t('pages.more_information.description.signature_sheet') %></span>
|
||||
<% end %>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<%= link_to page_path('how_to_use') do %>
|
||||
<%= t('pages.more_information.titles.how_to_use') %>
|
||||
<br>
|
||||
<span><%= t('pages.more_information.description.how_to_use') %></span>
|
||||
<% end %>
|
||||
</li>
|
||||
<li>
|
||||
<%= link_to page_path('participation') do %>
|
||||
<%= t('pages.more_information.titles.participation') %>
|
||||
<br>
|
||||
<span><%= t('pages.more_information.description.participation') %></span>
|
||||
<% end %>
|
||||
</li>
|
||||
<li>
|
||||
<%= link_to page_path('proposals_info') do %>
|
||||
<%= t('pages.more_information.titles.proposals_info') %>
|
||||
<br>
|
||||
<span><%= t('pages.more_information.description.proposals_info') %></span>
|
||||
<% end %>
|
||||
</li>
|
||||
<li>
|
||||
<%= link_to page_path('spending_proposals_info') do %>
|
||||
<%= t('pages.more_information.titles.spending_proposals_info') %>
|
||||
<br>
|
||||
<span><%= t('pages.more_information.description.spending_proposals_info') %></span>
|
||||
<% end %>
|
||||
</li>
|
||||
<li>
|
||||
<%= link_to page_path('participation_world') do %>
|
||||
<%= t('pages.more_information.titles.participation_world') %>
|
||||
<br>
|
||||
<span><%= t('pages.more_information.description.participation_world') %></span>
|
||||
<% end %>
|
||||
</li>
|
||||
<li>
|
||||
<%= link_to page_path('participation_facts') do %>
|
||||
<%= t('pages.more_information.titles.participation_facts') %>
|
||||
<br>
|
||||
<span><%= t('pages.more_information.description.participation_facts') %></span>
|
||||
<% end %>
|
||||
</li>
|
||||
<li>
|
||||
<%= link_to page_path('faq') do %>
|
||||
<%= t('pages.more_information.titles.faq') %>
|
||||
<br>
|
||||
<span><%= t('pages.more_information.description.faq') %></span>
|
||||
<% end %>
|
||||
</li>
|
||||
<li>
|
||||
<%= link_to page_path('proposals_info', :anchor => "iii") do %>
|
||||
<%= t('pages.more_information.titles.signature_sheet') %>
|
||||
<br>
|
||||
<span><%= t('pages.more_information.description.signature_sheet') %></span>
|
||||
<% end %>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
</div>
|
||||
|
||||
<div class="small-12 medium-3 column">
|
||||
<aside class="margin-bottom" role="complementary">
|
||||
<aside class="margin-bottom">
|
||||
<%= link_to t("proposals.index.start_proposal"), new_proposal_path, class: 'button expanded' %>
|
||||
<%= render "shared/tag_cloud", taggable: 'proposal' %>
|
||||
<%= render 'categories' %>
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
</div>
|
||||
|
||||
<div class="small-12 medium-3 column">
|
||||
<aside class="sidebar" role="complementary">
|
||||
<aside class="sidebar">
|
||||
<%= link_to t("proposals.index.start_proposal"), new_proposal_path, class: 'button radius expand' %>
|
||||
<%= render "shared/tag_cloud", taggable: 'proposal' %>
|
||||
<%= render 'categories' %>
|
||||
|
||||
@@ -10,4 +10,10 @@
|
||||
<%= link_to t("layouts.header.moderation"), moderation_root_path %>
|
||||
</li>
|
||||
<% end %>
|
||||
|
||||
<% if current_user.valuator? || current_user.administrator? %>
|
||||
<li>
|
||||
<%= link_to t("layouts.header.valuation"), valuation_root_path %>
|
||||
</li>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<% if I18n.available_locales.size > 1 %>
|
||||
<div class="locale" id="js-locale" data-current-local="<%= I18n.locale %>">
|
||||
<span class="inline-block">
|
||||
<%= t("layouts.header.locale") %>
|
||||
</span>
|
||||
<form class="locale-form">
|
||||
<select class="js-location-changer locale-switcher" name="locale-switcher">
|
||||
<label class="inline-block" for="locale-switcher">
|
||||
<%= t("layouts.header.locale") %>
|
||||
</label>
|
||||
<select class="js-location-changer locale-switcher inline-block" name="locale-switcher" id="locale-switcher">
|
||||
<% I18n.available_locales.map do |loc| %>
|
||||
<option <%= "selected" if loc == I18n.locale %>
|
||||
value="<%= current_path_with_query_params(locale: loc) %>">
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
</div>
|
||||
|
||||
<div class="small-12 medium-3 column">
|
||||
<aside class="sidebar" role="complementary">
|
||||
<aside class="sidebar">
|
||||
<%= link_to t("map.start_proposal"),
|
||||
new_proposal_path, class: 'button radius expand' %>
|
||||
<%= render "shared/tag_cloud", taggable: 'proposal' %>
|
||||
|
||||
@@ -1,10 +1,20 @@
|
||||
<div class="small-12 medium-9 column">
|
||||
<% if feature?(:debates) %>
|
||||
<%= link_to t("layouts.header.debates"), debates_path, class: ("active" if controller_name == "debates") %>
|
||||
<% end %>
|
||||
<%= link_to t("layouts.header.proposals"), proposals_path, class: ("active" if controller_name == "proposals") %>
|
||||
<% if feature?(:spending_proposals) %>
|
||||
<%= link_to t("layouts.header.spending_proposals"), spending_proposals_path, class: ("active" if controller_name == "spending_proposals") %>
|
||||
<% end %>
|
||||
<%= link_to t("layouts.header.more_information"), page_path('more_information'), class: ("active" if current_page?("/more_information")) %>
|
||||
<ul>
|
||||
<% if feature?(:debates) %>
|
||||
<li>
|
||||
<%= link_to t("layouts.header.debates"), debates_path, class: ("active" if controller_name == "debates"), accesskey: "d" %>
|
||||
</li>
|
||||
<% end %>
|
||||
<li>
|
||||
<%= link_to t("layouts.header.proposals"), proposals_path, class: ("active" if controller_name == "proposals"), accesskey: "p" %>
|
||||
</li>
|
||||
<% if feature?(:spending_proposals) %>
|
||||
<li>
|
||||
<%= link_to t("layouts.header.spending_proposals"), spending_proposals_path, class: ("active" if controller_name == "spending_proposals"), accesskey: "s" %>
|
||||
</li>
|
||||
<% end %>
|
||||
<li>
|
||||
<%= link_to t("layouts.header.more_information"), page_path('more_information'), class: ("active" if current_page?("/more_information")), accesskey: "i" %>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
17
app/views/valuation/_menu.html.erb
Normal file
17
app/views/valuation/_menu.html.erb
Normal file
@@ -0,0 +1,17 @@
|
||||
<nav class="admin-sidebar">
|
||||
<ul id="valuation_menu">
|
||||
<li>
|
||||
<%= link_to t("valuation.menu.title"), valuation_root_path %>
|
||||
</li>
|
||||
|
||||
<% if feature?(:spending_proposals) %>
|
||||
<li <%= "class=active" if controller_name == "spending_proposals" %>>
|
||||
<%= link_to valuation_spending_proposals_path do %>
|
||||
<i class="icon-budget"></i>
|
||||
<%= t("valuation.menu.spending_proposals") %>
|
||||
<% end %>
|
||||
</li>
|
||||
<% end %>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
132
app/views/valuation/spending_proposals/edit.html.erb
Normal file
132
app/views/valuation/spending_proposals/edit.html.erb
Normal file
@@ -0,0 +1,132 @@
|
||||
<%= link_to "#{t('valuation.spending_proposals.show.heading')} #{@spending_proposal.id}", valuation_spending_proposal_path(@spending_proposal), class: 'back' %>
|
||||
<h2><%= t("valuation.spending_proposals.edit.dossier") %></h2>
|
||||
|
||||
<%= form_for(@spending_proposal, url: valuate_valuation_spending_proposal_path(@spending_proposal)) do |f| %>
|
||||
<%= render 'shared/errors', resource: @spending_proposal %>
|
||||
<div class="row">
|
||||
<div class="small-12 medium-4 column">
|
||||
<%= f.label :price, "#{t('valuation.spending_proposals.edit.price')} (#{t('valuation.spending_proposals.edit.currency')})" %>
|
||||
<%= f.number_field :price, label: false %>
|
||||
</div>
|
||||
|
||||
<div class="small-12 medium-4 column end">
|
||||
<%= f.label :price_first_year, "#{t('valuation.spending_proposals.edit.price_first_year')} ( #{t('valuation.spending_proposals.edit.currency')})" %>
|
||||
<%= f.number_field :price_first_year, label: false %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="small-12 medium-8 column">
|
||||
<%= f.label :price_explanation, t("valuation.spending_proposals.edit.price_explanation") %>
|
||||
<%= f.text_area :price_explanation, label: false, rows: 3 %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="small-12 medium-8 column">
|
||||
<fieldset class="fieldset">
|
||||
<legend><%= t('valuation.spending_proposals.edit.feasibility') %></legend>
|
||||
<div class="small-6 column">
|
||||
<span class="checkbox">
|
||||
<%= f.radio_button :feasible, true, value: true, label: false %>
|
||||
<%= f.label :feasible_true, t('valuation.spending_proposals.edit.feasible') %>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="small-6 column">
|
||||
<span class="checkbox">
|
||||
<%= f.radio_button :feasible, false, value: false, label: false %>
|
||||
<%= f.label :feasible_false, t('valuation.spending_proposals.edit.not_feasible') %>
|
||||
</span>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="small-12 medium-8 column">
|
||||
<%= f.label :feasible_explanation, t("valuation.spending_proposals.edit.feasible_explanation") %>
|
||||
<%= f.text_area :feasible_explanation, label: false, rows: 3 %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="small-12 medium-8 column">
|
||||
<%= f.label :time_scope, t("valuation.spending_proposals.edit.time_scope") %>
|
||||
<%= f.text_field :time_scope, label: false %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="small-12 medium-8 column">
|
||||
<%= f.label :valuation_finished do %>
|
||||
<%= f.check_box :valuation_finished, label: false %>
|
||||
<span class="checkbox"><%= t("valuation.spending_proposals.edit.valuation_finished") %></span>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="small-12 medium-8 column">
|
||||
<%= f.label :internal_comments, t("valuation.spending_proposals.edit.internal_comments") %>
|
||||
<%= f.text_area :internal_comments, label: false, rows: 3 %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="actions small-12 medium-4 column">
|
||||
<%= f.submit(class: "button expanded large", value: t("valuation.spending_proposals.edit.save")) %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<h1><%= @spending_proposal.title %></h1>
|
||||
|
||||
<%= safe_html_with_links @spending_proposal.description %>
|
||||
|
||||
<% if @spending_proposal.external_url.present? %>
|
||||
<p><%= text_with_links @spending_proposal.external_url %></p>
|
||||
<% end %>
|
||||
|
||||
<h2><%= t("valuation.spending_proposals.show.info") %></h2>
|
||||
|
||||
<p><strong><%= t("valuation.spending_proposals.show.by") %>:</strong>
|
||||
<%= link_to @spending_proposal.author.name, user_path(@spending_proposal.author) %>
|
||||
</p>
|
||||
|
||||
<% if @spending_proposal.association_name.present? %>
|
||||
<p><strong><%= t("valuation.spending_proposals.show.association_name") %>:</strong>
|
||||
<%= @spending_proposal.association_name %>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<p><strong><%= t("valuation.spending_proposals.show.geozone") %>:</strong>
|
||||
<%= geozone_name(@spending_proposal) %>
|
||||
</p>
|
||||
|
||||
<p><strong><%= t("valuation.spending_proposals.show.sent") %>:</strong>
|
||||
<%= l @spending_proposal.created_at, format: :datetime %>
|
||||
</p>
|
||||
|
||||
<h2><%= t("valuation.spending_proposals.show.responsibles") %></h2>
|
||||
|
||||
<p><strong><%= t("valuation.spending_proposals.show.assigned_admin") %>:</strong>
|
||||
<% if @spending_proposal.administrator.present? %>
|
||||
<%= @spending_proposal.administrator.name %> (<%= @spending_proposal.administrator.email %>)
|
||||
<% else %>
|
||||
<%= t("valuation.spending_proposals.show.undefined") %></li>
|
||||
<% end %>
|
||||
</p>
|
||||
|
||||
<p><strong><%= t("valuation.spending_proposals.show.assigned_valuators") %>:</strong></p>
|
||||
<div id="assigned_valuators">
|
||||
<ul>
|
||||
<% @spending_proposal.valuators.each do |valuator| %>
|
||||
<li><%= valuator.name %> (<%= valuator.email %>)</li>
|
||||
<% end %>
|
||||
|
||||
<% if @spending_proposal.valuators.empty? %>
|
||||
<li><%= t("valuation.spending_proposals.show.undefined") %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
41
app/views/valuation/spending_proposals/index.html.erb
Normal file
41
app/views/valuation/spending_proposals/index.html.erb
Normal file
@@ -0,0 +1,41 @@
|
||||
<h2><%= t("valuation.spending_proposals.index.title") %></h2>
|
||||
|
||||
<div>
|
||||
<%= form_tag valuation_spending_proposals_path, method: :get, enforce_utf8: false do %>
|
||||
<div class="small-12 medium-4 column float-right">
|
||||
<%= select_tag :geozone_id,
|
||||
options_for_select(geozone_select_options.unshift([t("geozones.none"), "all"]), params[:geozone_id]),
|
||||
{ prompt: t("valuation.spending_proposals.index.geozone_filter_all"),
|
||||
label: false,
|
||||
class: "js-submit-on-change" } %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<%= render 'shared/filter_subnav', i18n_namespace: "valuation.spending_proposals.index" %>
|
||||
|
||||
<h3><%= page_entries_info @spending_proposals %></h3>
|
||||
|
||||
<table>
|
||||
<% @spending_proposals.each do |spending_proposal| %>
|
||||
<tr id="<%= dom_id(spending_proposal) %>">
|
||||
<td>
|
||||
<strong><%= spending_proposal.id %></strong>
|
||||
</td>
|
||||
<td>
|
||||
<%= link_to spending_proposal.title, valuation_spending_proposal_path(spending_proposal) %>
|
||||
</td>
|
||||
<td class="small">
|
||||
<%= link_to t("valuation.spending_proposals.index.edit"), edit_valuation_spending_proposal_path(spending_proposal) %>
|
||||
</td>
|
||||
<td class="small">
|
||||
<%= assigned_valuators_info(spending_proposal.valuators) %>
|
||||
</td>
|
||||
<td class="small">
|
||||
<%= geozone_name(spending_proposal) %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</table>
|
||||
|
||||
<%= paginate @spending_proposals %>
|
||||
92
app/views/valuation/spending_proposals/show.html.erb
Normal file
92
app/views/valuation/spending_proposals/show.html.erb
Normal file
@@ -0,0 +1,92 @@
|
||||
<%= link_to t("valuation.spending_proposals.show.back"), :back, class: 'back' %>
|
||||
<h2><%= t("valuation.spending_proposals.show.heading") %> <%= @spending_proposal.id %> </h2>
|
||||
<h1><%= @spending_proposal.title %></h1>
|
||||
|
||||
<%= safe_html_with_links @spending_proposal.description %>
|
||||
|
||||
<% if @spending_proposal.external_url.present? %>
|
||||
<p><%= text_with_links @spending_proposal.external_url %></p>
|
||||
<% end %>
|
||||
|
||||
<h2><%= t("valuation.spending_proposals.show.info") %></h2>
|
||||
|
||||
<p><strong><%= t("valuation.spending_proposals.show.by") %>:</strong>
|
||||
<%= link_to @spending_proposal.author.name, user_path(@spending_proposal.author) %>
|
||||
</p>
|
||||
|
||||
<% if @spending_proposal.association_name.present? %>
|
||||
<p><strong><%= t("valuation.spending_proposals.show.association_name") %>:</strong>
|
||||
<%= @spending_proposal.association_name %>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<p><strong><%= t("valuation.spending_proposals.show.geozone") %>:</strong>
|
||||
<%= geozone_name(@spending_proposal) %>
|
||||
</p>
|
||||
|
||||
<p><strong><%= t("valuation.spending_proposals.show.sent") %>:</strong>
|
||||
<%= l @spending_proposal.created_at, format: :datetime %>
|
||||
</p>
|
||||
|
||||
<h2><%= t("valuation.spending_proposals.show.responsibles") %></h2>
|
||||
|
||||
<p><strong><%= t("valuation.spending_proposals.show.assigned_admin") %>:</strong>
|
||||
<% if @spending_proposal.administrator.present? %>
|
||||
<%= @spending_proposal.administrator.name %> (<%= @spending_proposal.administrator.email %>)
|
||||
<% else %>
|
||||
<%= t("valuation.spending_proposals.show.undefined") %></li>
|
||||
<% end %>
|
||||
</p>
|
||||
|
||||
<p><strong><%= t("valuation.spending_proposals.show.assigned_valuators") %>:</strong></p>
|
||||
<div id="assigned_valuators">
|
||||
<ul>
|
||||
<% @spending_proposal.valuators.each do |valuator| %>
|
||||
<li><%= valuator.name %> (<%= valuator.email %>)</li>
|
||||
<% end %>
|
||||
|
||||
<% if @spending_proposal.valuators.empty? %>
|
||||
<li><%= t("valuation.spending_proposals.show.undefined") %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h2><%= t("valuation.spending_proposals.show.dossier") %></h2>
|
||||
|
||||
<p>
|
||||
<%= link_to t("valuation.spending_proposals.show.edit_dossier"), edit_valuation_spending_proposal_path(@spending_proposal) %>
|
||||
</p>
|
||||
|
||||
<p id="price">
|
||||
<strong><%= t("valuation.spending_proposals.show.price") %> (<%= t("valuation.spending_proposals.show.currency") %>):</strong>
|
||||
<%= @spending_proposal.price.presence or t("valuation.spending_proposals.show.undefined") %>
|
||||
</p>
|
||||
<p id="price_first_year">
|
||||
<strong><%= t("valuation.spending_proposals.show.price_first_year") %> (<%= t("valuation.spending_proposals.show.currency") %>):</strong>
|
||||
<%= @spending_proposal.price_first_year.presence or t("valuation.spending_proposals.show.undefined") %>
|
||||
</p>
|
||||
|
||||
<%= explanation_field @spending_proposal.price_explanation %>
|
||||
|
||||
<p id="time_scope">
|
||||
<strong><%= t("valuation.spending_proposals.show.time_scope") %>:</strong>
|
||||
<%= @spending_proposal.time_scope.presence or t("valuation.spending_proposals.show.undefined") %>
|
||||
</p>
|
||||
|
||||
<p id="feasibility">
|
||||
<strong><%= t("valuation.spending_proposals.show.feasibility") %>:</strong>
|
||||
<%= t("valuation.spending_proposals.show.#{@spending_proposal.feasibility}") %>
|
||||
</p>
|
||||
|
||||
<%= explanation_field @spending_proposal.feasible_explanation %>
|
||||
|
||||
<% if @spending_proposal.valuation_finished %>
|
||||
<p>
|
||||
<strong><%= t("valuation.spending_proposals.show.valuation_finished") %></strong>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<% if @spending_proposal.internal_comments.present? %>
|
||||
<h2><%= t("valuation.spending_proposals.show.internal_comments") %></h2>
|
||||
<%= simple_format_no_tags_no_sanitize(safe_html_with_links(@spending_proposal.internal_comments.html_safe)) %>
|
||||
<% end %>
|
||||
@@ -24,6 +24,7 @@ data:
|
||||
- config/locales/%{locale}.yml
|
||||
- config/locales/admin.%{locale}.yml
|
||||
- config/locales/moderation.%{locale}.yml
|
||||
- config/locales/valuation.%{locale}.yml
|
||||
- config/locales/management.%{locale}.yml
|
||||
- config/locales/verification.%{locale}.yml
|
||||
- config/locales/mailers.%{locale}.yml
|
||||
@@ -122,6 +123,7 @@ ignore_unused:
|
||||
- 'moderation.proposals.index.order*'
|
||||
- 'moderation.debates.index.filter*'
|
||||
- 'moderation.debates.index.order*'
|
||||
- 'valuation.spending_proposals.index.filter*'
|
||||
- 'users.show.filters.*'
|
||||
- 'debates.index.select_order'
|
||||
- 'debates.index.orders.*'
|
||||
|
||||
@@ -174,6 +174,7 @@ en:
|
||||
geozone: Scope
|
||||
dossier: Dossier
|
||||
price: Price
|
||||
price_first_year: Cost during the first year
|
||||
currency: "€"
|
||||
feasibility: Feasibility
|
||||
feasible: Feasible
|
||||
|
||||
@@ -174,6 +174,7 @@ es:
|
||||
geozone: Ámbito
|
||||
dossier: Informe
|
||||
price: Coste
|
||||
price_first_year: Coste en el primer año
|
||||
currency: "€"
|
||||
feasibility: Viabilidad
|
||||
feasible: Viable
|
||||
|
||||
@@ -190,6 +190,7 @@ en:
|
||||
locale: 'Language:'
|
||||
logo: Madrid
|
||||
moderation: Moderation
|
||||
valuation: Valuation
|
||||
more_information: More information
|
||||
my_account_link: My account
|
||||
my_activity_link: My activity
|
||||
|
||||
@@ -190,6 +190,7 @@ es:
|
||||
locale: 'Idioma:'
|
||||
logo: Madrid
|
||||
moderation: Moderar
|
||||
valuation: Evaluación
|
||||
more_information: Más información
|
||||
my_account_link: Mi cuenta
|
||||
my_activity_link: Mi actividad
|
||||
@@ -198,7 +199,7 @@ es:
|
||||
other: Tienes %{count} notificaciones nuevas
|
||||
no_notifications: No tienes notificaciones nuevas
|
||||
open: abierto
|
||||
open_city_slogan_html: Existen ciudades gobernadas directamente por sus habitantes, que <b>debaten</b> sobre temas que les preocupan, <b>proponen</b> ideas para mejorar sus vidas y <b>deciden</b> entre todas y todos las que se llevan a cabo. Madrid ya es una de ellas.
|
||||
open_city_slogan_html: Existen ciudades gobernadas directamente por sus habitantes, que <strong>debaten</strong> sobre temas que les preocupan, <strong>proponen</strong> ideas para mejorar sus vidas y <strong>deciden</strong> entre todas y todos las que se llevan a cabo. Madrid ya es una de ellas.
|
||||
open_city_title: La ciudad que quieres será la ciudad que quieras.
|
||||
open_data: Datos abiertos
|
||||
open_gov: Gobierno %{open}
|
||||
|
||||
60
config/locales/valuation.en.yml
Normal file
60
config/locales/valuation.en.yml
Normal file
@@ -0,0 +1,60 @@
|
||||
---
|
||||
en:
|
||||
valuation:
|
||||
menu:
|
||||
title: Valuation
|
||||
spending_proposals: Spending proposals
|
||||
spending_proposals:
|
||||
index:
|
||||
geozone_filter_all: All zones
|
||||
filters:
|
||||
valuation_open: Open
|
||||
valuating: Under valuation
|
||||
valuation_finished: Valuation finished
|
||||
title: Investment projects for participatory budgeting
|
||||
edit: Edit
|
||||
valuators_assigned:
|
||||
one: Assigned valuator
|
||||
other: "%{count} valuators assigned"
|
||||
no_valuators_assigned: No valuators assigned
|
||||
show:
|
||||
back: Back
|
||||
heading: Investment project
|
||||
info: Author info
|
||||
association_name: Asociación
|
||||
by: Sent by
|
||||
sent: Sent at
|
||||
geozone: Scope
|
||||
dossier: Dossier
|
||||
edit_dossier: Edit dossier
|
||||
price: Price
|
||||
price_first_year: Cost during the first year
|
||||
currency: "€"
|
||||
feasibility: Feasibility
|
||||
feasible: Feasible
|
||||
not_feasible: Not feasible
|
||||
undefined: Undefined
|
||||
valuation_finished: Valuation finished
|
||||
time_scope: Time scope
|
||||
internal_comments: Internal comments
|
||||
responsibles: Responsibles
|
||||
assigned_admin: Assigned admin
|
||||
assigned_valuators: Assigned valuators
|
||||
edit:
|
||||
dossier: Dossier
|
||||
price: Price
|
||||
price_first_year: Cost during the first year
|
||||
currency: "€"
|
||||
price_explanation: Price explanation
|
||||
feasibility: Feasibility
|
||||
feasible: Feasible
|
||||
not_feasible: Not feasible
|
||||
feasible_explanation: Feasibility explanation
|
||||
valuation_finished: Valuation finished
|
||||
time_scope: Time scope
|
||||
internal_comments: Internal comments
|
||||
save: Save changes
|
||||
notice:
|
||||
valuate: "Dossier updated"
|
||||
|
||||
|
||||
58
config/locales/valuation.es.yml
Normal file
58
config/locales/valuation.es.yml
Normal file
@@ -0,0 +1,58 @@
|
||||
---
|
||||
es:
|
||||
valuation:
|
||||
menu:
|
||||
title: Evaluación
|
||||
spending_proposals: Propuestas de inversión
|
||||
spending_proposals:
|
||||
index:
|
||||
geozone_filter_all: Todos los ámbitos de actuación
|
||||
filters:
|
||||
valuation_open: Abiertas
|
||||
valuating: En evaluación
|
||||
valuation_finished: Evaluación finalizada
|
||||
title: Propuestas de inversión para presupuestos participativos
|
||||
edit: Editar
|
||||
valuators_assigned:
|
||||
one: Evaluador asignado
|
||||
other: "%{count} evaluadores asignados"
|
||||
no_valuators_assigned: Sin evaluador
|
||||
show:
|
||||
back: Volver
|
||||
heading: Propuesta de inversión
|
||||
info: Datos de envío
|
||||
association_name: Asociación
|
||||
by: Enviada por
|
||||
sent: Fecha de creación
|
||||
geozone: Ámbito
|
||||
dossier: Informe
|
||||
edit_dossier: Editar informe
|
||||
price: Coste
|
||||
price_first_year: Coste en el primer año
|
||||
currency: "€"
|
||||
feasibility: Viabilidad
|
||||
feasible: Viable
|
||||
not_feasible: No viable
|
||||
undefined: Sin definir
|
||||
valuation_finished: Informe finalizado
|
||||
time_scope: Plazo de ejecución
|
||||
internal_comments: Comentarios internos
|
||||
responsibles: Responsables
|
||||
assigned_admin: Administrador asignado
|
||||
assigned_valuators: Evaluadores asignados
|
||||
edit:
|
||||
dossier: Informe
|
||||
price: Coste
|
||||
price_first_year: Coste en el primer año
|
||||
currency: "€"
|
||||
price_explanation: Justificación del precio
|
||||
feasibility: Viabilidad
|
||||
feasible: Viable
|
||||
not_feasible: No viable
|
||||
feasible_explanation: Justificación de la viabilidad
|
||||
valuation_finished: Informe finalizado
|
||||
time_scope: Plazo de ejecución
|
||||
internal_comments: Comentarios internos
|
||||
save: Guardar cambios
|
||||
notice:
|
||||
valuate: "Informe actualizado"
|
||||
@@ -208,6 +208,16 @@ Rails.application.routes.draw do
|
||||
end
|
||||
end
|
||||
|
||||
namespace :valuation do
|
||||
root to: "spending_proposals#index"
|
||||
|
||||
resources :spending_proposals, only: [:index, :show, :edit] do
|
||||
member do
|
||||
patch :valuate
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
namespace :management do
|
||||
root to: "dashboard#index"
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
class AddPriceFieldsToSpendingProposals < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :spending_proposals, :price_first_year, :float
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
class AddTimeScopeToSpendingProposals < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :spending_proposals, :time_scope, :string
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,11 @@
|
||||
class ChangePriceFieldsInSpendingProposals < ActiveRecord::Migration
|
||||
def up
|
||||
change_column :spending_proposals, :price, :integer
|
||||
change_column :spending_proposals, :price_first_year, :integer
|
||||
end
|
||||
|
||||
def down
|
||||
change_column :spending_proposals, :price, :float
|
||||
change_column :spending_proposals, :price_first_year, :float
|
||||
end
|
||||
end
|
||||
@@ -11,7 +11,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20160225171916) do
|
||||
ActiveRecord::Schema.define(version: 20160308103548) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
@@ -299,7 +299,7 @@ ActiveRecord::Schema.define(version: 20160225171916) do
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.integer "geozone_id"
|
||||
t.float "price"
|
||||
t.integer "price"
|
||||
t.boolean "feasible"
|
||||
t.string "association_name"
|
||||
t.text "price_explanation"
|
||||
@@ -309,6 +309,8 @@ ActiveRecord::Schema.define(version: 20160225171916) do
|
||||
t.text "explanations_log"
|
||||
t.integer "administrator_id"
|
||||
t.integer "valuation_assignments_count", default: 0
|
||||
t.integer "price_first_year"
|
||||
t.string "time_scope"
|
||||
end
|
||||
|
||||
add_index "spending_proposals", ["author_id"], name: "index_spending_proposals_on_author_id", using: :btree
|
||||
|
||||
@@ -188,7 +188,8 @@ feature 'Admin spending proposals' do
|
||||
spending_proposal = create(:spending_proposal,
|
||||
geozone: create(:geozone),
|
||||
association_name: 'People of the neighbourhood',
|
||||
price: 1234.56,
|
||||
price: 1234,
|
||||
price_first_year: 1000,
|
||||
feasible: false,
|
||||
feasible_explanation: 'It is impossible',
|
||||
administrator: administrator)
|
||||
@@ -203,7 +204,8 @@ feature 'Admin spending proposals' do
|
||||
expect(page).to have_content(spending_proposal.author.name)
|
||||
expect(page).to have_content(spending_proposal.association_name)
|
||||
expect(page).to have_content(spending_proposal.geozone.name)
|
||||
expect(page).to have_content('1234.56')
|
||||
expect(page).to have_content('1234')
|
||||
expect(page).to have_content('1000')
|
||||
expect(page).to have_content('Not feasible')
|
||||
expect(page).to have_content('It is impossible')
|
||||
expect(page).to have_content('Ana (ana@admins.org)')
|
||||
|
||||
@@ -6,10 +6,6 @@ feature 'Admin' do
|
||||
create(:administrator, user: user)
|
||||
user
|
||||
end
|
||||
let(:moderator) do
|
||||
create(:moderator, user: user)
|
||||
user
|
||||
end
|
||||
|
||||
scenario 'Access as regular user is not authorized' do
|
||||
login_as(user)
|
||||
@@ -21,7 +17,18 @@ feature 'Admin' do
|
||||
end
|
||||
|
||||
scenario 'Access as a moderator is not authorized' do
|
||||
login_as(moderator)
|
||||
create(:moderator, user: user)
|
||||
login_as(user)
|
||||
visit admin_root_path
|
||||
|
||||
expect(current_path).not_to eq(admin_root_path)
|
||||
expect(current_path).to eq(proposals_path)
|
||||
expect(page).to have_content "You do not have permission to access this page"
|
||||
end
|
||||
|
||||
scenario 'Access as a valuator is not authorized' do
|
||||
create(:valuator, user: user)
|
||||
login_as(user)
|
||||
visit admin_root_path
|
||||
|
||||
expect(current_path).not_to eq(admin_root_path)
|
||||
@@ -42,15 +49,8 @@ feature 'Admin' do
|
||||
visit root_path
|
||||
|
||||
expect(page).to have_link('Administration')
|
||||
expect(page).to_not have_link('Moderator')
|
||||
end
|
||||
|
||||
scenario "Moderation access links" do
|
||||
login_as(moderator)
|
||||
visit root_path
|
||||
|
||||
expect(page).to have_link('Moderation')
|
||||
expect(page).to_not have_link('Administration')
|
||||
expect(page).to have_link('Valuation')
|
||||
end
|
||||
|
||||
scenario 'Admin dashboard' do
|
||||
@@ -62,17 +62,7 @@ feature 'Admin' do
|
||||
expect(current_path).to eq(admin_root_path)
|
||||
expect(page).to have_css('#admin_menu')
|
||||
expect(page).to_not have_css('#moderation_menu')
|
||||
end
|
||||
|
||||
scenario 'Moderation dashboard' do
|
||||
login_as(moderator)
|
||||
visit root_path
|
||||
|
||||
click_link 'Moderation'
|
||||
|
||||
expect(current_path).to eq(moderation_root_path)
|
||||
expect(page).to have_css('#moderation_menu')
|
||||
expect(page).to_not have_css('#admin_menu')
|
||||
expect(page).to_not have_css('#valuation_menu')
|
||||
end
|
||||
|
||||
context 'Tags' do
|
||||
|
||||
@@ -465,7 +465,7 @@ feature 'Debates' do
|
||||
|
||||
visit debates_path
|
||||
|
||||
within "#search_form" do
|
||||
within(".expanded #search_form") do
|
||||
fill_in "search", with: "Schwifty"
|
||||
click_button "Search"
|
||||
end
|
||||
@@ -482,7 +482,7 @@ feature 'Debates' do
|
||||
scenario "Maintain search criteria" do
|
||||
visit debates_path
|
||||
|
||||
within "#search_form" do
|
||||
within(".expanded #search_form") do
|
||||
fill_in "search", with: "Schwifty"
|
||||
click_button "Search"
|
||||
end
|
||||
@@ -843,7 +843,7 @@ feature 'Debates' do
|
||||
debate = create(:debate, title: "Abcdefghi")
|
||||
|
||||
visit debates_path
|
||||
within "#search_form" do
|
||||
within(".expanded #search_form") do
|
||||
fill_in "search", with: debate.title
|
||||
click_button "Search"
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
require 'rails_helper'
|
||||
|
||||
feature 'Admin' do
|
||||
feature 'Moderation' do
|
||||
let(:user) { create(:user) }
|
||||
|
||||
scenario 'Access as regular user is not authorized' do
|
||||
@@ -15,6 +15,20 @@ feature 'Admin' do
|
||||
expect(page).to have_content "You do not have permission to access this page"
|
||||
end
|
||||
|
||||
scenario 'Access as valuator is not authorized' do
|
||||
create(:valuator, user: user)
|
||||
|
||||
login_as(user)
|
||||
visit root_path
|
||||
|
||||
expect(page).to_not have_link("Moderation")
|
||||
visit moderation_root_path
|
||||
|
||||
expect(current_path).not_to eq(moderation_root_path)
|
||||
expect(current_path).to eq(proposals_path)
|
||||
expect(page).to have_content "You do not have permission to access this page"
|
||||
end
|
||||
|
||||
scenario 'Access as a moderator is authorized' do
|
||||
create(:moderator, user: user)
|
||||
|
||||
@@ -41,4 +55,27 @@ feature 'Admin' do
|
||||
expect(page).to_not have_content "You do not have permission to access this page"
|
||||
end
|
||||
|
||||
scenario "Moderation access links" do
|
||||
create(:moderator, user: user)
|
||||
login_as(user)
|
||||
visit root_path
|
||||
|
||||
expect(page).to have_link('Moderation')
|
||||
expect(page).to_not have_link('Administration')
|
||||
expect(page).to_not have_link('Valuation')
|
||||
end
|
||||
|
||||
scenario 'Moderation dashboard' do
|
||||
create(:moderator, user: user)
|
||||
login_as(user)
|
||||
visit root_path
|
||||
|
||||
click_link 'Moderation'
|
||||
|
||||
expect(current_path).to eq(moderation_root_path)
|
||||
expect(page).to have_css('#moderation_menu')
|
||||
expect(page).to_not have_css('#admin_menu')
|
||||
expect(page).to_not have_css('#valuation_menu')
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -583,7 +583,7 @@ feature 'Proposals' do
|
||||
|
||||
visit proposals_path
|
||||
|
||||
within "#search_form" do
|
||||
within(".expanded #search_form") do
|
||||
fill_in "search", with: "Schwifty"
|
||||
click_button "Search"
|
||||
end
|
||||
@@ -603,7 +603,7 @@ feature 'Proposals' do
|
||||
|
||||
visit proposals_path
|
||||
|
||||
within "#search_form" do
|
||||
within(".expanded #search_form") do
|
||||
fill_in "search", with: proposal1.code
|
||||
click_button "Search"
|
||||
end
|
||||
@@ -619,7 +619,7 @@ feature 'Proposals' do
|
||||
scenario "Maintain search criteria" do
|
||||
visit proposals_path
|
||||
|
||||
within "#search_form" do
|
||||
within(".expanded #search_form") do
|
||||
fill_in "search", with: "Schwifty"
|
||||
click_button "Search"
|
||||
end
|
||||
@@ -986,7 +986,7 @@ feature 'Proposals' do
|
||||
proposal = create(:proposal, title: "Abcdefghi")
|
||||
|
||||
visit proposals_path
|
||||
within "#search_form" do
|
||||
within(".expanded #search_form") do
|
||||
fill_in "search", with: proposal.title
|
||||
click_button "Search"
|
||||
end
|
||||
|
||||
289
spec/features/valuation/spending_proposals_spec.rb
Normal file
289
spec/features/valuation/spending_proposals_spec.rb
Normal file
@@ -0,0 +1,289 @@
|
||||
require 'rails_helper'
|
||||
|
||||
feature 'Valuation spending proposals' do
|
||||
|
||||
background do
|
||||
@valuator = create(:valuator, user: create(:user, username: 'Rachel', email: 'rachel@valuators.org'))
|
||||
login_as(@valuator.user)
|
||||
end
|
||||
|
||||
scenario 'Disabled with a feature flag' do
|
||||
Setting['feature.spending_proposals'] = nil
|
||||
expect{ visit valuation_spending_proposals_path }.to raise_exception(FeatureFlags::FeatureDisabled)
|
||||
end
|
||||
|
||||
scenario 'Index shows spending proposals assigned to current valuator' do
|
||||
spending_proposal1 = create(:spending_proposal)
|
||||
spending_proposal2 = create(:spending_proposal)
|
||||
|
||||
spending_proposal1.valuators << @valuator
|
||||
|
||||
visit valuation_spending_proposals_path
|
||||
|
||||
expect(page).to have_content(spending_proposal1.title)
|
||||
expect(page).to_not have_content(spending_proposal2.title)
|
||||
end
|
||||
|
||||
scenario 'Index shows no spending proposals to admins no valuators' do
|
||||
spending_proposal1 = create(:spending_proposal)
|
||||
spending_proposal2 = create(:spending_proposal)
|
||||
spending_proposal1.valuators << @valuator
|
||||
|
||||
logout
|
||||
login_as create(:administrator).user
|
||||
visit valuation_spending_proposals_path
|
||||
|
||||
expect(page).to_not have_content(spending_proposal1.title)
|
||||
expect(page).to_not have_content(spending_proposal2.title)
|
||||
end
|
||||
|
||||
scenario 'Index shows assignments info' do
|
||||
spending_proposal1 = create(:spending_proposal)
|
||||
spending_proposal2 = create(:spending_proposal)
|
||||
spending_proposal3 = create(:spending_proposal)
|
||||
|
||||
valuator1 = create(:valuator, user: create(:user))
|
||||
valuator2 = create(:valuator, user: create(:user))
|
||||
valuator3 = create(:valuator, user: create(:user))
|
||||
|
||||
spending_proposal1.valuator_ids = [@valuator.id]
|
||||
spending_proposal2.valuator_ids = [@valuator.id, valuator1.id, valuator2.id]
|
||||
spending_proposal3.valuator_ids = [@valuator.id, valuator3.id]
|
||||
|
||||
visit valuation_spending_proposals_path
|
||||
|
||||
within("#spending_proposal_#{spending_proposal1.id}") do
|
||||
expect(page).to have_content("Rachel")
|
||||
end
|
||||
|
||||
within("#spending_proposal_#{spending_proposal2.id}") do
|
||||
expect(page).to have_content("3 valuators assigned")
|
||||
end
|
||||
|
||||
within("#spending_proposal_#{spending_proposal3.id}") do
|
||||
expect(page).to have_content("2 valuators assigned")
|
||||
end
|
||||
end
|
||||
|
||||
scenario "Index filtering by geozone", :js do
|
||||
geozone = create(:geozone, name: "District 9")
|
||||
spending_proposal1 = create(:spending_proposal, title: "Realocate visitors", geozone: geozone)
|
||||
spending_proposal2 = create(:spending_proposal, title: "Destroy the city")
|
||||
spending_proposal1.valuators << @valuator
|
||||
spending_proposal2.valuators << @valuator
|
||||
|
||||
visit valuation_spending_proposals_path
|
||||
expect(page).to have_link("Realocate visitors")
|
||||
expect(page).to have_link("Destroy the city")
|
||||
|
||||
select "District 9", from: "geozone_id"
|
||||
|
||||
expect(page).to have_link("Realocate visitors")
|
||||
expect(page).to_not have_link("Destroy the city")
|
||||
|
||||
select "All city", from: "geozone_id"
|
||||
|
||||
expect(page).to have_link("Destroy the city")
|
||||
expect(page).to_not have_link("Realocate visitors")
|
||||
|
||||
select "All zones", from: "geozone_id"
|
||||
expect(page).to have_link("Realocate visitors")
|
||||
expect(page).to have_link("Destroy the city")
|
||||
end
|
||||
|
||||
scenario "Current filter is properly highlighted" do
|
||||
filters_links = {'valuating' => 'Under valuation',
|
||||
'valuation_finished' => 'Valuation finished'}
|
||||
|
||||
visit valuation_spending_proposals_path
|
||||
|
||||
expect(page).to_not have_link(filters_links.values.first)
|
||||
filters_links.keys.drop(1).each { |filter| expect(page).to have_link(filters_links[filter]) }
|
||||
|
||||
filters_links.each_pair do |current_filter, link|
|
||||
visit valuation_spending_proposals_path(filter: current_filter)
|
||||
|
||||
expect(page).to_not have_link(link)
|
||||
|
||||
(filters_links.keys - [current_filter]).each do |filter|
|
||||
expect(page).to have_link(filters_links[filter])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
scenario "Index filtering by valuation status" do
|
||||
valuating = create(:spending_proposal, title: "Ongoing valuation")
|
||||
valuated = create(:spending_proposal, title: "Old idea", valuation_finished: true)
|
||||
valuating.valuators << @valuator
|
||||
valuated.valuators << @valuator
|
||||
|
||||
visit valuation_spending_proposals_path(filter: 'valuation_open')
|
||||
|
||||
expect(page).to have_content("Ongoing valuation")
|
||||
expect(page).to_not have_content("Old idea")
|
||||
|
||||
visit valuation_spending_proposals_path(filter: 'valuating')
|
||||
|
||||
expect(page).to have_content("Ongoing valuation")
|
||||
expect(page).to_not have_content("Old idea")
|
||||
|
||||
visit valuation_spending_proposals_path(filter: 'valuation_finished')
|
||||
|
||||
expect(page).to_not have_content("Ongoing valuation")
|
||||
expect(page).to have_content("Old idea")
|
||||
end
|
||||
|
||||
feature 'Show' do
|
||||
scenario 'visible for assigned valuators' do
|
||||
administrator = create(:administrator, user: create(:user, username: 'Ana', email: 'ana@admins.org'))
|
||||
valuator2 = create(:valuator, user: create(:user, username: 'Rick', email: 'rick@valuators.org'))
|
||||
spending_proposal = create(:spending_proposal,
|
||||
geozone: create(:geozone),
|
||||
association_name: 'People of the neighbourhood',
|
||||
price: 1234,
|
||||
feasible: false,
|
||||
feasible_explanation: 'It is impossible',
|
||||
administrator: administrator)
|
||||
spending_proposal.valuators << [@valuator, valuator2]
|
||||
|
||||
visit valuation_spending_proposals_path
|
||||
|
||||
click_link spending_proposal.title
|
||||
|
||||
expect(page).to have_content(spending_proposal.title)
|
||||
expect(page).to have_content(spending_proposal.description)
|
||||
expect(page).to have_content(spending_proposal.author.name)
|
||||
expect(page).to have_content(spending_proposal.association_name)
|
||||
expect(page).to have_content(spending_proposal.geozone.name)
|
||||
expect(page).to have_content('1234')
|
||||
expect(page).to have_content('Not feasible')
|
||||
expect(page).to have_content('It is impossible')
|
||||
expect(page).to have_content('Ana (ana@admins.org)')
|
||||
|
||||
within('#assigned_valuators') do
|
||||
expect(page).to have_content('Rachel (rachel@valuators.org)')
|
||||
expect(page).to have_content('Rick (rick@valuators.org)')
|
||||
end
|
||||
end
|
||||
|
||||
scenario 'visible for admins' do
|
||||
logout
|
||||
login_as create(:administrator).user
|
||||
|
||||
administrator = create(:administrator, user: create(:user, username: 'Ana', email: 'ana@admins.org'))
|
||||
valuator2 = create(:valuator, user: create(:user, username: 'Rick', email: 'rick@valuators.org'))
|
||||
spending_proposal = create(:spending_proposal,
|
||||
geozone: create(:geozone),
|
||||
association_name: 'People of the neighbourhood',
|
||||
price: 1234,
|
||||
feasible: false,
|
||||
feasible_explanation: 'It is impossible',
|
||||
administrator: administrator)
|
||||
spending_proposal.valuators << [@valuator, valuator2]
|
||||
|
||||
visit valuation_spending_proposal_path(spending_proposal)
|
||||
|
||||
expect(page).to have_content(spending_proposal.title)
|
||||
expect(page).to have_content(spending_proposal.description)
|
||||
expect(page).to have_content(spending_proposal.author.name)
|
||||
expect(page).to have_content(spending_proposal.association_name)
|
||||
expect(page).to have_content(spending_proposal.geozone.name)
|
||||
expect(page).to have_content('1234')
|
||||
expect(page).to have_content('Not feasible')
|
||||
expect(page).to have_content('It is impossible')
|
||||
expect(page).to have_content('Ana (ana@admins.org)')
|
||||
|
||||
within('#assigned_valuators') do
|
||||
expect(page).to have_content('Rachel (rachel@valuators.org)')
|
||||
expect(page).to have_content('Rick (rick@valuators.org)')
|
||||
end
|
||||
end
|
||||
|
||||
scenario 'not visible for not assigned valuators' do
|
||||
logout
|
||||
login_as create(:valuator).user
|
||||
|
||||
administrator = create(:administrator, user: create(:user, username: 'Ana', email: 'ana@admins.org'))
|
||||
valuator2 = create(:valuator, user: create(:user, username: 'Rick', email: 'rick@valuators.org'))
|
||||
spending_proposal = create(:spending_proposal,
|
||||
geozone: create(:geozone),
|
||||
association_name: 'People of the neighbourhood',
|
||||
price: 1234,
|
||||
feasible: false,
|
||||
feasible_explanation: 'It is impossible',
|
||||
administrator: administrator)
|
||||
spending_proposal.valuators << [@valuator, valuator2]
|
||||
|
||||
expect { visit valuation_spending_proposal_path(spending_proposal) }.to raise_error "Not Found"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
feature 'Valuate' do
|
||||
background do
|
||||
@spending_proposal = create(:spending_proposal,
|
||||
geozone: create(:geozone),
|
||||
administrator: create(:administrator))
|
||||
@spending_proposal.valuators << @valuator
|
||||
end
|
||||
|
||||
scenario 'Dossier empty by default' do
|
||||
visit valuation_spending_proposals_path
|
||||
click_link @spending_proposal.title
|
||||
|
||||
within('#price') { expect(page).to have_content('Undefined') }
|
||||
within('#price_first_year') { expect(page).to have_content('Undefined') }
|
||||
within('#time_scope') { expect(page).to have_content('Undefined') }
|
||||
within('#feasibility') { expect(page).to have_content('Undefined') }
|
||||
expect(page).to_not have_content('Valuation finished')
|
||||
expect(page).to_not have_content('Internal comments')
|
||||
end
|
||||
|
||||
scenario 'Edit dossier' do
|
||||
visit valuation_spending_proposals_path
|
||||
within("#spending_proposal_#{@spending_proposal.id}") do
|
||||
click_link "Edit"
|
||||
end
|
||||
|
||||
fill_in 'spending_proposal_price', with: '12345'
|
||||
fill_in 'spending_proposal_price_first_year', with: '9876'
|
||||
fill_in 'spending_proposal_price_explanation', with: 'Very cheap idea'
|
||||
choose 'spending_proposal_feasible_true'
|
||||
fill_in 'spending_proposal_feasible_explanation', with: 'Everything is legal and easy to do'
|
||||
fill_in 'spending_proposal_time_scope', with: '19 months'
|
||||
fill_in 'spending_proposal_internal_comments', with: 'Should be double checked by the urbanism area'
|
||||
click_button 'Save changes'
|
||||
|
||||
expect(page).to have_content "Dossier updated"
|
||||
|
||||
visit valuation_spending_proposals_path
|
||||
click_link @spending_proposal.title
|
||||
|
||||
within('#price') { expect(page).to have_content('12345') }
|
||||
within('#price_first_year') { expect(page).to have_content('9876') }
|
||||
expect(page).to have_content('Very cheap idea')
|
||||
within('#time_scope') { expect(page).to have_content('19 months') }
|
||||
within('#feasibility') { expect(page).to have_content('Feasible') }
|
||||
expect(page).to_not have_content('Valuation finished')
|
||||
expect(page).to have_content('Internal comments')
|
||||
expect(page).to have_content('Should be double checked by the urbanism area')
|
||||
end
|
||||
|
||||
scenario 'Finish valuation' do
|
||||
visit valuation_spending_proposal_path(@spending_proposal)
|
||||
click_link 'Edit dossier'
|
||||
|
||||
check 'spending_proposal_valuation_finished'
|
||||
click_button 'Save changes'
|
||||
|
||||
visit valuation_spending_proposals_path
|
||||
expect(page).to_not have_content @spending_proposal.title
|
||||
click_link 'Valuation finished'
|
||||
|
||||
expect(page).to have_content @spending_proposal.title
|
||||
click_link @spending_proposal.title
|
||||
expect(page).to have_content('Valuation finished')
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
78
spec/features/valuation_spec.rb
Normal file
78
spec/features/valuation_spec.rb
Normal file
@@ -0,0 +1,78 @@
|
||||
require 'rails_helper'
|
||||
|
||||
feature 'Valuation' do
|
||||
let(:user) { create(:user) }
|
||||
|
||||
scenario 'Access as regular user is not authorized' do
|
||||
login_as(user)
|
||||
visit root_path
|
||||
|
||||
expect(page).to_not have_link("Valuation")
|
||||
visit valuation_root_path
|
||||
|
||||
expect(current_path).not_to eq(valuation_root_path)
|
||||
expect(current_path).to eq(proposals_path)
|
||||
expect(page).to have_content "You do not have permission to access this page"
|
||||
end
|
||||
|
||||
scenario 'Access as moderator is not authorized' do
|
||||
create(:moderator, user: user)
|
||||
login_as(user)
|
||||
visit root_path
|
||||
|
||||
expect(page).to_not have_link("Valuation")
|
||||
visit valuation_root_path
|
||||
|
||||
expect(current_path).not_to eq(valuation_root_path)
|
||||
expect(current_path).to eq(proposals_path)
|
||||
expect(page).to have_content "You do not have permission to access this page"
|
||||
end
|
||||
|
||||
scenario 'Access as a valuator is authorized' do
|
||||
create(:valuator, user: user)
|
||||
login_as(user)
|
||||
visit root_path
|
||||
|
||||
expect(page).to have_link("Valuation")
|
||||
click_on "Valuation"
|
||||
|
||||
expect(current_path).to eq(valuation_root_path)
|
||||
expect(page).to_not have_content "You do not have permission to access this page"
|
||||
end
|
||||
|
||||
scenario 'Access as an administrator is authorized' do
|
||||
create(:administrator, user: user)
|
||||
login_as(user)
|
||||
visit root_path
|
||||
|
||||
expect(page).to have_link("Valuation")
|
||||
click_on "Valuation"
|
||||
|
||||
expect(current_path).to eq(valuation_root_path)
|
||||
expect(page).to_not have_content "You do not have permission to access this page"
|
||||
end
|
||||
|
||||
scenario "Valuation access links" do
|
||||
create(:valuator, user: user)
|
||||
login_as(user)
|
||||
visit root_path
|
||||
|
||||
expect(page).to have_link('Valuation')
|
||||
expect(page).to_not have_link('Administration')
|
||||
expect(page).to_not have_link('Moderation')
|
||||
end
|
||||
|
||||
scenario 'Valuation dashboard' do
|
||||
create(:valuator, user: user)
|
||||
login_as(user)
|
||||
visit root_path
|
||||
|
||||
click_link 'Valuation'
|
||||
|
||||
expect(current_path).to eq(valuation_root_path)
|
||||
expect(page).to have_css('#valuation_menu')
|
||||
expect(page).to_not have_css('#admin_menu')
|
||||
expect(page).to_not have_css('#moderation_menu')
|
||||
end
|
||||
|
||||
end
|
||||
10
spec/models/abilities/valuator_spec.rb
Normal file
10
spec/models/abilities/valuator_spec.rb
Normal file
@@ -0,0 +1,10 @@
|
||||
require 'rails_helper'
|
||||
require 'cancan/matchers'
|
||||
|
||||
describe "Abilities::Valuator" do
|
||||
subject(:ability) { Ability.new(user) }
|
||||
let(:user) { valuator.user }
|
||||
let(:valuator) { create(:valuator) }
|
||||
|
||||
it { should be_able_to(:manage, SpendingProposal) }
|
||||
end
|
||||
@@ -61,6 +61,38 @@ describe SpendingProposal do
|
||||
end
|
||||
end
|
||||
|
||||
describe "by_administrator" do
|
||||
it "should return spending proposals assigned to specific administrator" do
|
||||
spending_proposal1 = create(:spending_proposal, administrator_id: 33)
|
||||
spending_proposal2 = create(:spending_proposal)
|
||||
|
||||
by_administrator = SpendingProposal.by_administrator(33)
|
||||
|
||||
expect(by_administrator.size).to eq(1)
|
||||
expect(by_administrator.first).to eq(spending_proposal1)
|
||||
end
|
||||
end
|
||||
|
||||
describe "by_valuator" do
|
||||
it "should return spending proposals assigned to specific valuator" do
|
||||
spending_proposal1 = create(:spending_proposal)
|
||||
spending_proposal2 = create(:spending_proposal)
|
||||
spending_proposal3 = create(:spending_proposal)
|
||||
|
||||
valuator1 = create(:valuator)
|
||||
valuator2 = create(:valuator)
|
||||
|
||||
spending_proposal1.valuators << valuator1
|
||||
spending_proposal2.valuators << valuator2
|
||||
spending_proposal3.valuators << [valuator1, valuator2]
|
||||
|
||||
by_valuator = SpendingProposal.by_valuator(valuator1.id)
|
||||
|
||||
expect(by_valuator.size).to eq(2)
|
||||
expect(by_valuator.sort).to eq([spending_proposal1,spending_proposal3].sort)
|
||||
end
|
||||
end
|
||||
|
||||
describe "scopes" do
|
||||
describe "valuation_open" do
|
||||
it "should return all spending proposals with false valuation_finished" do
|
||||
|
||||
Reference in New Issue
Block a user