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) {
{ title }
{ message }
if section == "list" {
} else {
}
}
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.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
}
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
@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) {
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",
)
}
ID
Filename
Size
Processed
Status
Job
Actions
if len(data.Files) > 0 {
for _, file := range data.Files {
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 {
}