Merge pull request #1906 from consul/1856-legislation_processes_proposals_phase

[WIP] Legislation Process Proposals
This commit is contained in:
Alberto García
2017-10-27 12:41:09 +02:00
committed by GitHub
62 changed files with 1227 additions and 31 deletions

View File

@@ -109,16 +109,13 @@ $border-dark: darken($border, 10%);
li {
cursor: pointer;
display: inline-block;
margin: 0 1rem 1rem 0;
margin-bottom: $line-height;
margin-right: $line-height;
transition: all 0.4s;
border-bottom: 2px solid transparent;
@include breakpoint(medium) {
margin-left: $line-height * 2;
}
&:first-of-type {
margin-left: 0;
margin-bottom: 0;
}
&:hover,

View File

@@ -855,7 +855,9 @@
}
.debate,
.debate-show {
.debate-show,
.proposal-show,
.legislation-proposals {
.votes {
@include votes;
@@ -870,6 +872,7 @@
}
}
.proposal-show .votes,
.debate-show .votes {
border: 0;
padding: $line-height / 2 0;

View File

@@ -19,8 +19,10 @@ class Admin::Legislation::ProcessesController < Admin::Legislation::BaseControll
def update
if @process.update(process_params)
set_tag_list
link = legislation_process_path(@process).html_safe
redirect_to edit_admin_legislation_process_path(@process), notice: t('admin.legislation.processes.update.notice', link: link)
redirect_to :back, notice: t('admin.legislation.processes.update.notice', link: link)
else
flash.now[:error] = t('admin.legislation.processes.update.error')
render :edit
@@ -47,12 +49,22 @@ class Admin::Legislation::ProcessesController < Admin::Legislation::BaseControll
:draft_publication_date,
:allegations_start_date,
:allegations_end_date,
:proposals_phase_start_date,
:proposals_phase_end_date,
:result_publication_date,
:debate_phase_enabled,
:allegations_phase_enabled,
:proposals_phase_enabled,
:draft_publication_enabled,
:result_publication_enabled,
:published
:published,
:proposals_description,
:custom_list
)
end
def set_tag_list
@process.set_tag_list_on(:customs, process_params[:custom_list])
@process.save
end
end

View File

@@ -0,0 +1,7 @@
class Admin::Legislation::ProposalsController < Admin::Legislation::BaseController
load_and_authorize_resource :process, class: "Legislation::Process"
load_and_authorize_resource :proposal, class: "Legislation::Proposal", through: :process
def index
end
end

View File

@@ -2,4 +2,8 @@ class Legislation::BaseController < ApplicationController
include FeatureFlags
feature_flag :legislation
def set_legislation_proposal_votes(proposals)
@legislation_proposal_votes = current_user ? current_user.legislation_proposal_votes(proposals) : {}
end
end

View File

@@ -14,6 +14,8 @@ class Legislation::ProcessesController < Legislation::BaseController
redirect_to legislation_process_draft_version_path(@process, draft_version)
elsif @process.debate_phase.enabled?
redirect_to debate_legislation_process_path(@process)
elsif @process.proposals_phase.enabled?
redirect_to proposals_legislation_process_path(@process)
else
redirect_to allegations_legislation_process_path(@process)
end
@@ -81,6 +83,18 @@ class Legislation::ProcessesController < Legislation::BaseController
end
end
def proposals
set_process
@phase = :proposals_phase
if @process.proposals_phase.started?
set_legislation_proposal_votes(@process.proposals)
render :proposals
else
render :phase_not_open
end
end
private
def member_method?

View File

@@ -0,0 +1,70 @@
class Legislation::ProposalsController < Legislation::BaseController
include CommentableActions
include FlagActions
load_and_authorize_resource :process, class: "Legislation::Process"
load_and_authorize_resource :proposal, class: "Legislation::Proposal", through: :process
before_action :parse_tag_filter, only: :index
before_action :load_categories, only: [:index, :new, :create, :edit, :map, :summary]
before_action :load_geozones, only: [:edit, :map, :summary]
before_action :authenticate_user!, except: [:index, :show, :map, :summary]
invisible_captcha only: [:create, :update], honeypot: :subtitle
has_orders %w{confidence_score created_at}, only: :index
has_orders %w{most_voted newest oldest}, only: :show
helper_method :resource_model, :resource_name
respond_to :html, :js
def show
super
set_legislation_proposal_votes(@process.proposals)
@document = Document.new(documentable: @proposal)
redirect_to legislation_process_proposal_path(params[:process_id], @proposal),
status: :moved_permanently if request.path != legislation_process_proposal_path(params[:process_id], @proposal)
end
def create
@proposal = Legislation::Proposal.new(proposal_params.merge(author: current_user))
if @proposal.save
redirect_to legislation_process_proposal_path(params[:process_id], @proposal), notice: I18n.t('flash.actions.create.proposal')
else
render :new
end
end
def index_customization
load_successful_proposals
load_featured unless @proposal_successful_exists
end
def vote
@proposal.register_vote(current_user, params[:value])
set_legislation_proposal_votes(@proposal)
end
private
def proposal_params
params.require(:legislation_proposal).permit(:legislation_process_id, :title,
:question, :summary, :description, :video_url, :tag_list,
:terms_of_service, :geozone_id,
documents_attributes: [:id, :title, :attachment, :cached_attachment, :user_id] )
end
def resource_model
Legislation::Proposal
end
def resource_name
'proposal'
end
def load_successful_proposals
@proposal_successful_exists = Legislation::Proposal.successful.exists?
end
end

View File

@@ -17,7 +17,7 @@ module AdminHelper
end
def menu_moderated_content?
["proposals", "debates", "comments", "hidden_users"].include? controller_name
["proposals", "debates", "comments", "hidden_users"].include? controller_name && controller.class.parent != Admin::Legislation
end
def menu_budget?

View File

@@ -8,6 +8,8 @@ module TagsHelper
proposals_path(search: tag_name)
when 'budget/investment'
budget_investments_path(@budget, search: tag_name)
when 'legislation/proposal'
legislation_process_proposals_path(@process, search: tag_name)
else
'#'
end
@@ -22,6 +24,8 @@ module TagsHelper
proposal_path(taggable)
when 'budget/investment'
budget_investment_path(taggable.budget_id, taggable)
when 'legislation/proposal'
legislation_process_proposal_path(@process, taggable)
else
'#'
end

View File

@@ -14,6 +14,9 @@ module Abilities
can :restore, Proposal
cannot :restore, Proposal, hidden_at: nil
can :restore, Legislation::Proposal
cannot :restore, Legislation::Proposal, hidden_at: nil
can :restore, User
cannot :restore, User, hidden_at: nil
@@ -26,6 +29,9 @@ module Abilities
can :confirm_hide, Proposal
cannot :confirm_hide, Proposal, hidden_at: nil
can :confirm_hide, Legislation::Proposal
cannot :confirm_hide, Legislation::Proposal, hidden_at: nil
can :confirm_hide, User
cannot :confirm_hide, User, hidden_at: nil
@@ -33,7 +39,7 @@ module Abilities
can :unmark_featured, Debate
can :comment_as_administrator, [Debate, Comment, Proposal, Poll::Question, Budget::Investment,
Legislation::Question, Legislation::Annotation, Topic]
Legislation::Question, Legislation::Proposal, Legislation::Annotation, Topic]
can [:search, :create, :index, :destroy], ::Administrator
can [:search, :create, :index, :destroy], ::Moderator
@@ -71,7 +77,8 @@ module Abilities
can [:manage], ::Legislation::Process
can [:manage], ::Legislation::DraftVersion
can [:manage], ::Legislation::Question
cannot :comment_as_moderator, [::Legislation::Question, Legislation::Annotation]
can [:manage], ::Legislation::Proposal
cannot :comment_as_moderator, [::Legislation::Question, Legislation::Annotation, ::Legislation::Proposal]
can [:create, :destroy], Document
can [:destroy], Image

