Skip to content

Commit

Permalink
Merge pull request #821 from consul/spending_proposals
Browse files Browse the repository at this point in the history
Spending proposals
  • Loading branch information
kikito committed Jan 13, 2016
2 parents e165f1d + 0c6aa3d commit 15ce538
Show file tree
Hide file tree
Showing 48 changed files with 942 additions and 20 deletions.
23 changes: 23 additions & 0 deletions app/controllers/admin/spending_proposals_controller.rb
@@ -0,0 +1,23 @@
class Admin::SpendingProposalsController < Admin::BaseController
has_filters %w{unresolved accepted rejected}, only: :index

load_and_authorize_resource

def index
@spending_proposals = @spending_proposals.includes([:geozone]).send(@current_filter).order(created_at: :desc).page(params[:page])
end

def show
end

def accept
@spending_proposal.accept
redirect_to request.query_parameters.merge(action: :index)
end

def reject
@spending_proposal.reject
redirect_to request.query_parameters.merge(action: :index)
end

end
2 changes: 1 addition & 1 deletion app/controllers/moderation/users_controller.rb
Expand Up @@ -30,4 +30,4 @@ def block_user
Activity.log(current_user, :block, @user)
end

end
end
32 changes: 32 additions & 0 deletions app/controllers/spending_proposals_controller.rb
@@ -0,0 +1,32 @@
class SpendingProposalsController < ApplicationController
before_action :authenticate_user!, except: [:index]

load_and_authorize_resource

def index
end

def new
@spending_proposal = SpendingProposal.new
@featured_tags = ActsAsTaggableOn::Tag.where(featured: true)
end

def create
@spending_proposal = SpendingProposal.new(spending_proposal_params)
@spending_proposal.author = current_user

if @spending_proposal.save_with_captcha
redirect_to spending_proposals_path, notice: t('flash.actions.create.notice', resource_name: t("activerecord.models.spending_proposal", count: 1))
else
@featured_tags = ActsAsTaggableOn::Tag.where(featured: true)
render :new
end
end

private

def spending_proposal_params
params.require(:spending_proposal).permit(:title, :description, :external_url, :geozone_id, :terms_of_service, :captcha, :captcha_key)
end

end
11 changes: 11 additions & 0 deletions app/helpers/geozones_helper.rb
@@ -0,0 +1,11 @@
module GeozonesHelper

def geozone_name(geozonable)
geozonable.geozone ? geozonable.geozone.name : t("geozones.none")
end

def geozone_select_options
Geozone.all.order(name: :asc).collect { |g| [ g.name, g.id ] }
end

end
2 changes: 2 additions & 0 deletions app/models/abilities/administrator.rb
Expand Up @@ -34,6 +34,8 @@ def initialize(user)
can [:search, :create, :index, :destroy], ::Moderator

can :manage, Annotation

can :manage, SpendingProposal
end
end
end
3 changes: 3 additions & 0 deletions app/models/abilities/common.rb
Expand Up @@ -17,6 +17,8 @@ def initialize(user)
proposal.editable_by?(user)
end

can :read, SpendingProposal

can :create, Comment
can :create, Debate
can :create, Proposal
Expand All @@ -38,6 +40,7 @@ def initialize(user)
if user.level_two_or_three_verified?
can :vote, Proposal
can :vote_featured, Proposal
can :create, SpendingProposal
end

can :create, Annotation
Expand Down
1 change: 1 addition & 0 deletions app/models/abilities/everyone.rb
Expand Up @@ -6,6 +6,7 @@ def initialize(user)
can :read, Debate
can :read, Proposal
can :read, Comment
can :read, SpendingProposal
can :read, Legislation
can :read, User
can [:search, :read], Annotation
Expand Down
2 changes: 1 addition & 1 deletion app/models/concerns/sanitizable.rb
Expand Up @@ -13,7 +13,7 @@ def sanitize_description
end

def sanitize_tag_list
self.tag_list = TagSanitizer.new.sanitize_tag_list(self.tag_list)
self.tag_list = TagSanitizer.new.sanitize_tag_list(self.tag_list) if self.class.taggable?
end

end
3 changes: 3 additions & 0 deletions app/models/geozone.rb
@@ -0,0 +1,3 @@
class Geozone < ActiveRecord::Base
validates :name, presence: true
end
44 changes: 44 additions & 0 deletions app/models/spending_proposal.rb
@@ -0,0 +1,44 @@
class SpendingProposal < ActiveRecord::Base
include Measurable
include Sanitizable

apply_simple_captcha

RESOLUTIONS = ["accepted", "rejected"]

belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id'
belongs_to :geozone

validates :title, presence: true
validates :author, presence: true
validates :description, presence: true

validates :title, length: { in: 4..SpendingProposal.title_max_length }
validates :description, length: { maximum: SpendingProposal.description_max_length }
validates :resolution, inclusion: { in: RESOLUTIONS, allow_nil: true }
validates :terms_of_service, acceptance: { allow_nil: false }, on: :create

