Skip to content

Commit

Permalink
add votes to idea
Browse files Browse the repository at this point in the history
  • Loading branch information
reabiliti committed Jul 21, 2018
1 parent 6b92ba5 commit 7aa71cf
Show file tree
Hide file tree
Showing 31 changed files with 1,088 additions and 180 deletions.
2 changes: 1 addition & 1 deletion .ruby-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.5.1
2.5.1
54 changes: 37 additions & 17 deletions app/cells/web/dashboard/idea_status_button.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,57 @@ module Dashboard
# This cell renders status idea
class IdeaStatusButton < BaseCell
def idea_status
policy(%i[dashboard idea]).activate? ? idea_state : model.state
end

private

def idea_state
link_to model.state,
link_to button_name,
change_state,
method: :put,
class: "btn btn-#{color_status} btn-sm#{button_state}",
class: "btn btn-#{color_status} btn-sm#{button_status}",
data: { confirm: t("dashboard.ideas.confirm.#{confirm_status}") }
end

def color_status
model.active? ? 'success' : color_not_success_status
private

def button_status
model.rejected? ? ' disabled' : ''
end

def color_not_success_status
model.pending? ? 'warning' : 'danger'
def button_name
if model.pending?
t('dashboard.ideas.button.voting')
elsif model.active?
t('dashboard.ideas.button.disable')
else
t('dashboard.ideas.button.activate')
end
end

def confirm_status
model.active? ? 'disable' : 'activate'
def color_status
if model.active?
'danger'
elsif model.pending?
'warning'
else
'success'
end
end

def button_state
model.rejected? ? ' disabled' : ''
def confirm_status
if model.pending?
'voting'
elsif model.active?
'disable'
else
'active'
end
end

def change_state
model.active? ? deactivate_dashboard_idea_url(model) : activate_dashboard_idea_url(model)
if model.pending?
voting_dashboard_idea_url(model)
elsif model.active?
deactivate_dashboard_idea_url(model)
else
activate_dashboard_idea_url(model)
end
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion app/cells/web/dashboard/idea_status_button/show.haml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
= idea_status
- if model.pending?
- if ::Dashboard::IdeaPolicy.new(current_user, model).reject?
= link_to t('dashboard.ideas.button.reject'),
reject_dashboard_idea_url(model),
method: :put,
Expand Down
4 changes: 2 additions & 2 deletions app/cells/web/dashboard/skill_status_button.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def skill_status
change_state,
method: :put,
class: "btn btn-#{color_status} btn-sm",
data: { confirm: t("dashboard.ideas.confirm.#{confirm_status}") }
data: { confirm: t("dashboard.skills.confirm.#{confirm_status}") }
end

private
Expand All @@ -19,7 +19,7 @@ def color_status
end

def confirm_status
model.active? ? 'disable' : 'activate'
model.active? ? 'disable' : 'active'
end

def change_state
Expand Down
20 changes: 15 additions & 5 deletions app/controllers/web/dashboard/ideas_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,18 @@ module Web
module Dashboard
# Manage ideas
class IdeasController < BaseController
before_action :idea_find, only: %i[show edit update activate deactivate reject]
before_action :authorize_role
before_action :idea, only: %i[show edit update voting activate deactivate reject]
before_action :authorize_role, only: %i[index new create]
rescue_from Pundit::NotAuthorizedError, with: :redirect_to_dashboard_root

def index
@ideas = ::Dashboard::IdeaPolicy::Scope.new(current_user, ::Idea).resolve.page params[:page]
end

def show; end
def show
@count_idea_votes_up = @idea.votes.up.count
@count_idea_votes_down = @idea.votes.down.count
end

def new
@idea = ::Idea.new
Expand Down Expand Up @@ -40,6 +43,12 @@ def update
end
end

def voting
Ops::Idea::Voting.call(idea: @idea)
redirect_to dashboard_idea_url(@idea),
flash: { success: "#{t('dashboard.ideas.notice.voting')}: #{@idea.name}" }
end

def activate
Ops::Idea::Activate.call(idea: @idea)
redirect_to dashboard_idea_url(@idea),
Expand Down Expand Up @@ -68,8 +77,9 @@ def authorize_role
authorize %i[dashboard idea], "#{action_name}?".to_sym
end

def idea_find
@idea = ::Idea.find(params[:id])
def idea
@idea ||= ::Idea.find(params[:id])
authorize @idea, policy_class: ::Dashboard::IdeaPolicy
end
end
end
Expand Down
39 changes: 39 additions & 0 deletions app/controllers/web/dashboard/votes_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# frozen_string_literal: true

module Web
module Dashboard
# Manage votes to ideas
class VotesController < BaseController
before_action :idea_find, only: %i[index up down]
rescue_from Pundit::NotAuthorizedError, with: :redirect_to_dashboard_idea

def index
@votes = @idea.votes
end

def up
Ops::Idea::Vote.call(idea: @idea, user: current_user, vote_type: 'up')
redirect_to dashboard_idea_url(@idea),
flash: { success: t('dashboard.votes.notice.success') }
end