View File

@@ -18,12 +18,20 @@ module Abilities
end
can [:retire_form, :retire], Proposal, author_id: user.id
can :read, Legislation::Proposal
cannot [:edit, :update], Legislation::Proposal do |proposal|
proposal.editable_by?(user)
end
can [:retire_form, :retire], Legislation::Proposal, author_id: user.id
can :create, Comment
can :create, Debate
can :create, Proposal
can :create, Legislation::Proposal
can :suggest, Debate
can :suggest, Proposal
can :suggest, Legislation::Proposal
can :suggest, ActsAsTaggableOn::Tag
can [:flag, :unflag], Comment
@@ -35,6 +43,9 @@ module Abilities
can [:flag, :unflag], Proposal
cannot [:flag, :unflag], Proposal, author_id: user.id
can [:flag, :unflag], Legislation::Proposal
cannot [:flag, :unflag], Legislation::Proposal, author_id: user.id
can [:create, :destroy], Follow
can [:destroy], Document, documentable: { author_id: user.id }
@@ -54,6 +65,10 @@ module Abilities
can :vote, SpendingProposal
can :create, SpendingProposal
can :vote, Legislation::Proposal
can :vote_featured, Legislation::Proposal
can :create, Legislation::Answer
can :create, Budget::Investment, budget: { phase: "accepting" }
can :suggest, Budget::Investment, budget: { phase: "accepting" }
can :destroy, Budget::Investment, budget: { phase: ["accepting", "reviewing"] }, author_id: user.id

View File

@@ -24,10 +24,10 @@ module Abilities
can [:read, :print], Budget::Investment
can :read_results, Budget, phase: "finished"
can :new, DirectMessage
can [:read, :debate, :draft_publication, :allegations, :result_publication], Legislation::Process, published: true
can [:read, :debate, :draft_publication, :allegations, :result_publication, :proposals], Legislation::Process, published: true
can [:read, :changes, :go_to_version], Legislation::DraftVersion
can [:read], Legislation::Question
can [:create], Legislation::Answer
can [:read, :map, :share], Legislation::Proposal
can [:search, :comments, :read, :create, :new_comment], Legislation::Annotation
end
end

View File

@@ -38,6 +38,15 @@ module Abilities
can :moderate, Proposal
cannot :moderate, Proposal, author_id: user.id
can :hide, Legislation::Proposal, hidden_at: nil
cannot :hide, Legislation::Proposal, author_id: user.id
can :ignore_flag, Legislation::Proposal, ignored_flag_at: nil, hidden_at: nil
cannot :ignore_flag, Legislation::Proposal, author_id: user.id
can :moderate, Legislation::Proposal
cannot :moderate, Legislation::Proposal, author_id: user.id
can :hide, User
cannot :hide, User, id: user.id

View File

@@ -6,7 +6,7 @@ module Abilities
merge Abilities::Moderation.new(user)
can :comment_as_moderator, [Debate, Comment, Proposal, Budget::Investment, Poll::Question,
Legislation::Question, Legislation::Annotation, Topic]
Legislation::Question, Legislation::Annotation, Legislation::Proposal, Topic]
end
end
end

View File

@@ -3,7 +3,7 @@ class Comment < ActiveRecord::Base
include HasPublicAuthor
include Graphqlable
COMMENTABLE_TYPES = %w(Debate Proposal Budget::Investment Poll::Question Legislation::Question Legislation::Annotation Topic Poll).freeze
COMMENTABLE_TYPES = %w(Debate Proposal Budget::Investment Poll::Question Legislation::Question Legislation::Annotation Topic Legislation::Proposal Poll).freeze
acts_as_paranoid column: :hidden_at
include ActsAsParanoidAliases

View File

@@ -1,14 +1,18 @@
class Legislation::Process < ActiveRecord::Base
acts_as_paranoid column: :hidden_at
include ActsAsParanoidAliases
include Taggable
PHASES_AND_PUBLICATIONS = %i(debate_phase allegations_phase draft_publication result_publication).freeze
acts_as_paranoid column: :hidden_at
acts_as_taggable_on :customs
PHASES_AND_PUBLICATIONS = %i(debate_phase allegations_phase proposals_phase draft_publication result_publication).freeze
has_many :draft_versions, -> { order(:id) }, class_name: 'Legislation::DraftVersion',
foreign_key: 'legislation_process_id', dependent: :destroy
has_one :final_draft_version, -> { where final_version: true, status: 'published' }, class_name: 'Legislation::DraftVersion',
foreign_key: 'legislation_process_id'
has_many :questions, -> { order(:id) }, class_name: 'Legislation::Question', foreign_key: 'legislation_process_id', dependent: :destroy
has_many :proposals, -> { order(:id) }, class_name: 'Legislation::Proposal', foreign_key: 'legislation_process_id', dependent: :destroy
validates :title, presence: true
validates :start_date, presence: true
@@ -17,6 +21,7 @@ class Legislation::Process < ActiveRecord::Base
validates :debate_end_date, presence: true, if: :debate_start_date?
validates :allegations_start_date, presence: true, if: :allegations_end_date?
validates :allegations_end_date, presence: true, if: :allegations_start_date?
validates :proposals_phase_end_date, presence: true, if: :proposals_phase_start_date?
validate :valid_date_ranges
scope :open, -> { where("start_date <= ? and end_date >= ?", Date.current, Date.current).order('id DESC') }
@@ -33,6 +38,10 @@ class Legislation::Process < ActiveRecord::Base
Legislation::Process::Phase.new(allegations_start_date, allegations_end_date, allegations_phase_enabled)
end
def proposals_phase
Legislation::Process::Phase.new(proposals_phase_start_date, proposals_phase_end_date, proposals_phase_enabled)
end
def draft_publication
Legislation::Process::Publication.new(draft_publication_date, draft_publication_enabled)
end

View File

