feat: integrate TanStack Query for data fetching (Task F)
Add composables for API integration with TanStack Query: 1. useShadowRuns.ts (shadow-run feature) - useShadowRunsList() with pagination & filtering - useShadowRunDetail() for detail view - useCreateShadowRun() mutation - useRefreshShadowRuns() for manual refresh - shadowRunQueryKeys factory for cache management 2. useModels.ts (models feature) - useModelsList() with filtering by phase/active - useModelDetail() for detail view - useActivateModel() / useDeactivateModel() mutations - useTransitionPhase() for lifecycle transitions - modelQueryKeys factory 3. Updated pages (ShadowRunList, ShadowRunDetail, ModelsList, ModelDetail) - Replace mock data with useQuery hooks - Auto-refetch on filter changes - Optimistic updates (activate/deactivate/transition) - Computed state management (idle/pending/ready/error/empty) - Cache invalidation on mutations Features: - Stale time: 5 minutes, garbage collection: 10 minutes - Query key factories for cache management - Mock API client (replace with real HTTP endpoints) - Support for pagination, filtering, sorting - Keyboard shortcuts still functional Mock API client provides realistic data for testing. Replace apiClient.* functions with actual HTTP calls in next phase. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { computed, onMounted, onUnmounted } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import KbxButton from '@shared/ui/adapter/KbxButton.vue'
|
||||
import { useKbxRegistry } from '@shared/composables/useKbxRegistry'
|
||||
import { useShadowRunDetail } from '../composables/useShadowRuns'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
@@ -16,32 +17,32 @@ const screenDef = computed(() =>
|
||||
// Extract runId from route
|
||||
const runId = computed(() => route.params.runId as string)
|
||||
|
||||
// Mock run data (will be replaced with TanStack Query)
|
||||
const run = ref({
|
||||
runId: '00000000-0000-0000-0000-000000000001',
|
||||
modelName: 'Alpha Strategy',
|
||||
windowStart: '2024-01-02',
|
||||
windowEnd: '2024-09-10',
|
||||
tradingDays: 187,
|
||||
totalReturn: 12.5,
|
||||
sharpeRatio: 1.8,
|
||||
pbo: 15.2,
|
||||
dsr: 96.5,
|
||||
oos: 1.8,
|
||||
maxDrawdown: -8.3,
|
||||
winRate: 58.5,
|
||||
profitFactor: 2.1,
|
||||
phases: {
|
||||
bull: { return: 18.2, sharpe: 2.3, trades: 45 },
|
||||
bear: { return: -2.1, sharpe: -0.5, trades: 28 },
|
||||
sideways: { return: 5.3, sharpe: 1.1, trades: 32 },
|
||||
},
|
||||
status: 'completed',
|
||||
createdAt: '2026-08-01',
|
||||
})
|
||||
// TanStack Query hook
|
||||
const shadowRunQuery = useShadowRunDetail(runId.value)
|
||||
|
||||
const isLoading = ref(false)
|
||||
const error = ref<string | null>(null)
|
||||
// Computed property for run data
|
||||
const run = computed(() => shadowRunQuery.data.value || {
|
||||
runId: runId.value,
|
||||
modelName: 'Loading...',
|
||||
windowStart: '',
|
||||
windowEnd: '',
|
||||
tradingDays: 0,
|
||||
totalReturn: 0,
|
||||
sharpeRatio: 0,
|
||||
pbo: 0,
|
||||
dsr: 0,
|
||||
oos: 0,
|
||||
maxDrawdown: 0,
|
||||
winRate: 0,
|
||||
profitFactor: 0,
|
||||
phases: {
|
||||
bull: { return: 0, sharpe: 0, trades: 0 },
|
||||
bear: { return: 0, sharpe: 0, trades: 0 },
|
||||
sideways: { return: 0, sharpe: 0, trades: 0 },
|
||||
},
|
||||
status: 'pending' as const,
|
||||
createdAt: '',
|
||||
})
|
||||
|
||||
// Validation indicators
|
||||
const validationStatus = computed(() => {
|
||||
@@ -86,8 +87,6 @@ const handleKeydown = (e: KeyboardEvent) => {
|
||||
}
|
||||
}
|
||||
|
||||
import { onMounted, onUnmounted } from 'vue'
|
||||
|
||||
onMounted(() => {
|
||||
window.addEventListener('keydown', handleKeydown)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user