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. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
925334d8df
commit
12b2b221b9
|
|
@ -153,6 +153,7 @@ func sortedKeys(m map[string][]fyne.CanvasObject) []string {
|
||||||
// BuildHistorySidebar creates the history sidebar with tabs
|
// BuildHistorySidebar creates the history sidebar with tabs
|
||||||
func BuildHistorySidebar(
|
func BuildHistorySidebar(
|
||||||
entries []HistoryEntry,
|
entries []HistoryEntry,
|
||||||
|
activeJobs []HistoryEntry,
|
||||||
onEntryClick func(HistoryEntry),
|
onEntryClick func(HistoryEntry),
|
||||||
onEntryDelete func(HistoryEntry),
|
onEntryDelete func(HistoryEntry),
|
||||||
titleColor, bgColor, textColor color.Color,
|
titleColor, bgColor, textColor color.Color,
|
||||||
|
|
@ -168,11 +169,13 @@ func BuildHistorySidebar(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build lists
|
// Build lists
|
||||||
|
inProgressList := buildHistoryList(activeJobs, onEntryClick, nil, bgColor, textColor) // No delete for active jobs
|
||||||
completedList := buildHistoryList(completedEntries, onEntryClick, onEntryDelete, bgColor, textColor)
|
completedList := buildHistoryList(completedEntries, onEntryClick, onEntryDelete, bgColor, textColor)
|
||||||
failedList := buildHistoryList(failedEntries, onEntryClick, onEntryDelete, bgColor, textColor)
|
failedList := buildHistoryList(failedEntries, onEntryClick, onEntryDelete, bgColor, textColor)
|
||||||
|
|
||||||
// Tabs
|
// Tabs - In Progress first for quick visibility
|
||||||
tabs := container.NewAppTabs(
|
tabs := container.NewAppTabs(
|
||||||
|
container.NewTabItem("In Progress", container.NewVScroll(inProgressList)),
|
||||||
container.NewTabItem("Completed", container.NewVScroll(completedList)),
|
container.NewTabItem("Completed", container.NewVScroll(completedList)),
|
||||||
container.NewTabItem("Failed", container.NewVScroll(failedList)),
|
container.NewTabItem("Failed", container.NewVScroll(failedList)),
|
||||||
)
|
)
|
||||||
|
|
@ -220,20 +223,37 @@ func buildHistoryItem(
|
||||||
// Capture entry for closures
|
// Capture entry for closures
|
||||||
capturedEntry := entry
|
capturedEntry := entry
|
||||||
|
|
||||||
// Delete button - small "×" button
|
// Build header row with badge and optional delete button
|
||||||
deleteBtn := widget.NewButton("×", func() {
|
headerItems := []fyne.CanvasObject{badge, layout.NewSpacer()}
|
||||||
onEntryDelete(capturedEntry)
|
if onEntryDelete != nil {
|
||||||
})
|
// Delete button - small "×" button (only for completed/failed)
|
||||||
deleteBtn.Importance = widget.LowImportance
|
deleteBtn := widget.NewButton("×", func() {
|
||||||
|
onEntryDelete(capturedEntry)
|
||||||
|
})
|
||||||
|
deleteBtn.Importance = widget.LowImportance
|
||||||
|
headerItems = append(headerItems, deleteBtn)
|
||||||
|
}
|
||||||
|
|
||||||
// Title
|
// Title
|
||||||
titleLabel := widget.NewLabel(utils.ShortenMiddle(entry.Title, 25))
|
titleLabel := widget.NewLabel(utils.ShortenMiddle(entry.Title, 25))
|
||||||
titleLabel.TextStyle = fyne.TextStyle{Bold: true}
|
titleLabel.TextStyle = fyne.TextStyle{Bold: true}
|
||||||
|
|
||||||
// Timestamp
|
// Timestamp or status info
|
||||||
timeStr := "Unknown"
|
var timeStr string
|
||||||
if entry.CompletedAt != nil {
|
if entry.Status == queue.JobStatusRunning || entry.Status == queue.JobStatusPending {
|
||||||
timeStr = entry.CompletedAt.Format("Jan 2, 15:04")
|
// 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 := widget.NewLabel(timeStr)
|
||||||
timeLabel.TextStyle = fyne.TextStyle{Monospace: true}
|
timeLabel.TextStyle = fyne.TextStyle{Monospace: true}
|
||||||
|
|
@ -246,7 +266,7 @@ func buildHistoryItem(
|
||||||
content := container.NewBorder(
|
content := container.NewBorder(
|
||||||
nil, nil, statusRect, nil,
|
nil, nil, statusRect, nil,
|
||||||
container.NewVBox(
|
container.NewVBox(
|
||||||
container.NewHBox(badge, layout.NewSpacer(), deleteBtn),
|
container.NewHBox(headerItems...),
|
||||||
titleLabel,
|
titleLabel,
|
||||||
timeLabel,
|
timeLabel,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
25
main.go
25
main.go
|
|
@ -1372,8 +1372,33 @@ func (s *appState) showMainMenu() {
|
||||||
// Build sidebar if visible
|
// Build sidebar if visible
|
||||||
var sidebar fyne.CanvasObject
|
var sidebar fyne.CanvasObject
|
||||||
if s.sidebarVisible {
|
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(
|
sidebar = ui.BuildHistorySidebar(
|
||||||
s.historyEntries,
|
s.historyEntries,
|
||||||
|
activeJobs,
|
||||||
s.showHistoryDetails,
|
s.showHistoryDetails,
|
||||||
s.deleteHistoryEntry,
|
s.deleteHistoryEntry,
|
||||||
titleColor,
|
titleColor,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user