Files
KArtSell.Aegis/frontend/src/features/wbs/pages/WbsWorkspacePage.vue
T
kjh2064 1be7029f8f
deploy / deploy (push) Failing after 51s
deploy / notify (push) Successful in 1s
refactor(fe): viewport-fit zero-scroll layout for 11 pages (Part 2)
## Summary
- BatchOperationsPageV2: add overflow-y: auto (ShadowRunQueue, DataQualityPage)
- ModelsList: add flex:1 + min-height:0 + overflow-y:auto
- ShadowRunList: change height to 100% (from calc(100vh - 210px))
- ModelOperationsPage: add overflow-y: auto
- WbsWorkspacePage: add flex:1 + min-height:0 + overflow-y:auto
- IngestionStatus, CommonCodeManagementPage: already fitted (via component inheritance)
- MarketDataIngestion: already fitted (EditFormPage)
- HomePage, RebalanceForm, UiStandardPage: already fitted (earlier session)

Total: 11 pages viewport-fit, 7 pages already compliant

Still needed:
- ModelDetail, ShadowRunDetail: need PageLayout wrapping or refactoring

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-16 15:00:03 +09:00

25 lines
4.3 KiB
Vue

<script setup lang="ts">
import { ref } from 'vue'
import { KsStatusTag } from '@/shared/ui/components'
type WbsItem = { id: string; title: string; owner: string; state: 'DONE' | 'IN_PROGRESS' | 'DECISION_REQUIRED' }
const selectedId = ref('UI-001')
const items: WbsItem[] = [
{ id: 'UI-001', title: '공유 컴포넌트 카탈로그와 상태 프리뷰', owner: 'FE Platform', state: 'IN_PROGRESS' },
{ id: 'UI-002', title: 'WBS 실행 화면 및 요구사항 추적', owner: 'Delivery', state: 'IN_PROGRESS' },
{ id: 'DATA-001', title: 'DB 스키마 Read Model/API 계약', owner: 'Data Platform', state: 'DECISION_REQUIRED' },
{ id: 'OPS-001', title: 'Playwright 시각·상태행렬 검증', owner: 'QA', state: 'IN_PROGRESS' },
]
</script>
<template>
<section class="page" aria-labelledby="wbs-title">
<header class="page-header"><div><p class="eyebrow">INTERNAL · READ ONLY</p><h1 id="wbs-title">WBS 실행공간</h1><p>요구사항·Slice·검증 상태를 화면에서 추적합니다. 화면은 작업을 자동 실행하거나 배포하지 않습니다.</p></div><KsStatusTag value="AUTOMATION OFF" severity="warning" /></header>
<div class="summary-grid"><div class="ks-card"><strong>4</strong><span>현재 Slice</span></div><div class="ks-card"><strong>1</strong><span>Decision Required</span></div><div class="ks-card"><strong>UI-CONTRACT-4.0</strong><span>계약 버전</span></div></div>
<div class="workspace">
<section class="ks-card list" aria-labelledby="wbs-list-title"><h2 id="wbs-list-title">작업 목록</h2><button v-for="item in items" :key="item.id" class="wbs-row" :class="{ selected: selectedId === item.id }" type="button" @click="selectedId = item.id"><span><b>{{ item.id }}</b>{{ item.title }}</span><small>{{ item.owner }}</small><KsStatusTag :value="item.state" :severity="item.state === 'DONE' ? 'success' : item.state === 'DECISION_REQUIRED' ? 'danger' : 'info'" /></button></section>
<section class="ks-card detail" aria-labelledby="wbs-detail-title"><h2 id="wbs-detail-title">선택 작업 증거</h2><template v-if="selectedId === 'DATA-001'"><p class="warning">서버 Read Model, 권한 정책, PIT 범위가 승인되기 전에는 DB 스키마를 직접 노출하지 않습니다.</p><dl><dt>필요 계약</dt><dd>API/DB/Role/Projection Version</dd><dt>상태</dt><dd>DECISION_REQUIRED</dd></dl></template><template v-else><p>현재 작업은 내부 검토용이며, 구현·테스트·스크린샷 증거를 Slice 기록에 연결해야 합니다.</p><dl><dt>Slice</dt><dd>{{ selectedId }}</dd><dt>자동주문/KIS</dt><dd>OFF</dd><dt>검증</dt><dd>Playwright 실행 증거화 예정</dd></dl></template></section>
</div>
</section>
</template>
<style scoped>.page{display:grid;gap:var(--ks-space-5)}.page-header{display:flex;justify-content:space-between;gap:var(--ks-space-4);align-items:start}.eyebrow{font-size:var(--ks-font-caption);color:var(--ks-color-neutral-600);letter-spacing:.08em}.page-header h1{margin:.25rem 0}.summary-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--ks-space-3)}.summary-grid .ks-card{display:grid;gap:.25rem;padding:var(--ks-space-4)}.summary-grid strong{font-size:1.35rem}.summary-grid span{color:var(--ks-color-neutral-600)}.workspace{display:grid;grid-template-columns:minmax(0,1.25fr) minmax(18rem,.75fr);gap:var(--ks-space-4);flex:1;min-height:0;overflow-y:auto}.list,.detail{padding:var(--ks-space-4)}.list h2,.detail h2{margin-top:0}.wbs-row{display:grid;grid-template-columns:minmax(0,1fr) auto auto;align-items:center;gap:var(--ks-space-3);width:100%;padding:var(--ks-space-3);border:0;border-top:1px solid var(--ks-color-neutral-200);background:var(--ks-color-surface);text-align:left;cursor:pointer}.wbs-row span{display:grid;gap:.25rem}.wbs-row b{font-size:var(--ks-font-caption);color:var(--ks-color-primary-700)}.wbs-row small{color:var(--ks-color-neutral-600)}.wbs-row.selected{background:var(--ks-color-neutral-100)}.warning{padding:var(--ks-space-3);border-left:3px solid var(--ks-color-warning);background:var(--ks-color-neutral-100)}.detail dl{display:grid;grid-template-columns:auto 1fr;gap:var(--ks-space-2);font-size:var(--ks-font-caption)}.detail dt{font-weight:700}.detail dd{margin:0}@media(max-width:800px){.workspace,.summary-grid{grid-template-columns:1fr}.page-header{flex-direction:column}.wbs-row{grid-template-columns:1fr auto}}</style>