Merge pull request #3260 from Platoniq/dashboard-actions-for-published-proposals
Dashboard actions for published proposals
This commit is contained in:
@@ -55,7 +55,7 @@ class Admin::Dashboard::ActionsController < Admin::Dashboard::BaseController
|
|||||||
.require(:dashboard_action)
|
.require(:dashboard_action)
|
||||||
.permit(
|
.permit(
|
||||||
:title, :description, :short_description, :request_to_administrators, :day_offset,
|
:title, :description, :short_description, :request_to_administrators, :day_offset,
|
||||||
:required_supports, :order, :active, :action_type,
|
:required_supports, :order, :active, :action_type, :published_proposal,
|
||||||
documents_attributes: [:id, :title, :attachment, :cached_attachment, :user_id, :_destroy],
|
documents_attributes: [:id, :title, :attachment, :cached_attachment, :user_id, :_destroy],
|
||||||
links_attributes: [:id, :label, :url, :open_in_new_tab, :_destroy]
|
links_attributes: [:id, :label, :url, :open_in_new_tab, :_destroy]
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -23,7 +23,10 @@ class DashboardController < Dashboard::BaseController
|
|||||||
private
|
private
|
||||||
|
|
||||||
def active_resources
|
def active_resources
|
||||||
@active_resources ||= Dashboard::Action.active.resources.order(required_supports: :asc, day_offset: :asc)
|
@active_resources ||= Dashboard::Action.active
|
||||||
|
.resources
|
||||||
|
.by_proposal(proposal)
|
||||||
|
.order(required_supports: :asc, day_offset: :asc)
|
||||||
end
|
end
|
||||||
|
|
||||||
def course
|
def course
|
||||||
|
|||||||
@@ -43,13 +43,16 @@ class Dashboard::Action < ActiveRecord::Base
|
|||||||
scope :inactive, -> { where(active: false) }
|
scope :inactive, -> { where(active: false) }
|
||||||
scope :resources, -> { where(action_type: 1) }
|
scope :resources, -> { where(action_type: 1) }
|
||||||
scope :proposed_actions, -> { where(action_type: 0) }
|
scope :proposed_actions, -> { where(action_type: 0) }
|
||||||
|
scope :by_proposal, lambda { |proposal|
|
||||||
|
return where(published_proposal: false) if proposal.draft?
|
||||||
|
}
|
||||||
|
|
||||||
def self.active_for(proposal)
|
def self.active_for(proposal)
|
||||||
published_at = proposal.published_at&.to_date || Date.today
|
published_at = proposal.published_at&.to_date || Date.today
|
||||||
|
|
||||||
active
|
active.where('required_supports <= ?', proposal.cached_votes_up)
|
||||||
.where('required_supports <= ?', proposal.cached_votes_up)
|
.where('day_offset <= ?', (Date.today - published_at).to_i)
|
||||||
.where('day_offset <= ?', (Date.today - published_at).to_i)
|
.by_proposal(proposal)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.course_for(proposal)
|
def self.course_for(proposal)
|
||||||
|
|||||||
@@ -33,6 +33,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="row expanded margin-top">
|
||||||
|
<div class="small-12 medium-12 column">
|
||||||
|
<%= f.check_box :published_proposal, label: t("admin.dashboard.actions.form.published_proposal") %>
|
||||||
|
<p class="help-text"><%= t("admin.dashboard.actions.form.published_proposal_help_text") %></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="row expanded margin-top">
|
<div class="row expanded margin-top">
|
||||||
<div class="small-12 medium-4 column">
|
<div class="small-12 medium-4 column">
|
||||||
<%= f.label :day_offset %>
|
<%= f.label :day_offset %>
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
<th><%= t("admin.dashboard.actions.index.action_title") %></th>
|
<th><%= t("admin.dashboard.actions.index.action_title") %></th>
|
||||||
<th><%= t("admin.dashboard.actions.index.action_type") %></th>
|
<th><%= t("admin.dashboard.actions.index.action_type") %></th>
|
||||||
<th class="text-center"><%= t("admin.dashboard.actions.index.action_active") %></th>
|
<th class="text-center"><%= t("admin.dashboard.actions.index.action_active") %></th>
|
||||||
|
<th class="text-center"><%= t("admin.dashboard.actions.index.published_proposal") %></th>
|
||||||
<th class="text-center"><%= t("admin.dashboard.actions.index.day_offset") %></th>
|
<th class="text-center"><%= t("admin.dashboard.actions.index.day_offset") %></th>
|
||||||
<th class="text-center"><%= t("admin.dashboard.actions.index.required_supports") %></th>
|
<th class="text-center"><%= t("admin.dashboard.actions.index.required_supports") %></th>
|
||||||
<th class="text-center"><%= t("admin.dashboard.actions.index.order") %></th>
|
<th class="text-center"><%= t("admin.dashboard.actions.index.order") %></th>
|
||||||
@@ -30,6 +31,7 @@
|
|||||||
<td><%= action.title %></td>
|
<td><%= action.title %></td>
|
||||||
<td><%= t("admin.dashboard.actions.action_type.#{action.action_type}") %></td>
|
<td><%= t("admin.dashboard.actions.action_type.#{action.action_type}") %></td>
|
||||||
<td class="text-center"><%= active_human_readable(action.active) %></td>
|
<td class="text-center"><%= active_human_readable(action.active) %></td>
|
||||||
|
<td class="text-center"><%= active_human_readable(action.published_proposal) %></td>
|
||||||
<td class="text-center"><%= number_with_delimiter(action.day_offset, delimiter: '.') %></td>
|
<td class="text-center"><%= number_with_delimiter(action.day_offset, delimiter: '.') %></td>
|
||||||
<td class="text-center"><%= number_with_delimiter(action.required_supports, delimiter: '.') %></td>
|
<td class="text-center"><%= number_with_delimiter(action.required_supports, delimiter: '.') %></td>
|
||||||
<td class="text-center"><%= action.order %></td>
|
<td class="text-center"><%= action.order %></td>
|
||||||
|
|||||||
@@ -337,6 +337,7 @@ en:
|
|||||||
day_offset: Required days
|
day_offset: Required days
|
||||||
action_active: Active
|
action_active: Active
|
||||||
order: Order
|
order: Order
|
||||||
|
published_proposal: Published proposal
|
||||||
new:
|
new:
|
||||||
creating: New action for the proposals dashboard
|
creating: New action for the proposals dashboard
|
||||||
back: Back to list
|
back: Back to list
|
||||||
@@ -352,6 +353,8 @@ en:
|
|||||||
day_offset_help_text: Enter 0 so that this value is not taken into account
|
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
|
required_supports_help_text: Enter 0 so that this value is not taken into account
|
||||||
order_help_text: Order to show to user
|
order_help_text: Order to show to user
|
||||||
|
published_proposal: For published proposals?
|
||||||
|
published_proposal_help_text: Mark this checkbox to create the action only for published proposals
|
||||||
administrator_tasks:
|
administrator_tasks:
|
||||||
index:
|
index:
|
||||||
title: Pending tasks
|
title: Pending tasks
|
||||||
|
|||||||
@@ -337,6 +337,7 @@ es:
|
|||||||
day_offset: Días necesarios
|
day_offset: Días necesarios
|
||||||
action_active: Activo
|
action_active: Activo
|
||||||
order: Orden
|
order: Orden
|
||||||
|
published_proposal: Propuesta publicada
|
||||||
new:
|
new:
|
||||||
creating: Nueva acción para el dashboard de propuestas
|
creating: Nueva acción para el dashboard de propuestas
|
||||||
back: Volver a la lista
|
back: Volver a la lista
|
||||||
@@ -350,6 +351,8 @@ es:
|
|||||||
day_offset_help_text: Introduce 0 para que este valor no se tenga en cuenta
|
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
|
required_supports_help_text: Introduce 0 para que este valor no se tenga en cuenta
|
||||||
order_help_text: Orden para mostrar al usuario
|
order_help_text: Orden para mostrar al usuario
|
||||||
|
published_proposal: ¿Para propuestas publicadas?
|
||||||
|
published_proposal_help_text: Marca este checkbox para crear la acción solo para propuestas publicadas
|
||||||
delete:
|
delete:
|
||||||
success: Acción borrada con éxito
|
success: Acción borrada con éxito
|
||||||
administrator_tasks:
|
administrator_tasks:
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
class AddPublishedProposalToDashboardActions < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_column :dashboard_actions, :published_proposal, :boolean, default: :false
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 20180924071722) do
|
ActiveRecord::Schema.define(version: 20190108133246) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
@@ -370,6 +370,7 @@ ActiveRecord::Schema.define(version: 20180924071722) do
|
|||||||
t.string "short_description"
|
t.string "short_description"
|
||||||
t.datetime "created_at"
|
t.datetime "created_at"
|
||||||
t.datetime "updated_at"
|
t.datetime "updated_at"
|
||||||
|
t.boolean "published_proposal", default: false
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "dashboard_administrator_tasks", force: :cascade do |t|
|
create_table "dashboard_administrator_tasks", force: :cascade do |t|
|
||||||
|
|||||||
@@ -56,47 +56,120 @@ feature "Proposal's dashboard" do
|
|||||||
expect(page).not_to have_selector(:css, "#dashboard_action_#{action.id}_execute")
|
expect(page).not_to have_selector(:css, "#dashboard_action_#{action.id}_execute")
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario 'Dashboard progress show available resources' do
|
scenario "Dashboard progress dont show proposed actions with published_proposal: true" do
|
||||||
|
action = create(:dashboard_action, :proposed_action, :active, published_proposal: true)
|
||||||
|
|
||||||
|
visit progress_proposal_dashboard_path(proposal)
|
||||||
|
|
||||||
|
expect(page).not_to have_content(action.title)
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "Dashboard progress show available resources for proposal draft" do
|
||||||
available = create(:dashboard_action, :resource, :active)
|
available = create(:dashboard_action, :resource, :active)
|
||||||
|
|
||||||
requested = create(:dashboard_action, :resource, :admin_request, :active)
|
requested = create(:dashboard_action, :resource, :admin_request, :active)
|
||||||
executed_action = create(:dashboard_executed_action, action: requested, proposal: proposal, executed_at: Time.current)
|
executed_action = create(:dashboard_executed_action, action: requested,
|
||||||
|
proposal: proposal, executed_at: Time.current)
|
||||||
_task = create(:dashboard_administrator_task, :pending, source: executed_action)
|
_task = create(:dashboard_administrator_task, :pending, source: executed_action)
|
||||||
|
|
||||||
solved = create(:dashboard_action, :resource, :admin_request, :active)
|
solved = create(:dashboard_action, :resource, :admin_request, :active)
|
||||||
executed_solved_action = create(:dashboard_executed_action, action: solved, proposal: proposal, executed_at: Time.current)
|
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)
|
_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)
|
unavailable = create(:dashboard_action, :resource, :active,
|
||||||
|
required_supports: proposal.votes_for.size + 1_000)
|
||||||
|
|
||||||
visit progress_proposal_dashboard_path(proposal)
|
visit progress_proposal_dashboard_path(proposal)
|
||||||
within 'div#available-resources-section' do
|
within "div#available-resources-section" do
|
||||||
expect(page).to have_content('Polls')
|
expect(page).to have_content("Polls")
|
||||||
expect(page).to have_content('E-mail')
|
expect(page).to have_content("E-mail")
|
||||||
expect(page).to have_content('Poster')
|
expect(page).to have_content("Poster")
|
||||||
expect(page).to have_content(available.title)
|
expect(page).to have_content(available.title)
|
||||||
expect(page).to have_content(unavailable.title)
|
expect(page).to have_content(unavailable.title)
|
||||||
expect(page).to have_content(requested.title)
|
expect(page).to have_content(requested.title)
|
||||||
expect(page).to have_content(solved.title)
|
expect(page).to have_content(solved.title)
|
||||||
|
|
||||||
within "div#dashboard_action_#{available.id}" do
|
within "div#dashboard_action_#{available.id}" do
|
||||||
expect(page).to have_link('Request resource')
|
expect(page).to have_link("Request resource")
|
||||||
end
|
end
|
||||||
|
|
||||||
within "div#dashboard_action_#{requested.id}" do
|
within "div#dashboard_action_#{requested.id}" do
|
||||||
expect(page).to have_content('Resource already requested')
|
expect(page).to have_content("Resource already requested")
|
||||||
end
|
end
|
||||||
|
|
||||||
within "div#dashboard_action_#{unavailable.id}" do
|
within "div#dashboard_action_#{unavailable.id}" do
|
||||||
expect(page).to have_content('1.000 supports required')
|
expect(page).to have_content("1.000 supports required")
|
||||||
end
|
end
|
||||||
|
|
||||||
within "div#dashboard_action_#{solved.id}" do
|
within "div#dashboard_action_#{solved.id}" do
|
||||||
expect(page).to have_link('See resource')
|
expect(page).to have_link("See resource")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
scenario "Dashboard progress show available resources for published proposal" do
|
||||||
|
proposal.update(published_at: Date.today)
|
||||||
|
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_path(proposal)
|
||||||
|
within "div#available-resources-section" do
|
||||||
|
expect(page).to have_content("Polls")
|
||||||
|
expect(page).to have_content("E-mail")
|
||||||
|
expect(page).to have_content("Poster")
|
||||||
|
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 progress dont show resources with published_proposal: true" do
|
||||||
|
available = create(:dashboard_action, :resource, :active, published_proposal: true)
|
||||||
|
unavailable = create(:dashboard_action, :resource, :active,
|
||||||
|
required_supports: proposal.votes_for.size + 1_000,
|
||||||
|
published_proposal: true)
|
||||||
|
|
||||||
|
visit progress_proposal_dashboard_path(proposal)
|
||||||
|
|
||||||
|
within "div#available-resources-section" do
|
||||||
|
expect(page).to have_content("Polls")
|
||||||
|
expect(page).to have_content("E-mail")
|
||||||
|
expect(page).to have_content("Poster")
|
||||||
|
expect(page).not_to have_content(available.title)
|
||||||
|
expect(page).not_to have_content(unavailable.title)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
scenario 'Dashboard has a link to polls feature' do
|
scenario 'Dashboard has a link to polls feature' do
|
||||||
expect(page).to have_link('Polls')
|
expect(page).to have_link('Polls')
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -155,23 +155,50 @@ describe Dashboard::Action do
|
|||||||
let!(:not_enough_supports_action) { create :dashboard_action, :active, day_offset: 0, required_supports: 10_000 }
|
let!(:not_enough_supports_action) { create :dashboard_action, :active, day_offset: 0, required_supports: 10_000 }
|
||||||
let!(:inactive_action) { create :dashboard_action, :inactive }
|
let!(:inactive_action) { create :dashboard_action, :inactive }
|
||||||
let!(:future_action) { create :dashboard_action, :active, day_offset: 300, required_supports: 0 }
|
let!(:future_action) { create :dashboard_action, :active, day_offset: 300, required_supports: 0 }
|
||||||
|
let!(:action_for_published_proposal) { create :dashboard_action,
|
||||||
|
:active,
|
||||||
|
day_offset: 0,
|
||||||
|
required_supports: 0,
|
||||||
|
published_proposal: true }
|
||||||
|
let!(:action_for_draft_proposal) { create :dashboard_action,
|
||||||
|
:active,
|
||||||
|
day_offset: 0,
|
||||||
|
required_supports: 0,
|
||||||
|
published_proposal: false }
|
||||||
let(:proposal) { create :proposal }
|
let(:proposal) { create :proposal }
|
||||||
|
let(:draft_proposal) { create :proposal, :draft }
|
||||||
|
|
||||||
it 'actions with enough supports or days are active' do
|
it "actions with enough supports or days are active" do
|
||||||
expect(described_class.active_for(proposal)).to include(active_action)
|
expect(described_class.active_for(proposal)).to include(active_action)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'inactive actions are not included' do
|
it "inactive actions are not included" do
|
||||||
expect(described_class.active_for(proposal)).not_to include(inactive_action)
|
expect(described_class.active_for(proposal)).not_to include(inactive_action)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'actions without enough supports are not active' do
|
it "actions without enough supports are not active" do
|
||||||
expect(described_class.active_for(proposal)).not_to include(not_enough_supports_action)
|
expect(described_class.active_for(proposal)).not_to include(not_enough_supports_action)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'actions planned to be active in the future are not active' do
|
it "actions planned to be active in the future are not active" do
|
||||||
expect(described_class.active_for(proposal)).not_to include(future_action)
|
expect(described_class.active_for(proposal)).not_to include(future_action)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "actions with published_proposal: true, are not included on draft proposal" do
|
||||||
|
expect(described_class.active_for(draft_proposal)).not_to include(action_for_published_proposal)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "actions with published_proposal: true, are included on published proposal" do
|
||||||
|
expect(described_class.active_for(proposal)).to include(action_for_published_proposal)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "actions with published_proposal: false, are included on draft proposal" do
|
||||||
|
expect(described_class.active_for(draft_proposal)).to include(action_for_draft_proposal)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "actions with published_proposal: false, are included on published proposal" do
|
||||||
|
expect(described_class.active_for(proposal)).to include(action_for_draft_proposal)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context '#course_for' do
|
context '#course_for' do
|
||||||
|
|||||||
Reference in New Issue
Block a user