@@ -0,0 +1,147 @@
class Legislation::Proposal < ActiveRecord::Base
include ActsAsParanoidAliases
include Flaggable
include Taggable
include Conflictable
include Measurable
include Sanitizable
include Searchable
include Filterable
include Followable
include Communitable
include Documentable
documentable max_documents_allowed: 3,
max_file_size: 3.megabytes,
accepted_content_types: [ "application/pdf" ]
accepts_nested_attributes_for :documents, allow_destroy: true
acts_as_votable
acts_as_paranoid column: :hidden_at
belongs_to :process, class_name: 'Legislation::Process', foreign_key: 'legislation_process_id'
belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id'
belongs_to :geozone
has_many :comments, as: :commentable
validates :title, presence: true
validates :summary, presence: true
validates :author, presence: true
validates :title, length: { in: 4..Legislation::Proposal.title_max_length }
validates :description, length: { maximum: Legislation::Proposal.description_max_length }
validates :terms_of_service, acceptance: { allow_nil: false }, on: :create
before_validation :set_responsible_name
before_save :calculate_hot_score, :calculate_confidence_score
scope :for_render, -> { includes(:tags) }
scope :sort_by_hot_score, -> { reorder(hot_score: :desc) }
scope :sort_by_confidence_score, -> { reorder(confidence_score: :desc) }
scope :sort_by_created_at, -> { reorder(created_at: :desc) }
scope :sort_by_most_commented, -> { reorder(comments_count: :desc) }
scope :sort_by_random, -> { reorder("RANDOM()") }
scope :sort_by_flags, -> { order(flags_count: :desc, updated_at: :desc) }
scope :last_week, -> { where("proposals.created_at >= ?", 7.days.ago)}
def to_param
"#{id}-#{title}".parameterize
end
def searchable_values
{ title => 'A',
question => 'B',
author.username => 'B',
tag_list.join(' ') => 'B',
geozone.try(:name) => 'B',
summary => 'C',
description => 'D'
}
end
def self.search(terms)
by_code = search_by_code(terms.strip)
by_code.present? ? by_code : pg_search(terms)
end
def self.search_by_code(terms)
matched_code = match_code(terms)
results = where(id: matched_code[1]) if matched_code
return results if (results.present? && results.first.code == terms)
end
def self.match_code(terms)
/\A#{Setting["proposal_code_prefix"]}-\d\d\d\d-\d\d-(\d*)\z/.match(terms)
end
def likes
cached_votes_up
end
def dislikes
cached_votes_down
end
def total_votes
cached_votes_total
end
def voters
User.active.where(id: votes_for.voters)
end
def editable?
total_votes <= Setting["max_votes_for_proposal_edit"].to_i
end
def editable_by?(user)
author_id == user.id && editable?
end
def votable_by?(user)
user && user.level_two_or_three_verified?
end
def register_vote(user, vote_value)
if votable_by?(user)
vote_by(voter: user, vote: vote_value)
end
end
def code
"#{Setting['proposal_code_prefix']}-#{created_at.strftime('%Y-%m')}-#{id}"
end
def after_commented
save # updates the hot_score because there is a before_save
end
def calculate_hot_score
self.hot_score = ScoreCalculator.hot_score(created_at,
total_votes,
total_votes,
comments_count)
end
def calculate_confidence_score
self.confidence_score = ScoreCalculator.confidence_score(total_votes, total_votes)
end
def after_hide
tags.each{ |t| t.decrement_custom_counter_for('LegislationProposal') }
end
def after_restore
tags.each{ |t| t.increment_custom_counter_for('LegislationProposal') }
end
protected
def set_responsible_name
if author && author.document_number?
self.responsible_name = author.document_number
end
end
end

View File

@@ -97,6 +97,12 @@ class User < ActiveRecord::Base
voted.each_with_object({}) { |v, h| h[v.votable_id] = v.value }
end
def legislation_proposal_votes(proposals)
voted = votes.for_legislation_proposals(proposals)
voted.each_with_object({}) { |v, h| h[v.votable_id] = v.value }
end
def spending_proposal_votes(spending_proposals)
voted = votes.for_spending_proposals(spending_proposals)
voted.each_with_object({}) { |v, h| h[v.votable_id] = v.value }

View File

@@ -19,7 +19,7 @@
<strong><%= t("admin.menu.title_moderated_content") %></strong>
</a>
<ul <%= "class=is-active" if menu_moderated_content? %>>
<li <%= "class=active" if controller_name == "proposals" %>>
<li <%= "class=active" if controller_name == "proposals" && controller.class.parent != Admin::Legislation %>>
<%= link_to t("admin.menu.hidden_proposals"), admin_proposals_path %>
</li>

View File

@@ -114,6 +114,39 @@
</div>
</div>
<div class="row">
<div class="small-12 medium-4 column">
<label><%= t('admin.legislation.processes.form.proposals_phase') %></label>
</div>
<div class="small-12 medium-1 column legislation-process-start">
<%= t('admin.legislation.processes.form.start') %>
</div>
<div class="small-12 medium-2 column">
<%= f.text_field :proposals_phase_start_date,
label: false,
value: format_date_for_calendar_form(@process.proposals_phase_start_date),
class: "js-calendar-full",
id: "proposals_phase_start_date" %>
</div>
<div class="small-12 medium-1 column legislation-process-end">
<%= t('admin.legislation.processes.form.end') %>
</div>
<div class="small-12 medium-2 column">
<%= f.text_field :proposals_phase_end_date,
label: false,
value: format_date_for_calendar_form(@process.proposals_phase_end_date),
class: "js-calendar-full",
id: "proposals_phase_end_date" %>
</div>
<div class="small-12 medium-2 column">
<%= f.check_box :proposals_phase_enabled, checked: @process.proposals_phase.enabled?, label: t('admin.legislation.processes.form.enabled') %>
</div>
<div class="small-12 column">
<hr>
</div>
</div>
<div class="row">
<div class="small-12 medium-4 column">
<%= f.label :draft_publication_date %>

View File

@@ -19,6 +19,16 @@
</li>
<% end %>
<% if active == 'proposals' %>
<li class="active">
<h2><%= t("admin.legislation.processes.subnav.proposals") %></h2>
</li>
<% else %>
<li>
<%= link_to t("admin.legislation.processes.subnav.proposals"), admin_legislation_process_proposals_path(process) %>
</li>
<% end %>
<% if active == 'draft_versions' %>
<li class="active">
<h2><%= t("admin.legislation.processes.subnav.draft_texts") %></h2>

View File

@@ -0,0 +1,50 @@
<%= form_for [:admin, @process], html: {data: {watch_changes: true}} do |f| %>
<% if @process.errors.any? %>
<div id="error_explanation" data-alert class="callout alert" data-closable>
<button class="close-button" aria-label="<%= t("application.close") %>" type="button" data-close>
<span aria-hidden="true">&times;</span>
</button>
<strong>
<%= @process.errors.count %>
<%= t("admin.legislation.processes.errors.form.error", count: @process.errors.count) %>
</strong>
</div>
<% end %>
<div class="row">
<div class="small-12 medium-4 column">
<%= label_tag t('admin.legislation.proposals.form.header_information') %>
<small><%= t('admin.legislation.proposals.form.header_information_description') %></small>
</div>
<div class="small-12 medium-8 column">
<%= f.text_area :proposals_description,
label: false,
rows: 5,
placeholder: t('admin.legislation.proposals.form.header_information_placeholder') %>
</div>
</div>
<div class="row">
<div class="small-12 medium-4 column">
<%= label_tag t('admin.legislation.proposals.form.custom_categories') %>
<small><%= t('admin.legislation.proposals.form.custom_categories_description') %></small>
</div>
<div class="small-12 medium-8 column">
<%= f.text_field :custom_list, value: @process.tag_list_on(:customs).to_s,
label: false,
placeholder: t("proposals.form.tags_placeholder"),
class: 'js-tag-list',
aria: {describedby: "tag-list-help-text"} %>
</div>
</div>
<div class="row">
<div class="actions small-12 medium-3 column legislation-process-save">
<%= f.submit(class: "button expanded", value: t("admin.legislation.processes.#{admin_submit_action(@process)}.submit_button")) %>
</div>
</div>
<% end %>

View File

@@ -0,0 +1,16 @@
<% provide :title do %>
Admin - <%= t("admin.menu.legislation") %> - <%= @process.title %> - <%= t("admin.legislation.proposals.index.title") %>
<% end %>
<div class="legislation-admin legislation-draft-versions-index row">
<div class="small-12 column">
<%= back_link_to admin_legislation_processes_path, t("admin.legislation.proposals.index.back") %>
<h2><%= @process.title %></h2>
<%= render 'admin/legislation/processes/subnav', process: @process, active: 'proposals' %>
<%= render "form" %>
</div>
</div>

