Merge pull request #241 from medialab-prado/issue_239

Fixed #239
This commit is contained in:
Juan Salvador Pérez García
2018-07-25 13:16:24 +02:00
committed by GitHub
82 changed files with 1131 additions and 694 deletions

View File

@@ -284,10 +284,10 @@
i {
display: inline-block;
width: rem-calc(20);
height: rem-calc(20);
width: rem-calc(24);
height: rem-calc(24);
border-radius: rem-calc(10);
padding-right: rem-calc(4);
padding-right: rem-calc(5);
}
}

View File

@@ -0,0 +1,67 @@
class Admin::Dashboard::ActionsController < Admin::Dashboard::BaseController
helper_method :dashboard_action, :resource
def index
@dashboard_actions = ::Dashboard::Action.order(required_supports: :asc)
end
def new
@dashboard_action = ::Dashboard::Action.new(
active: true,
day_offset: 0,
required_supports: 0,
request_to_administrators: true,
action_type: 'proposed_action'
)
end
def create
@dashboard_action = ::Dashboard::Action.new(dashboard_action_params)
if @dashboard_action.save
redirect_to admin_dashboard_actions_path, notice: t('admin.dashboard.actions.create.notice')
else
render :new
end
end
def edit; end
def update
if dashboard_action.update(dashboard_action_params)
redirect_to admin_dashboard_actions_path
else
render :edit
end
end
def destroy
if dashboard_action.destroy
flash[:notice] = t('admin.dashboard.actions.delete.success')
else
flash[:error] = dashboard_action.errors.full_messages.join(',')
end
redirect_to admin_dashboard_actions_path
end
private
def resource
@dashboard_action
end
def dashboard_action_params
params
.require(:dashboard_action)
.permit(
:title, :description, :short_description, :request_to_administrators, :day_offset,
:required_supports, :order, :active, :action_type,
documents_attributes: [:id, :title, :attachment, :cached_attachment, :user_id, :_destroy],
links_attributes: [:id, :label, :url, :open_in_new_tab, :_destroy]
)
end
def dashboard_action
@dashboard_action ||= ::Dashboard::Action.find(params[:id])
end
end

View File

@@ -0,0 +1,26 @@
class Admin::Dashboard::AdministratorTasksController < Admin::Dashboard::BaseController
helper_method :administrator_task
def index
authorize! :index, ::Dashboard::AdministratorTask
@administrator_tasks = ::Dashboard::AdministratorTask.pending
end
def edit
authorize! :edit, administrator_task
end
def update
authorize! :update, administrator_task
administrator_task.update(user: current_user, executed_at: Time.now)
redirect_to admin_dashboard_administrator_tasks_path,
{ flash: { notice: t("admin.dashboard.administrator_tasks.update.success") } }
end
private
def administrator_task
@administrator_task ||= ::Dashboard::AdministratorTask.find(params[:id])
end
end

View File

@@ -1,4 +1,4 @@
class Admin::ProposalDashboard::BaseController < Admin::BaseController
class Admin::Dashboard::BaseController < Admin::BaseController
helper_method :namespace
private

View File

@@ -1,67 +0,0 @@
class Admin::ProposalDashboard::ActionsController < Admin::ProposalDashboard::BaseController
helper_method :proposal_dashboard_action, :resource
def index
@proposal_dashboard_actions = ProposalDashboardAction.order(required_supports: :asc)
end
def new
@proposal_dashboard_action = ProposalDashboardAction.new(
active: true,
day_offset: 0,
required_supports: 0,
request_to_administrators: true,
action_type: 'proposed_action'
)
end
def create
@proposal_dashboard_action = ProposalDashboardAction.new(proposal_dashboard_action_params)
if @proposal_dashboard_action.save
redirect_to admin_proposal_dashboard_actions_path, notice: t('admin.proposal_dashboard_actions.create.notice')
else
render :new
end
end
def edit; end
def update
if proposal_dashboard_action.update(proposal_dashboard_action_params)
redirect_to admin_proposal_dashboard_actions_path
else
render :edit
end
end
def destroy
if proposal_dashboard_action.destroy
flash[:notice] = t('admin.proposal_dashboard_actions.delete.success')
else
flash[:error] = proposal_dashboard_action.errors.full_messages.join(',')
end
redirect_to admin_proposal_dashboard_actions_path
end
private
def resource
@proposal_dashboard_action
end
def proposal_dashboard_action_params
params
.require(:proposal_dashboard_action)
.permit(
:title, :description, :short_description, :request_to_administrators, :day_offset, :required_supports, :order, :active, :action_type,
documents_attributes: [:id, :title, :attachment, :cached_attachment, :user_id, :_destroy],
links_attributes: [:id, :label, :url, :open_in_new_tab, :_destroy]
)
end
def proposal_dashboard_action
@proposal_dashboard_action ||= ProposalDashboardAction.find(params[:id])
end
end

View File

@@ -1,25 +0,0 @@
class Admin::ProposalDashboard::AdministratorTasksController < Admin::ProposalDashboard::BaseController
helper_method :administrator_task
def index
authorize! :index, AdministratorTask
@administrator_tasks = AdministratorTask.pending
end
def edit
authorize! :edit, administrator_task
end
def update
authorize! :update, administrator_task
administrator_task.update(user: current_user, executed_at: Time.now)
redirect_to admin_proposal_dashboard_administrator_tasks_path, { flash: { notice: t('.success') } }
end
private
def administrator_task
@administrator_task ||= AdministratorTask.find(params[:id])
end
end

View File

@@ -4,7 +4,7 @@ class Dashboard::BaseController < ApplicationController
helper_method :proposal, :proposed_actions, :resource, :resources, :next_goal, :next_goal_supports, :next_goal_progress, :community_members_count
respond_to :html
layout 'proposals_dashboard'
layout 'dashboard'
private
@@ -13,11 +13,11 @@ class Dashboard::BaseController < ApplicationController
end
def proposed_actions
@proposed_actions ||= ProposalDashboardAction.proposed_actions.active_for(proposal).order(order: :asc)
@proposed_actions ||= Dashboard::Action.proposed_actions.active_for(proposal).order(order: :asc)
end
def resources
@resources ||= ProposalDashboardAction.resources.active_for(proposal).order(order: :asc)
@resources ||= Dashboard::Action.resources.active_for(proposal).order(order: :asc)
end
def next_goal_supports
@@ -35,6 +35,6 @@ class Dashboard::BaseController < ApplicationController
end
def next_goal
@next_goal ||= ProposalDashboardAction.next_goal_for(proposal)
@next_goal ||= Dashboard::Action.next_goal_for(proposal)
end
end

View File

@@ -2,7 +2,7 @@ class Dashboard::ResourcesController < Dashboard::BaseController
skip_authorization_check
def index
@resources = ProposalDashboardAction
@resources = Dashboard::Action
.active
.resources
.where('required_supports > 0')

View File

@@ -1,5 +1,5 @@
class ProposalsDashboardController < Dashboard::BaseController
helper_method :proposal_dashboard_action, :active_resources, :course
class DashboardController < Dashboard::BaseController
helper_method :dashboard_action, :active_resources, :course
def index
authorize! :dashboard, proposal
@@ -15,13 +15,13 @@ class ProposalsDashboardController < Dashboard::BaseController
def execute
authorize! :dashboard, proposal
ProposalExecutedDashboardAction.create(proposal: proposal, proposal_dashboard_action: proposal_dashboard_action, executed_at: Time.now)
Dashboard::ExecutedAction.create(proposal: proposal, action: dashboard_action, executed_at: Time.now)
redirect_to progress_proposal_dashboard_index_path(proposal.to_param)
end
def new_request
authorize! :dashboard, proposal
@proposal_executed_dashboard_action = ProposalExecutedDashboardAction.new
@dashboard_executed_action = Dashboard::ExecutedAction.new
end
def create_request
@@ -29,17 +29,17 @@ class ProposalsDashboardController < Dashboard::BaseController
source_params = {
proposal: proposal,
proposal_dashboard_action: proposal_dashboard_action,
action: dashboard_action,
executed_at: Time.now
}
@proposal_executed_dashboard_action = ProposalExecutedDashboardAction.new(source_params)
if @proposal_executed_dashboard_action.save
AdministratorTask.create(source: @proposal_executed_dashboard_action)
@dashboard_executed_action = Dashboard::ExecutedAction.new(source_params)
if @dashboard_executed_action.save
Dashboard::AdministratorTask.create(source: @dashboard_executed_action)
redirect_to progress_proposal_dashboard_index_path(proposal.to_param), { flash: { info: t('.success') } }
else
flash.now[:alert] = @proposal_executed_dashboard_action.errors.full_messages.join('<br>')
flash.now[:alert] = @dashboard_executed_action.errors.full_messages.join('<br>')
render :new_request
end
end
@@ -69,15 +69,15 @@ class ProposalsDashboardController < Dashboard::BaseController
private
def proposal_dashboard_action
@proposal_dashboard_action ||= ProposalDashboardAction.find(params[:id])
def dashboard_action
@dashboard_action ||= Dashboard::Action.find(params[:id])
end
def active_resources
@active_resources ||= ProposalDashboardAction.active.resources.order(required_supports: :asc, day_offset: :asc)
@active_resources ||= Dashboard::Action.active.resources.order(required_supports: :asc, day_offset: :asc)
end
def course
@course ||= ProposalDashboardAction.course_for(proposal)
@course ||= Dashboard::Action.course_for(proposal)
end
end

View File

@@ -1,6 +1,6 @@
module Admin::ProposalDashboardActionsHelper
def active_human_readable(active)
return t('admin.proposal_dashboard_actions.index.active') if active
t('admin.proposal_dashboard_actions.index.inactive')
return t('admin.dashboard.actions.index.active') if active
t('admin.dashboard.actions.index.inactive')
end
end

View File

@@ -44,7 +44,7 @@ module AdminHelper
["homepage", "cards"].include?(controller_name)
end
def menu_proposals_dashboard?
def menu_dashboard?
["actions", "administrator_tasks"].include?(controller_name)
end

View File

