refactor(fe): migrate ApprovalQueue to KsSplitter - standardize master-detail layout

- Replace custom grid layout with KsSplitter component
- Add storageKey to prevent ratio conflicts with other pages
- Remove dead .content CSS class
- Update .request-list height constraint (flex: 1 → height: 100%)
- Maintain overflow-y: auto for scrollable panes
- Simplifies code by ~50 lines, adds drag-to-resize functionality
This commit is contained in:
2026-08-15 23:59:26 +09:00
parent a1eccadca1
commit 05e279174f
@@ -1,6 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { reactive, computed, ref, onMounted } from 'vue' import { reactive, computed, ref, onMounted } from 'vue'
import ApprovalWorkbenchPage from '../../../shared/ui/screen-types/v2/ApprovalWorkbenchPage.vue' import ApprovalWorkbenchPage from '../../../shared/ui/screen-types/v2/ApprovalWorkbenchPage.vue'
import KsSplitter from '../../../shared/ui/components/KsSplitter.vue'
import { KsButton, KsStatusTag } from '../../../shared/ui/components' import { KsButton, KsStatusTag } from '../../../shared/ui/components'
import type { StandardScreenState } from '../../../shared/ui/contracts/screenContract' import type { StandardScreenState } from '../../../shared/ui/contracts/screenContract'
@@ -166,12 +167,13 @@ const handleRetry = () => {
</div> </div>
</template> </template>
<!-- Default Slot: List & Detail Workbench Layout --> <!-- Master-Detail Layout: KsSplitter -->
<div class="content"> <KsSplitter storageKey="ks_splitter_ratio_approval_queue" initialRatio="25">
<!-- Request Master List --> <template #left>
<aside class="request-list" aria-label="승인 요청 목록"> <!-- Request Master List -->
<h2>Requests ({{ filteredRequests.length }})</h2> <aside class="request-list" aria-label="승인 요청 목록">
<div class="items" role="list"> <h2>Requests ({{ filteredRequests.length }})</h2>
<div class="items" role="list">
<div <div
v-for="req in filteredRequests" v-for="req in filteredRequests"
:key="req.requestId" :key="req.requestId"
@@ -196,8 +198,10 @@ const handleRetry = () => {
</div> </div>
</div> </div>
</aside> </aside>
</template>
<!-- Detail Workbench Panel --> <!-- Detail Workbench Panel -->
<template #right>
<main class="detail-panel" aria-label="선택 요청 상세 검토"> <main class="detail-panel" aria-label="선택 요청 상세 검토">
<h2 v-if="selectedRequest">{{ selectedRequest.modelName }}</h2> <h2 v-if="selectedRequest">{{ selectedRequest.modelName }}</h2>
<div v-else class="empty-detail">Select a request from list</div> <div v-else class="empty-detail">Select a request from list</div>
@@ -286,7 +290,8 @@ const handleRetry = () => {
</div> </div>
</div> </div>
</main> </main>
</div> </template>
</KsSplitter>
</ApprovalWorkbenchPage> </ApprovalWorkbenchPage>
</template> </template>
@@ -399,14 +404,6 @@ h3 {
border-radius: var(--border-radius-lg); border-radius: var(--border-radius-lg);
} }
.content {
display: grid;
grid-template-columns: 350px 1fr;
gap: var(--spacing-5);
height: 100%;
min-height: 0;
}
.request-list { .request-list {
border: var(--border-width-1) solid var(--color-border-primary); border: var(--border-width-1) solid var(--color-border-primary);
border-radius: var(--border-radius-lg); border-radius: var(--border-radius-lg);
@@ -414,7 +411,7 @@ h3 {
background: var(--color-background-primary); background: var(--color-background-primary);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
flex: 1; height: 100%;
min-height: 0; min-height: 0;
} }