283 lines
11 KiB
HTML
283 lines
11 KiB
HTML
<div class="artifacts-section">
|
|
<!-- Debug Loading State -->
|
|
<div style="background: red; color: white; padding: 10px; margin: 10px;">
|
|
LOADING STATE: {{ loading ? 'TRUE (Loading...)' : 'FALSE (Not Loading)' }}
|
|
</div>
|
|
|
|
<!-- Toolbar -->
|
|
<mat-card class="toolbar-card">
|
|
<mat-card-content>
|
|
<div class="toolbar">
|
|
<div class="toolbar-buttons">
|
|
<button mat-raised-button color="primary" (click)="loadArtifacts()">
|
|
<mat-icon>refresh</mat-icon>
|
|
Refresh
|
|
</button>
|
|
<button mat-raised-button color="accent" (click)="generateSeedData()">
|
|
<mat-icon>scatter_plot</mat-icon>
|
|
Generate Seed Data
|
|
</button>
|
|
</div>
|
|
<mat-chip-set class="count-chip">
|
|
<mat-chip>
|
|
<mat-icon matChipAvatar>storage</mat-icon>
|
|
{{ filteredArtifacts.length }} artifacts
|
|
</mat-chip>
|
|
</mat-chip-set>
|
|
</div>
|
|
</mat-card-content>
|
|
</mat-card>
|
|
|
|
<!-- Loading Spinner -->
|
|
<div *ngIf="loading" class="loading-container">
|
|
<mat-spinner diameter="50"></mat-spinner>
|
|
<p>Loading artifacts...</p>
|
|
</div>
|
|
|
|
<!-- Simple List Test (No Material Components) -->
|
|
<div *ngIf="!loading" style="background: lightgreen; padding: 20px; margin: 20px;">
|
|
<h3>Simple List Test</h3>
|
|
<p><strong>Filtered Artifacts Count:</strong> {{ filteredArtifacts.length }}</p>
|
|
<div *ngFor="let artifact of filteredArtifacts.slice(0, 5)" style="border: 1px solid black; padding: 10px; margin: 5px;">
|
|
<strong>ID:</strong> {{ artifact.id }} |
|
|
<strong>Filename:</strong> {{ artifact.filename }} |
|
|
<strong>Type:</strong> {{ artifact.file_type }}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Material Table -->
|
|
<mat-card *ngIf="!loading" class="table-card">
|
|
<div class="table-container">
|
|
<table mat-table [dataSource]="filteredArtifacts" class="artifacts-table">
|
|
|
|
<!-- ID Column -->
|
|
<ng-container matColumnDef="id">
|
|
<th mat-header-cell *matHeaderCellDef>ID</th>
|
|
<td mat-cell *matCellDef="let artifact">
|
|
<strong>{{ artifact.id }}</strong>
|
|
</td>
|
|
</ng-container>
|
|
|
|
<!-- Event ID Column -->
|
|
<ng-container matColumnDef="eventId">
|
|
<th mat-header-cell *matHeaderCellDef>Event ID</th>
|
|
<td mat-cell *matCellDef="let artifact">
|
|
<mat-chip *ngIf="artifact.event_id" color="primary">
|
|
{{ artifact.event_id }}
|
|
</mat-chip>
|
|
<span *ngIf="!artifact.event_id" class="text-muted">{{ artifact.id }}</span>
|
|
</td>
|
|
</ng-container>
|
|
|
|
<!-- Filename Column -->
|
|
<ng-container matColumnDef="filename">
|
|
<th mat-header-cell *matHeaderCellDef>Filename</th>
|
|
<td mat-cell *matCellDef="let artifact">
|
|
<button mat-button (click)="showDetail(artifact)" class="filename-link">
|
|
<mat-icon>description</mat-icon>
|
|
{{ artifact.filename }}
|
|
</button>
|
|
</td>
|
|
</ng-container>
|
|
|
|
<!-- Type Column -->
|
|
<ng-container matColumnDef="type">
|
|
<th mat-header-cell *matHeaderCellDef>Type</th>
|
|
<td mat-cell *matCellDef="let artifact">
|
|
<mat-chip class="type-chip">{{ artifact.file_type }}</mat-chip>
|
|
</td>
|
|
</ng-container>
|
|
|
|
<!-- Size Column -->
|
|
<ng-container matColumnDef="size">
|
|
<th mat-header-cell *matHeaderCellDef>Size</th>
|
|
<td mat-cell *matCellDef="let artifact">{{ formatBytes(artifact.file_size) }}</td>
|
|
</ng-container>
|
|
|
|
<!-- Binaries Column -->
|
|
<ng-container matColumnDef="binaries">
|
|
<th mat-header-cell *matHeaderCellDef>Binaries</th>
|
|
<td mat-cell *matCellDef="let artifact" class="binaries-cell">
|
|
<div *ngIf="artifact.binaries && artifact.binaries.length > 0; else noBinaries">
|
|
<mat-chip-set>
|
|
<mat-chip *ngFor="let binary of getVisibleBinaries(artifact.binaries)" class="binary-chip">
|
|
<mat-icon matChipAvatar>code</mat-icon>
|
|
{{ binary }}
|
|
</mat-chip>
|
|
<mat-chip
|
|
*ngIf="getHiddenBinariesCount(artifact.binaries) > 0"
|
|
(click)="toggleBinariesExpansion(artifact.id)"
|
|
class="expand-chip">
|
|
<span *ngIf="!expandedBinaries[artifact.id]">
|
|
+{{ getHiddenBinariesCount(artifact.binaries) }} more
|
|
</span>
|
|
<span *ngIf="expandedBinaries[artifact.id]">- less</span>
|
|
</mat-chip>
|
|
</mat-chip-set>
|
|
<mat-chip-set *ngIf="expandedBinaries[artifact.id]" class="expanded-binaries">
|
|
<mat-chip *ngFor="let binary of artifact.binaries.slice(4)" class="binary-chip">
|
|
<mat-icon matChipAvatar>code</mat-icon>
|
|
{{ binary }}
|
|
</mat-chip>
|
|
</mat-chip-set>
|
|
</div>
|
|
<ng-template #noBinaries>
|
|
<span class="text-muted">-</span>
|
|
</ng-template>
|
|
</td>
|
|
</ng-container>
|
|
|
|
<!-- Test Name Column -->
|
|
<ng-container matColumnDef="testName">
|
|
<th mat-header-cell *matHeaderCellDef>Test Name</th>
|
|
<td mat-cell *matCellDef="let artifact">
|
|
<span>{{ artifact.test_name || '-' }}</span>
|
|
</td>
|
|
</ng-container>
|
|
|
|
<!-- Suite Column -->
|
|
<ng-container matColumnDef="suite">
|
|
<th mat-header-cell *matHeaderCellDef>Suite</th>
|
|
<td mat-cell *matCellDef="let artifact">
|
|
<span>{{ artifact.test_suite || '-' }}</span>
|
|
</td>
|
|
</ng-container>
|
|
|
|
<!-- Result Column -->
|
|
<ng-container matColumnDef="result">
|
|
<th mat-header-cell *matHeaderCellDef>Result</th>
|
|
<td mat-cell *matCellDef="let artifact">
|
|
<mat-chip
|
|
*ngIf="artifact.test_result"
|
|
[class]="'result-' + artifact.test_result">
|
|
<mat-icon matChipAvatar>{{ getResultIcon(artifact.test_result) }}</mat-icon>
|
|
{{ artifact.test_result }}
|
|
</mat-chip>
|
|
<span *ngIf="!artifact.test_result" class="text-muted">-</span>
|
|
</td>
|
|
</ng-container>
|
|
|
|
<!-- Tags Column -->
|
|
<ng-container matColumnDef="tags">
|
|
<th mat-header-cell *matHeaderCellDef>Tags</th>
|
|
<td mat-cell *matCellDef="let artifact" class="tags-cell">
|
|
<div *ngIf="artifact.tags && artifact.tags.length > 0; else noTags">
|
|
<mat-chip-set>
|
|
<mat-chip *ngFor="let tag of getVisibleTags(artifact.tags)" class="tag-chip">
|
|
{{ tag }}
|
|
</mat-chip>
|
|
<mat-chip
|
|
*ngIf="getHiddenTagsCount(artifact.tags) > 0"
|
|
(click)="toggleTagsExpansion(artifact.id)"
|
|
class="expand-chip">
|
|
<span *ngIf="!expandedTags[artifact.id]">
|
|
+{{ getHiddenTagsCount(artifact.tags) }} more
|
|
</span>
|
|
<span *ngIf="expandedTags[artifact.id]">- less</span>
|
|
</mat-chip>
|
|
</mat-chip-set>
|
|
<mat-chip-set *ngIf="expandedTags[artifact.id]" class="expanded-tags">
|
|
<mat-chip *ngFor="let tag of artifact.tags.slice(3)" class="tag-chip">
|
|
{{ tag }}
|
|
</mat-chip>
|
|
</mat-chip-set>
|
|
<app-tag-manager
|
|
[artifactId]="artifact.id"
|
|
[currentTags]="artifact.tags"
|
|
(tagsUpdated)="onTagsUpdated()">
|
|
</app-tag-manager>
|
|
</div>
|
|
<ng-template #noTags>
|
|
<app-tag-manager
|
|
[artifactId]="artifact.id"
|
|
[currentTags]="[]"
|
|
(tagsUpdated)="onTagsUpdated()">
|
|
</app-tag-manager>
|
|
</ng-template>
|
|
</td>
|
|
</ng-container>
|
|
|
|
<!-- Created Column -->
|
|
<ng-container matColumnDef="created">
|
|
<th mat-header-cell *matHeaderCellDef>Created</th>
|
|
<td mat-cell *matCellDef="let artifact">
|
|
<small>{{ formatDate(artifact.created_at) }}</small>
|
|
</td>
|
|
</ng-container>
|
|
|
|
<!-- Actions Column -->
|
|
<ng-container matColumnDef="actions">
|
|
<th mat-header-cell *matHeaderCellDef>Actions</th>
|
|
<td mat-cell *matCellDef="let artifact">
|
|
<div class="action-buttons">
|
|
<button mat-icon-button
|
|
(click)="downloadArtifact(artifact)"
|
|
matTooltip="Download"
|
|
color="primary">
|
|
<mat-icon>download</mat-icon>
|
|
</button>
|
|
<button mat-icon-button
|
|
(click)="deleteArtifact(artifact)"
|
|
matTooltip="Delete"
|
|
color="warn">
|
|
<mat-icon>delete</mat-icon>
|
|
</button>
|
|
</div>
|
|
</td>
|
|
</ng-container>
|
|
|
|
<!-- Table Header and Rows -->
|
|
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
|
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
|
|
|
<!-- No Data Row -->
|
|
<tr class="mat-row" *matNoDataRow>
|
|
<td class="mat-cell no-data" [attr.colspan]="displayedColumns.length">
|
|
<div class="no-data-content">
|
|
<mat-icon>inbox</mat-icon>
|
|
<p>No artifacts found. Upload some files to get started!</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</mat-card>
|
|
|
|
<!-- Pagination -->
|
|
<mat-card class="pagination-card" *ngIf="!loading">
|
|
<mat-card-content>
|
|
<div class="pagination">
|
|
<button mat-icon-button
|
|
(click)="previousPage()"
|
|
[disabled]="currentPage === 1"
|
|
matTooltip="Previous page">
|
|
<mat-icon>chevron_left</mat-icon>
|
|
</button>
|
|
<mat-chip>Page {{ currentPage }}</mat-chip>
|
|
<button mat-icon-button
|
|
(click)="nextPage()"
|
|
[disabled]="filteredArtifacts.length < pageSize"
|
|
matTooltip="Next page">
|
|
<mat-icon>chevron_right</mat-icon>
|
|
</button>
|
|
</div>
|
|
</mat-card-content>
|
|
</mat-card>
|
|
</div>
|
|
|
|
<!-- Artifact Detail Modal (placeholder for now) -->
|
|
<div *ngIf="showDetailModal && selectedArtifact" class="detail-backdrop" (click)="closeDetailModal()">
|
|
<mat-card class="detail-modal" (click)="$event.stopPropagation()">
|
|
<mat-card-header>
|
|
<mat-card-title>Artifact Details</mat-card-title>
|
|
<button mat-icon-button (click)="closeDetailModal()" class="close-button">
|
|
<mat-icon>close</mat-icon>
|
|
</button>
|
|
</mat-card-header>
|
|
<mat-card-content>
|
|
<!-- Detail content will be added later -->
|
|
<p>Artifact ID: {{ selectedArtifact.id }}</p>
|
|
<p>Filename: {{ selectedArtifact.filename }}</p>
|
|
</mat-card-content>
|
|
</mat-card>
|
|
</div> |