@extends('layouts.app') @section('title', 'Redmine 看板') @push('styles') @endpush @section('content')
{{-- 頂部工具列 --}}
{{-- 第一行:標題(左)+ 篩選器(右) --}}

Redmine 看板

{{-- 人員 --}}
{{-- 專案(可搜尋 combobox) --}}
{{-- 清除 --}} @if($selectedProject) @endif
{{-- 排序 --}}
{{-- 泳道篩選 --}}
{{-- 第二行:統計(左)+ 新增按鈕(右) --}} @php $today = now()->timezone('Asia/Taipei')->toDateString(); $totalCount = count($issues); $progressCount = collect($issues)->filter(fn($i) => preg_match('/處理|進行|doing|in.prog/iu', $i['status']['name'] ?? ''))->count(); $resolvedCount = collect($issues)->filter(fn($i) => preg_match('/完成|解決|done|resolv/iu', $i['status']['name'] ?? ''))->count(); $todayCount = collect($issues)->filter(function($i) use ($today) { if (!preg_match('/完成|解決|done|resolv/iu', $i['status']['name'] ?? '')) return false; return substr($i['updated_on'] ?? '', 0, 10) === $today; })->count(); @endphp
全部 {{ $totalCount }} 處理中 {{ $progressCount }} 今日已完成 {{ $todayCount }} 全部已完成 {{ $resolvedCount }}
{{-- 新增議題 Modal --}} {{-- 編輯議題 Modal --}} {{-- 載入提示 --}} {{-- 看板主體 --}} @if (count($issues) === 0)
目前沒有開放中的議題
@else
@foreach ($openStatuses as $statusIdx => $status) @php $colIssues = $issuesByStatus[$status['id']] ?? []; $count = count($colIssues); $sn = $status['name']; $colColor = match(true) { (bool) preg_match('/新|new|open/iu', $sn) => 'col-new', (bool) preg_match('/處理|進行|doing|in.prog/iu', $sn) => 'col-progress', (bool) preg_match('/意見|回饋|feedback/iu', $sn) => 'col-feedback', (bool) preg_match('/完成|解決|done|resolv/iu', $sn) => 'col-resolved', (bool) preg_match('/關閉|closed|reject|拒/iu', $sn) => 'col-closed', default => 'col-default-' . ($statusIdx % 5), }; @endphp @php $statGroup = match($colColor) { 'col-progress' => 'progress', 'col-resolved' => 'resolved', default => 'other', }; @endphp
{{ $status['name'] }} {{ $count }}
@foreach ($colIssues as $issue) @php $isMine = ($issue['assigned_to']['id'] ?? null) === $redmineUser['id']; $priClass = match(true) { in_array($issue['priority']['name'] ?? '', ['Urgent','Immediate','緊急','立即']) => 'pri-urgent', in_array($issue['priority']['name'] ?? '', ['High','高']) => 'pri-high', in_array($issue['priority']['name'] ?? '', ['Low','低']) => 'pri-low', default => 'pri-normal', }; $overdue = !empty($issue['due_date']) && \Carbon\Carbon::parse($issue['due_date'])->isPast(); @endphp @php $closedOn = !empty($issue['closed_on']) ? substr($issue['closed_on'], 0, 10) : null; @endphp
{{-- 卡片頂部 --}}
@if ($isMine)@endif #{{ $issue['id'] }} @if (!empty($issue['project']['name'])) {{ $issue['project']['name'] }} @endif
@if (!empty($issue['tracker']['name'])) {{ $issue['tracker']['name'] }} @endif @if (($issue['author']['id'] ?? null) === $redmineUser['id']) @endif
{{-- 主旨 --}} {{ Str::limit($issue['subject'], 60) }} {{-- 指派人(左)+ 日期(右下)--}}
{{ $issue['assigned_to']['name'] ?? '未指派' }}
{{ substr($issue['created_on'] ?? '', 0, 10) ?: '—' }}
{{ $issue['due_date'] ?? '—' }}
@if($closedOn)
{{ $closedOn }}
@endif
{{-- 工時 --}} @php $estimated = $issue['estimated_hours'] ?? null; $spent = $issue['spent_hours'] ?? null; @endphp @if ($estimated || $spent)
@if ($estimated) 預估 {{ number_format($estimated, 1) }}小時 @endif @if ($spent) 已用 {{ number_format($spent, 1) }}小時 @endif
@endif {{-- 完成度 --}} @if (($issue['done_ratio'] ?? 0) > 0)
@endif
@endforeach
@endforeach
@endif
@endsection @push('scripts') @endpush