Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8f75318e8c | |||
| ed81443d29 |
@@ -14,4 +14,5 @@ type Job struct {
|
|||||||
Arguments string `json:"arguments,omitempty"`
|
Arguments string `json:"arguments,omitempty"`
|
||||||
StartOnly bool `json:"start_only,omitempty"`
|
StartOnly bool `json:"start_only,omitempty"`
|
||||||
Enabled bool `json:"enabled"`
|
Enabled bool `json:"enabled"`
|
||||||
|
OverlapPolicy string `json:"overlap_policy,omitempty"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ type yamlJob struct {
|
|||||||
Arguments string `yaml:"arguments,omitempty"`
|
Arguments string `yaml:"arguments,omitempty"`
|
||||||
StartOnly bool `yaml:"start_only,omitempty"`
|
StartOnly bool `yaml:"start_only,omitempty"`
|
||||||
Enabled bool `yaml:"enabled"`
|
Enabled bool `yaml:"enabled"`
|
||||||
|
OverlapPolicy string `yaml:"overlap_policy,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type yamlJobsFile struct {
|
type yamlJobsFile struct {
|
||||||
|
|||||||
+43
-3
@@ -9,6 +9,7 @@ import (
|
|||||||
|
|
||||||
"fyne.io/fyne/v2"
|
"fyne.io/fyne/v2"
|
||||||
"fyne.io/fyne/v2/container"
|
"fyne.io/fyne/v2/container"
|
||||||
|
"fyne.io/fyne/v2/theme"
|
||||||
"fyne.io/fyne/v2/widget"
|
"fyne.io/fyne/v2/widget"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -41,7 +42,38 @@ func collectActivity(jobs []job, runtimes map[int]*domain.JobRuntime) []event {
|
|||||||
return events
|
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
|
descending := false
|
||||||
headerText := func(id widget.TableCellID) string {
|
headerText := func(id widget.TableCellID) string {
|
||||||
headers := []string{"Time", "Trigger", "Job", "State", "Detail", "Log"}
|
headers := []string{"Time", "Trigger", "Job", "State", "Detail", "Log"}
|
||||||
@@ -107,8 +139,16 @@ func newHistoryView(events *[]event) *fyne.Container {
|
|||||||
table.SetColumnWidth(2, 170)
|
table.SetColumnWidth(2, 170)
|
||||||
table.SetColumnWidth(3, 90)
|
table.SetColumnWidth(3, 90)
|
||||||
table.SetColumnWidth(4, 260)
|
table.SetColumnWidth(4, 260)
|
||||||
table.SetColumnWidth(5, 240)
|
table.SetColumnWidth(5, logColumnWidth(*events))
|
||||||
return container.NewPadded(table)
|
|
||||||
|
// 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 {
|
func historyCellText(id widget.TableCellID, events []event) string {
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ func newMainView(w fyne.Window) (fyne.CanvasObject, func(time.Duration, bool)) {
|
|||||||
|
|
||||||
jobsPanel, refreshJobsView := newJobsView(w, svc)
|
jobsPanel, refreshJobsView := newJobsView(w, svc)
|
||||||
|
|
||||||
history := newHistoryView(&events)
|
history, refreshHistory := newHistoryView(&events)
|
||||||
recordStartup := func(duration time.Duration, windowShown bool) {
|
recordStartup := func(duration time.Duration, windowShown bool) {
|
||||||
// Startup is recorded as an in-memory History event instead of being
|
// Startup is recorded as an in-memory History event instead of being
|
||||||
// persisted into jobs.yaml. It is session diagnostics, not durable job
|
// 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()
|
detail = "Started in tray in " + duration.Round(time.Millisecond).String()
|
||||||
}
|
}
|
||||||
events = append(events, newEvent(0, "Application", "Started", detail))
|
events = append(events, newEvent(0, "Application", "Started", detail))
|
||||||
history.Refresh()
|
refreshHistory()
|
||||||
}
|
}
|
||||||
|
|
||||||
refresh := func() {
|
refresh := func() {
|
||||||
refreshJobsView()
|
refreshJobsView()
|
||||||
history.Refresh()
|
refreshHistory()
|
||||||
}
|
}
|
||||||
|
|
||||||
// The Service announces every change through events. This single listener is
|
// The Service announces every change through events. This single listener is
|
||||||
|
|||||||
Reference in New Issue
Block a user