fix(fe): remove duplicate script setup block in ModelsList.vue
Removed the incomplete first <script setup> block that was causing Vite plugin errors. The complete implementation in the second block already contains all necessary logic. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,68 +1,119 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { SkeletonLoader } from '../../../shared/ui/components'
|
||||
import { useModelsList } from '../composables/useModels'
|
||||
import PageLayout from '../../../shared/ui/layouts/PageLayout.vue'
|
||||
import { KsDataGrid, EmptyStatePlaceholder, SkeletonLoader } from '../../../shared/ui/components'
|
||||
import type { UiGridColumn } from '../../../shared/ui/adapter/contracts'
|
||||
import { useModelsList, type Model } from '../composables/useModels'
|
||||
|
||||
const currentPage = ref(1)
|
||||
const pageSize = ref(20)
|
||||
const searchQuery = ref('')
|
||||
const selectedPhase = ref('')
|
||||
|
||||
const queryParams = computed(() => ({
|
||||
page: currentPage.value,
|
||||
pageSize: pageSize.value,
|
||||
search: searchQuery.value,
|
||||
phase: selectedPhase.value,
|
||||
}))
|
||||
|
||||
const modelsQuery = useModelsList(queryParams.value)
|
||||
|
||||
const items = computed(() => {
|
||||
const data = modelsQuery.data as any
|
||||
const data = modelsQuery.data.value as any
|
||||
return data?.items || []
|
||||
})
|
||||
|
||||
const columns: UiGridColumn[] = [
|
||||
{ field: 'modelId', header: '모델 ID', width: 140 },
|
||||
{ field: 'name', header: '모델명', flex: 1, minWidth: 180 },
|
||||
{ field: 'phase', header: '진행 단계', width: 120 },
|
||||
{
|
||||
field: 'active',
|
||||
header: '활성화 상태',
|
||||
width: 120,
|
||||
formatter: (value) => (value ? 'Active (활성)' : 'Inactive (비활성)'),
|
||||
},
|
||||
{
|
||||
field: 'pbo',
|
||||
header: 'PBO (%)',
|
||||
width: 110,
|
||||
formatter: (value) => (typeof value === 'number' ? `${value.toFixed(2)}%` : '-'),
|
||||
},
|
||||
{
|
||||
field: 'dsr',
|
||||
header: 'DSR (%)',
|
||||
width: 110,
|
||||
formatter: (value) => (typeof value === 'number' ? `${value.toFixed(2)}%` : '-'),
|
||||
},
|
||||
{
|
||||
field: 'returnMtd',
|
||||
header: 'Return MTD (%)',
|
||||
width: 130,
|
||||
formatter: (value) => (typeof value === 'number' ? `${value.toFixed(2)}%` : '-'),
|
||||
},
|
||||
{ field: 'createdAt', header: '생성일', width: 110 },
|
||||
]
|
||||
|
||||
function handleSearch() {
|
||||
modelsQuery.refetch()
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="models-page">
|
||||
<header class="page-header">
|
||||
<h1>Model Management</h1>
|
||||
<p>Manage trading models across their complete lifecycle</p>
|
||||
</header>
|
||||
<PageLayout title="트레이딩 모델 목록 (Model Management)" subtitle="전체 트레이딩 모델의 라이프사이클 및 성과 지표를 조회·관리합니다.">
|
||||
<template #commandBar>
|
||||
<button type="button" class="p-button p-button-sm p-button-primary" @click="handleSearch">
|
||||
🔍 조회 [F3]
|
||||
</button>
|
||||
<button type="button" class="p-button p-button-sm p-button-secondary">
|
||||
➕ 신규 등록
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<template #filters>
|
||||
<div class="filters">
|
||||
<input
|
||||
v-model="searchQuery"
|
||||
type="text"
|
||||
class="search-input"
|
||||
placeholder="모델명 검색..."
|
||||
@keyup.enter="handleSearch"
|
||||
/>
|
||||
<select v-model="selectedPhase" class="status-select" @change="handleSearch">
|
||||
<option value="">전체 단계 (All Phases)</option>
|
||||
<option value="Validate">Validate</option>
|
||||
<option value="Review">Review</option>
|
||||
<option value="Mature">Mature</option>
|
||||
</select>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Loading State -->
|
||||
<div v-if="modelsQuery.isPending" class="loading-state">
|
||||
<SkeletonLoader type="table" :rows="5" />
|
||||
<div v-if="modelsQuery.isPending.value" class="state-container">
|
||||
<SkeletonLoader type="table" :rows="8" />
|
||||
</div>
|
||||
|
||||
<!-- Error State -->
|
||||
<div v-else-if="modelsQuery.isError" class="error-state">
|
||||
<p>Failed to load models</p>
|
||||
<div v-else-if="modelsQuery.isError.value" class="state-container">
|
||||
<EmptyStatePlaceholder title="데이터 로드 실패" description="모델 목록 데이터를 불러오지 못했습니다. 다시 시도해 주세요." />
|
||||
</div>
|
||||
|
||||
<!-- Empty State -->
|
||||
<div v-else-if="!items.length" class="empty-state">
|
||||
<p>No models found. Create a new model to get started.</p>
|
||||
<div v-else-if="!items.length" class="state-container">
|
||||
<EmptyStatePlaceholder title="조회된 모델이 없습니다" description="새로운 트레이딩 모델을 등록하거나 검색 조건을 변경하세요." />
|
||||
</div>
|
||||
|
||||
<!-- Data State -->
|
||||
<div v-else class="models-grid">
|
||||
<table class="models-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Model ID</th>
|
||||
<th>Name</th>
|
||||
<th>Phase</th>
|
||||
<th>Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="model in items" :key="model.id" data-testid="model-row">
|
||||
<td>{{ (model as any).id }}</td>
|
||||
<td>{{ (model as any).name }}</td>
|
||||
<td>{{ (model as any).phase }}</td>
|
||||
<td>{{ (model as any).active ? 'Active' : 'Inactive' }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<!-- Grid Data State -->
|
||||
<div v-else class="grid-container">
|
||||
<KsDataGrid
|
||||
:rows="items"
|
||||
:columns="columns"
|
||||
height="100%"
|
||||
:show-row-number="true"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</PageLayout>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
Reference in New Issue
Block a user