@@ -1,6 +1,6 @@
module ProposalsDashboardHelper
def my_proposal_menu_class
return 'is-active' if controller_name == 'proposals_dashboard' && action_name == 'index'
return 'is-active' if controller_name == 'dashboard' && action_name == 'index'
nil
end
@@ -10,12 +10,12 @@ module ProposalsDashboardHelper
end
def community_menu_class
return 'is-active' if controller_name == 'proposals_dashboard' && action_name == 'community'
return 'is-active' if controller_name == 'dashboard' && action_name == 'community'
nil
end
def progress_menu_active?
is_proposed_action_request? || (controller_name == 'proposals_dashboard' && action_name == 'progress')
is_proposed_action_request? || (controller_name == 'dashboard' && action_name == 'progress')
end
def resources_menu_visible?(proposal, resources)
@@ -56,24 +56,24 @@ module ProposalsDashboardHelper
end
def is_resource_request?
controller_name == 'proposals_dashboard' && action_name == 'new_request' && proposal_dashboard_action&.resource?
controller_name == 'dashboard' && action_name == 'new_request' && dashboard_action&.resource?
end
def is_proposed_action_request?
controller_name == 'proposals_dashboard' && action_name == 'new_request' && proposal_dashboard_action&.proposed_action?
controller_name == 'dashboard' && action_name == 'new_request' && dashboard_action&.proposed_action?
end
def is_request_active(id)
controller_name == 'proposals_dashboard' && action_name == 'new_request' && proposal_dashboard_action&.id == id
controller_name == 'dashboard' && action_name == 'new_request' && dashboard_action&.id == id
end
def resoure_availability_label(resource)
label = []
label << t('proposals_dashboard.resource.required_days', days: resource.day_offset) if resource.day_offset > 0
label << t('proposals_dashboard.resource.required_supports', supports: number_with_delimiter(resource.required_supports, delimiter: '.')) if resource.required_supports > 0
label << t("dashboard.resource.required_days", days: resource.day_offset) if resource.day_offset > 0
label << t("dashboard.resource.required_supports", supports: number_with_delimiter(resource.required_supports, delimiter: '.')) if resource.required_supports > 0
label.join(" #{t('proposals_dashboard.resource.and')}<br>")
label.join(" #{t("dashboard.resource.and")}<br>")
end
def daily_selected_class
@@ -98,9 +98,9 @@ module ProposalsDashboardHelper
end
def resource_tooltip(resource, proposal)
return t('proposals_dashboard.resource.resource_locked') unless resource.active_for?(proposal)
return t('proposals_dashboard.resource.view_resource') if resource.executed_for?(proposal)
return t('proposals_dashboard.resource.resource_requested') if resource.requested_for?(proposal)
t('proposals_dashboard.resource.request_resource')
return t("dashboard.resource.resource_locked") unless resource.active_for?(proposal)
return t("dashboard.resource.view_resource") if resource.executed_for?(proposal)
return t("dashboard.resource.resource_requested") if resource.requested_for?(proposal)
t("dashboard.resource.request_resource")
end
end

View File

@@ -48,7 +48,7 @@ module Abilities
can [:search, :index], ::User
can :manage, Annotation
can :manage, ProposalDashboardAction
can :manage, Dashboard::Action
can [:read, :update, :valuate, :destroy, :summary], SpendingProposal
@@ -85,6 +85,7 @@ module Abilities
can [:create, :destroy], DirectUpload
can [:deliver], Newsletter, hidden_at: nil
can [:manage], Dashboard::AdministratorTask
end
end
end

View File

@@ -63,7 +63,6 @@ module Abilities
cannot :moderate, ProposalNotification, author_id: user.id
can :index, ProposalNotification
can :manage, AdministratorTask
end
end
end

5
app/models/dashboard.rb Normal file
View File

@@ -0,0 +1,5 @@
module Dashboard
def self.table_name_prefix
'dashboard_'
end
end

View File

@@ -0,0 +1,84 @@
class Dashboard::Action < ActiveRecord::Base
include Documentable
documentable max_documents_allowed: 3,
max_file_size: 3.megabytes,
accepted_content_types: [ 'application/pdf' ]
include Linkable
acts_as_paranoid column: :hidden_at
include ActsAsParanoidAliases
has_many :executed_actions, dependent: :restrict_with_error, class_name: 'Dashboard::ExecutedAction'
has_many :proposals, through: :executed_actions
enum action_type: [:proposed_action, :resource]
validates :title,
presence: true,
allow_blank: false,
length: { in: 4..80 }
validates :action_type, presence: true
validates :day_offset,
presence: true,
numericality: {
only_integer: true,
greater_than_or_equal_to: 0
}
validates :required_supports,
presence: true,
numericality: {
only_integer: true,
greater_than_or_equal_to: 0
}
scope :active, -> { where(active: true) }
scope :inactive, -> { where(active: false) }
scope :resources, -> { where(action_type: 1) }
scope :proposed_actions, -> { where(action_type: 0) }
scope :active_for, ->(proposal) do
published_at = proposal.published_at&.to_date || Date.today
active
.where('required_supports <= ?', proposal.cached_votes_up)
.where('day_offset <= ?', (Date.today - published_at).to_i)
end
scope :course_for, lambda { |proposal|
active
.resources
.where('required_supports > ?', proposal.cached_votes_up)
.order(required_supports: :asc)
}
def active_for?(proposal)
published_at = proposal.published_at&.to_date || Date.today
required_supports <= proposal.cached_votes_up && day_offset <= (Date.today - published_at).to_i
end
def requested_for?(proposal)
executed_action = executed_actions.find_by(proposal: proposal)
return false if executed_action.nil?
executed_action.administrator_tasks.any?
end
def executed_for?(proposal)
executed_action = executed_actions.find_by(proposal: proposal)
return false if executed_action.nil?
executed_action.administrator_tasks.where.not(executed_at: nil).any?
end
def self.next_goal_for(proposal)
course_for(proposal).first
end
def request_to_administrators?
request_to_administrators || false
end
end

View File

@@ -0,0 +1,11 @@
class Dashboard::AdministratorTask < ActiveRecord::Base
belongs_to :source, polymorphic: true
belongs_to :user
validates :source, presence: true
default_scope { order(created_at: :asc) }
scope :pending, -> { where(executed_at: nil) }
scope :done, -> { where.not(executed_at: nil) }
end

View File

@@ -0,0 +1,10 @@
class Dashboard::ExecutedAction < ActiveRecord::Base
belongs_to :proposal
belongs_to :action, class_name: 'Dashboard::Action'
has_many :administrator_tasks, as: :source, dependent: :destroy, class_name: 'Dashboard::AdministratorTask'
validates :proposal, presence: true, uniqueness: { scope: :action }
validates :action, presence: true
validates :executed_at, presence: true
end

View File

@@ -31,8 +31,8 @@ class Proposal < ActiveRecord::Base
belongs_to :geozone
has_many :comments, as: :commentable, dependent: :destroy
has_many :proposal_notifications, dependent: :destroy
has_many :proposal_executed_dashboard_actions, dependent: :destroy
has_many :proposal_dashboard_actions, through: :proposal_executed_dashboard_actions
has_many :dashboard_executed_actions, dependent: :destroy, class_name: 'Dashboard::ExecutedAction'
has_many :dashboard_actions, through: :dashboard_executed_actions, class_name: 'Dashboard::Action'
has_many :polls, as: :related
validates :title, presence: true

View File

@@ -18,7 +18,7 @@ class ProposalAchievementsQuery
achievements.each do |achievement|
grouped_results[key] << {
executed_at: achievements.last.executed_at,
title: achievements.last.proposal_dashboard_action.title
title: achievements.last.action.title
}
end
end
@@ -36,11 +36,11 @@ class ProposalAchievementsQuery
end
def achievements
ProposalExecutedDashboardAction
.joins(:proposal_dashboard_action)
.includes(:proposal_dashboard_action)
Dashboard::ExecutedAction
.joins(:action)
.includes(:action)
.where(proposal: proposal, executed_at: start_date.beginning_of_day..end_date.end_of_day)
.where(proposal_dashboard_actions: { action_type: 0 })
.where(dashboard_actions: { action_type: 0 })
.order(executed_at: :asc)
end

View File

@@ -237,15 +237,15 @@
<li class="section-title">
<a href="#">
<span class="icon-check"></span>
<strong><%= t("admin.menu.proposals_dashboard") %></strong>
<strong><%= t("admin.menu.dashboard") %></strong>
</a>
<ul <%= "class=is-active" if menu_proposals_dashboard? %>>
<ul <%= "class=is-active" if menu_dashboard? %>>
<li <%= "class=is-active" if controller_name == "actions" %>>
<%= link_to ProposalDashboardAction.model_name.human(count: 2), admin_proposal_dashboard_actions_path %>
<%= link_to t("admin.menu.dashboard_actions"), admin_dashboard_actions_path %>
</li>
<li <%= "class=is-active" if controller_name == "administrator_tasks" %>>
<%= link_to admin_proposal_dashboard_administrator_tasks_path do %>
<%= link_to admin_dashboard_administrator_tasks_path do %>
<%= t("admin.menu.administrator_tasks") %>
<% end %>
</li>

View File

@@ -0,0 +1,88 @@
<%= render 'shared/errors' %>
<div class="row">
<div class="small-12 column">
<%= f.label :title %>
<%= f.text_field :title, label: false %>
</div>
</div>
<div class="row">
<div class="small-12 column">
<%= f.label :short_description %>
<%= f.text_field :short_description, label: false %>
</div>
</div>
<div class="row">
<div class="small-12 column">
<%= f.cktext_area :description,
ckeditor: { language: I18n.locale } %>
</div>
</div>
<div class="row">
<div class="small-12 medium-3 column">
<%= f.label :action_type %>
<% ::Dashboard::Action.action_types.keys.each do |action_type_value| %>
<%= f.radio_button :action_type, action_type_value, label: false %>
<%= f.label "action_type_#{action_type_value}", t("admin.dashboard.actions.action_type.#{action_type_value}") %>
<br>
<% end %>
</div>
</div>
<div class="small-12 column">
<%= f.check_box :request_to_administrators, label: ::Dashboard::Action.human_attribute_name(:request_to_administrators) %>
</div>
<div class="row">
<div class="small-12 medium-4 large-4 column">
<%= f.label :day_offset %>
<%= f.number_field :day_offset, label: false, step: 1, min: 0 %>
<p class="help-text"><%= t("admin.dashboard.actions.form.day_offset_help_text") %></p>
</div>
<div class="small-12 medium-4 large-4 column">
<%= f.label :required_supports %>
<%= f.number_field :required_supports, label: false, step: 1, min: 0 %>
<p class="help-text"><%= t("admin.dashboard.actions.form.required_supports_help_text") %></p>
</div>
<div class="small-12 medium-4 large-4 column">
<%= f.label :order %>
<%= f.number_field :order, label: false, step: 1, min: 0 %>
</div>
</div>
<div class="small-12 column">
<%= f.check_box :active, label: ::Dashboard::Action.human_attribute_name(:active) %>
</div>
<div class="small-12 column">
<hr>
</div>
<% if feature?(:allow_attached_documents) %>
<div class="documents small-12 column">
<%= render 'documents/nested_documents', documentable: dashboard_action, f: f %>
</div>
<% end %>
<div class="small-12 column">
<hr>
</div>
<div class="links small-12 column">
<%= render 'links/nested_links', linkable: dashboard_action, f: f %>
</div>
<div class="small-12 column">
<hr>
</div>
<div class="row">
<div class="actions small-12 large-3 medium-3 column">
<%= f.submit(class: 'button expanded', value: t("admin.dashboard.actions.form.submit_button")) %>
</div>
</div>

