feat: 업무 상세 해야 할 일을 카테고리 탭 구조로 변경
그룹 나열 → 필수/관리/보안/부가 탭으로 전환(생성 화면·보고 모달과 동일한 탭 UI 재사용). 검토 모달은 기존 그룹 구조 유지. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -64,13 +64,22 @@ const checklistPct = computed(() => {
|
||||
// 수정 요청(changes) 상태 — 미완료 항목을 '보완 필요(X)'로 표기
|
||||
const isChangesReview = computed(() => task.value?.status === 'changes')
|
||||
|
||||
// 카테고리별 그룹(항목 있는 카테고리만, 필수/관리/보안/부가 고정 순서)
|
||||
// 카테고리별 그룹(항목 있는 카테고리만, 필수/관리/보안/부가 고정 순서) — 검토 모달에서 사용
|
||||
const checklistGroups = computed(() =>
|
||||
CHECKLIST_CATEGORIES.map((cat) => ({
|
||||
category: cat,
|
||||
items: task.value?.checklist.filter((c) => c.category === cat) ?? [],
|
||||
})).filter((g) => g.items.length > 0),
|
||||
)
|
||||
|
||||
// 상세 체크리스트 — 카테고리 탭 구조
|
||||
const checklistTab = ref<ChecklistCategory>('필수')
|
||||
const checklistTabItems = computed(
|
||||
() => task.value?.checklist.filter((c) => c.category === checklistTab.value) ?? [],
|
||||
)
|
||||
function checklistCatCount(cat: ChecklistCategory): number {
|
||||
return task.value?.checklist.filter((c) => c.category === cat).length ?? 0
|
||||
}
|
||||
// 카테고리 → 색상 클래스(필수=sec-1 …)
|
||||
function categoryClass(cat: ChecklistCategory): string {
|
||||
const map: Record<ChecklistCategory, string> = {
|
||||
@@ -642,71 +651,78 @@ function badgeFor(name: string | undefined): { label: string; cls: string } {
|
||||
완료 처리는 승인 워크플로우(승인 완료 시 일괄 완료)로만 이루어진다.
|
||||
-->
|
||||
<div class="checklist">
|
||||
<!-- 카테고리 탭 -->
|
||||
<div
|
||||
v-for="group in checklistGroups"
|
||||
:key="group.category"
|
||||
class="cat-group"
|
||||
class="cat-tabs ck-tabs"
|
||||
role="tablist"
|
||||
>
|
||||
<div
|
||||
class="cat-group-head"
|
||||
:class="categoryClass(group.category)"
|
||||
<button
|
||||
v-for="tab in CHECKLIST_CATEGORIES"
|
||||
:key="tab"
|
||||
type="button"
|
||||
class="cat-tab"
|
||||
:class="[categoryClass(tab), { active: checklistTab === tab }]"
|
||||
role="tab"
|
||||
:aria-selected="checklistTab === tab"
|
||||
@click="checklistTab = tab"
|
||||
>
|
||||
<span class="cat-dot" />
|
||||
<span class="cat-name">{{ group.category }}</span>
|
||||
<span class="cat-count">{{ group.items.length }}</span>
|
||||
</div>
|
||||
{{ tab }}
|
||||
<span class="cat-count">{{ checklistCatCount(tab) }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- 활성 탭 항목 -->
|
||||
<div
|
||||
v-for="(item, i) in checklistTabItems"
|
||||
:key="item.id ?? i"
|
||||
class="citem-wrap"
|
||||
>
|
||||
<div
|
||||
v-for="(item, i) in group.items"
|
||||
:key="item.id ?? i"
|
||||
class="citem-wrap"
|
||||
class="citem"
|
||||
:class="{ done: item.done, todo: !item.done && isChangesReview }"
|
||||
>
|
||||
<div
|
||||
class="citem"
|
||||
<span
|
||||
class="cbox"
|
||||
:class="{ done: item.done, todo: !item.done && isChangesReview }"
|
||||
>
|
||||
<span
|
||||
class="cbox"
|
||||
:class="{ done: item.done, todo: !item.done && isChangesReview }"
|
||||
>
|
||||
<svg
|
||||
v-if="item.done"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="3.5"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
><path d="M20 6 9 17l-5-5" /></svg>
|
||||
<svg
|
||||
v-else-if="isChangesReview"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="3.5"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
><path d="M18 6 6 18M6 6l12 12" /></svg>
|
||||
</span>
|
||||
<span class="ctext">{{ item.text }}</span>
|
||||
<span
|
||||
v-if="!item.done && isChangesReview"
|
||||
class="citem-tag"
|
||||
>보완 필요</span>
|
||||
</div>
|
||||
<!-- 항목별 보완 내용(수정 요청 시 입력된 경우) -->
|
||||
<div
|
||||
v-if="!item.done && isChangesReview && item.reviewNote"
|
||||
class="citem-note"
|
||||
>
|
||||
{{ item.reviewNote }}
|
||||
</div>
|
||||
<svg
|
||||
v-if="item.done"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="3.5"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
><path d="M20 6 9 17l-5-5" /></svg>
|
||||
<svg
|
||||
v-else-if="isChangesReview"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="3.5"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
><path d="M18 6 6 18M6 6l12 12" /></svg>
|
||||
</span>
|
||||
<span class="ctext">{{ item.text }}</span>
|
||||
<span
|
||||
v-if="!item.done && isChangesReview"
|
||||
class="citem-tag"
|
||||
>보완 필요</span>
|
||||
</div>
|
||||
<!-- 항목별 보완 내용(수정 요청 시 입력된 경우) -->
|
||||
<div
|
||||
v-if="!item.done && isChangesReview && item.reviewNote"
|
||||
class="citem-note"
|
||||
>
|
||||
{{ item.reviewNote }}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="checklistGroups.length === 0"
|
||||
v-if="checklistTabItems.length === 0"
|
||||
class="check-empty"
|
||||
>
|
||||
등록된 할 일이 없습니다.
|
||||
'{{ checklistTab }}' 항목이 없습니다.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -3512,6 +3528,14 @@ a.file-info {
|
||||
gap: 0.25rem;
|
||||
padding: 0.75rem 1.25rem 0;
|
||||
}
|
||||
/* 체크리스트 카드용 탭 — 모달과 달리 좌우 패딩 없이, 항목과 구분선 */
|
||||
.ck-tabs {
|
||||
flex-wrap: wrap;
|
||||
padding: 0;
|
||||
margin-bottom: 0.75rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
.cat-tab {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
|
||||
Reference in New Issue
Block a user