feat: API Flow Tester 기능 기반 구조 추가
- 모델: AdminApiFlow, AdminApiFlowRun - 컨트롤러: FlowTesterController - 뷰: index, create, edit, history, run-detail - 사이드바 메뉴에 "개발 도구" 그룹 추가 - 라우트 설정
This commit is contained in:
145
resources/views/dev-tools/flow-tester/run-detail.blade.php
Normal file
145
resources/views/dev-tools/flow-tester/run-detail.blade.php
Normal file
@@ -0,0 +1,145 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', '실행 상세 - #' . $run->id)
|
||||
|
||||
@section('content')
|
||||
<!-- 페이지 헤더 -->
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<div class="flex items-center gap-4">
|
||||
<a href="{{ route('dev-tools.flow-tester.history', $run->flow_id) }}"
|
||||
class="p-2 text-gray-600 hover:bg-gray-100 rounded-lg transition">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7" />
|
||||
</svg>
|
||||
</a>
|
||||
<div>
|
||||
<h1 class="text-2xl font-bold text-gray-800">실행 상세 #{{ $run->id }}</h1>
|
||||
<p class="text-sm text-gray-500">{{ $run->flow->name }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<span class="px-3 py-1 text-sm font-medium rounded {{ $run->status_color }}">
|
||||
{{ $run->status_label }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||
<!-- 요약 정보 -->
|
||||
<div class="lg:col-span-1">
|
||||
<div class="bg-white rounded-lg shadow-sm p-6">
|
||||
<h2 class="text-lg font-semibold text-gray-800 mb-4">실행 정보</h2>
|
||||
|
||||
<dl class="space-y-3">
|
||||
<div class="flex justify-between">
|
||||
<dt class="text-gray-500">상태</dt>
|
||||
<dd>
|
||||
<span class="px-2 py-1 text-xs font-medium rounded {{ $run->status_color }}">
|
||||
{{ $run->status_label }}
|
||||
</span>
|
||||
</dd>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<dt class="text-gray-500">진행률</dt>
|
||||
<dd class="text-gray-900">{{ $run->progress }}%</dd>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<dt class="text-gray-500">완료 스텝</dt>
|
||||
<dd class="text-gray-900">{{ $run->completed_steps }}/{{ $run->total_steps ?? '-' }}</dd>
|
||||
</div>
|
||||
@if($run->failed_step)
|
||||
<div class="flex justify-between">
|
||||
<dt class="text-gray-500">실패 스텝</dt>
|
||||
<dd class="text-red-600">Step {{ $run->failed_step }}</dd>
|
||||
</div>
|
||||
@endif
|
||||
<div class="flex justify-between">
|
||||
<dt class="text-gray-500">소요시간</dt>
|
||||
<dd class="text-gray-900">
|
||||
@if($run->duration_ms)
|
||||
{{ number_format($run->duration_ms / 1000, 2) }}s
|
||||
@else
|
||||
-
|
||||
@endif
|
||||
</dd>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<dt class="text-gray-500">시작시간</dt>
|
||||
<dd class="text-gray-900">{{ $run->started_at?->format('H:i:s') ?? '-' }}</dd>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<dt class="text-gray-500">완료시간</dt>
|
||||
<dd class="text-gray-900">{{ $run->completed_at?->format('H:i:s') ?? '-' }}</dd>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<dt class="text-gray-500">실행일</dt>
|
||||
<dd class="text-gray-900">{{ $run->created_at->format('Y-m-d') }}</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
@if($run->error_message)
|
||||
<div class="mt-4 bg-red-50 border border-red-200 rounded-lg p-4">
|
||||
<h3 class="text-sm font-medium text-red-800 mb-2">에러 메시지</h3>
|
||||
<p class="text-sm text-red-700">{{ $run->error_message }}</p>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<!-- 실행 로그 -->
|
||||
<div class="lg:col-span-2">
|
||||
<div class="bg-white rounded-lg shadow-sm p-6">
|
||||
<h2 class="text-lg font-semibold text-gray-800 mb-4">실행 로그</h2>
|
||||
|
||||
@if($run->execution_log)
|
||||
<div class="space-y-4">
|
||||
@foreach($run->execution_log as $index => $log)
|
||||
<div class="border rounded-lg p-4 {{ ($log['success'] ?? false) ? 'border-green-200 bg-green-50' : 'border-red-200 bg-red-50' }}">
|
||||
<div class="flex justify-between items-start mb-2">
|
||||
<div class="flex items-center gap-2">
|
||||
@if($log['success'] ?? false)
|
||||
<svg class="w-5 h-5 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
@else
|
||||
<svg class="w-5 h-5 text-red-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
@endif
|
||||
<span class="font-medium">{{ $log['step_id'] ?? 'Step '.($index + 1) }}</span>
|
||||
<span class="text-gray-500">{{ $log['name'] ?? '' }}</span>
|
||||
</div>
|
||||
<span class="text-sm text-gray-500">{{ $log['duration'] ?? '' }}ms</span>
|
||||
</div>
|
||||
|
||||
@if(isset($log['request']))
|
||||
<div class="text-sm mb-2">
|
||||
<span class="font-medium text-gray-600">Request:</span>
|
||||
<code class="ml-2 text-gray-800">{{ $log['request']['method'] ?? '' }} {{ $log['request']['endpoint'] ?? '' }}</code>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if(isset($log['response']))
|
||||
<div class="text-sm">
|
||||
<span class="font-medium text-gray-600">Response:</span>
|
||||
<span class="ml-2 {{ ($log['response']['status'] ?? 0) < 400 ? 'text-green-600' : 'text-red-600' }}">
|
||||
{{ $log['response']['status'] ?? '-' }}
|
||||
</span>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if(isset($log['error']))
|
||||
<div class="mt-2 text-sm text-red-600">
|
||||
{{ $log['error'] }}
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
@else
|
||||
<div class="text-center py-8 text-gray-500">
|
||||
<p>실행 로그가 없습니다.</p>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
Reference in New Issue
Block a user