View File

@@ -0,0 +1,11 @@
<div class="row">
<div class="small-12 column">
<%= back_link_to admin_dashboard_actions_path, t("admin.dashboard.actions.edit.back") %>
<h1><%= t("admin.dashboard.actions.edit.editing") %></h1>
<%= form_for dashboard_action, url: { action: 'update' } do |f| %>
<%= render 'form', f: f %>
<% end %>
</div>
</div>

View File

@@ -0,0 +1,45 @@
<%= link_to t("admin.dashboard.actions.index.create"),
new_admin_dashboard_action_path, class: 'button success float-right' %>
<h2 class="inline-block">
<%= t("admin.dashboard.actions.index.title") %>
</h2>
<table>
<thead>
<tr>
<th><%= t("admin.dashboard.actions.index.action_title") %></th>
<th><%= t("admin.dashboard.actions.index.action_type") %></th>
<th class="text-right"><%= t("admin.dashboard.actions.index.required_supports") %></th>
<th class="text-center"><%= t("admin.dashboard.actions.index.action_active") %></th>
<th></th>
</tr>
</thead>
<tbody>
<% if @dashboard_actions.empty? %>
<tr>
<td colspan="100%"><%= t("admin.dashboard.actions.index.no_records") %></td>
</tr>
<% end %>
<% @dashboard_actions.each do |action| %>
<tr id="<%= dom_id(action) %>">
<td><%= action.title %></td>
<td><%= t("admin.dashboard.actions.action_type.#{action.action_type}") %></td>
<td class="text-right"><%= number_with_delimiter(action.required_supports, delimiter: '.') %></td>
<td class="text-center"><%= active_human_readable(action.active) %></td>
<td class="text-right">
<%= link_to t("admin.dashboard.actions.index.edit"),
edit_admin_dashboard_action_path(action),
class: 'edit-banner button hollow' %>
<%= link_to t("admin.dashboard.actions.index.delete"),
admin_dashboard_action_path(action),
method: :delete,
class: 'button hollow alert',
data: { confirm: t("admin.actions.confirm") } %>
</td>
</tr>
<% end %>
</tbody>
</table>

View File

@@ -0,0 +1,11 @@
<div class="dashboard-action-new row">
<div class="small-12 column">
<%= back_link_to admin_dashboard_actions_path, t("admin.dashboard.actions.new.back") %>
<h1><%= t("admin.dashboard.actions.new.creating") %></h1>
<%= form_for dashboard_action, url: { action: 'create' } do |f| %>
<%= render 'form', f: f %>
<% end %>
</div>
</div>

View File

@@ -0,0 +1,16 @@
<%= form_for administrator_task, url: { action: 'update' } do |f| %>
<div class="callout">
<h5><%= t("admin.dashboard.administrator_tasks.form.proposal", title: administrator_task.source.proposal.title) %></h5>
<p><%= t("admin.dashboard.administrator_tasks.form.request", title: administrator_task.source.action.title) %></p>
<%= link_to t("admin.dashboard.administrator_tasks.form.check_details"),
proposal_path(administrator_task.source.proposal),
target: '_blank' %>
</div>
<div class="row">
<div class="actions small-12 large-3 medium-3 column">
<%= f.submit(class: 'button expanded', value: t("admin.dashboard.administrator_tasks.form.solve")) %>
</div>
</div>
<% end %>

View File

@@ -0,0 +1,9 @@
<div class="row">
<div class="small-12 column">
<%= back_link_to admin_dashboard_administrator_tasks_path, t("admin.dashboard.administrator_tasks.edit.back") %>
<h1><%= t("admin.dashboard.administrator_tasks.edit.solving") %></h1>
<%= render 'form' %>
</div>
</div>

View File

@@ -1,11 +1,11 @@
<h2 class="inline-block">
<%= t("admin.proposal_dashboard.administrator_tasks.index.title") %>
<%= t("admin.dashboard.administrator_tasks.index.title") %>
</h2>
<table>
<thead>
<tr>
<th><%= AdministratorTask.human_attribute_name(:source) %></th>
<th><%= t("admin.dashboard.administrator_tasks.index.source") %></th>
<th></th>
</tr>
</thead>
@@ -13,7 +13,7 @@
<tbody>
<% if @administrator_tasks.empty? %>
<tr>
<td colspan="100%"><%= t("admin.proposal_dashboard.administrator_tasks.index.no_records") %></td>
<td colspan="100%"><%= t("admin.dashboard.administrator_tasks.index.no_records") %></td>
</tr>
<% end %>
@@ -21,11 +21,11 @@
<tr id="<%= dom_id(task) %>">
<td>
<%= task.source.proposal.title %>:
<%= task.source.proposal_dashboard_action.title %>
<%= task.source.action.title %>
</td>
<td style="text-align: right">
<%= link_to t("admin.proposal_dashboard.administrator_tasks.index.solve"),
edit_admin_proposal_dashboard_administrator_task_path(task),
<%= link_to t("admin.dashboard.administrator_tasks.index.solve"),
edit_admin_dashboard_administrator_task_path(task),
class: 'edit-banner button hollow' %>
</td>
</tr>

View File

@@ -1,90 +0,0 @@
<%= form_for [:admin, proposal_dashboard_action] do |f| %>
<%= render 'shared/errors' %>
<div class="row">
<div class="small-12 column">
<%= f.label :title %>
<%= f.text_field :title, label: false %>
</div>
</div>
<div class="row">
<div class="small-12 column">
<%= f.label :short_description %>
<%= f.text_field :short_description, label: false %>
</div>
</div>
<div class="row">
<div class="small-12 column">
<%= f.cktext_area :description,
ckeditor: { language: I18n.locale } %>
</div>
</div>
<div class="row">
<div class="small-12 medium-3 column">
<%= f.label :action_type %>
<% ProposalDashboardAction.action_types.keys.each do |action_type_value| %>
<%= f.radio_button :action_type, action_type_value, label: false %>
<%= f.label "action_type_#{action_type_value}", t("admin.proposal_dashboard_actions.action_type.#{action_type_value}") %>
<br>
<% end %>
</div>
</div>
<div class="small-12 column">
<%= f.check_box :request_to_administrators, label: ProposalDashboardAction.human_attribute_name(:request_to_administrators) %>
</div>
<div class="row">
<div class="small-12 medium-4 large-4 column">
<%= f.label :day_offset %>
<%= f.number_field :day_offset, label: false, step: 1, min: 0 %>
<p class="help-text"><%= t("admin.proposal_dashboard_actions.form.day_offset_help_text") %></p>
</div>
<div class="small-12 medium-4 large-4 column">
<%= f.label :required_supports %>
<%= f.number_field :required_supports, label: false, step: 1, min: 0 %>
<p class="help-text"><%= t("admin.proposal_dashboard_actions.form.required_supports_help_text") %></p>
</div>
<div class="small-12 medium-4 large-4 column">
<%= f.label :order %>
<%= f.number_field :order, label: false, step: 1, min: 0 %>
</div>
</div>
<div class="small-12 column">
<%= f.check_box :active, label: ProposalDashboardAction.human_attribute_name(:active) %>
</div>
<div class="small-12 column">
<hr>
</div>
<% if feature?(:allow_attached_documents) %>
<div class="documents small-12 column">
<%= render 'documents/nested_documents', documentable: proposal_dashboard_action, f: f %>
</div>
<% end %>
<div class="small-12 column">
<hr>
</div>
<div class="links small-12 column">
<%= render 'links/nested_links', linkable: proposal_dashboard_action, f: f %>
</div>
<div class="small-12 column">
<hr>
</div>
<div class="row">
<div class="actions small-12 large-3 medium-3 column">
<%= f.submit(class: 'button expanded', value: t("admin.proposal_dashboard_actions.form.submit_button")) %>
</div>
</div>
<% end %>

View File

@@ -1,9 +0,0 @@
<div class="row">
<div class="small-12 column">
<%= back_link_to admin_proposal_dashboard_actions_path, t("admin.proposal_dashboard_actions.edit.back") %>
<h1><%= t("admin.proposal_dashboard_actions.edit.editing") %></h1>
<%= render 'form' %>
</div>
</div>

View File

@@ -1,45 +0,0 @@
<%= link_to t("admin.proposal_dashboard_actions.index.create"),
new_admin_proposal_dashboard_action_path, class: 'button success float-right' %>
<h2 class="inline-block">
<%= t("admin.proposal_dashboard_actions.index.title") %>
</h2>
<table>
<thead>
<tr>
<th><%= t("admin.proposal_dashboard_actions.index.action_title") %></th>
<th><%= t("admin.proposal_dashboard_actions.index.action_type") %></th>
<th class="text-right"><%= t("admin.proposal_dashboard_actions.index.required_supports") %></th>
<th class="text-center"><%= t("admin.proposal_dashboard_actions.index.action_active") %></th>
<th></th>
</tr>
</thead>
<tbody>
<% if @proposal_dashboard_actions.empty? %>
<tr>
<td colspan="100%"><%= t("admin.proposal_dashboard_actions.index.no_records") %></td>
</tr>
<% end %>
<% @proposal_dashboard_actions.each do |action| %>
<tr id="<%= dom_id(action) %>">
<td><%= action.title %></td>
<td><%= t("admin.proposal_dashboard_actions.action_type.#{action.action_type}") %></td>
<td class="text-right"><%= number_with_delimiter(action.required_supports, delimiter: '.') %></td>
<td class="text-center"><%= active_human_readable(action.active) %></td>
<td class="text-right">
<%= link_to t("admin.proposal_dashboard_actions.index.edit"),
edit_admin_proposal_dashboard_action_path(action),
class: 'edit-banner button hollow' %>
<%= link_to t("admin.proposal_dashboard_actions.index.delete"),
admin_proposal_dashboard_action_path(action),
method: :delete,
class: 'button hollow alert',
data: { confirm: t("admin.actions.confirm") } %>
</td>
</tr>
<% end %>
</tbody>
</table>

View File

@@ -1,9 +0,0 @@
<div class="proposal-dashboard-action-new row">
<div class="small-12 column">
<%= back_link_to admin_proposal_dashboard_actions_path, t("admin.proposal_dashboard_actions.new.back") %>
<h1><%= t("admin.proposal_dashboard_actions.new.creating") %></h1>
<%= render 'form' %>
</div>
</div>

View File