View File

@@ -6,7 +6,7 @@
<ul>
<% if process.debate_phase.enabled? %>
<li <%= 'class="active"' if phase.to_sym == :debate_phase %>>
<li <%= 'class=active' if phase.to_sym == :debate_phase %>>
<%= link_to debate_legislation_process_path(process) do %>
<h4><%= t('legislation.processes.shared.debate_dates') %></h4>
<p><%= format_date(process.debate_start_date) %> - <%= format_date(process.debate_end_date) %></p>
@@ -14,8 +14,17 @@
</li>
<% end %>
<% if process.proposals_phase.enabled? %>
<li <%= 'class=active' if phase.to_sym == :proposals_phase %>>
<%= link_to proposals_legislation_process_path(process) do %>
<h4><%= t('legislation.processes.shared.proposals_dates') %></h4>
<p><%= format_date(process.proposals_phase_start_date) %> - <%= format_date(process.proposals_phase_end_date) %></p>
<% end %>
</li>
<% end %>
<% if process.draft_publication.enabled? %>
<li <%= 'class="active"' if phase.to_sym == :draft_publication %>>
<li <%= 'class=active' if phase.to_sym == :draft_publication %>>
<%= link_to draft_publication_legislation_process_path(process) do %>
<h4><%= t('legislation.processes.shared.draft_publication_date') %></h4>
<p><%= format_date(process.draft_publication_date) %></p>
@@ -24,7 +33,7 @@
<% end %>
<% if process.allegations_phase.enabled? %>
<li <%= 'class="active"' if phase.to_sym == :allegations_phase %>>
<li <%= 'class=active' if phase.to_sym == :allegations_phase %>>
<%= link_to allegations_legislation_process_path(process) do %>
<h4><%= t('legislation.processes.shared.allegations_dates') %></h4>
<p><%= format_date(process.allegations_start_date) %> - <%= format_date(process.allegations_end_date) %></p>
@@ -33,7 +42,7 @@
<% end %>
<% if process.result_publication.enabled? %>
<li <%= 'class="active"' if phase.to_sym == :result_publication %>>
<li <%= 'class=active' if phase.to_sym == :result_publication %>>
<%= link_to result_publication_legislation_process_path(process) do %>
<h4><%= t('legislation.processes.shared.result_publication_date') %></h4>
<p><%= format_date(process.result_publication_date) %></p>

View File

@@ -40,6 +40,13 @@
</div>
<% end %>
<% if process.proposals_phase.enabled? %>
<div class="small-6 medium-<%= column_width %> column">
<h5><%= t('legislation.processes.shared.proposals_dates') %></h5>
<p><%= format_date(process.proposals_phase_start_date) %> - <%= format_date(process.proposals_phase_end_date) %></p>
</div>
<% end %>
<% if process.allegations_phase.enabled? %>
<div class="small-6 medium-<%= column_width %> column">
<h5><%= t('legislation.processes.shared.allegations_dates') %></h5>

View File

@@ -0,0 +1,30 @@
<% provide :title do %><%= @process.title %><% end %>
<%= render 'legislation/processes/header', process: @process, header: :full %>
<%= render 'key_dates', process: @process, phase: :proposals %>
<div class="row">
<div class="debate-chooser">
<div class="row">
<div class="small-12 medium-9 column">
<div class="legislation-proposals">
<% if @process.proposals.empty? %>
<div class="callout primary">
<p><%= t('.empty_proposals') %></p>
</div>
<% else %>
<%= render @process.proposals %>
<% end %>
</div>
</div>
<div class="small-12 medium-3 column">
<% if @process.proposals_phase.open? %>
<p><%= link_to t("proposals.index.start_proposal"), new_legislation_process_proposal_path(@process), class: 'button expanded' %></p>
<% end %>
<%= render 'legislation/proposals/categories', taggable: @process %>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,10 @@
<% if can? :hide, proposal %>
<%= link_to t("admin.actions.hide").capitalize, hide_moderation_proposal_path(proposal),
method: :put, remote: true, data: { confirm: t('admin.actions.confirm') } %>
<% end %>
<% if can? :hide, proposal.author %>
&nbsp;|&nbsp;
<%= link_to t("admin.actions.hide_author").capitalize, hide_moderation_user_path(proposal.author_id),
method: :put, data: { confirm: t('admin.actions.confirm') } %>
<% end %>

View File

@@ -0,0 +1,14 @@
<div class="sidebar-divider"></div>
<h2 class="sidebar-title"><%= t("shared.tags_cloud.categories") %></h2>
<br>
<ul id="categories" class="no-bullet categories">
<% @process.tag_list_on(:customs).each do |tag| %>
<li class="inline-block">
<% css_class = { class: 'active' } if params[:search] == tag %>
<%= link_to tag,
legislation_process_proposals_path(process_id: @process, search: tag),
css_class || {} %>
</li>
<% end %>
</ul>

View File

@@ -0,0 +1,24 @@
<% cache [locale_and_user_status, @current_order, commentable_cache_key(@proposal), @comment_tree.comments, @comment_tree.comment_authors, @proposal.comments_count, @comment_flags] do %>
<div class="row comments">
<div id="comments" class="small-12 column">
<%= render 'shared/wide_order_selector', i18n_namespace: "comments" %>
<% if user_signed_in? %>
<%= render 'comments/form', {commentable: @proposal, parent_id: nil, toggeable: false} %>
<% else %>
<br>
<div data-alert class="callout primary">
<%= t("proposals.show.login_to_comment",
signin: link_to(t("votes.signin"), new_user_session_path),
signup: link_to(t("votes.signup"), new_user_registration_path)).html_safe %>
</div>
<% end %>
<% @comment_tree.root_comments.each do |comment| %>
<%= render 'comments/comment', comment: comment %>
<% end %>
<%= paginate @comment_tree.root_comments %>
</div>
</div>
<% end %>

View File

@@ -0,0 +1,27 @@
<div id="<%= dom_id(proposal) %>" class="proposal-featured clear">
<div class="small-12 medium-9 column">
<h3><%= link_to proposal.title, proposal %></h3>
<div class="info">
<% if proposal.author.hidden? || proposal.author.erased? %>
<%= t("proposals.show.author_deleted") %>
<% else %>
<%= proposal.author.name %>
<% end %>
&nbsp;&bull;&nbsp;
<% if proposal.author.display_official_position_badge? %>
<span class="label round level-<%= proposal.author.official_level %>">
<%= proposal.author.official_position %>
</span>
&nbsp;&bull;&nbsp;
<% end %>
<strong><%= t("proposals.proposal.votes", count: proposal.total_votes) %></strong>
</div>
</div>
<div id="<%= dom_id(proposal) %>_votes" class="small-12 medium-3 column">
<%= render 'featured_votes', proposal: proposal %>
</div>
</div>

View File

