feat: ADIF export field picker — choose exactly which fields to write
Global "Export to ADIF" gains a third option "Choose fields…" next to the standard-only and full-OpsLog choices, and right-clicking selected QSOs adds "Export selected — choose fields…". The picker separates official ADIF 3.1.7 fields (grouped by category) from OpsLog/non-standard tags actually present in the log (discovered via DistinctExtraKeys over extras_json), with All/None per group and reset-to-defaults; the selection is persisted per user. Backend: adif.Exporter gains a Fields allow-set that gates every promoted and extras field in writeRecord; app.go ExportADIF/ExportADIFFiltered/ ExportADIFSelected take a fields []string param, plus new ADIFExtraFields.
This commit is contained in:
@@ -366,6 +366,42 @@ func decodeExtras(s string) map[string]string {
|
||||
return m
|
||||
}
|
||||
|
||||
// DistinctExtraKeys returns the set of keys present across stored QSO extras
|
||||
// (the non-promoted ADIF tags kept verbatim), scanning the most recent `sample`
|
||||
// rows that have any extras. Capped so it stays fast on a large remote logbook —
|
||||
// the extras vocabulary is small and stable, so a recent sample finds it all.
|
||||
func (r *Repo) DistinctExtraKeys(ctx context.Context, sample int) ([]string, error) {
|
||||
if sample <= 0 {
|
||||
sample = 5000
|
||||
}
|
||||
rows, err := r.db.QueryContext(ctx,
|
||||
`SELECT extras_json FROM qso
|
||||
WHERE extras_json IS NOT NULL AND extras_json <> '' AND extras_json <> '{}'
|
||||
ORDER BY id DESC LIMIT ?`, sample)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
seen := map[string]bool{}
|
||||
for rows.Next() {
|
||||
var s sql.NullString
|
||||
if err := rows.Scan(&s); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for k := range decodeExtras(s.String) {
|
||||
seen[k] = true
|
||||
}
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out := make([]string, 0, len(seen))
|
||||
for k := range seen {
|
||||
out = append(out, k)
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Add inserts a QSO and returns its ID.
|
||||
func (r *Repo) Add(ctx context.Context, q QSO) (int64, error) {
|
||||
q.Callsign = strings.ToUpper(strings.TrimSpace(q.Callsign))
|
||||
|
||||
Reference in New Issue
Block a user