Features:
- Custom workflow creation per project/tracker
- Step-by-step workflow definition
- Assignees per step (user, role group, department)
- Next/Previous step navigation
- Reject to first step
- Skip step (admin only)
- Step deadline settings
- Workflow dashboard
- Group member selection when proceeding
🤖 Generated with Claude Code
93 lines
3.0 KiB
Ruby
93 lines
3.0 KiB
Ruby
class WorkflowDashboardController < ApplicationController
|
|
before_action :require_login
|
|
|
|
def index
|
|
@projects = Project.visible.has_module(:issue_tracking).to_a
|
|
|
|
# 전체 워크플로우 통계
|
|
@total_stats = {
|
|
active_workflows: CustomWorkflow.where(active: true).count,
|
|
issues_in_workflow: IssueWorkflowState.where(completed_at: nil).count,
|
|
completed_today: IssueWorkflowState.where('completed_at >= ?', Date.today).count
|
|
}
|
|
|
|
# 프로젝트별 현황
|
|
@project_stats = []
|
|
@projects.each do |project|
|
|
workflows = CustomWorkflow.where(project_id: [project.id, nil]).where(active: true)
|
|
issue_ids = Issue.where(project_id: project.id).pluck(:id)
|
|
states = IssueWorkflowState.where(issue_id: issue_ids)
|
|
|
|
in_progress = states.where(completed_at: nil).count
|
|
completed = states.where.not(completed_at: nil).count
|
|
|
|
if in_progress > 0 || completed > 0
|
|
@project_stats << {
|
|
project: project,
|
|
workflows_count: workflows.count,
|
|
in_progress: in_progress,
|
|
completed: completed
|
|
}
|
|
end
|
|
end
|
|
|
|
# 내 담당 이슈 (현재 단계 담당자가 나인 경우)
|
|
@my_issues = find_my_workflow_issues(User.current)
|
|
|
|
# 지연된 이슈 (기한이 있고 초과된 경우)
|
|
@overdue_issues = find_overdue_issues
|
|
end
|
|
|
|
def project
|
|
@project = Project.find(params[:project_id])
|
|
|
|
# 해당 프로젝트의 워크플로우들
|
|
@workflows = CustomWorkflow.where(project_id: [params[:project_id], nil]).where(active: true)
|
|
|
|
# 프로젝트 이슈들의 워크플로우 상태
|
|
issue_ids = Issue.where(project_id: @project.id).pluck(:id)
|
|
@workflow_states = IssueWorkflowState.includes(:issue, :current_step, :custom_workflow)
|
|
.where(issue_id: issue_ids)
|
|
.order(updated_at: :desc)
|
|
|
|
# 단계별 그룹핑
|
|
@steps_summary = {}
|
|
@workflow_states.where(completed_at: nil).each do |state|
|
|
step_name = state.current_step&.name || '(알 수 없음)'
|
|
@steps_summary[step_name] ||= []
|
|
@steps_summary[step_name] << state
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def find_my_workflow_issues(user)
|
|
return [] unless user.logged?
|
|
|
|
states = IssueWorkflowState.includes(:issue, :current_step, :custom_workflow)
|
|
.where(completed_at: nil)
|
|
|
|
my_states = states.select do |state|
|
|
state.current_step&.assignee?(user)
|
|
end
|
|
|
|
my_states.take(20) # 최대 20개
|
|
end
|
|
|
|
def find_overdue_issues
|
|
states = IssueWorkflowState.includes(:issue, :current_step)
|
|
.where(completed_at: nil)
|
|
|
|
overdue = states.select do |state|
|
|
next false unless state.current_step&.due_days.present?
|
|
|
|
# 현재 단계에 머문 시간 계산
|
|
step_started_at = state.updated_at
|
|
due_date = step_started_at + state.current_step.due_days.days
|
|
due_date < Time.current
|
|
end
|
|
|
|
overdue.take(20)
|
|
end
|
|
end
|