@@ -1,16 +0,0 @@
<%= form_for [:admin_proposal_dashboard, administrator_task] do |f| %>
<div class="callout">
<h5><%= t("admin.proposal_dashboard.administrator_tasks.form.proposal", title: administrator_task.source.proposal.title) %></h5>
<p><%= t("admin.proposal_dashboard.administrator_tasks.form.request", title: administrator_task.source.proposal_dashboard_action.title) %></p>
<%= link_to t("admin.proposal_dashboard.administrator_tasks.form.check_details"),
proposal_path(administrator_task.source.proposal),
target: '_blank' %>
</div>
<div class="row">
<div class="actions small-12 large-3 medium-3 column">
<%= f.submit(class: 'button expanded', value: t("admin.proposal_dashboard.administrator_tasks.form.solve")) %>
</div>
</div>
<% end %>

View File

@@ -1,9 +0,0 @@
<div class="row">
<div class="small-12 column">
<%= back_link_to admin_proposal_dashboard_administrator_tasks_path, t("admin.proposal_dashboard.administrator_tasks.edit.back") %>
<h1><%= t("admin.proposal_dashboard.administrator_tasks.edit.solving") %></h1>
<%= render 'form' %>
</div>
</div>

View File

@@ -0,0 +1,8 @@
<% if dashboard_action.request_to_administrators && !dashboard_action.requested_for?(proposal) %>
<%= form_for @dashboard_executed_action,
url: create_request_proposal_dashboard_url(proposal, dashboard_action) do |f| %>
<div class="actions">
<%= f.submit(class: 'button', value: t("dashboard.form.request")) %>
</div>
<% end %>
<% end %>

View File

@@ -2,7 +2,7 @@
<div class="column small-12">
<i class="fi-flag"></i>
<strong>
<%= t("proposals_dashboard.goal.target_supports", count: number_with_precision(goal.required_supports, delimiter: '.', precision: 0)) %>
<%= t("dashboard.goal.target_supports", count: number_with_precision(goal.required_supports, delimiter: '.', precision: 0)) %>
</strong>
</div>
<div class="column small-12">&nbsp;</div>
@@ -12,15 +12,15 @@
<strong><%= goal.title %></strong>
</div>
<div class="column small-12 skip-icon">
<p class="help-text"><%= t("proposals_dashboard.goal.unlocked_resource") %></p>
<p class="help-text"><%= t("dashboard.goal.unlocked_resource") %></p>
</div>
<% if goal.day_offset.positive? %>
<div class="column small-12">
<strong><%= t("proposals_dashboard.goal.days", count: goal.day_offset) %></strong>
<strong><%= t("dashboard.goal.days", count: goal.day_offset) %></strong>
</div>
<div class="column small-12">
<p class="help-text"><%= t("proposals_dashboard.goal.ideal_time") %></p>
<p class="help-text"><%= t("dashboard.goal.ideal_time") %></p>
</div>
<% end %>
</div>

View File

@@ -2,7 +2,7 @@
<li class="section-title">
<%= link_to proposal_dashboard_index_path(proposal.to_param), class: my_proposal_menu_class do %>
<i class="fi-lightbulb"></i>
<strong><%= t("proposals_dashboard.menu.my_proposal") %></strong>
<strong><%= t("dashboard.menu.my_proposal") %></strong>
<% end %>
</li>
@@ -10,7 +10,7 @@
<%= link_to progress_proposal_dashboard_index_path(proposal.to_param),
class: progress_menu_class do %>
<span class="fi-graph-trend"></span>
<strong><%= t("proposals_dashboard.menu.progress") %></strong>
<strong><%= t("dashboard.menu.progress") %></strong>
<% end %>
</li>
@@ -18,15 +18,15 @@
<li class="section-title">
<a href="#" <%= 'class=is-active' if resources_menu_active? %>>
<span class="icon-file-text-o"></span>
<strong><%= t("proposals_dashboard.menu.resources") %></strong>
<strong><%= t("dashboard.menu.resources") %></strong>
</a>
<%= resources_menu do %>
<% if can?(:manage_polls, proposal) %>
<%= polls_menu do %>
<%= link_to proposal_dashboard_polls_path(proposal.to_param) do %>
<span data-tooltip title="<%= Setting['proposals.poll_short_title'] || t("proposals_dashboard.menu.polls") %>">
<%= t("proposals_dashboard.menu.polls") %>
<span data-tooltip title="<%= Setting['proposals.poll_short_title'] || t("dashboard.menu.polls") %>">
<%= t("dashboard.menu.polls") %>
</span>
<% end %>
<% end %>
@@ -49,7 +49,7 @@
<%= link_to community_proposal_dashboard_index_path(proposal.to_param),
class: community_menu_class do %>
<span class="fi-torsos-all"></span>
<strong><%= t("proposals_dashboard.menu.community") %></strong>
<strong><%= t("dashboard.menu.community") %></strong>
<% end %>
</li>
</ul>

View File

@@ -0,0 +1,29 @@
<% if next_goal.present? %>
<div id='goals-section'>
<br><br>
<div class="action-title">
<h5><%= t("dashboard.next_goal.title") %></h5>
<hr>
</div>
<div id="next-goal" data-toggler=".hide">
<%= render 'goal', goal: next_goal %>
<div class="column small-12">
<a data-toggle="complete-course next-goal" id='see-complete-course-link'>
<%= t("dashboard.next_goal.see_complete_course") %>
</a>
</div>
</div>
<% if course.count > 1 %>
<div class="hide" id="complete-course" data-toggler=".hide">
<%= render partial: 'goal', collection: course %>
<div class="column small-12">
<a data-toggle="complete-course next-goal"><%= t("dashboard.next_goal.hide_course") %></a>
</div>
</div>
<% end %>
</div>
<% end %>

View File

@@ -1,13 +1,13 @@
<% if can?(:manage_polls, proposal) %>
<div class="column">
<div class="card resource-card primary"
data-tooltip title="<%= t("proposals_dashboard.resource.request_resource") %>"
data-tooltip title="<%= t("dashboard.resource.request_resource") %>"
data-position="bottom" data-alignment="right">
<div class="card-section">
<p class="text-right">
<i class="fi-pencil"></i>
<i class="fi-pencil resource-icon"></i>
</p>
<h4 class="text-center"><%= t("proposals_dashboard.menu.polls") %></h4>
<h4 class="text-center"><%= t("dashboard.menu.polls") %></h4>
<p class="text-center">
<%= Setting['proposals.poll_short_title'] %>
</p>
@@ -15,7 +15,9 @@
<div class="card-section text-center bottom-container">
<div class="bottom-element text-center">
<%= link_to t("proposals_dashboard.resource.request_resource"), proposal_dashboard_polls_path(proposal.to_param), class: 'button primary' %>
<%= link_to t("dashboard.resource.request_resource"),
proposal_dashboard_polls_path(proposal.to_param),
class: 'button primary' %>
</div>
</div>
</div>

View File

@@ -14,7 +14,7 @@
<div>
<h4><%= proposed_action.title %></h4>
<% if proposed_action.proposals.where(id: proposal.id).any? %>
<p><%=l(proposed_action.proposal_executed_dashboard_actions.find_by(proposal: proposal).executed_at.to_date) %></p>
<p><%=l(proposed_action.executed_actions.find_by(proposal: proposal).executed_at.to_date) %></p>
<% else %>
<% unless proposed_action.short_description.blank? %>
<p><%= proposed_action.short_description %></p>

View File

@@ -1,7 +1,7 @@
<% if proposed_actions.any? %>
<br><br>
<div class="action-title">
<h5><%= t("proposals_dashboard.recommended_actions.title") %></h5>
<h5><%= t("dashboard.recommended_actions.title") %></h5>
<hr>
</div>

View File

@@ -21,15 +21,15 @@
<div class="card-section text-center bottom-container">
<% if resource.executed_for?(proposal) %>
<div class="bottom-element text-center">
<%= link_to t("proposals_dashboard.resource.view_resource"),
<%= link_to t("dashboard.resource.view_resource"),
new_request_proposal_dashboard_path(proposal, resource),
class: 'button success' %>
</div>
<% elsif resource.requested_for?(proposal) %>
<strong><%= t("proposals_dashboard.resource.resource_requested") %></strong>
<strong><%= t("dashboard.resource.resource_requested") %></strong>
<% elsif resource.active_for?(proposal) %>
<div class="bottom-element text-center">
<%= link_to t("proposals_dashboard.resource.request_resource"),
<%= link_to t("dashboard.resource.request_resource"),
new_request_proposal_dashboard_path(proposal, resource),
class: 'button primary' %>
</div>

View File

@@ -0,0 +1,12 @@
<div id='available-resources-section'>
<br><br>
<div class="action-title">
<h5><%= t("dashboard.resources.available_resources") %></h5>
<hr>
</div>
<div class="row small-up-2 medium-up-3 large-up-4">
<%= render 'poll_resource' %>
<%= render partial: 'resource', collection: active_resources %>
</div>
</div>

View File

@@ -1,35 +1,35 @@
<% content_for :action_title, t("proposals_dashboard.menu.community") %>
<% content_for :action_title, t("dashboard.menu.community") %>
<div class="row">
<div class="small-12 large-9 column">
<%= link_to t("proposals_dashboard.community.access_community"), community_path(proposal.community), class: 'button hollow' %>
<%= link_to t("dashboard.community.access_community"), community_path(proposal.community), class: 'button hollow' %>
<% unless proposal.community.latest_activity.nil? %>
<p class="help-text"><%= t("proposals_dashboard.community.latest_activity", at: l(proposal.community.latest_activity.to_date)) %></p>
<p class="help-text"><%= t("dashboard.community.latest_activity", at: l(proposal.community.latest_activity.to_date)) %></p>
<% end %>
</div>
<div class="small-12 large-1 column community-totals">
<span class="fi-torsos-all"></span>
&nbsp;<strong><%= number_with_delimiter(proposal.community.participants_count, delimiter: '.') %></strong>
<p><%= t("proposals_dashboard.community.participants") %></p>
<p><%= t("dashboard.community.participants") %></p>
</div>
<div class="small-12 large-1 column community-totals">
<span class="fi-comment-quotes"></span>
&nbsp;<strong><%= number_with_delimiter(proposal.community.debates_count, delimiter: '.') %></strong>
<p><%= t("proposals_dashboard.community.debates") %></p>
<p><%= t("dashboard.community.debates") %></p>
</div>
<div class="small-12 large-1 column community-totals">
<span class="fi-comments"></span>
&nbsp;<strong><%= number_with_delimiter(proposal.community.comments_count, delimiter: '.') %></strong>
<p><%= t("proposals_dashboard.community.comments") %></p>
<p><%= t("dashboard.community.comments") %></p>
</div>
</div>
<% if proposal.community.comments.any? %>
<div class="action-title">
<h5><%= t("proposals_dashboard.community.latest_comments") %></h5>
<h5><%= t("dashboard.community.latest_comments") %></h5>
<hr>
</div>

View File