scope :accepted, -> { where(resolution: "accepted") }
scope :rejected, -> { where(resolution: "rejected") }
scope :unresolved, -> { where(resolution: nil) }

def accept
update_attribute(:resolution, "accepted")
end

def reject
update_attribute(:resolution, "rejected")
end

def accepted?
resolution == "accepted"
end

def rejected?
resolution == "rejected"
end

def unresolved?
resolution.blank?
end
end
7 changes: 7 additions & 0 deletions app/views/admin/_menu.html.erb
Expand Up @@ -32,6 +32,13 @@
<% end %>
</li>

<li <%= "class=active" if controller_name == "spending_proposals" %>>
<%= link_to admin_spending_proposals_path do %>
<i class="icon-proposals"></i>
<%= t("admin.menu.spending_proposals") %>
<% end %>
</li>

<li <%= "class=active" if controller_name == "users" %>>
<%= link_to admin_users_path do %>
<i class="icon-eye"></i>
Expand Down
36 changes: 36 additions & 0 deletions app/views/admin/spending_proposals/index.html.erb
@@ -0,0 +1,36 @@
<h2><%= t("admin.spending_proposals.index.title") %></h2>

<%= render 'shared/filter_subnav', i18n_namespace: "admin.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><%= link_to spending_proposal.title, admin_spending_proposal_path(spending_proposal) %></strong>
</td>
<td>
<%= geozone_name(spending_proposal) %>
</td>
<td>
<% unless spending_proposal.accepted? %>
<%= link_to t("admin.spending_proposals.actions.accept"),
accept_admin_spending_proposal_path(spending_proposal, request.query_parameters),
method: :put,
data: { confirm: t("admin.actions.confirm") },
class: "button radius tiny success no-margin" %>
<% end %>
<% unless spending_proposal.rejected? %>
<%= link_to t("admin.spending_proposals.actions.reject"),
reject_admin_spending_proposal_path(spending_proposal, request.query_parameters),
method: :put,
data: { confirm: t("admin.actions.confirm") },
class: "button radius tiny warning right" %>
<% end %>
</td>
</tr>
<% end %>
</table>

<%= paginate @spending_proposals %>
28 changes: 28 additions & 0 deletions app/views/admin/spending_proposals/show.html.erb
@@ -0,0 +1,28 @@
<h2><%= @spending_proposal.title %></h2>

<%= safe_html_with_links @spending_proposal.description.html_safe %>
<% if @spending_proposal.external_url.present? %>
<p><%= text_with_links @spending_proposal.external_url %></p>
<% end %>

<p><%= t("admin.spending_proposals.show.by") %>: <%= link_to @spending_proposal.author.name, admin_user_path(@spending_proposal.author) %></p>
<p><%= t("admin.spending_proposals.show.geozone") %>: <%= geozone_name(@spending_proposal) %></p>
<p><%= l @spending_proposal.created_at, format: :datetime %></p>

<p>
<% unless @spending_proposal.accepted? %>
<%= link_to t("admin.spending_proposals.actions.accept"),
accept_admin_spending_proposal_path(@spending_proposal),
method: :put,
data: { confirm: t("admin.actions.confirm") },
class: "button radius tiny success no-margin" %>
<% end %>
<% unless @spending_proposal.rejected? %>
<%= link_to t("admin.spending_proposals.actions.reject"),
reject_admin_spending_proposal_path(@spending_proposal),
method: :put,
data: { confirm: t("admin.actions.confirm") },
class: "button radius tiny warning" %>
<% end %>
</p>
16 changes: 9 additions & 7 deletions app/views/layouts/_header.html.erb
Expand Up @@ -33,14 +33,16 @@
</section>

<section class="subnavigation row">

