1st iter
This commit is contained in:
164
frontend/src/components/tools/DebugTool.svelte
Normal file
164
frontend/src/components/tools/DebugTool.svelte
Normal file
@@ -0,0 +1,164 @@
|
||||
<!-- [DEF:DebugTool:Component] -->
|
||||
<!--
|
||||
@SEMANTICS: debug, tool, api, structure
|
||||
@PURPOSE: UI component for system diagnostics and debugging API responses.
|
||||
@LAYER: UI
|
||||
@RELATION: USES -> frontend/src/services/toolsService.js
|
||||
-->
|
||||
<script>
|
||||
// [SECTION: IMPORTS]
|
||||
import { onMount } from 'svelte';
|
||||
import { runTask, getTaskStatus } from '../../services/toolsService.js';
|
||||
import { selectedTask } from '../../lib/stores.js';
|
||||
import { addToast } from '../../lib/toasts.js';
|
||||
// [/SECTION]
|
||||
|
||||
let envs = [];
|
||||
let action = 'test-db-api';
|
||||
let selectedEnv = '';
|
||||
let datasetId = '';
|
||||
let sourceEnv = '';
|
||||
let targetEnv = '';
|
||||
let isRunning = false;
|
||||
let results = null;
|
||||
let pollInterval;
|
||||
|
||||
async function fetchEnvironments() {
|
||||
try {
|
||||
const res = await fetch('/api/environments');
|
||||
envs = await res.json();
|
||||
} catch (e) {
|
||||
addToast('Failed to fetch environments', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
async function handleRunDebug() {
|
||||
isRunning = true;
|
||||
results = null;
|
||||
try {
|
||||
let params = { action };
|
||||
if (action === 'test-db-api') {
|
||||
if (!sourceEnv || !targetEnv) {
|
||||
addToast('Source and Target environments are required', 'warning');
|
||||
isRunning = false;
|
||||
return;
|
||||
}
|
||||
const sEnv = envs.find(e => e.id === sourceEnv);
|
||||
const tEnv = envs.find(e => e.id === targetEnv);
|
||||
params.source_env = sEnv.name;
|
||||
params.target_env = tEnv.name;
|
||||
} else {
|
||||
if (!selectedEnv || !datasetId) {
|
||||
addToast('Environment and Dataset ID are required', 'warning');
|
||||
isRunning = false;
|
||||
return;
|
||||
}
|
||||
const env = envs.find(e => e.id === selectedEnv);
|
||||
params.env = env.name;
|
||||
params.dataset_id = parseInt(datasetId);
|
||||
}
|
||||
|
||||
const task = await runTask('system-debug', params);
|
||||
selectedTask.set(task);
|
||||
startPolling(task.id);
|
||||
} catch (e) {
|
||||
isRunning = false;
|
||||
addToast(e.message, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
function startPolling(taskId) {
|
||||
if (pollInterval) clearInterval(pollInterval);
|
||||
pollInterval = setInterval(async () => {
|
||||
try {
|
||||
const task = await getTaskStatus(taskId);
|
||||
selectedTask.set(task);
|
||||
if (task.status === 'SUCCESS') {
|
||||
clearInterval(pollInterval);
|
||||
isRunning = false;
|
||||
results = task.result;
|
||||
addToast('Debug task completed', 'success');
|
||||
} else if (task.status === 'FAILED') {
|
||||
clearInterval(pollInterval);
|
||||
isRunning = false;
|
||||
addToast('Debug task failed', 'error');
|
||||
}
|
||||
} catch (e) {
|
||||
clearInterval(pollInterval);
|
||||
isRunning = false;
|
||||
}
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
onMount(fetchEnvironments);
|
||||
</script>
|
||||
|
||||
<div class="space-y-6">
|
||||
<div class="bg-white p-6 rounded-lg shadow-sm border border-gray-200">
|
||||
<h3 class="text-lg font-medium text-gray-900 mb-4">System Diagnostics</h3>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="block text-sm font-medium text-gray-700">Debug Action</label>
|
||||
<select bind:value={action} class="mt-1 block w-full border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
|
||||
<option value="test-db-api">Test Database API (Compare Envs)</option>
|
||||
<option value="get-dataset-structure">Get Dataset Structure (JSON)</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{#if action === 'test-db-api'}
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label for="src-env" class="block text-sm font-medium text-gray-700">Source Environment</label>
|
||||
<select id="src-env" bind:value={sourceEnv} class="mt-1 block w-full border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
|
||||
<option value="" disabled>-- Select Source --</option>
|
||||
{#each envs as env}
|
||||
<option value={env.id}>{env.name}</option>
|
||||
{/each}
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="tgt-env" class="block text-sm font-medium text-gray-700">Target Environment</label>
|
||||
<select id="tgt-env" bind:value={targetEnv} class="mt-1 block w-full border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
|
||||
<option value="" disabled>-- Select Target --</option>
|
||||
{#each envs as env}
|
||||
<option value={env.id}>{env.name}</option>
|
||||
{/each}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label for="debug-env" class="block text-sm font-medium text-gray-700">Environment</label>
|
||||
<select id="debug-env" bind:value={selectedEnv} class="mt-1 block w-full border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
|
||||
<option value="" disabled>-- Select Environment --</option>
|
||||
{#each envs as env}
|
||||
<option value={env.id}>{env.name}</option>
|
||||
{/each}
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="debug-ds-id" class="block text-sm font-medium text-gray-700">Dataset ID</label>
|
||||
<input type="number" id="debug-ds-id" bind:value={datasetId} class="mt-1 block w-full border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" />
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="mt-4 flex justify-end">
|
||||
<button on:click={handleRunDebug} disabled={isRunning} class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 disabled:opacity-50">
|
||||
{isRunning ? 'Running...' : 'Run Diagnostics'}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if results}
|
||||
<div class="bg-white shadow overflow-hidden sm:rounded-md border border-gray-200">
|
||||
<div class="px-4 py-5 sm:px-6 bg-gray-50 border-b border-gray-200">
|
||||
<h3 class="text-lg leading-6 font-medium text-gray-900">Debug Output</h3>
|
||||
</div>
|
||||
<div class="p-4">
|
||||
<pre class="text-xs text-gray-600 bg-gray-900 text-green-400 p-4 rounded-md overflow-x-auto h-96">{JSON.stringify(results, null, 2)}</pre>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
Reference in New Issue
Block a user