feat(daily-logs, pm): 스크럼 UI/UX 개선

Daily Logs 페이지:
- 미완료 항목 상태 변경 시 카드 유지 (done만 제거)
- 카드 정렬을 날짜 오래된 순으로 변경
- 요약 내용 nl2br 적용 및 접힘 시 2줄 제한
- 아코디언 항목 담당자별 그룹핑으로 통합

Project Management 페이지:
- 오늘의 활동을 칸반(3열) → 담당자 카드 스타일로 변경
- 완료 항목도 함께 표시 (취소선, 초록 배지)
- 미완료/완료 건수 헤더에 표시
This commit is contained in:
2025-12-04 22:25:50 +09:00
parent 6b87dc63f9
commit 1930c2ef9f
7 changed files with 1038 additions and 308 deletions

View File

@@ -24,6 +24,7 @@ public function index(): View
$projects = $this->projectService->getActiveProjects();
$stats = $this->dailyLogService->getStats($tenantId);
$weeklyTimeline = $this->dailyLogService->getWeeklyTimeline($tenantId);
$pendingEntries = $this->dailyLogService->getPendingEntries($tenantId);
$assigneeTypes = AdminPmDailyLogEntry::getAssigneeTypes();
$entryStatuses = AdminPmDailyLogEntry::getStatuses();
$assignees = $this->dailyLogService->getAssigneeList($tenantId);
@@ -32,6 +33,7 @@ public function index(): View
'projects',
'stats',
'weeklyTimeline',
'pendingEntries',
'assigneeTypes',
'entryStatuses',
'assignees'

View File

@@ -441,4 +441,55 @@ public function getAssigneeList(int $tenantId): array
'teams' => $teams,
];
}
/**
* 미완료 항목(예정, 진행중) 조회 - 담당자별 그룹핑, 날짜 오래된 순 정렬
*/
public function getPendingEntries(int $tenantId, ?int $projectId = null, int $limit = 100): array
{
$query = AdminPmDailyLogEntry::query()
->select('admin_pm_daily_log_entries.*')
->with(['dailyLog:id,log_date,project_id', 'dailyLog.project:id,name'])
->join('admin_pm_daily_logs', 'admin_pm_daily_log_entries.daily_log_id', '=', 'admin_pm_daily_logs.id')
->where('admin_pm_daily_logs.tenant_id', $tenantId)
->when($projectId, fn ($q) => $q->where('admin_pm_daily_logs.project_id', $projectId))
->whereIn('admin_pm_daily_log_entries.status', ['todo', 'in_progress'])
->orderBy('admin_pm_daily_logs.log_date', 'asc') // 날짜 오래된 순
->orderBy('admin_pm_daily_log_entries.id', 'asc')
->limit($limit);
$entries = $query->get();
// 담당자별로 그룹핑
$grouped = $entries->groupBy('assignee_name')->map(function ($items, $assigneeName) {
$todoItems = $items->where('status', 'todo');
$inProgressItems = $items->where('status', 'in_progress');
// 항목들을 날짜 오래된 순으로 정렬
$sortedEntries = $items->sortBy(fn ($e) => $e->dailyLog?->log_date)->values();
return [
'assignee_name' => $assigneeName,
'total_count' => $items->count(),
'todo_count' => $todoItems->count(),
'in_progress_count' => $inProgressItems->count(),
'oldest_date' => $sortedEntries->first()?->dailyLog?->log_date, // 카드 정렬용
'entries' => $sortedEntries->map(function ($entry) {
return [
'id' => $entry->id,
'daily_log_id' => $entry->daily_log_id,
'log_date' => $entry->dailyLog?->log_date,
'project_name' => $entry->dailyLog?->project?->name,
'content' => $entry->content,
'status' => $entry->status,
];
})->values()->toArray(),
];
});
// 담당자 카드도 가장 오래된 항목 날짜 기준으로 정렬
$sorted = $grouped->sortBy('oldest_date')->values()->toArray();
return $sorted;
}
}