Implemented a complete Angular 20 migration with modern standalone components architecture and production-ready Docker deployment: **Frontend Migration:** - Created Angular 20 application with standalone components (no NgModules) - Implemented three main components: artifacts-list, upload-form, query-form - Added TypeScript models and services for type-safe API communication - Migrated dark theme UI with all existing features - Configured routing and navigation between views - Set up development proxy for seamless API integration - Reactive forms with validation for upload and query functionality - Auto-refresh artifacts every 5 seconds with RxJS observables - Client-side sorting, filtering, and search capabilities - Tags displayed as inline badges, SIM source grouping support **Docker Integration:** - Multi-stage Dockerfile for Angular (Node 24 build, nginx Alpine serve) - nginx configuration for SPA routing and API proxy - Updated docker-compose.yml with frontend service on port 80 - Health checks for all services - Production-optimized build with gzip compression and asset caching **Technical Stack:** - Angular 20 with standalone components - TypeScript for type safety - RxJS for reactive programming - nginx as reverse proxy - Multi-stage Docker builds for optimal image size All features fully functional and tested in Docker environment. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
103 lines
2.9 KiB
HTML
103 lines
2.9 KiB
HTML
<div class="query-section">
|
|
<h2>Query Artifacts</h2>
|
|
<form [formGroup]="queryForm" (ngSubmit)="onSubmit()">
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label for="q-filename">Filename</label>
|
|
<input
|
|
type="text"
|
|
id="q-filename"
|
|
formControlName="filename"
|
|
placeholder="Search filename...">
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="q-type">File Type</label>
|
|
<select id="q-type" formControlName="file_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"
|
|
formControlName="test_name"
|
|
placeholder="Search test name...">
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="q-suite">Test Suite</label>
|
|
<input
|
|
type="text"
|
|
id="q-suite"
|
|
formControlName="test_suite"
|
|
placeholder="e.g., integration">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label for="q-sim-source-id">SIM Source ID</label>
|
|
<input
|
|
type="text"
|
|
id="q-sim-source-id"
|
|
formControlName="sim_source_id"
|
|
placeholder="e.g., sim_run_abc123">
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="q-result">Test Result</label>
|
|
<select id="q-result" formControlName="test_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>
|
|
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label for="q-tags">Tags (comma-separated)</label>
|
|
<input
|
|
type="text"
|
|
id="q-tags"
|
|
formControlName="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"
|
|
formControlName="start_date">
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="q-end-date">End Date</label>
|
|
<input
|
|
type="datetime-local"
|
|
id="q-end-date"
|
|
formControlName="end_date">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="button-group">
|
|
<button type="submit" class="btn btn-primary btn-large">
|
|
🔍 Search
|
|
</button>
|
|
<button type="button" (click)="clearForm()" class="btn btn-secondary">
|
|
✕ Clear
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|