From 0a477fd288d064d265395c88dbd0f261b723804e Mon Sep 17 00:00:00 2001 From: spiperac Date: Mon, 15 Jun 2026 06:42:13 +0200 Subject: Initial release --- internal/ui/har.go | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 internal/ui/har.go (limited to 'internal/ui/har.go') diff --git a/internal/ui/har.go b/internal/ui/har.go new file mode 100644 index 0000000..ba3e085 --- /dev/null +++ b/internal/ui/har.go @@ -0,0 +1,88 @@ +package ui + +import ( + "fmt" + "time" + + "fyne.io/fyne/v2" + "fyne.io/fyne/v2/dialog" + + "github.com/shiv/internal/logger" + "github.com/shiv/internal/store" +) + +// exportHAR exports all transactions matching the current filter to a HAR file. +// It paginates through the DB so all rows are exported, not just the visible page. +func (h *historyTab) exportHAR() { + if len(h.displayed) == 0 { + dialog.ShowInformation("Export HAR", "No transactions to export.", h.win) + return + } + + f := h.currentFilter() + + go func() { + // Paginate through all matching rows from DB. + var all []store.Transaction + var cursor uint64 + for { + page, err := h.projectStore.TransactionsPage(cursor, f) + if err != nil { + fyne.Do(func() { + dialog.ShowError(fmt.Errorf("HAR export failed: %w", err), h.win) + }) + return + } + if len(page) == 0 { + break + } + all = append(all, page...) + if len(page) < store.PageSize { + break + } + cursor = page[len(page)-1].ID + } + + if len(all) == 0 { + fyne.Do(func() { + dialog.ShowInformation("Export HAR", "No transactions to export.", h.win) + }) + return + } + + // Fetch full bodies — page rows omit bodies for performance. + full := make([]store.Transaction, 0, len(all)) + for _, tx := range all { + fullTx, err := h.projectStore.GetTransaction(tx.ID) + if err != nil { + logger.Error("har: get transaction %d: %v", tx.ID, err) + full = append(full, tx) + continue + } + full = append(full, *fullTx) + } + + data, err := store.ExportHAR(full) + if err != nil { + fyne.Do(func() { + dialog.ShowError(fmt.Errorf("HAR export failed: %w", err), h.win) + }) + return + } + + fyne.Do(func() { + saveDialog := dialog.NewFileSave(func(wc fyne.URIWriteCloser, err error) { + if err != nil || wc == nil { + return + } + defer wc.Close() + if _, err := wc.Write(data); err != nil { + logger.Error("har: write: %v", err) + dialog.ShowError(err, h.win) + } + }, h.win) + saveDialog.SetFileName(fmt.Sprintf("shiv-%s.har", time.Now().Format("2006-01-02-150405"))) + saveDialog.Show() + }) + }() +} -- cgit v1.2.3