Add 'In Progress' tab to history sidebar
Features: - New "In Progress" tab shows running/pending jobs - Displays active jobs without opening full queue - Tab positioned first for quick visibility - Shows "Running..." or "Pending" status - No delete button on active jobs (only completed/failed) Implementation: - Updated BuildHistorySidebar to accept activeJobs parameter - Converts queue.Job to ui.HistoryEntry for display - Filters running/pending jobs from queue - Conditional delete button (nil check) - Dynamic status text based on job state UX Improvements: - Quick glance at current activity without queue view - Three-tab layout: In Progress → Completed → Failed - Consistent styling with existing history entries - Tappable entries to view full job details This allows users to monitor active conversions directly from the history sidebar, reducing the need to constantly check the full job queue view.
This commit is contained in:
parent
f6729a07ea
commit
dad5d34d34
|
|
@ -153,6 +153,7 @@ func sortedKeys(m map[string][]fyne.CanvasObject) []string {
|
|||
// BuildHistorySidebar creates the history sidebar with tabs
|
||||
func BuildHistorySidebar(
|
||||
entries []HistoryEntry,
|
||||
activeJobs []HistoryEntry,
|
||||
onEntryClick func(HistoryEntry),
|
||||
onEntryDelete func(HistoryEntry),
|
||||
titleColor, bgColor, textColor color.Color,
|
||||
|
|
@ -168,11 +169,13 @@ func BuildHistorySidebar(
|
|||
}
|
||||
|
||||
// Build lists
|
||||
inProgressList := buildHistoryList(activeJobs, onEntryClick, nil, bgColor, textColor) // No delete for active jobs
|
||||
completedList := buildHistoryList(completedEntries, onEntryClick, onEntryDelete, bgColor, textColor)
|
||||
failedList := buildHistoryList(failedEntries, onEntryClick, onEntryDelete, bgColor, textColor)
|
||||
|
||||
// Tabs
|
||||
// Tabs - In Progress first for quick visibility
|
||||
tabs := container.NewAppTabs(
|
||||
container.NewTabItem("In Progress", container.NewVScroll(inProgressList)),
|
||||
container.NewTabItem("Completed", container.NewVScroll(completedList)),
|
||||
container.NewTabItem("Failed", container.NewVScroll(failedList)),
|
||||
)
|
||||
|
|
@ -220,20 +223,37 @@ func buildHistoryItem(
|
|||
// Capture entry for closures
|
||||
capturedEntry := entry
|
||||
|
||||
// Delete button - small "×" button
|
||||
deleteBtn := widget.NewButton("×", func() {
|
||||
onEntryDelete(capturedEntry)
|
||||
})
|
||||
deleteBtn.Importance = widget.LowImportance
|
||||
// Build header row with badge and optional delete button
|
||||
headerItems := []fyne.CanvasObject{badge, layout.NewSpacer()}
|
||||
if onEntryDelete != nil {
|
||||
// Delete button - small "×" button (only for completed/failed)
|
||||
deleteBtn := widget.NewButton("×", func() {
|
||||
onEntryDelete(capturedEntry)
|
||||
})
|
||||
deleteBtn.Importance = widget.LowImportance
|
||||
headerItems = append(headerItems, deleteBtn)
|
||||
}
|
||||
|
||||
// Title
|
||||
titleLabel := widget.NewLabel(utils.ShortenMiddle(entry.Title, 25))
|
||||
titleLabel.TextStyle = fyne.TextStyle{Bold: true}
|
||||
|
||||
// Timestamp
|
||||
timeStr := "Unknown"
|
||||
if entry.CompletedAt != nil {
|
||||
timeStr = entry.CompletedAt.Format("Jan 2, 15:04")
|
||||
// Timestamp or status info
|
||||
var timeStr string
|
||||
if entry.Status == queue.JobStatusRunning || entry.Status == queue.JobStatusPending {
|
||||
// For in-progress jobs, show status
|
||||
if entry.Status == queue.JobStatusRunning {
|
||||
timeStr = "Running..."
|
||||
} else {
|
||||
timeStr = "Pending"
|
||||
}
|
||||
} else {
|
||||
// For completed/failed jobs, show timestamp
|
||||
if entry.CompletedAt != nil {
|
||||
timeStr = entry.CompletedAt.Format("Jan 2, 15:04")
|
||||
} else {
|
||||
timeStr = "Unknown"
|
||||
}
|
||||
}
|
||||
timeLabel := widget.NewLabel(timeStr)
|
||||
timeLabel.TextStyle = fyne.TextStyle{Monospace: true}
|
||||
|
|
@ -246,7 +266,7 @@ func buildHistoryItem(
|
|||
content := container.NewBorder(
|
||||
nil, nil, statusRect, nil,
|
||||
container.NewVBox(
|
||||
container.NewHBox(badge, layout.NewSpacer(), deleteBtn),
|
||||
container.NewHBox(headerItems...),
|
||||
titleLabel,
|
||||
timeLabel,
|
||||
),
|
||||
|
|
|
|||
25
main.go
25
main.go
|
|
@ -1372,8 +1372,33 @@ func (s *appState) showMainMenu() {
|
|||
// Build sidebar if visible
|
||||
var sidebar fyne.CanvasObject
|
||||
if s.sidebarVisible {
|
||||
// Get active jobs from queue (running/pending)
|
||||
var activeJobs []ui.HistoryEntry
|
||||
if s.jobQueue != nil {
|
||||
for _, job := range s.jobQueue.List() {
|
||||
if job.Status == queue.JobStatusRunning || job.Status == queue.JobStatusPending {
|
||||
// Convert queue.Job to ui.HistoryEntry
|
||||
entry := ui.HistoryEntry{
|
||||
ID: job.ID,
|
||||
Type: job.Type,
|
||||
Status: job.Status,
|
||||
Title: job.Title,
|
||||
InputFile: job.InputFile,
|
||||
OutputFile: job.OutputFile,
|
||||
LogPath: job.LogPath,
|
||||
Config: job.Config,
|
||||
CreatedAt: job.CreatedAt,
|
||||
StartedAt: job.StartedAt,
|
||||
Error: job.Error,
|
||||
}
|
||||
activeJobs = append(activeJobs, entry)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sidebar = ui.BuildHistorySidebar(
|
||||
s.historyEntries,
|
||||
activeJobs,
|
||||
s.showHistoryDetails,
|
||||
s.deleteHistoryEntry,
|
||||
titleColor,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user