Compare commits

..

2 Commits

Author SHA1 Message Date
mixeme 8f75318e8c domain/job.go: add OverlapPolicy field for per-job run policy
Adds OverlapPolicy field to Job struct with json:"overlap_policy,omitempty"
tag. When empty, the field signals that the job should inherit the global
overlap policy setting from Config. Also updates yamlJob shadow struct to
maintain field-layout equivalence for YAML→JSON import compatibility.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-06-24 20:57:00 +03:00
mixeme ed81443d29 ui/history_view: size Log column to content so file names aren't truncated
The Log column was fixed at 240px with TextTruncate, clipping log file
names like 20260601-100000_<JobName>.log. Measure the widest value and
size the column to fit (bounded 240–520px), recomputing on refresh so
newly recorded events widen the column instead of being cut off.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 20:54:23 +03:00
4 changed files with 56 additions and 14 deletions
+1
View File
@@ -14,4 +14,5 @@ type Job struct {
Arguments string `json:"arguments,omitempty"`
StartOnly bool `json:"start_only,omitempty"`
Enabled bool `json:"enabled"`
OverlapPolicy string `json:"overlap_policy,omitempty"`
}
+1
View File
@@ -44,6 +44,7 @@ type yamlJob struct {
Arguments string `yaml:"arguments,omitempty"`
StartOnly bool `yaml:"start_only,omitempty"`
Enabled bool `yaml:"enabled"`
OverlapPolicy string `yaml:"overlap_policy,omitempty"`
}
type yamlJobsFile struct {
+43 -3
View File
@@ -9,6 +9,7 @@ import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget"
)
@@ -41,7 +42,38 @@ func collectActivity(jobs []job, runtimes map[int]*domain.JobRuntime) []event {
return events
}
func newHistoryView(events *[]event) *fyne.Container {
// logColumnMinWidth/logColumnMaxWidth bound the dynamically sized Log column.
// The minimum keeps the column readable when names are short or absent; the
// maximum stops a single very long file name from dominating the table (the
// table still scrolls horizontally past it).
const (
logColumnMinWidth = 240
logColumnMaxWidth = 520
logColumnPadding = 24
)
// logColumnWidth measures the widest Log cell value so the column can be sized
// to fit its content. Fyne tables do not auto-size columns, so without this the
// fixed width clips file names like "20260601-100000_SomeJobName.log".
func logColumnWidth(events []event) float32 {
width := float32(logColumnMinWidth)
for _, current := range events {
text := logFileName(current.LogFile)
if text == "" {
continue
}
w := fyne.MeasureText(text, theme.TextSize(), fyne.TextStyle{}).Width + logColumnPadding
if w > width {
width = w
}
}
if width > logColumnMaxWidth {
width = logColumnMaxWidth
}
return width
}
func newHistoryView(events *[]event) (*fyne.Container, func()) {
descending := false
headerText := func(id widget.TableCellID) string {
headers := []string{"Time", "Trigger", "Job", "State", "Detail", "Log"}
@@ -107,8 +139,16 @@ func newHistoryView(events *[]event) *fyne.Container {
table.SetColumnWidth(2, 170)
table.SetColumnWidth(3, 90)
table.SetColumnWidth(4, 260)
table.SetColumnWidth(5, 240)
return container.NewPadded(table)
table.SetColumnWidth(5, logColumnWidth(*events))
// refresh recomputes the content-fit Log column width before redrawing, so
// newly recorded events with longer file names widen the column instead of
// being truncated.
refresh := func() {
table.SetColumnWidth(5, logColumnWidth(*events))
table.Refresh()
}
return container.NewPadded(table), refresh
}
func historyCellText(id widget.TableCellID, events []event) string {
+3 -3
View File
@@ -40,7 +40,7 @@ func newMainView(w fyne.Window) (fyne.CanvasObject, func(time.Duration, bool)) {
jobsPanel, refreshJobsView := newJobsView(w, svc)
history := newHistoryView(&events)
history, refreshHistory := newHistoryView(&events)
recordStartup := func(duration time.Duration, windowShown bool) {
// Startup is recorded as an in-memory History event instead of being
// persisted into jobs.yaml. It is session diagnostics, not durable job
@@ -51,12 +51,12 @@ func newMainView(w fyne.Window) (fyne.CanvasObject, func(time.Duration, bool)) {
detail = "Started in tray in " + duration.Round(time.Millisecond).String()
}
events = append(events, newEvent(0, "Application", "Started", detail))
history.Refresh()
refreshHistory()
}
refresh := func() {
refreshJobsView()
history.Refresh()
refreshHistory()
}
// The Service announces every change through events. This single listener is