@@ -1,6 +1,6 @@
<% content_for :action_title, t("proposals_dashboard.index.title") %>
<% content_for :action_title, t("dashboard.index.title") %>
<% if current_editable?(proposal) %>
<%= link_to t("proposals_dashboard.index.edit_proposal_link"), edit_proposal_path(proposal), target: '_blank', class: 'button hollow' %>
<%= link_to t("dashboard.index.edit_proposal_link"), edit_proposal_path(proposal), target: '_blank', class: 'button hollow' %>
<% end %>
@@ -13,13 +13,13 @@
<% end %>
<% unless proposal.retired? %>
<%= link_to t("proposals_dashboard.index.retire"),
<%= link_to t("dashboard.index.retire"),
retire_form_proposal_path(proposal),
class: 'button hollow alert',
target: '_blank' %>
<% end %>
<% if can?(:publish, proposal) %>
<%= link_to t("proposals_dashboard.index.publish"), publish_proposal_dashboard_index_path(proposal), class: 'button success', method: :patch %>
<%= link_to t("dashboard.index.publish"), publish_proposal_dashboard_index_path(proposal), class: 'button success', method: :patch %>
<% end %>

View File

@@ -0,0 +1,26 @@
<% content_for :action_title, dashboard_action.title %>
<div class="row">
<div class="small-12 medium-8 column">
<%== dashboard_action.description %>
<%= render 'dashboard/form' %>
</div>
<div class="small-12 medium-4 column">
<% if dashboard_action.links.any? %>
<div class="proposal-dashboard-action-links">
<h3><%= t("dashboard.new_request.links") %></h3>
<% dashboard_action.links.each do |link| %>
<% if link.open_in_new_tab %>
<%= link_to link.label, link.url, target: '_blank' %>
<% else %>
<%= link_to link.label, link.url %>
<% end %>
<% end %>
</div>
<% end %>
<%= render 'documents/documents', documents: dashboard_action.documents %>
</div>
</div>

View File

@@ -1,15 +1,15 @@
<% content_for :action_title, t("proposals_dashboard.progress.title") %>
<% content_for :action_title, t("dashboard.progress.title") %>
<div class="row">
<div class="small-12 column">
<div class="button-group">
<%= link_to t("proposals_dashboard.progress.group_by_date"),
<%= link_to t("dashboard.progress.group_by_date"),
progress_proposal_dashboard_index_path(proposal),
class: "button #{daily_selected_class}" %>
<%= link_to t("proposals_dashboard.progress.group_by_week"),
<%= link_to t("dashboard.progress.group_by_week"),
progress_proposal_dashboard_index_path(proposal, group_by: 'week'),
class: "button #{weekly_selected_class}" %>
<%= link_to t("proposals_dashboard.progress.group_by_month"),
<%= link_to t("dashboard.progress.group_by_month"),
progress_proposal_dashboard_index_path(proposal, group_by: 'month'),
class: "button #{monthly_selected_class}" %>
</div>
@@ -22,9 +22,9 @@
data-successful-proposal-graph-url="<%= successful_supports_proposal_dashboard_index_path(proposal, format: :json) %>"
data-proposal-achievements-url="<%= achievements_proposal_dashboard_index_path(proposal, format: :json) %>"
data-proposal-graph-group-by="<%= params[:group_by] %>"
data-proposal-graph-progress-label="<%= t("proposals_dashboard.progress.progress") %>"
data-proposal-graph-supports-label="<%= t("proposals_dashboard.progress.supports") %>"
data-proposal-graph-success-label="<%= t("proposals_dashboard.progress.success") %>"
data-proposal-graph-progress-label="<%= t("dashboard.progress.progress") %>"
data-proposal-graph-supports-label="<%= t("dashboard.progress.supports") %>"
data-proposal-graph-success-label="<%= t("dashboard.progress.success") %>"
data-proposal-success="<%= Setting["votes_for_proposal_success"] %>"
class="c3 proposal-graph"
style="max-height: 320px; position: relative;"></div>

View File

@@ -0,0 +1,68 @@
<!DOCTYPE html>
<html lang="<%= I18n.locale %>" data-current-user-id="<%= current_user.try(:id) %>">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<%= render "layouts/tracking_data" %>
<%= render "layouts/meta_tags" %>
<title><%= content_for?(:title) ? yield(:title) : setting['org_name'] %></title>
<%= content_for :canonical %>
<%= stylesheet_link_tag "application" %>
<!--[if lt IE 9]>
<%= stylesheet_link_tag "ie" %>
<![endif]-->
<%= javascript_include_tag "application", 'data-turbolinks-track' => true %>
<%= csrf_meta_tags %>
<%= favicon_link_tag "favicon.ico" %>
<%= favicon_link_tag image_path_for("apple-touch-icon-200.png"),
rel: "icon apple-touch-icon",
sizes: "200x200",
type: "image/png" %>
<%= content_for :social_media_meta_tags %>
<%= setting['per_page_code_head'].try(:html_safe) %>
</head>
<body class="proposal-dashboard">
<%= setting['per_page_code_body'].try(:html_safe) %>
<h1 class="show-for-sr"><%= setting['org_name'] %></h1>
<div class="off-canvas-wrapper">
<div class="off-canvas-wrapper-inner" data-off-canvas-wrapper>
<div class="off-canvas position-left" id="offCanvas" data-off-canvas>
<div class="show-for-small-only">
<div class="dashboard-sidebar" data-equalizer-watch>
<%= render partial: 'dashboard/menu' %>
</div>
</div>
</div>
<div class="off-canvas-content" data-off-canvas-content>
<%= render partial: 'layouts/header', locals: {with_subnavigation: false} %>
<div class="no-margin-top row expanded collapse" data-equalizer>
<div class="small-12 medium-3 column" data-equalizer-watch>
<div class="show-for-small-only">
<button type="button" class="button hollow expanded" data-toggle="offCanvas"><%= t("admin.menu.admin") %></button>
</div>
<div id="side_menu" class="hide-for-small-only">
<div class="dashboard-sidebar" data-equalizer-watch>
<%= render partial: 'dashboard/menu' %>
</div>
</div>
</div>
<div class="admin-content small-12 medium-9 column" data-equalizer-watch>
<%= render partial: 'layouts/flash' %>
<%= render partial: 'layouts/dashboard/proposal_totals' %>
<%= render partial: 'layouts/dashboard/proposal_header' %>
<%= yield %>
</div>
</div>
</div>
</div>
</div>
</body>
</html>

View File

@@ -8,9 +8,9 @@
<div class="counter">
<div class="counter-value">
<%= ProposalDashboardAction.active.resources.active_for(proposal).count %>
<%= Dashboard::Action.active.resources.active_for(proposal).count %>
/
<%= ProposalDashboardAction.active.resources.count %>
<%= Dashboard::Action.active.resources.count %>
</div>
<div class="counter-label"><%= t('.active_resources') %></div>
</div>

View File

@@ -1,8 +0,0 @@
<% if proposal_dashboard_action.request_to_administrators && !proposal_dashboard_action.requested_for?(proposal) %>
<%= form_for @proposal_executed_dashboard_action,
url: create_request_proposal_dashboard_url(proposal, proposal_dashboard_action) do |f| %>
<div class="actions">
<%= f.submit(class: 'button', value: t("proposals_dashboard.form.request")) %>
</div>
<% end %>
<% end %>

View File

@@ -1,25 +0,0 @@
<% if next_goal.present? %>
<br><br>
<div class="action-title">
<h5><%= t("proposals_dashboard.next_goal.title") %></h5>
<hr>
</div>
<div id="next-goal" data-toggler=".hide">
<%= render 'goal', goal: next_goal %>
<div class="column small-12">
<a data-toggle="complete-course next-goal"><%= t("proposals_dashboard.next_goal.see_complete_course") %></a>
</div>
</div>
<% if course.count > 1 %>
<div class="hide" id="complete-course" data-toggler=".hide">
<%= render partial: 'goal', collection: course %>
<div class="column small-12">
<a data-toggle="complete-course next-goal"><%= t("proposals_dashboard.next_goal.hide_course") %></a>
</div>
</div>
<% end %>
<% end %>

View File

@@ -1,10 +0,0 @@
<br><br>
<div class="action-title">
<h5><%= t("proposals_dashboard.resources.available_resources") %></h5>
<hr>
</div>
<div class="row small-up-2 medium-up-3 large-up-4">
<%= render 'poll_resource' %>
<%= render partial: 'resource', collection: active_resources %>
</div>

View File

@@ -1,26 +0,0 @@
<% content_for :action_title, proposal_dashboard_action.title %>
<div class="row">
<div class="small-12 medium-8 column">
<%== proposal_dashboard_action.description %>
<%= render 'proposals_dashboard/form' %>
</div>
<div class="small-12 medium-4 column">
<% if proposal_dashboard_action.links.any? %>
<div class="proposal-dashboard-action-links">
<h3><%= t("proposals_dashboard.new_request.links") %></h3>
<% proposal_dashboard_action.links.each do |link| %>
<% if link.open_in_new_tab %>
<%= link_to link.label, link.url, target: '_blank' %>
<% else %>
<%= link_to link.label, link.url %>
<% end %>
<% end %>
</div>
<% end %>
<%= render 'documents/documents', documents: proposal_dashboard_action.documents %>
</div>
</div>

View File

@@ -106,10 +106,10 @@ en:
proposal_notification:
one: "Proposal notification"
other: "Proposal notifications"
proposal_dashboard_action:
dashboard/action:
one: Proposal dashboard action
other: Proposal dashboard actions
administrator_task:
dashboard/administrator_task:
one: Task
other: Tasks
link:
@@ -268,7 +268,7 @@ en:
link_url: Link URL
widget/feed:
limit: Number of items
proposal_dashboard_action:
dashboard/action:
title: Title
short_description: Short description
description: Description
@@ -279,7 +279,7 @@ en:
order: Order
active: Active
action_type: Type
administrator_task:
dashboard/administrator_task:
source: Source
user: Executed by
link:

View File