<div class="small-12 medium-9 column">
<%= link_to t("layouts.header.debates"), debates_path, class: ("active" if current_page?(controller: "/debates")) %>
<%= link_to t("layouts.header.proposals"), proposals_path, class: ("active" if current_page?(controller: "/proposals")) %>
<%= link_to t("layouts.header.more_information"), page_path('more_information'), class: ("active" if current_page?("/more_information")) %>
<%= link_to t("layouts.header.external_link_blog_url"), target: "_blank" do %>
<%= t("layouts.header.external_link_blog") %>
<small><i class="icon-external"></i></small>
<% end %>
<%= link_to t("layouts.header.debates"), debates_path, class: ("active" if controller_name == "debates") %>
<%= link_to t("layouts.header.proposals"), proposals_path, class: ("active" if controller_name == "proposals") %>
<%= link_to t("layouts.header.spending_proposals"), spending_proposals_path, class: ("active" if controller_name == "spending_proposals") %>
<%= link_to t("layouts.header.more_information"), page_path('more_information'), class: ("active" if current_page?("/more_information")) %>
<%= link_to t("layouts.header.external_link_blog_url"), target: "_blank" do %>
<%= t("layouts.header.external_link_blog") %>
<small><i class="icon-external"></i></small>
<% end %>
</div>
<div class="small-12 medium-3 column">
<%= yield :header_addon %>
Expand Down
6 changes: 6 additions & 0 deletions app/views/pages/more_information.html.erb
Expand Up @@ -29,6 +29,12 @@
<% end %>
</li>
<li>
<%= link_to page_path('spending_proposals_info') do %>
<%= t('pages.more_information.titles.spending_proposals_info') %>
<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') %>
<span><%= t('pages.more_information.description.participation_world') %></span>
Expand Down
20 changes: 20 additions & 0 deletions app/views/pages/spending_proposals_info.html.erb
@@ -0,0 +1,20 @@
<div class="page row-full">
<div class="row">
<div class="menu small-12 medium-3 column">
<i class="icon-angle-left left"></i>&nbsp;
<%= link_to t("spending_proposals.new.back_link"), "/more_information", class: 'left back' %>
<ul class="clear">
<li>
<a href="#i">Explicación detallada del proceso</a>
</li>
</ul>
</div>
<div class="text small-12 medium-9 column">
<h1>¿Cómo funcionan los presupuestos ciudadanos?</h1>

<h2 id="i">Explicación detallada del proceso</h2>
<p>Próximamente se podrá encontrar aquí una descripción del proceso de participación ciudadana en los presupuestos.</p>

</div>
</div>
</div>
4 changes: 1 addition & 3 deletions app/views/proposals/_form.html.erb
Expand Up @@ -79,6 +79,4 @@
<%= f.submit(class: "button radius", value: t("proposals.#{action_name}.form.submit_button")) %>
</div>
</div>
<% end %>


<% end %>
2 changes: 1 addition & 1 deletion app/views/shared/_errors.html.erb
Expand Up @@ -8,7 +8,7 @@
<% if local_assigns[:message].present? %>
<%= message %>
<% else %>
<%= t("form.not_saved", resource: t("form.#{resource.class.to_s.downcase}")) %>
<%= t("form.not_saved", resource: t("form.#{resource.class.to_s.underscore}")) %>
<% end %>
</strong>
</div>
Expand Down
46 changes: 46 additions & 0 deletions app/views/spending_proposals/_form.html.erb
@@ -0,0 +1,46 @@
<%= form_for(@spending_proposal, url: form_url) do |f| %>
<%= render 'shared/errors', resource: @spending_proposal %>

<div class="row">
<div class="small-12 column">
<%= f.label :title, t("spending_proposals.form.title") %>
<%= f.text_field :title, maxlength: SpendingProposal.title_max_length, placeholder: t("spending_proposals.form.title"), label: false %>
</div>

<div class="ckeditor small-12 column">
<%= f.label :description, t("spending_proposals.form.description") %>
<%= f.cktext_area :description, maxlength: SpendingProposal.description_max_length, ckeditor: { language: I18n.locale }, label: false %>
</div>

<div class="small-12 column">
<%= f.label :external_url, t("spending_proposals.form.external_url") %>
<%= f.text_field :external_url, placeholder: t("spending_proposals.form.external_url"), label: false %>
</div>

<div class="small-12 column">
<%= f.label :geozone_id, t("spending_proposals.form.geozone") %>
<%= f.select :geozone_id, geozone_select_options, {include_blank: t("geozones.none"), label: false} %>
</div>

<div class="small-12 column">
<% if @spending_proposal.new_record? %>
<%= f.label :terms_of_service do %>
<%= f.check_box :terms_of_service, label: false %>
<span class="checkbox">
<%= t("form.accept_terms",
policy: link_to(t("form.policy"), "/privacy", target: "blank"),
conditions: link_to(t("form.conditions"), "/conditions", target: "blank")).html_safe %>
</span>
<% end %>
<% end %>
</div>

<div class="small-12 column">
<%= f.simple_captcha input_html: { required: false } %>
</div>

<div class="actions small-12 column">
<%= f.submit(class: "button radius", value: t("spending_proposals.form.submit_buttons.#{action_name}")) %>
</div>
</div>
<% end %>
16 changes: 16 additions & 0 deletions app/views/spending_proposals/index.html.erb
@@ -0,0 +1,16 @@
<% provide :title do %><%= t('spending_proposals.index.title') %><% end %>
<div class="page row-full">
<div class="row">
<div class="more-information text small-12 medium-8 column">
<h1><%= t('spending_proposals.index.title') %></h1>

<p><%= t('spending_proposals.index.text') %></p>

<% if can? :create, SpendingProposal %>
<%= link_to t('spending_proposals.index.create_link'), new_spending_proposal_path, class: 'button radius' %>
<% else %>
<p><%= t('spending_proposals.index.verified_only', verify_account: link_to(t('spending_proposals.index.verify_account'), verification_path)).html_safe %></p>
<% end %>
</div>
</div>
</div>

0 comments on commit 15ce538

Please sign in to comment.