Features: - Modern web interface with table view of all artifacts - Display all metadata: filename, type, size, test info, tags - Upload form with full metadata support - Query/filter interface - Detail modal for viewing full artifact information - Download and delete actions - Integrated seed data generation via UI - Responsive design with gradient theme Technical: - Pure HTML/CSS/JavaScript (no frameworks) - FastAPI serves static files - Seed data API endpoint for easy testing - Pagination support - Real-time deployment mode display The UI is now accessible at http://localhost:8000/ 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
209 lines
9.4 KiB
HTML
209 lines
9.4 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Test Artifact Data Lake</title>
|
|
<link rel="stylesheet" href="/static/css/styles.css">
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<header>
|
|
<h1>🗄️ Test Artifact Data Lake</h1>
|
|
<div class="header-info">
|
|
<span id="deployment-mode" class="badge"></span>
|
|
<span id="storage-backend" class="badge"></span>
|
|
</div>
|
|
</header>
|
|
|
|
<nav class="tabs">
|
|
<button class="tab-button active" onclick="showTab('artifacts')">📋 Artifacts</button>
|
|
<button class="tab-button" onclick="showTab('upload')">⬆️ Upload</button>
|
|
<button class="tab-button" onclick="showTab('query')">🔍 Query</button>
|
|
</nav>
|
|
|
|
<!-- Artifacts Tab -->
|
|
<div id="artifacts-tab" class="tab-content active">
|
|
<div class="toolbar">
|
|
<button onclick="loadArtifacts()" class="btn btn-primary">🔄 Refresh</button>
|
|
<button onclick="generateSeedData()" class="btn btn-secondary">🌱 Generate Seed Data</button>
|
|
<span id="artifact-count" class="count-badge"></span>
|
|
</div>
|
|
|
|
<div class="table-container">
|
|
<table id="artifacts-table">
|
|
<thead>
|
|
<tr>
|
|
<th>ID</th>
|
|
<th>Filename</th>
|
|
<th>Type</th>
|
|
<th>Size</th>
|
|
<th>Test Name</th>
|
|
<th>Suite</th>
|
|
<th>Result</th>
|
|
<th>Tags</th>
|
|
<th>Created</th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="artifacts-tbody">
|
|
<tr>
|
|
<td colspan="10" class="loading">Loading artifacts...</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="pagination">
|
|
<button onclick="previousPage()" id="prev-btn" class="btn">← Previous</button>
|
|
<span id="page-info">Page 1</span>
|
|
<button onclick="nextPage()" id="next-btn" class="btn">Next →</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Upload Tab -->
|
|
<div id="upload-tab" class="tab-content">
|
|
<div class="upload-section">
|
|
<h2>Upload Artifact</h2>
|
|
<form id="upload-form" onsubmit="uploadArtifact(event)">
|
|
<div class="form-group">
|
|
<label for="file">File *</label>
|
|
<input type="file" id="file" name="file" required>
|
|
<small>Supported: CSV, JSON, binary files, PCAP</small>
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label for="test-name">Test Name</label>
|
|
<input type="text" id="test-name" name="test_name" placeholder="e.g., login_test">
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="test-suite">Test Suite</label>
|
|
<input type="text" id="test-suite" name="test_suite" placeholder="e.g., integration">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label for="test-result">Test Result</label>
|
|
<select id="test-result" name="test_result">
|
|
<option value="">-- Select --</option>
|
|
<option value="pass">Pass</option>
|
|
<option value="fail">Fail</option>
|
|
<option value="skip">Skip</option>
|
|
<option value="error">Error</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="version">Version</label>
|
|
<input type="text" id="version" name="version" placeholder="e.g., v1.0.0">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="tags">Tags (comma-separated)</label>
|
|
<input type="text" id="tags" name="tags" placeholder="e.g., regression, smoke, critical">
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="description">Description</label>
|
|
<textarea id="description" name="description" rows="3" placeholder="Describe this artifact..."></textarea>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="test-config">Test Config (JSON)</label>
|
|
<textarea id="test-config" name="test_config" rows="4" placeholder='{"browser": "chrome", "timeout": 30}'></textarea>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="custom-metadata">Custom Metadata (JSON)</label>
|
|
<textarea id="custom-metadata" name="custom_metadata" rows="4" placeholder='{"build": "1234", "commit": "abc123"}'></textarea>
|
|
</div>
|
|
|
|
<button type="submit" class="btn btn-primary btn-large">📤 Upload Artifact</button>
|
|
</form>
|
|
<div id="upload-status"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Query Tab -->
|
|
<div id="query-tab" class="tab-content">
|
|
<div class="query-section">
|
|
<h2>Query Artifacts</h2>
|
|
<form id="query-form" onsubmit="queryArtifacts(event)">
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label for="q-filename">Filename</label>
|
|
<input type="text" id="q-filename" placeholder="Search filename...">
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="q-type">File Type</label>
|
|
<select id="q-type">
|
|
<option value="">All</option>
|
|
<option value="csv">CSV</option>
|
|
<option value="json">JSON</option>
|
|
<option value="binary">Binary</option>
|
|
<option value="pcap">PCAP</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label for="q-test-name">Test Name</label>
|
|
<input type="text" id="q-test-name" placeholder="Search test name...">
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="q-suite">Test Suite</label>
|
|
<input type="text" id="q-suite" placeholder="e.g., integration">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label for="q-result">Test Result</label>
|
|
<select id="q-result">
|
|
<option value="">All</option>
|
|
<option value="pass">Pass</option>
|
|
<option value="fail">Fail</option>
|
|
<option value="skip">Skip</option>
|
|
<option value="error">Error</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="q-tags">Tags (comma-separated)</label>
|
|
<input type="text" id="q-tags" placeholder="e.g., regression, smoke">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label for="q-start-date">Start Date</label>
|
|
<input type="datetime-local" id="q-start-date">
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="q-end-date">End Date</label>
|
|
<input type="datetime-local" id="q-end-date">
|
|
</div>
|
|
</div>
|
|
|
|
<button type="submit" class="btn btn-primary btn-large">🔍 Search</button>
|
|
<button type="button" onclick="clearQuery()" class="btn btn-secondary">Clear</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Artifact Detail Modal -->
|
|
<div id="detail-modal" class="modal">
|
|
<div class="modal-content">
|
|
<span class="close" onclick="closeDetailModal()">×</span>
|
|
<h2>Artifact Details</h2>
|
|
<div id="detail-content"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="/static/js/app.js"></script>
|
|
</body>
|
|
</html>
|