@@ -0,0 +1,44 @@
<div class="supports text-center">
<div class="in-favor">
<% if voted_for?(@featured_proposals_votes, proposal) %>
<div class="supported">
<%= t("proposals.proposal.already_supported") %>
</div>
<% else %>
<%= link_to vote_featured_proposal_path(proposal, value: 'yes'),
class: "button button-support small expanded",
title: t('proposals.proposal.support_title'), method: "post", remote: true do %>
<%= t("proposals.proposal.support") %>
<% end %>
<% end %>
</div>
<% if user_signed_in? && current_user.organization? %>
<div class="participation-not-allowed" style='display:none' aria-hidden="false">
<p>
<%= t("votes.organizations") %>
</p>
</div>
<% elsif user_signed_in? && !proposal.votable_by?(current_user)%>
<div class="participation-not-allowed" style='display:none' aria-hidden="false">
<p>
<%= t("votes.verified_only",
verify_account: link_to(t("votes.verify_account"), verification_path )).html_safe %>
</p>
</div>
<% elsif !user_signed_in? %>
<div class="participation-not-allowed" style='display:none' aria-hidden="false">
<%= t("votes.unauthenticated",
signin: link_to(t("votes.signin"), new_user_session_path),
signup: link_to(t("votes.signup"), new_user_registration_path)).html_safe %>
</div>
<% end %>
<% if voted_for?(@featured_proposals_votes, proposal) %>
<% if setting['twitter_handle'] %>
<div class="share-supported">
<%= social_share_button_tag("#{proposal.title} #{setting['twitter_hashtag']}", url: proposal_url(proposal), via: setting['twitter_handle']) %>
</div>
<% end %>
<% end %>
</div>

View File

@@ -0,0 +1,22 @@
<div class="row">
<div class="small-12 column">
<ul class="tabs" data-tabs id="proposals-tabs">
<li class="tabs-title is-active">
<%= link_to "#tab-comments" do %>
<h3>
<%= t("proposals.show.comments_tab") %>
<span class="js-comments-count">(<%= @proposal.comments_count %>)</span>
</h3>
<% end %>
</li>
<li class="tabs-title">
<%= link_to "#tab-documents" do %>
<h3>
<%= t("documents.tab") %>
(<%= @proposal.documents.count %>)
</h3>
<% end %>
</li>
</ul>
</div>
</div>

View File

@@ -0,0 +1,21 @@
<span class="js-flag-actions">
<span class="flag-content">
<% if show_flag_action? proposal %>
<a id="flag-expand-proposal-<%= proposal.id %>" data-toggle="flag-drop-proposal-<%= proposal.id %>" title="<%= t('shared.flag') %>">
<span class="icon-flag flag-disable"></span>
</a>
<span class="dropdown-pane" id="flag-drop-proposal-<%= proposal.id %>" data-dropdown data-auto-focus="true">
<%= link_to t('shared.flag'), flag_proposal_path(proposal), method: :put, remote: true, id: "flag-proposal-#{ proposal.id }" %>
</span>
<% end %>
<% if show_unflag_action? proposal %>
<a id="unflag-expand-proposal-<%= proposal.id %>" data-toggle="unflag-drop-proposal-<%= proposal.id %>" title="<%= t('shared.unflag') %>">
<span class="icon-flag flag-active"></span>
</a>
<span class="dropdown-pane" id="unflag-drop-proposal-<%= proposal.id %>" data-dropdown data-auto-focus="true">
<%= link_to t('shared.unflag'), unflag_proposal_path(proposal), method: :put, remote: true, id: "unflag-proposal-#{ proposal.id }" %>
</span>
<% end %>
</span>
</span>

View File

@@ -0,0 +1,78 @@
<%= form_for(@proposal, url: form_url) do |f| %>
<%= render 'shared/errors', resource: @proposal %>
<%= f.hidden_field(:legislation_process_id, :value => params[:process_id]) %>
<div class="row">
<div class="small-12 column">
<%= f.label :title, t("proposals.form.proposal_title") %>
<%= f.text_field :title, maxlength: Legislation::Proposal.title_max_length, placeholder: t("proposals.form.proposal_title"), label: false %>
</div>
<%= f.invisible_captcha :subtitle %>
<div class="small-12 column">
<%= f.label :summary, t("proposals.form.proposal_summary") %>
<p class="help-text" id="summary-help-text"><%= t("proposals.form.proposal_summary_note") %></p>
<%= f.text_area :summary, rows: 4, maxlength: 200, label: false,
placeholder: t('proposals.form.proposal_summary'),
aria: {describedby: "summary-help-text"} %>
</div>
<div class="ckeditor small-12 column">
<%= f.label :description, t("proposals.form.proposal_text") %>
<%= f.cktext_area :description, maxlength: Legislation::Proposal.description_max_length, ckeditor: { language: I18n.locale }, label: false %>
</div>
<div class="small-12 column">
<%= f.label :video_url, t("proposals.form.proposal_video_url") %>
<p class="help-text" id="video-url-help-text"><%= t("proposals.form.proposal_video_url_note") %></p>
<%= f.text_field :video_url, placeholder: t("proposals.form.proposal_video_url"), label: false,
aria: {describedby: "video-url-help-text"} %>
</div>
<div class="documents small-12 column" data-max-documents="<%= Legislation::Proposal.max_documents_allowed %>">
<%= render 'documents/nested_documents', documentable: @proposal, f: f %>
</div>
<div class="small-12 medium-6 column">
<%= f.label :geozone_id, t("proposals.form.geozone") %>
<%= f.select :geozone_id, geozone_select_options, {include_blank: t("geozones.none"), label: false} %>
</div>
<div class="small-12 column">
<%= f.label :tag_list, t("legislation.proposals.form.tags_label") %>
<p class="help-text" id="tag-list-help-text"><%= t("proposals.form.tags_instructions") %></p>
<div id="category_tags" class="tags">
<% @process.tag_list_on(:customs).each do |tag| %>
<a class="js-add-tag-link"><%= tag %></a>
<% end %>
</div>
<br>
<%= f.text_field :tag_list, value: @proposal.tag_list.to_s,
label: false,
placeholder: t("proposals.form.tags_placeholder"),
class: 'js-tag-list',
aria: {describedby: "tag-list-help-text"} %>
</div>
<div class="small-12 column">
<% if @proposal.new_record? %>
<%= f.label :terms_of_service do %>
<%= f.check_box :terms_of_service, title: t('form.accept_terms_title'), 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="actions small-12 column">
<%= f.submit(class: "button", value: t("proposals.#{action_name}.form.submit_button")) %>
</div>
</div>
<% end %>

View File

@@ -0,0 +1,6 @@
<div class="sidebar-divider"></div>
<h2 class="sidebar-title"><%= t("shared.tags_cloud.districts") %></h2>
<br>
<%= link_to map_proposals_path, id: 'map', title: t("shared.tags_cloud.districts_list") do %>
<%= image_tag("map.jpg", alt: t("shared.tags_cloud.districts_list")) %>
<% end %>

View File

@@ -0,0 +1,17 @@
<div class="tabs-panel" id="tab-notifications">
<div class="row">
<div class="small-12 column">
<% if @notifications.blank? %>
<div class="callout primary text-center">
<%= t('proposals.show.no_notifications') %>
</div>
<% end %>
<% @notifications.each do |notification| %>
<h3><%= notification.title %></h3>
<p class="more-info"><%= notification.created_at.to_date %></p>
<p><%= notification.body %></p>
<% end %>
</div>
</div>
</div>

View File

@@ -0,0 +1,6 @@
<div class="sidebar-divider"></div>
<h2 class="sidebar-title"><%= t("proposals.index.top") %></h2>
<p>
<%= link_to t("proposals.index.top_link_proposals"), summary_proposals_path, class: "small" %><br>
</p>

View File

