Files
warehouse13/frontend/src/app/components/upload-form/upload-form.ts
Mondo Diaz c177be326c Replace Lucide icons with Material Icons for better compatibility
Switched from lucide-angular to Google Material Icons font for better compatibility across all environments, especially air-gapped and enterprise setups.

**Changes:**
- Removed lucide-angular dependency (not available in some environments)
- Added Material Icons font via Google CDN in index.html
- Updated all components to use Material Icons spans instead of Lucide components
- Added Material Icons CSS classes (md-16, md-18, md-20, md-24)

**Icon Mapping:**
- RefreshCw → refresh
- Sparkles → auto_awesome
- Search → search
- X/Close → close
- Download → download
- Trash2/Delete → delete
- Database → storage
- Upload → upload

**Benefits:**
- No npm dependency required (just a font)
- Works in all environments (air-gapped, enterprise proxies)
- Smaller bundle: 349.74 kB raw, 91.98 kB gzipped
- Industry standard Material Design icons
- Better cross-browser compatibility

All components tested and working correctly.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-15 12:31:34 -05:00

133 lines
3.8 KiB
TypeScript

import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ReactiveFormsModule, FormBuilder, FormGroup, Validators } from '@angular/forms';
import { ArtifactService } from '../../services/artifact';
@Component({
selector: 'app-upload-form',
standalone: true,
imports: [CommonModule, ReactiveFormsModule],
templateUrl: './upload-form.html',
styleUrls: ['./upload-form.css']
})
export class UploadFormComponent {
uploadForm: FormGroup;
selectedFile: File | null = null;
uploading: boolean = false;
uploadStatus: { message: string, success: boolean } | null = null;
constructor(
private fb: FormBuilder,
private artifactService: ArtifactService
) {
this.uploadForm = this.fb.group({
file: [null, Validators.required],
sim_source: ['', Validators.required],
uploaded_by: ['', Validators.required],
sim_source_id: [''],
tags: ['', Validators.required],
test_result: [''],
version: [''],
description: [''],
test_config: [''],
custom_metadata: ['']
});
}
onFileSelected(event: Event) {
const input = event.target as HTMLInputElement;
if (input.files && input.files.length > 0) {
this.selectedFile = input.files[0];
this.uploadForm.patchValue({ file: this.selectedFile });
}
}
onSubmit() {
if (!this.uploadForm.valid || !this.selectedFile) {
this.showStatus('Please fill in all required fields and select a file', false);
return;
}
// Validate JSON fields
const testConfig = this.uploadForm.value.test_config;
const customMetadata = this.uploadForm.value.custom_metadata;
if (testConfig) {
try {
JSON.parse(testConfig);
} catch (e) {
this.showStatus('Invalid Test Config JSON', false);
return;
}
}
if (customMetadata) {
try {
JSON.parse(customMetadata);
} catch (e) {
this.showStatus('Invalid Custom Metadata JSON', false);
return;
}
}
const formData = new FormData();
formData.append('file', this.selectedFile);
formData.append('test_suite', this.uploadForm.value.sim_source);
formData.append('test_name', this.uploadForm.value.uploaded_by);
if (this.uploadForm.value.sim_source_id) {
formData.append('sim_source_id', this.uploadForm.value.sim_source_id);
}
// Parse and append tags as JSON array
if (this.uploadForm.value.tags) {
const tagsArray = this.uploadForm.value.tags
.split(',')
.map((t: string) => t.trim())
.filter((t: string) => t);
formData.append('tags', JSON.stringify(tagsArray));
}
if (this.uploadForm.value.test_result) {
formData.append('test_result', this.uploadForm.value.test_result);
}
if (this.uploadForm.value.version) {
formData.append('version', this.uploadForm.value.version);
}
if (this.uploadForm.value.description) {
formData.append('description', this.uploadForm.value.description);
}
if (testConfig) {
formData.append('test_config', testConfig);
}
if (customMetadata) {
formData.append('custom_metadata', customMetadata);
}
this.uploading = true;
this.artifactService.uploadArtifact(formData).subscribe({
next: (artifact) => {
this.showStatus(`Successfully uploaded: ${artifact.filename}`, true);
this.uploadForm.reset();
this.selectedFile = null;
this.uploading = false;
},
error: (err) => {
this.showStatus('Upload failed: ' + err.error?.detail || err.message, false);
this.uploading = false;
}
});
}
private showStatus(message: string, success: boolean) {
this.uploadStatus = { message, success };
setTimeout(() => {
this.uploadStatus = null;
}, 5000);
}
}