@@ -318,6 +318,52 @@ en:
back: Go back to %{org}
title: Administration
description: Welcome to the %{org} admin panel.
actions:
action_type:
proposed_action: Proposed action
resource: Resource
index:
create: Create
edit: Edit
delete: Delete
no_records: No records found
active: 'Yes'
inactive: 'No'
title: Resources/Recomended actions
action_title: Title
action_type: Type
required_supports: Required supports
action_active: Active
new:
creating: New action for the proposals dashboard
back: Back to list
create:
notice: Action created successfully
edit:
editing: Edit action for the proposals dashboard
back: Back to list
delete:
success: Action successfully deleted
form:
submit_button: Save
day_offset_help_text: Enter 0 so that this value is not taken into account.
required_supports_help_text: Enter 0 so that this value is not taken into account.
administrator_tasks:
index:
title: Pending tasks
solve: Solve
no_records: There are no pending tasks
source: Source
edit:
back: Back to pending tasks list
solving: Solve pending task
form:
solve: Mark as solved
proposal: "The proposal: %{title}"
request: "Has requested: %{title}"
check_details: Check the proposal details
update:
success: The task has been marked as solved.
debates:
index:
filter: Filter
@@ -545,8 +591,9 @@ en:
title_booths: Voting booths
legislation: Collaborative Legislation
users: Users
proposals_dashboard: Proposals dashboard
dashboard: Proposals dashboard
administrator_tasks: Pending tasks
dashboard_actions: Proposal dashboard actions
administrators:
index:
title: Administrators
@@ -1094,36 +1141,6 @@ en:
delete:
success: Geozone successfully deleted
error: This geozone can't be deleted since there are elements attached to it
proposal_dashboard_actions:
action_type:
proposed_action: Proposed action
resource: Resource
index:
create: Create
edit: Edit
delete: Delete
no_records: No records found
active: 'Yes'
inactive: 'No'
title: Resources/Recomended actions
action_title: Title
action_type: Type
required_supports: Required supports
action_active: Active
new:
creating: New action for the proposals dashboard
back: Back to list
create:
notice: Action created successfully
edit:
editing: Edit action for the proposals dashboard
back: Back to list
delete:
success: Action successfully deleted
form:
submit_button: Save
day_offset_help_text: Enter 0 so that this value is not taken into account.
required_supports_help_text: Enter 0 so that this value is not taken into account.
signature_sheets:
author: Author
created_at: Creation date
@@ -1324,19 +1341,3 @@ en:
submit_header: Save header
card_title: Edit card
submit_card: Save card
proposal_dashboard:
administrator_tasks:
index:
title: Pending tasks
solve: Solve
no_records: There are no pending tasks
edit:
back: Back to pending tasks list
solving: Solve pending task
form:
solve: Mark as solved
proposal: "The proposal: %{title}"
request: "Has requested: %{title}"
check_details: Check the proposal details
update:
success: The task has been marked as solved.

View File

@@ -503,7 +503,7 @@ en:
update:
form:
submit_button: Save changes
proposals_dashboard:
dashboard:
menu:
my_proposal: My proposal
progress: Progress
@@ -561,7 +561,6 @@ en:
debates: Debates
comments: Comments
latest_comments: Latest messages
dashboard:
polls:
index:
title: Polls

View File

@@ -106,10 +106,10 @@ es:
proposal_notification:
one: "Notificación de propuesta"
other: "Notificaciones de propuestas"
proposal_dashboard_action:
dashboard/action:
one: Acción del panel de control de propuestas
other: Acciones del panel de control de propuestas
administrator_task:
dashboard/administrator_task:
one: Tarea
other: Tareas
link:
@@ -269,7 +269,7 @@ es:
link_url: URL del enlace
widget/feed:
limit: Número de elementos
proposal_dashboard_action:
dashboard/action:
title: Título
short_description: Descripción corta
description: Descripción
@@ -280,7 +280,7 @@ es:
order: Orden
active: Activa
action_type: Tipo
administrator_task:
dashboard/administrator_task:
source: Fuente
user: Ejecutado por
executed_at: Ejecutado el

View File

@@ -318,6 +318,52 @@ es:
back: Volver a %{org}
title: Administración
description: Bienvenido al panel de administración de %{org}.
actions:
action_type:
proposed_action: Acción propuesta
resource: Recurso
index:
create: Crear
edit: Editar
delete: Borrar
no_records: No se encontraron registros
active: 'Si'
inactive: 'No'
title: Recursos/Acciones recomendadas
action_title: Título
action_type: Tipo
required_supports: Apoyos necesarios
action_active: Activo
new:
creating: Nueva acción para el dashboard de propuestas
back: Volver a la lista
create:
notice: Acción creada con éxito
edit:
editing: Editar acción para el dashboard de propuestas
back: Volver a la lista
form:
submit_button: Guardar
day_offset_help_text: Introduce 0 para que este valor no se tenga en cuenta.
required_supports_help_text: Introduce 0 para que este valor no se tenga en cuenta.
delete:
success: Acción borrada con éxito
administrator_tasks:
index:
title: Tareas pendientes
solve: Resolver
no_records: No hay tareas pendientes
source: Origen
edit:
back: Volver a la lista de tareas pendientes
solving: Resolver tarea pendiente
form:
solve: Marcar como resuelta
proposal: "La propuesta: %{title}"
request: "Ha solicitado: %{title}"
check_details: Ver los detalles de la propuesta
update:
success: La tarea ha sido marcada como resuelta
debates:
index:
filter: Filtro
@@ -545,8 +591,9 @@ es:
title_booths: Urnas de votación
legislation: Legislación colaborativa
users: Usuarios
proposals_dashboard: Panel de control de propuestas
dashboard: Panel de control de propuestas
administrator_tasks: Tareas pendientes
dashboard_actions: Acciones del panel de control de propuestas
administrators:
index:
title: Administradores
@@ -1094,36 +1141,6 @@ es:
delete:
success: Distrito borrado correctamente
error: No se puede borrar el distrito porque ya tiene elementos asociados
proposal_dashboard_actions:
action_type:
proposed_action: Acción propuesta
resource: Recurso
index:
create: Crear
edit: Editar
delete: Borrar
no_records: No se encontraron registros
active: 'Si'
inactive: 'No'
title: Recursos/Acciones recomendadas
action_title: Título
action_type: Tipo
required_supports: Apoyos necesarios
action_active: Activo
new:
creating: Nueva acción para el dashboard de propuestas
back: Volver a la lista
create:
notice: Acción creada con éxito
edit:
editing: Editar acción para el dashboard de propuestas
back: Volver a la lista
form:
submit_button: Guardar
day_offset_help_text: Introduce 0 para que este valor no se tenga en cuenta.
required_supports_help_text: Introduce 0 para que este valor no se tenga en cuenta.
delete:
success: Acción borrada con éxito
signature_sheets:
author: Autor
created_at: Fecha de creación
@@ -1324,19 +1341,3 @@ es:
submit_header: Guardar encabezado
card_title: Editar tarjeta
submit_card: Guardar tarjeta
proposal_dashboard:
administrator_tasks:
index:
title: Tareas pendientes
solve: Resolver
no_records: No hay tareas pendientes
edit:
back: Volver a la lista de tareas pendientes
solving: Resolver tarea pendiente
form:
solve: Marcar como resuelta
proposal: "La propuesta: %{title}"
request: "Ha solicitado: %{title}"
check_details: Ver los detalles de la propuesta
update:
success: La tarea ha sido marcada como resuelta

View File

@@ -503,7 +503,7 @@ es:
update:
form:
submit_button: Guardar cambios
proposals_dashboard:
dashboard:
menu:
my_proposal: Mi propuesta
progress: Progreso
@@ -561,7 +561,6 @@ es:
debates: Debates
comments: Comentarios
latest_comments: Últimos mensajes
dashboard:
polls:
index:
title: Encuestas

View File

@@ -196,7 +196,7 @@ namespace :admin do
resources :feeds, only: [:update]
end
namespace :proposal_dashboard do
namespace :dashboard do
resources :actions, only: [:index, :new, :create, :edit, :update, :destroy]
resources :administrator_tasks, only: [:index, :edit, :update]
end

View File

@@ -3,7 +3,7 @@ namespace :dashboard do
end
resources :proposals do
resources :proposals_dashboard, as: :dashboard, path: :dashboard, only: [:index] do
resources :dashboard, only: [:index] do
collection do
patch :publish
get :supports

View File

@@ -0,0 +1,6 @@
class RenameProposalDashboardActionsToDashboardActions < ActiveRecord::Migration
def change
rename_table :proposal_dashboard_actions, :dashboard_actions
rename_column :proposal_executed_dashboard_actions, :proposal_dashboard_action_id, :dashboard_action_id
end
end

View File

@@ -0,0 +1,5 @@
class RenameProposalExecutedDashboardActionsToDashboardExecutedActions < ActiveRecord::Migration
def change
rename_table :proposal_executed_dashboard_actions, :dashboard_executed_actions
end
end

View File

@@ -0,0 +1,6 @@
class RenameAdministratorTaskToDashboardAdministratorTask < ActiveRecord::Migration
def change
rename_index :administrator_tasks, 'index_administrator_tasks_on_source_type_and_source_id', 'index_dashboard_administrator_tasks_on_source'
rename_table :administrator_tasks, :dashboard_administrator_tasks
end
end

View File