@@ -0,0 +1,59 @@
<div id="<%= dom_id(proposal) %>"
class="proposal clear <%= ("successful" if proposal.total_votes > Proposal.votes_needed_for_success) %>"
data-type="proposal">
<div class="panel">
<div class="icon-successful"></div>
<div class="row">
<div class="small-12 medium-9 column">
<div class="proposal-content">
<% cache [locale_and_user_status(proposal), 'index', proposal, proposal.author] do %>
<h3><%= link_to proposal.title, legislation_process_proposal_path(proposal.legislation_process_id, proposal) %></h3>
<p class="proposal-info">
<span class="icon-comments"></span>&nbsp;
<%= link_to t("proposals.proposal.comments", count: proposal.comments_count), legislation_process_proposal_path(proposal.legislation_process_id, proposal, anchor: "comments") %>
<span class="bullet">&nbsp;&bull;&nbsp;</span>
<%= l proposal.created_at.to_date %>
<% if proposal.author.hidden? || proposal.author.erased? %>
<span class="bullet">&nbsp;&bull;&nbsp;</span>
<span class="author">
<%= t("proposals.show.author_deleted") %>
</span>
<% else %>
<span class="bullet">&nbsp;&bull;&nbsp;</span>
<span class="author">
<%= proposal.author.name %>
</span>
<% if proposal.author.display_official_position_badge? %>
<span class="bullet">&nbsp;&bull;&nbsp;</span>
<span class="label round level-<%= proposal.author.official_level %>">
<%= proposal.author.official_position %>
</span>
<% end %>
<% end %>
<% if proposal.author.verified_organization? %>
<span class="bullet">&nbsp;&bull;&nbsp;</span>
<span class="label round is-association">
<%= t("shared.collective") %>
</span>
<% end %>
</p>
<div class="proposal-description">
<p><%= proposal.summary %></p>
<div class="truncate"></div>
</div>
<%= render "shared/tags", taggable: proposal, limit: 5 %>
<% end %>
</div>
</div>
<div id="<%= dom_id(proposal) %>_votes" class="small-12 medium-3 column">
<%= render 'legislation/proposals/votes',
{ proposal: proposal, vote_url: vote_legislation_process_proposal_path(proposal.legislation_process_id, proposal, value: 'yes') } %>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1 @@
$("#<%= dom_id(@proposal) %> .js-flag-actions").html('<%= j render("proposals/flag_actions", proposal: @proposal) %>');

View File

@@ -0,0 +1,78 @@
<% voted_classes = css_classes_for_vote(@legislation_proposal_votes, proposal) %>
<div class="votes">
<% if @process.proposals_phase.open? %>
<div class="in-favor inline-block">
<% if user_signed_in? %>
<%= link_to vote_legislation_process_proposal_path(process_id: proposal.process, id: proposal, value: 'yes'),
class: "like #{voted_classes[:in_favor]}", title: t('votes.agree'), method: "post", remote: true do %>
<span class="icon-like">
<span class="show-for-sr"><%= t('votes.agree') %></span>
</span>
<span class="percentage"><%= votes_percentage('likes', proposal) %></span>
<% end %>
<% else %>
<div class="like">
<span class="icon-like">
<span class="show-for-sr"><%= t('votes.agree') %></span>
</span>
<span class="percentage"><%= votes_percentage('likes', proposal) %></span>
</div>
<% end %>
</div>
<span class="divider"></span>
<div class="against inline-block">
<% if user_signed_in? %>
<%= link_to vote_legislation_process_proposal_path(process_id: proposal.process, id: proposal, value: 'no'), class: "unlike #{voted_classes[:against]}", title: t('votes.disagree'), method: "post", remote: true do %>
<span class="icon-unlike">
<span class="show-for-sr"><%= t('votes.disagree') %></span>
</span>
<span class="percentage"><%= votes_percentage('dislikes', proposal) %></span>
<% end %>
<% else %>
<div class="unlike">
<span class="icon-unlike">
<span class="show-for-sr"><%= t('votes.disagree') %></span>
</span>
<span class="percentage"><%= votes_percentage('dislikes', proposal) %></span>
</div>
<% end %>
</div>
<% else %>
<p><%= t("legislation.proposals.closed") %></p>
<% end %>
<span class="total-votes">
<%= t("proposals.proposal.votes", count: proposal.total_votes) %>
</span>
<% if user_signed_in? && current_user.organization? %>
<div class="participation-not-allowed" style='display:none' aria-hidden="false">
<p>
<%= t("votes.organizations") %>
</p>
</div>
<% elsif user_signed_in? && !proposal.votable_by?(current_user) %>
<div class="participation-not-allowed" style='display:none' aria-hidden="false">
<p>
<%= t("legislation.proposals.not_verified",
verify_account: link_to(t("votes.verify_account"), verification_path )).html_safe %>
</p>
</div>
<% elsif !user_signed_in? %>
<div tabindex="0">
<div class="participation-not-allowed" style='display:none' aria-hidden="false">
<%= t("votes.unauthenticated",
signin: link_to(t("votes.signin"), new_user_session_path),
signup: link_to(t("votes.signup"), new_user_registration_path)).html_safe %>
</div>
</div>
<% end %>
<% if voted_for?(@legislation_proposal_votes, proposal) && setting['twitter_handle'] %>
<div class="share-supported">
<%= social_share_button_tag("#{proposal.title} #{setting['twitter_hashtag']}", url: proposal_url(proposal), via: setting['twitter_handle']) %>
</div>
<% end %>
</div>

View File

@@ -0,0 +1,14 @@
<div class="proposal-edit row">
<div class="small-12 column">
<%= back_link_to %>
<div class="float-right">
<%= link_to t("proposals.edit.show_link"), legislation_process_proposal_path(@proposal.legislation_process_id, @proposal) %>
</div>
<h1><%= t("proposals.edit.editing") %></h1>
<%= render "form", form_url: legislation_process_proposal_url(@proposal.legislation_process_id, @proposal) %>
</div>
</div>

View File

@@ -0,0 +1 @@
<%= render 'shared/map', new_url_path: new_proposal_path %>

View File

@@ -0,0 +1,24 @@
<div class="proposal-form row">
<div class="small-12 medium-9 column">
<%= back_link_to %>
<h1><%= t("proposals.new.start_new") %></h1>
<div data-alert class="callout primary">
<%= link_to more_info_path(anchor: "proposals") ,title: t('shared.target_blank_html'), target: "_blank" do %>
<%= t("proposals.new.more_info")%>
<% end %>
</div>
<%= render "legislation/proposals/form", form_url: legislation_process_proposals_url, id: @proposal.id %>
</div>
<div class="small-12 medium-3 column">
<span class="icon-proposals float-right"></span>
<h2><%= t("proposals.new.recommendations_title") %></h2>
<ul class="recommendations">
<li><%= t("proposals.new.recommendation_one") %></li>
<li><%= t("proposals.new.recommendation_two") %></li>
<li><%= t("proposals.new.recommendation_three") %></li>
</ul>
</div>
</div>

View File

