summaryrefslogtreecommitdiff
path: root/internal/ui/har.go
blob: ba3e085f4bf762341fae376d16e422652483ad83 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
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()
		})
	}()
}