@@ -0,0 +1,5 @@
class RenameDashboardActionIdToActionId < ActiveRecord::Migration
def change
rename_column :dashboard_executed_actions, :dashboard_action_id, :action_id
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: 20180711224810) do
ActiveRecord::Schema.define(version: 20180723112930) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -30,18 +30,6 @@ ActiveRecord::Schema.define(version: 20180711224810) do
add_index "activities", ["actionable_id", "actionable_type"], name: "index_activities_on_actionable_id_and_actionable_type", using: :btree
add_index "activities", ["user_id"], name: "index_activities_on_user_id", using: :btree
create_table "administrator_tasks", force: :cascade do |t|
t.integer "source_id"
t.string "source_type"
t.integer "user_id"
t.datetime "executed_at"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "administrator_tasks", ["source_type", "source_id"], name: "index_administrator_tasks_on_source_type_and_source_id", using: :btree
add_index "administrator_tasks", ["user_id"], name: "index_administrator_tasks_on_user_id", using: :btree
create_table "administrators", force: :cascade do |t|
t.integer "user_id"
end
@@ -318,6 +306,43 @@ ActiveRecord::Schema.define(version: 20180711224810) do
t.datetime "updated_at", null: false
end
create_table "dashboard_actions", force: :cascade do |t|
t.string "title", limit: 80
t.text "description"
t.string "link"
t.boolean "request_to_administrators", default: false
t.integer "day_offset", default: 0
t.integer "required_supports", default: 0
t.integer "order", default: 0
t.boolean "active", default: true
t.datetime "hidden_at"
t.integer "action_type", default: 0, null: false
t.string "short_description"
end
create_table "dashboard_administrator_tasks", force: :cascade do |t|
t.integer "source_id"
t.string "source_type"
t.integer "user_id"
t.datetime "executed_at"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "dashboard_administrator_tasks", ["source_type", "source_id"], name: "index_dashboard_administrator_tasks_on_source", using: :btree
add_index "dashboard_administrator_tasks", ["user_id"], name: "index_dashboard_administrator_tasks_on_user_id", using: :btree
create_table "dashboard_executed_actions", force: :cascade do |t|
t.integer "proposal_id"
t.integer "action_id"
t.datetime "executed_at"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "dashboard_executed_actions", ["action_id"], name: "index_proposal_action", using: :btree
add_index "dashboard_executed_actions", ["proposal_id"], name: "index_dashboard_executed_actions_on_proposal_id", using: :btree
create_table "debates", force: :cascade do |t|
t.string "title", limit: 80
t.text "description"
@@ -905,31 +930,6 @@ ActiveRecord::Schema.define(version: 20180711224810) do
add_index "polls", ["related_type", "related_id"], name: "index_polls_on_related_type_and_related_id", using: :btree
add_index "polls", ["starts_at", "ends_at"], name: "index_polls_on_starts_at_and_ends_at", using: :btree
create_table "proposal_dashboard_actions", force: :cascade do |t|
t.string "title", limit: 80
t.text "description"
t.string "link"
t.boolean "request_to_administrators", default: false
t.integer "day_offset", default: 0
t.integer "required_supports", default: 0
t.integer "order", default: 0
t.boolean "active", default: true
t.datetime "hidden_at"
t.integer "action_type", default: 0, null: false
t.string "short_description"
end
create_table "proposal_executed_dashboard_actions", force: :cascade do |t|
t.integer "proposal_id"
t.integer "proposal_dashboard_action_id"
t.datetime "executed_at"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "proposal_executed_dashboard_actions", ["proposal_dashboard_action_id"], name: "index_proposal_action", using: :btree
add_index "proposal_executed_dashboard_actions", ["proposal_id"], name: "index_proposal_executed_dashboard_actions_on_proposal_id", using: :btree
create_table "proposal_notifications", force: :cascade do |t|
t.string "title"
t.text "body"
@@ -1328,11 +1328,13 @@ ActiveRecord::Schema.define(version: 20180711224810) do
t.datetime "updated_at", null: false
end
add_foreign_key "administrator_tasks", "users"
add_foreign_key "administrators", "users"
add_foreign_key "annotations", "legacy_legislations"
add_foreign_key "annotations", "users"
add_foreign_key "budget_investments", "communities"
add_foreign_key "dashboard_administrator_tasks", "users"
add_foreign_key "dashboard_executed_actions", "dashboard_actions", column: "action_id"
add_foreign_key "dashboard_executed_actions", "proposals"
add_foreign_key "documents", "users"
add_foreign_key "failed_census_calls", "poll_officers"
add_foreign_key "failed_census_calls", "users"
@@ -1364,8 +1366,6 @@ ActiveRecord::Schema.define(version: 20180711224810) do
add_foreign_key "poll_recounts", "poll_booth_assignments", column: "booth_assignment_id"
add_foreign_key "poll_recounts", "poll_officer_assignments", column: "officer_assignment_id"
add_foreign_key "poll_voters", "polls"
add_foreign_key "proposal_executed_dashboard_actions", "proposal_dashboard_actions"
add_foreign_key "proposal_executed_dashboard_actions", "proposals"
add_foreign_key "proposals", "communities"
add_foreign_key "related_content_scores", "related_contents"
add_foreign_key "related_content_scores", "users"

View File

@@ -217,6 +217,14 @@ FactoryBot.define do
trait :draft do
published_at nil
end
trait :retired do
retired_at { Time.current }
end
trait :published do
published_at { Time.current }
end
end
factory :spending_proposal do
@@ -1029,7 +1037,7 @@ LOREM_IPSUM
factory :widget_feed, class: 'Widget::Feed' do
end
factory :proposal_dashboard_action, class: 'ProposalDashboardAction' do
factory :dashboard_action, class: 'Dashboard::Action' do
title { Faker::Lorem.sentence }
description { Faker::Lorem.sentence }
link nil
@@ -1042,13 +1050,11 @@ LOREM_IPSUM
action_type 'proposed_action'
trait :admin_request do
link nil
request_to_administrators true
end
trait :external_link do
link { Faker::Internet.url }
request_to_administrators false
end
trait :inactive do
@@ -1072,14 +1078,14 @@ LOREM_IPSUM
end
end
factory :proposal_executed_dashboard_action, class: 'ProposalExecutedDashboardAction' do
factory :dashboard_executed_action, class: 'Dashboard::ExecutedAction' do
proposal
proposal_dashboard_action
action { |s| s.association(:dashboard_action) }
executed_at { Time.current }
end
factory :administrator_task do
source { |s| s.association(:proposal_executed_dashboard_action) }
factory :dashboard_administrator_task, class: 'Dashboard::AdministratorTask' do
source { |s| s.association(:dashboard_executed_action) }
user
executed_at { Time.current }
@@ -1095,7 +1101,7 @@ LOREM_IPSUM
end
factory :link do
linkable { |s| s.association(:proposal_dashboard_action) }
linkable { |s| s.association(:action) }
label { Faker::Lorem.sentence }
url { Faker::Internet.url }
open_in_new_tab false

View File

@@ -1,68 +0,0 @@
require 'rails_helper'
describe 'Administrator tasks' do
let(:administrator) { create(:administrator) }
before do
login_as administrator.user
end
context 'when accessing the pending task list' do
context 'and no pending task' do
before do
visit admin_proposal_dashboard_administrator_tasks_path
end
scenario 'informs that there are no pending tasks' do
expect(page).to have_content('There are no pending tasks')
end
end
context 'and there are pending tasks' do
let!(:task) { create :administrator_task, :pending }
before do
visit admin_proposal_dashboard_administrator_tasks_path
end
scenario 'shows the related proposal title' do
expect(page).to have_content(task.source.proposal.title)
end
scenario 'shows the requested action title' do
expect(page).to have_content(task.source.proposal_dashboard_action.title)
end
scenario 'has a link that allows solving the request' do
expect(page).to have_link('Solve')
end
end
end
context 'when solving a pending task' do
let!(:task) { create :administrator_task, :pending }
before do
visit admin_proposal_dashboard_administrator_tasks_path
click_link 'Solve'
end
scenario 'contains a link to the proposal' do
expect(page).to have_link('Check the proposal details')
end
scenario 'contains a button that solves the request' do
expect(page).to have_button('Mark as solved')
end
context 'and the Mark as solved button is pressed' do
before do
click_button 'Mark as solved'
end
scenario 'The proposal dissapears from the list' do
expect(page).not_to have_content(task.source.proposal.title)
end
end
end
end

View File

@@ -1,6 +1,6 @@
require 'rails_helper'
feature 'Admin proposal dasboard actions' do
feature 'Admin dashboard actions' do
let(:admin) { create :administrator }
before do
@@ -10,7 +10,7 @@ feature 'Admin proposal dasboard actions' do
context 'when visiting index' do
context 'and no actions defined' do
before do
visit admin_proposal_dashboard_actions_path
visit admin_dashboard_actions_path
end
scenario 'shows that there are no records available' do
@@ -19,10 +19,10 @@ feature 'Admin proposal dasboard actions' do
end
context 'and actions defined' do
let!(:action) { create :proposal_dashboard_action }
let!(:action) { create :dashboard_action }
before do
visit admin_proposal_dashboard_actions_path
visit admin_dashboard_actions_path
end
scenario 'shows the action data' do
@@ -32,16 +32,16 @@ feature 'Admin proposal dasboard actions' do
end
context 'when creating an action' do
let(:action) { build :proposal_dashboard_action }
let(:action) { build :dashboard_action }
before do
visit admin_proposal_dashboard_actions_path
visit admin_dashboard_actions_path
click_link 'Create'
end
scenario 'Creates a new action' do
fill_in 'proposal_dashboard_action_title', with: action.title
fill_in 'proposal_dashboard_action_description', with: action.description
fill_in 'dashboard_action_title', with: action.title
fill_in 'dashboard_action_description', with: action.description
click_button 'Save'
@@ -50,16 +50,16 @@ feature 'Admin proposal dasboard actions' do
end
context 'when editing an action' do
let!(:action) { create :proposal_dashboard_action }
let!(:action) { create :dashboard_action }
let(:title) { Faker::Lorem.sentence }
before do
visit admin_proposal_dashboard_actions_path
visit admin_dashboard_actions_path
click_link 'Edit'
end
scenario 'Updates the action' do
fill_in 'proposal_dashboard_action_title', with: title
fill_in 'dashboard_action_title', with: title
click_button 'Save'
expect(page).to have_content(title)
@@ -67,10 +67,10 @@ feature 'Admin proposal dasboard actions' do
end
context 'when destroying an action' do
let!(:action) { create :proposal_dashboard_action }
let!(:action) { create :dashboard_action }
before do
visit admin_proposal_dashboard_actions_path
visit admin_dashboard_actions_path
end
scenario 'deletes the action', js: true do

View File

@@ -0,0 +1,70 @@
require 'rails_helper'
feature 'Admin administrator tasks' do
let(:admin) { create :administrator }
before do
login_as(admin.user)
end
context 'when visiting index' do
context 'and no pending tasks' do
before do
visit admin_dashboard_administrator_tasks_path
end
scenario 'shows that there are no records available' do
expect(page).to have_content('There are no pending tasks')
end
end
context 'and actions defined' do
let!(:task) { create :dashboard_administrator_task, :pending }
before do
visit admin_dashboard_administrator_tasks_path
end
scenario 'shows the task data' do
expect(page).to have_content(task.source.proposal.title)
expect(page).to have_content(task.source.action.title)
end
scenario 'has a link that allows solving the request' do
expect(page).to have_link('Solve')
end
end
end
context 'when solving a task' do
let!(:task) { create :dashboard_administrator_task, :pending }
before do
visit admin_dashboard_administrator_tasks_path
click_link 'Solve'
end
scenario 'Shows task details' do
expect(page).to have_content(task.source.proposal.title)
expect(page).to have_content(task.source.action.title)
end
scenario 'contains a link to the proposal' do
expect(page).to have_link('Check the proposal details')
end
scenario 'contains a button that solves the request' do
expect(page).to have_button('Mark as solved')
end
scenario 'After it is solved dissapears from the list' do
click_button 'Mark as solved'
expect(page).not_to have_content(task.source.proposal.title)
expect(page).not_to have_content(task.source.action.title)
expect(page).to have_content('The task has been marked as solved')
end
end
end

View File

