package components import ( "context" "strconv" "fmt" "github.com/starfleetcptn/gomft/internal/db" ) // FileMetadataFilter represents filter parameters for file metadata queries type FileMetadataFilter struct { Status string JobID string FileName string Hash string StartDate string EndDate string } // FileMetadataListData contains data for the file metadata list template type FileMetadataListData struct { Files []db.FileMetadata TotalCount int64 Page int Limit int TotalPages int Job *db.Job // Optional: if viewing files for a specific job Filter FileMetadataFilter } // FileMetadataDetailsData contains data for the file metadata details template type FileMetadataDetailsData struct { File db.FileMetadata } // FileMetadataSearchData contains data for the file metadata search template type FileMetadataSearchData struct { Files []db.FileMetadata TotalCount int64 Page int Limit int TotalPages int Filter FileMetadataFilter } // getStatusBadgeClass returns the appropriate CSS class for a file status badge func getStatusBadgeClass(status string) string { switch status { case "processed": return "badge-success" case "archived": return "badge-info" case "deleted": return "badge-warning" case "archived_and_deleted": return "badge-warning" case "error": return "badge-danger" default: return "badge-secondary" } } // formatFileSize formats a file size in bytes to a human-readable string func formatFileSize(size int64) string { if size < 1024 { return fmt.Sprintf("%d B", size) } else if size < 1024*1024 { return fmt.Sprintf("%.2f KB", float64(size)/1024) } else if size < 1024*1024*1024 { return fmt.Sprintf("%.2f MB", float64(size)/(1024*1024)) } else { return fmt.Sprintf("%.2f GB", float64(size)/(1024*1024*1024)) } } // Dialog component for confirmation dialogs templ FileMetadataDialog(id string, title string, message string, confirmClass string, confirmText string, action string, fileID uint, fileName string, section string) { } script hideFileDialog(id string) { document.getElementById(id).classList.add("hidden"); } script showFileDialog(id string) { document.getElementById(id).classList.remove("hidden"); } script triggerFileDelete(dialogId string, fileID uint, fileName string) { // Hide the dialog document.getElementById(dialogId).classList.add("hidden"); // Store data in a way that's accessible to event handlers window.lastDeletedFile = { id: fileID, name: fileName }; // Add custom marker to track this deletion window.currentlyDeletingFile = true; } // Rename from FileMetadataListContent to FileMetadataListPartial to match what the handler expects templ FileMetadataListPartial(data FileMetadataListData) {
for _, file := range data.Files { @FileMetadataDialog( fmt.Sprintf("delete-file-dialog-%d", file.ID), "Delete File Metadata", fmt.Sprintf("Are you sure you want to delete the metadata for '%s'? This cannot be undone.", file.FileName), "btn-danger", "Delete", "delete", file.ID, file.FileName, "list", ) }
if data.Job == nil { } for _, file := range data.Files { if data.Job == nil && file.Job.ID > 0 { } }
ID Filename Size Processed StatusJobActions
{ strconv.FormatUint(uint64(file.ID), 10) } { file.FileName } { formatFileSize(file.FileSize) } { file.ProcessedTime.Format("2006-01-02 15:04:05") } { file.Status } { file.Job.Name }
if data.TotalPages > 1 {
if data.Page > 1 { } else { } for i := 1; i <= data.TotalPages; i++ { if i == data.Page { { strconv.Itoa(i) } } else if i == 1 || i == data.TotalPages || (i >= data.Page-2 && i <= data.Page+2) { { strconv.Itoa(i) } } else if i == data.Page-3 || i == data.Page+3 { ... } } if data.Page < data.TotalPages { } else { }
} } // Update the main FileMetadataList template to use the partial template templ FileMetadataList(ctx context.Context, data FileMetadataListData) { @LayoutWithContext("File Metadata", ctx) {

if data.Job != nil { Files for Job: { data.Job.Name } } else { File Metadata }

Filter Files

if data.Job == nil {
}

Files ({ strconv.FormatInt(data.TotalCount, 10) })

Page { strconv.Itoa(data.Page) } of { strconv.Itoa(data.TotalPages) }
if len(data.Files) > 0 { @FileMetadataListPartial(data) } else {

No file metadata found matching your criteria.

}
} } // FileMetadataDetails renders detailed information about a file templ FileMetadataDetails(ctx context.Context, data FileMetadataDetailsData) { @LayoutWithContext("File Details", ctx) {
Back to Files

File: { data.File.FileName }

File Information

ID { strconv.FormatUint(uint64(data.File.ID), 10) }
Filename { data.File.FileName }
Size { formatFileSize(data.File.FileSize) }
Hash if data.File.FileHash != "" { { data.File.FileHash } } else { Not available }
Status { data.File.Status }
Original Path { data.File.OriginalPath }
Destination Path { data.File.DestinationPath }

Processing Information

if data.File.Status == "error" && data.File.ErrorMessage != "" { }
Job { data.File.Job.Name }
Processed Time { data.File.ProcessedTime.Format("2006-01-02 15:04:05") }
Creation Time { data.File.CreationTime.Format("2006-01-02 15:04:05") }
Modification Time { data.File.ModTime.Format("2006-01-02 15:04:05") }
Error { data.File.ErrorMessage }
Record Created { data.File.CreatedAt.Format("2006-01-02 15:04:05") }
Record Updated { data.File.UpdatedAt.Format("2006-01-02 15:04:05") }
Back to Files @FileMetadataDialog( fmt.Sprintf("delete-file-dialog-%d", data.File.ID), "Delete File Metadata", fmt.Sprintf("Are you sure you want to delete the metadata for '%s'? This cannot be undone.", data.File.FileName), "btn-danger", "Delete", "delete", data.File.ID, data.File.FileName, "details", )
} } // FileMetadataSearch renders an advanced search form for file metadata templ FileMetadataSearch(ctx context.Context, data FileMetadataSearchData) { @LayoutWithContext("Search Files", ctx) {
Back to Files

Advanced File Search

Search Results ({ strconv.FormatInt(data.TotalCount, 10) })

Page { strconv.Itoa(data.Page) } of { strconv.Itoa(data.TotalPages) }
@FileMetadataSearchContent(data)
} } // Similarly, create a separate template for the search results templ FileMetadataSearchContent(data FileMetadataSearchData) {
for _, file := range data.Files { @FileMetadataDialog( fmt.Sprintf("delete-file-dialog-%d", file.ID), "Delete File Metadata", fmt.Sprintf("Are you sure you want to delete the metadata for '%s'? This cannot be undone.", file.FileName), "btn-danger", "Delete", "delete", file.ID, file.FileName, "list", ) }
if len(data.Files) > 0 { for _, file := range data.Files { } } else { }
ID Filename Size Processed Status Job Actions
{ strconv.FormatUint(uint64(file.ID), 10) } { file.FileName } { formatFileSize(file.FileSize) } { file.ProcessedTime.Format("2006-01-02 15:04:05") } { file.Status } if file.Job.ID > 0 { { file.Job.Name } } else { N/A }

No files found matching your search criteria.

if data.TotalPages > 1 {
if data.Page > 1 { } else { } for i := 1; i <= data.TotalPages; i++ { if i == data.Page { { strconv.Itoa(i) } } else if i == 1 || i == data.TotalPages || (i >= data.Page-2 && i <= data.Page+2) { { strconv.Itoa(i) } } else if i == data.Page-3 || i == data.Page+3 { ... } } if data.Page < data.TotalPages { } else { }
} }