@@ -0,0 +1,121 @@
<% provide :title do %><%= @proposal.title %><% end %>
<% content_for :meta_description do %><%= @proposal.summary %><% end %>
<% provide :social_media_meta_tags do %>
<%= render "shared/social_media_meta_tags",
social_url: proposal_url(@proposal),
social_title: @proposal.title,
social_description: @proposal.summary %>
<% end %>
<% content_for :canonical do %>
<%= render "shared/canonical", href: proposal_url(@proposal) %>
<% end %>
<% cache [locale_and_user_status(@proposal), @proposal, @proposal.author, Flag.flagged?(current_user, @proposal), @legislation_proposal_votes] do %>
<div class="proposal-show">
<div id="<%= dom_id(@proposal) %>" class="row">
<div class="small-12 medium-9 column">
<%= back_link_to legislation_process_proposals_path(process_id: @process) %>
<h1><%= @proposal.title %></h1>
<% if @proposal.conflictive? %>
<div data-alert class="callout alert margin-top">
<strong><%= t("proposals.show.flag") %></strong>
</div>
<% end %>
<div class="proposal-info">
<%= render '/shared/author_info', resource: @proposal %>
<span class="bullet">&nbsp;&bull;&nbsp;</span>
<%= l @proposal.created_at.to_date %>
<span class="bullet">&nbsp;&bull;&nbsp;</span>
<span class="icon-comments"></span>&nbsp;
<%= link_to t("proposals.show.comments", count: @proposal.comments_count), "#comments" %>
<% if current_user %>
<span class="bullet">&nbsp;&bull;&nbsp;</span>
<%= render 'proposals/flag_actions', proposal: @proposal %>
<% end %>
</div>
<br>
<p>
<%= t("proposals.show.code") %>
<strong><%= @proposal.code %></strong>
</p>
<blockquote><%= @proposal.summary %></blockquote>
<% if @proposal.video_url.present? %>
<div class="small-12 medium-7 small-centered">
<div class="flex-video">
<div id="js-embedded-video" data-video-code="<%= embedded_video_code %>"></div>
</div>
</div>
<% end %>
<%= safe_html_with_links @proposal.description %>
<% if @proposal.external_url.present? %>
<div class="document-link">
<p>
<span class="icon-document"></span>&nbsp;
<strong><%= t('proposals.show.title_external_url') %></strong>
</p>
<%= text_with_links @proposal.external_url %>
</div>
<% end %>
<% if @proposal.video_url.present? %>
<div class="video-link">
<p>
<span class="icon-video"></span>&nbsp;
<strong><%= t('proposals.show.title_video_url') %></strong>
</p>
<%= text_with_links @proposal.video_url %>
</div>
<% end %>
<h4><%= @proposal.question %></h4>
<%= render 'shared/tags', taggable: @proposal %>
<%= render 'shared/geozone', geozonable: @proposal %>
<div class="js-moderator-proposal-actions margin">
<%= render 'proposals/actions', proposal: @proposal %>
</div>
</div>
<aside class="small-12 medium-3 column">
<div class="sidebar-divider"></div>
<h2><%= t("votes.supports") %></h2>
<div id="<%= dom_id(@proposal) %>_votes">
<%= render 'votes',
{ proposal: @proposal, vote_url: vote_legislation_process_proposal_path(@proposal.legislation_process_id, @proposal, value: 'yes') } %>
</div>
<%= render partial: 'shared/social_share', locals: {
share_title: t("proposals.show.share"),
title: @proposal.title,
url: proposal_url(@proposal)
} %>
</aside>
</div>
</div>
<% end %>
<div class="tabs-content" data-tabs-content="proposals-tabs" role="tablist">
<%= render "legislation/proposals/filter_subnav" %>
<div class="tabs-panel is-active" id="tab-comments">
<%= render "legislation/proposals/comments" %>
</div>
<div class="tabs-panel" id="tab-documents">
<%= render 'documents/documents',
documents: @proposal.documents,
max_documents_allowed: Proposal.max_documents_allowed %>
</div>
</div>

View File

@@ -0,0 +1 @@
<%= render "shared/suggest" %>

View File

@@ -0,0 +1 @@
$("#<%= dom_id(@proposal) %>_votes").html('<%= j render("legislation/proposals/votes", proposal: @proposal) %>');

View File

@@ -12,7 +12,7 @@
<li>
<%= layout_menu_link_to t("layouts.header.proposals"),
proposals_path,
controller_name == 'proposals',
controller_name == 'proposals' && !controller.class.parent == Legislation,
accesskey: "2",
title: t("shared.go_to_page") + t("layouts.header.proposals") %>
</li>

View File

@@ -9,6 +9,10 @@ ActsAsVotable::Vote.class_eval do
where(votable_type: 'Proposal', votable_id: proposals)
end
def self.for_legislation_proposals(proposals)
where(votable_type: 'Legislation::Proposal', votable_id: proposals)
end
def self.for_spending_proposals(spending_proposals)
where(votable_type: 'SpendingProposal', votable_id: spending_proposals)
end

View File

@@ -265,6 +265,7 @@ en:
process: Process
debate_phase: Debate phase
allegations_phase: Allegations phase
proposals_phase: Proposals phase
start: Start
end: End
use_markdown: Use Markdown to format the text
@@ -297,6 +298,17 @@ en:
info: Information
draft_texts: Text
questions: Debate
proposals: Proposals
proposals:
index:
title: Proposals
back: Back
form:
header_information: Information header
header_information_description: Provide information about the proposals. This text will be displayed as an alert in the Proposals section inside this Process. Use Markdown to format the text.
header_information_placeholder: Add information for the proposals' header
custom_categories: Categories
custom_categories_description: Categories that users can select creating the proposal.
draft_versions:
create:
notice: 'Draft created successfully. <a href="%{link}">Click to visit</a>'

View File

@@ -421,6 +421,10 @@ en:
one: 1 support
other: "%{count} supports"
zero: No supports
votes:
one: 1 vote
other: "%{count} votes"
zero: No votes
supports_necessary: "%{number} supports needed"
total_percent: 100%
archived: "This proposal has been archived and can't collect supports."

View File

@@ -49,6 +49,8 @@ en:
processes:
header:
view_process_information: View process information
proposals:
empty_proposals: There are no proposals
debate:
empty_questions: There aren't any questions
participate: Participate in the debate
@@ -86,6 +88,7 @@ en:
draft_publication_date: Draft publication
allegations_dates: Allegations
result_publication_date: Final result publication
proposals_dates: Proposals
questions:
comments:
comment_button: Publish answer
@@ -117,3 +120,8 @@ en:
shared:
share: Share
share_comment: Comment on %{version_name} from process draft %{process_name}
proposals:
form:
tags_label: "Categories"
not_verified: "For vote proposals %{verify_account}."
closed: "This process has been closed and can not receive votes."

View File

@@ -265,6 +265,7 @@ es:
process: Proceso
debate_phase: Fase previa
allegations_phase: Fase de alegaciones
proposals_phase: Fase de propuestas
start: Inicio
end: Fin
use_markdown: Usa Markdown para formatear el texto
@@ -297,6 +298,17 @@ es:
info: Información
draft_texts: Texto
questions: Debate
proposals: Propuestas
proposals:
index:
title: Propuestas
back: Volver
form:
header_information: Encabezado de información
header_information_description: Proporciona información sobre el recorrido de las propuestas. Este texto se mostrará como una alerta en el encabezado de la sección de Propuestas dentro de este proceso. Usa Markdown para formatear el texto.
header_information_placeholder: Añade información para el encabezado de las las propuestas
custom_categories: Categorías
custom_categories_description: Categorías que el usuario puede seleccionar al crear la propuesta.
draft_versions:
create:
notice: 'Borrador creado correctamente. <a href="%{link}">Haz click para verlo</a>'

View File

@@ -421,6 +421,10 @@ es:
one: 1 apoyo
other: "%{count} apoyos"
zero: Sin apoyos
votes:
one: 1 voto
other: "%{count} votos"
zero: Sin votos
supports_necessary: "%{number} apoyos necesarios"
total_percent: 100%
archived: "Esta propuesta ha sido archivada y ya no puede recoger apoyos."

View File