@@ -0,0 +1,137 @@
require 'rails_helper'
feature "Proposal's dashboard" do
let!(:proposal) { create(:proposal, :draft) }
before do
login_as(proposal.author)
visit proposal_dashboard_index_path(proposal)
end
scenario 'Dashboard has a link to my proposal' do
expect(page).to have_link('My proposal')
end
scenario 'My proposal has a link to edit the proposal' do
expect(page).to have_link('Edit')
end
scenario 'My proposal has a link to retire the proposal' do
expect(page).to have_link('Retire')
end
scenario 'My proposal has a link to publish the proposal' do
expect(page).to have_link('Publish')
end
scenario "Publish link dissapears after proposal's publication" do
click_link 'Publish'
expect(page).not_to have_link('Publish')
end
scenario 'Dashboard progress shows current goal', js: true do
goal = create(:dashboard_action, :resource, :active, required_supports: proposal.votes_for.size + 1_000)
future_goal = create(:dashboard_action, :resource, :active, required_supports: proposal.votes_for.size + 2_000)
visit progress_proposal_dashboard_index_path(proposal)
within 'div#goals-section' do
expect(page).to have_content(goal.title)
expect(page).not_to have_content(future_goal.title)
find(:css, '#see-complete-course-link').click
expect(page).to have_content(goal.title)
expect(page).to have_content(future_goal.title)
end
end
scenario 'Dashboard progress show proposed actions' do
action = create(:dashboard_action, :proposed_action, :active)
visit progress_proposal_dashboard_index_path(proposal)
expect(page).to have_content(action.title)
find(:css, "#dashboard_action_#{action.id}_execute").click
expect(page).not_to have_selector(:css, "#dashboard_action_#{action.id}_execute")
end
scenario 'Dashboard progress show available resources' do
available = create(:dashboard_action, :resource, :active)
requested = create(:dashboard_action, :resource, :admin_request, :active)
executed_action = create(:dashboard_executed_action, action: requested, proposal: proposal, executed_at: Time.current)
_task = create(:dashboard_administrator_task, :pending, source: executed_action)
solved = create(:dashboard_action, :resource, :admin_request, :active)
executed_solved_action = create(:dashboard_executed_action, action: solved, proposal: proposal, executed_at: Time.current)
_solved_task = create(:dashboard_administrator_task, :done, source: executed_solved_action)
unavailable = create(:dashboard_action, :resource, :active, required_supports: proposal.votes_for.size + 1_000)
visit progress_proposal_dashboard_index_path(proposal)
within 'div#available-resources-section' do
expect(page).to have_content('Polls')
expect(page).to have_content(available.title)
expect(page).to have_content(unavailable.title)
expect(page).to have_content(requested.title)
expect(page).to have_content(solved.title)
within "div#dashboard_action_#{available.id}" do
expect(page).to have_link('Request resource')
end
within "div#dashboard_action_#{requested.id}" do
expect(page).to have_content('Resource already requested')
end
within "div#dashboard_action_#{unavailable.id}" do
expect(page).to have_content('1.000 supports required')
end
within "div#dashboard_action_#{solved.id}" do
expect(page).to have_link('See resource')
end
end
end
scenario 'Dashboard has a link to polls feature' do
expect(page).to have_link('Polls')
end
scenario 'Dashboard has a link to resources on main menu' do
feature = create(:dashboard_action, :resource, :active)
visit proposal_dashboard_index_path(proposal)
expect(page).to have_link(feature.title)
end
scenario 'Request resource with admin request', js: true do
feature = create(:dashboard_action, :resource, :active, :admin_request)
visit proposal_dashboard_index_path(proposal)
click_link(feature.title)
click_button 'Request'
expect(page).to have_content('The request for the administrator has been successfully sent.')
end
scenario 'Resource without admin request do not have a request link', js: true do
feature = create(:dashboard_action, :resource, :active)
visit proposal_dashboard_index_path(proposal)
click_link(feature.title)
expect(page).not_to have_button('Request')
end
scenario 'Dashboard has a link to dashboard community', js: true do
expect(page).to have_link('Community')
click_link 'Community'
expect(page).to have_content('Participants')
expect(page).to have_content('Debates')
expect(page).to have_content('Comments')
expect(page).to have_link('Access the community')
end
end

View File

@@ -492,6 +492,27 @@ feature 'Users' do
expect(page).to have_content proposal.title
end
scenario 'Retired proposals do not have a link to the dashboard', js: true do
proposal = create(:proposal, :retired, author: @user)
login_as @user
visit user_path(@user)
expect(page).to have_content proposal.title
expect(page).not_to have_link 'Dashboard'
expect(page).to have_content('Dashboard not available for retired proposals')
end
scenario 'Published proposals have a link to the dashboard' do
proposal = create(:proposal, :published, author: @user)
login_as @user
visit user_path(@user)
expect(page).to have_content proposal.title
expect(page).to have_link 'Dashboard'
end
end
describe 'Budget Investments' do
@@ -533,5 +554,4 @@ feature 'Users' do
end
end
end

View File

@@ -4,13 +4,13 @@ describe Admin::ProposalDashboardActionsHelper do
describe 'active_human_readable' do
context 'when active is true' do
it 'returns label for active state' do
expect(active_human_readable(true)).to eq(t('admin.proposal_dashboard_actions.index.active'))
expect(active_human_readable(true)).to eq(t('admin.dashboard.actions.index.active'))
end
end
context 'when active is false' do
it 'returns label for inactive state' do
expect(active_human_readable(false)).to eq(t('admin.proposal_dashboard_actions.index.inactive'))
expect(active_human_readable(false)).to eq(t('admin.dashboard.actions.index.inactive'))
end
end
end

View File

@@ -29,7 +29,7 @@ describe Abilities::Administrator do
let(:hidden_comment) { create(:comment, :hidden) }
let(:hidden_proposal) { create(:proposal, :hidden) }
let(:administrator_task) { create(:administrator_task) }
let(:dashboard_administrator_task) { create(:dashboard_administrator_task) }
it { should be_able_to(:index, Debate) }
it { should be_able_to(:show, debate) }
@@ -90,11 +90,11 @@ describe Abilities::Administrator do
it { should be_able_to(:destroy, proposal_document) }
it { should_not be_able_to(:destroy, budget_investment_image) }
it { should_not be_able_to(:destroy, budget_investment_document) }
it { should be_able_to(:manage, ProposalDashboardAction) }
it { should be_able_to(:manage, Dashboard::Action) }
it { should be_able_to(:stats, poll) }
it { should be_able_to(:results, poll) }
it { is_expected.to be_able_to :manage, AdministratorTask }
it { is_expected.to be_able_to :manage, administrator_task }
it { is_expected.to be_able_to :manage, Dashboard::AdministratorTask }
it { is_expected.to be_able_to :manage, dashboard_administrator_task }
end

View File

@@ -104,7 +104,7 @@ describe Abilities::Common do
it { should be_able_to(:destroy, own_budget_investment_image) }
it { should_not be_able_to(:destroy, budget_investment_image) }
it { should_not be_able_to(:manage, ProposalDashboardAction) }
it { should_not be_able_to(:manage, Dashboard::Action) }
describe 'flagging content' do
it { should be_able_to(:flag, debate) }

View File

@@ -34,7 +34,7 @@ describe Abilities::Everyone do
it { should be_able_to(:read_results, finished_budget) }
it { should_not be_able_to(:read_results, reviewing_ballot_budget) }
it { should_not be_able_to(:manage, ProposalDashboardAction) }
it { should_not be_able_to(:manage, Dashboard::Action) }
context 'when accessing poll results' do
let(:results_enabled) { true }

View File

@@ -1,8 +1,8 @@
require 'rails_helper'
describe ProposalDashboardAction do
describe Dashboard::Action do
subject do
build :proposal_dashboard_action,
build :dashboard_action,
title: title,
description: description,
day_offset: day_offset,
@@ -85,5 +85,51 @@ describe ProposalDashboardAction do
it { should_not be_valid }
end
context 'active_for?' do
let(:proposal) { create(:proposal, published_at: published_at, cached_votes_up: cached_votes_up) }
let(:published_at) { Time.current }
let(:cached_votes_up) { Proposal.votes_needed_for_success + 100 }
it { should be_active_for(proposal) }
context 'and not enough supports' do
let(:required_supports) { cached_votes_up + 100 }
it { should_not be_active_for(proposal) }
end
context 'and not passed enough time since publication' do
let(:day_offset) { 10 }
it { should_not be_active_for(proposal) }
end
end
context 'executed_for? and requested_for?' do
let(:proposal) { create(:proposal) }
subject { create(:dashboard_action, :active, :admin_request, :resource) }
it { should_not be_requested_for(proposal) }
it { should_not be_executed_for(proposal) }
context 'and executed action' do
let(:executed_action) { create(:dashboard_executed_action, proposal: proposal, action: subject) }
context 'and pending administrator task' do
let!(:task) { create(:dashboard_administrator_task, :pending, source: executed_action) }
it { should be_requested_for(proposal) }
it { should_not be_executed_for(proposal) }
end
context 'and solved administrator task' do
let!(:task) { create(:dashboard_administrator_task, :done, source: executed_action) }
it { should be_requested_for(proposal) }
it { should be_executed_for(proposal) }
end
end
end
end

View File

@@ -0,0 +1,15 @@
require 'rails_helper'
describe Dashboard::AdministratorTask do
subject { build :dashboard_administrator_task, source: executed_action }
let(:executed_action) { build :dashboard_executed_action }
it { should be_valid }
context 'when source is nil' do
let(:executed_action) { nil }
it { should_not be_valid }
end
end

View File

@@ -1,16 +1,16 @@
require 'rails_helper'
describe ProposalExecutedDashboardAction do
describe Dashboard::ExecutedAction do
subject do
build :proposal_executed_dashboard_action,
build :dashboard_executed_action,
proposal: proposal,
proposal_dashboard_action: proposal_dashboard_action,
action: action,
executed_at: executed_at
end
let(:proposal) { create :proposal }
let(:proposal_dashboard_action) do
create :proposal_dashboard_action, request_to_administrators: request_to_administrators, link: Faker::Internet.url
let(:action) do
create :dashboard_action, request_to_administrators: request_to_administrators, link: Faker::Internet.url
end
let(:request_to_administrators) { false }
let(:executed_at) { Time.current }
@@ -23,8 +23,8 @@ describe ProposalExecutedDashboardAction do
it { should_not be_valid }
end
context 'when proposal_dashboard_action is nil' do
let(:proposal_dashboard_action) { nil }
context 'when action is nil' do
let(:action) { nil }
it { should_not be_valid }
end
@@ -42,7 +42,7 @@ describe ProposalExecutedDashboardAction do
end
context 'when it has been already executed' do
let!(:executed) { create(:proposal_executed_dashboard_action, proposal: proposal, proposal_dashboard_action: proposal_dashboard_action) }
let!(:executed) { create(:dashboard_executed_action, proposal: proposal, action: action) }
it { should_not be_valid }
end

View File

@@ -3,13 +3,13 @@ require 'rails_helper'
describe Link do
subject do
build :link,
linkable: proposal_dashboard_action,
linkable: dashboard_action,
label: label,
url: url,
open_in_new_tab: true
end
let(:proposal_dashboard_action) { build :proposal_dashboard_action }
let(:dashboard_action) { build :dashboard_action }
let(:label) { Faker::Lorem.sentence }
let(:url) { Faker::Internet.url }