def down
Ops::Idea::Vote.call(idea: @idea, user: current_user, vote_type: 'down')
redirect_to dashboard_idea_url(@idea),
flash: { success: t('dashboard.votes.notice.success') }
end

private

def idea_find
@idea ||= ::Idea.find(params[:idea_id])
authorize @idea, policy_class: ::Dashboard::VotePolicy
end

def redirect_to_dashboard_idea
redirect_to dashboard_idea_url(@idea),
flash: { warning: t('dashboard.votes.notice.warning') }
end
end
end
end
12 changes: 9 additions & 3 deletions app/models/idea.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,24 @@ class Idea < ApplicationRecord
belongs_to :author, class_name: 'User'
has_one :project

has_many :votes

include AASM

aasm column: 'state' do
state :pending, initial: true
state :active, :disabled, :rejected
state :voting, :active, :disabled, :rejected

event :voting do
transitions from: :pending, to: :voting
end

event :activate do
transitions from: %i[pending disabled], to: :active
transitions from: %i[voting disabled], to: :active
end

event :reject do
transitions from: :pending, to: :rejected
transitions from: %i[pending voting], to: :rejected
end

event :disable do
Expand Down
2 changes: 2 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ class User < ApplicationRecord

has_many :notes, as: :noteable

has_many :votes

# TODO: move to some other model, that represents developer explicitly.
has_one :developer_onboarding, class_name: 'Developer::Onboarding', dependent: :destroy
has_many :test_task_assignments,
Expand Down
12 changes: 12 additions & 0 deletions app/models/vote.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

# This is the voting class for ideas
class Vote < ApplicationRecord
belongs_to :user
belongs_to :idea

validates :vote_type, presence: true

scope :up, -> { where(vote_type: 'up') }
scope :down, -> { where(vote_type: 'down') }
end
16 changes: 16 additions & 0 deletions app/operations/ops/idea/vote.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# frozen_string_literal: true

module Ops
module Idea
# This is the operation of creating a vote for the idea
class Vote < BaseOperation
step :create_vote!

private

def create_vote!(_ctx, idea:, user:, vote_type:, **)
::Vote.create!(vote_type: vote_type, user: user, idea: idea)
end
end
end
end
16 changes: 16 additions & 0 deletions app/operations/ops/idea/voting.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# frozen_string_literal: true

module Ops
module Idea
# Operation activate idea
class Voting < BaseOperation
step :change_state!

private

def change_state!(_ctx, idea:, **)
idea.voting!
end
end
end
end
63 changes: 54 additions & 9 deletions app/policies/dashboard/idea_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,79 @@ def index?
true
end

alias show? index?
def show?
current_user_allow_show?
end

def new?
not_developer?
end

alias create? new?
alias edit? new?
alias update? new?

def edit?
current_user_allow_edit?
end

alias update? edit?

def voting?
current_user_allow_voting?
end

def activate?
current_user_allow_activate?
end

def deactivate?
current_user_allow_deactivate?
end

def reject?
current_user_allow_reject?
end

def manage?
staff_or_mentor?
end

alias deactivate? activate?
alias reject? activate?
private

def current_user_allow_show?
staff_or_mentor? || record.voting? && developer? || record.author == user
end

def current_user_allow_edit?
staff_or_mentor? || author? && record.author == user
end

def current_user_allow_voting?
record.pending? && staff_or_mentor?
end

def current_user_allow_activate?
(record.disabled? || record.voting?) && staff_or_mentor?
end

def current_user_allow_deactivate?
record.active? && staff_or_mentor?
end

def current_user_allow_reject?
(record.pending? || record.voting?) && staff_or_mentor?
end

# Defines a scope of Ideas, who can be available for acting person
class Scope < Scope
def resolve
if all_ideas?
::Idea.all
elsif activated_and_current_user_ideas?
::Idea.where('author_id = ? OR state = ?', user.id, 'active')
elsif voting_and_current_user_ideas?
::Idea.where('author_id = ? OR state = ?', user.id, 'voting')
elsif current_user_ideas?
::Idea.where(author_id: user.id)
elsif active_ideas?
::Idea.active
::Idea.voting
end
end

Expand All @@ -44,7 +89,7 @@ def all_ideas?
user.has_role?(:staff) || user.has_role?(:mentor)
end

def activated_and_current_user_ideas?
def voting_and_current_user_ideas?
user.has_role?(:developer) && user.has_role?(:author)
end

Expand Down
26 changes: 26 additions & 0 deletions app/policies/dashboard/vote_policy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# frozen_string_literal: true

module Dashboard
# Voting policy for an idea
class VotePolicy < DashboardPolicy
def index?
true
end

def up?
current_user_allow_voting?
end

alias down? up?

def voting?
record.voting?
end

private

def current_user_allow_voting?
developer? && user.votes.where(idea_id: record.id).empty? && record.voting?
end
end
end
Loading

0 comments on commit 7aa71cf

Please sign in to comment.