@@ -49,6 +49,8 @@ es:
processes:
header:
view_process_information: Ver información del proceso
proposals:
empty_proposals: No hay propuestas
debate:
empty_questions: No hay preguntas
participate: Realiza tus aportaciones al debate previo participando en los siguientes temas.
@@ -86,6 +88,7 @@ es:
draft_publication_date: Publicación borrador
allegations_dates: Alegaciones
result_publication_date: Publicación resultados
proposals_dates: Propuestas
questions:
comments:
comment_button: Publicar respuesta
@@ -117,3 +120,8 @@ es:
shared:
share: Compartir
share_comment: Comentario sobre la %{version_name} del borrador del proceso %{process_name}
proposals:
form:
tags_label: "Categorías"
not_verified: Para votar propuestas %{verify_account}.
closed: "Este proceso se ha cerrado y ya no puede recoger votos."

View File

@@ -129,10 +129,22 @@ Rails.application.routes.draw do
get :draft_publication
get :allegations
get :result_publication
get :proposals
end
resources :questions, only: [:show] do
resources :answers, only: [:create]
end
resources :proposals do
member do
post :vote
put :flag
put :unflag
end
collection do
get :map
get :suggest
end
end
resources :draft_versions, only: [:show] do
get :go_to_version, on: :collection
get :changes
@@ -332,6 +344,7 @@ Rails.application.routes.draw do
namespace :legislation do
resources :processes do
resources :questions
resources :proposals
resources :draft_versions
end
end

View File

@@ -0,0 +1,7 @@
class AddProposalsPhaseToLegislationProcesses < ActiveRecord::Migration
def change
add_column :legislation_processes, :proposals_phase_start_date, :date
add_column :legislation_processes, :proposals_phase_end_date, :date
add_column :legislation_processes, :proposals_phase_enabled, :boolean
end
end

View File

@@ -0,0 +1,5 @@
class AddProposalsDescriptionToLegislationProcesses < ActiveRecord::Migration
def change
add_column :legislation_processes, :proposals_description, :text
end
end

View File

@@ -0,0 +1,32 @@
class CreateLegislationProposals < ActiveRecord::Migration
def change
create_table :legislation_proposals do |t|
t.references :legislation_process, index: true, foreign_key: true
t.string :title, limit: 80
t.text :description
t.string :question
t.string :external_url
t.integer :author_id
t.datetime :hidden_at
t.integer :flags_count, default: 0
t.datetime :ignored_flag_at
t.integer :cached_votes_up, default: 0
t.integer :comments_count, default: 0
t.datetime :confirmed_hide_at
t.integer :hot_score, limit: 8, default: 0
t.integer :confidence_score, default: 0
t.string :responsible_name, limit: 60
t.text :summary
t.string :video_url
t.tsvector :tsv
t.integer :geozone_id
t.datetime :retired_at
t.string :retired_reason
t.text :retired_explanation
t.integer :community_id
t.datetime :created_at, null: false
t.datetime :updated_at, null: false
end
end
end

View File

@@ -0,0 +1,6 @@
class AddLegislationProposalsCountToTags < ActiveRecord::Migration
def change
add_column :tags, "legislation/proposals_count", :integer, default: 0
add_index :tags, "legislation/proposals_count"
end
end

View File

@@ -0,0 +1,6 @@
class AddLegislationProcessesCountToTags < ActiveRecord::Migration
def change
add_column :tags, "legislation/processes_count", :integer, default: 0
add_index :tags, "legislation/processes_count"
end
end

View File

@@ -0,0 +1,6 @@
class AddCachedVotesToLegislationProposals < ActiveRecord::Migration
def change
add_column :legislation_proposals, :cached_votes_total, :integer, default: 0
add_column :legislation_proposals, :cached_votes_down, :integer, default: 0
end
end

View File

@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20171020163240) do
ActiveRecord::Schema.define(version: 20171025142440) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -486,6 +486,10 @@ ActiveRecord::Schema.define(version: 20171020163240) do
t.boolean "draft_publication_enabled", default: false
t.boolean "result_publication_enabled", default: false
t.boolean "published", default: true
t.date "proposals_phase_start_date"
t.date "proposals_phase_end_date"
t.boolean "proposals_phase_enabled"
t.text "proposals_description"
end
add_index "legislation_processes", ["allegations_end_date"], name: "index_legislation_processes_on_allegations_end_date", using: :btree
@@ -498,6 +502,38 @@ ActiveRecord::Schema.define(version: 20171020163240) do
add_index "legislation_processes", ["result_publication_date"], name: "index_legislation_processes_on_result_publication_date", using: :btree
add_index "legislation_processes", ["start_date"], name: "index_legislation_processes_on_start_date", using: :btree
create_table "legislation_proposals", force: :cascade do |t|
t.integer "legislation_process_id"
t.string "title", limit: 80
t.text "description"
t.string "question"
t.string "external_url"
t.integer "author_id"
t.datetime "hidden_at"
t.integer "flags_count", default: 0
t.datetime "ignored_flag_at"
t.integer "cached_votes_up", default: 0
t.integer "comments_count", default: 0
t.datetime "confirmed_hide_at"
t.integer "hot_score", limit: 8, default: 0
t.integer "confidence_score", default: 0
t.string "responsible_name", limit: 60
t.text "summary"
t.string "video_url"
t.tsvector "tsv"
t.integer "geozone_id"
t.datetime "retired_at"
t.string "retired_reason"
t.text "retired_explanation"
t.integer "community_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "cached_votes_total", default: 0
t.integer "cached_votes_down", default: 0
end
add_index "legislation_proposals", ["legislation_process_id"], name: "index_legislation_proposals_on_legislation_process_id", using: :btree
create_table "legislation_question_options", force: :cascade do |t|
t.integer "legislation_question_id"
t.string "value"
@@ -921,16 +957,20 @@ ActiveRecord::Schema.define(version: 20171020163240) do
add_index "taggings", ["taggable_id", "taggable_type", "context"], name: "index_taggings_on_taggable_id_and_taggable_type_and_context", using: :btree
create_table "tags", force: :cascade do |t|
t.string "name", limit: 40
t.integer "taggings_count", default: 0
t.integer "debates_count", default: 0
t.integer "proposals_count", default: 0
t.integer "spending_proposals_count", default: 0
t.string "name", limit: 40
t.integer "taggings_count", default: 0
t.integer "debates_count", default: 0
t.integer "proposals_count", default: 0
t.integer "spending_proposals_count", default: 0
t.string "kind"
t.integer "budget/investments_count", default: 0
t.integer "budget/investments_count", default: 0
t.integer "legislation/proposals_count", default: 0
t.integer "legislation/processes_count", default: 0
end
add_index "tags", ["debates_count"], name: "index_tags_on_debates_count", using: :btree
add_index "tags", ["legislation/processes_count"], name: "index_tags_on_legislation/processes_count", using: :btree
add_index "tags", ["legislation/proposals_count"], name: "index_tags_on_legislation/proposals_count", using: :btree
add_index "tags", ["name"], name: "index_tags_on_name", unique: true, using: :btree
add_index "tags", ["proposals_count"], name: "index_tags_on_proposals_count", using: :btree
add_index "tags", ["spending_proposals_count"], name: "index_tags_on_spending_proposals_count", using: :btree
@@ -1108,6 +1148,7 @@ ActiveRecord::Schema.define(version: 20171020163240) do
add_foreign_key "identities", "users"
add_foreign_key "images", "users"
add_foreign_key "legislation_draft_versions", "legislation_processes"
add_foreign_key "legislation_proposals", "legislation_processes"
add_foreign_key "locks", "users"
add_foreign_key "managers", "users"
add_foreign_key "moderators", "users"