feat(awards): follow-list picker in Settings → Awards, filter the Awards tab
New per-profile "tracked awards" selection: Settings → Awards (under User configuration) is a two-column transfer list — every defined award on the left, the ones you follow on the right, click to move either way. The Awards tab's list is narrowed to the followed set; an empty set means "show them all" so the tab is never blank. Backend: app_awards_tracked.go adds keyAwardsTracked (per-profile JSON array of award codes) with GetTrackedAwards/SaveTrackedAwards; saving emits awards:tracked-changed so the Awards tab re-filters live. Award definitions stay global — only the follow selection is per profile.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { Award as AwardIcon, RefreshCw, Loader2, Search, Pencil, X, Grid3x3, List, BarChart3, AlertTriangle, ChevronUp, ChevronDown } from 'lucide-react';
|
||||
import { GetAwardDefs, GetAward, AwardCellQSOs, GetAwardStats, AwardMissingQSOs, ListAwardReferences, AssignAwardRefToQSOs, RescanAwards } from '../../wailsjs/go/main/App';
|
||||
import { GetAwardDefs, GetAward, AwardCellQSOs, GetAwardStats, AwardMissingQSOs, ListAwardReferences, AssignAwardRefToQSOs, RescanAwards, GetTrackedAwards } from '../../wailsjs/go/main/App';
|
||||
import { EventsOn } from '../../wailsjs/runtime/runtime';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Checkbox } from '@/components/ui/checkbox';
|
||||
@@ -137,13 +138,20 @@ export function AwardsPanel({ onEditQSO, onAwardsChanged }: { onEditQSO?: (id: n
|
||||
}
|
||||
}
|
||||
|
||||
// Load the award list (no QSO scan), then compute only the first award.
|
||||
// Load the award list (no QSO scan), then compute only the first award. The
|
||||
// list is narrowed to the awards the operator follows (Settings → Awards); an
|
||||
// empty follow-set means "show them all" so the tab is never blank.
|
||||
async function loadList() {
|
||||
try {
|
||||
const defs = ((await GetAwardDefs()) ?? []) as any[];
|
||||
const list: AwardListItem[] = defs
|
||||
const [defs, tracked] = await Promise.all([
|
||||
GetAwardDefs().then((d) => (d ?? []) as any[]),
|
||||
GetTrackedAwards().then((t) => (t ?? []) as string[]).catch(() => [] as string[]),
|
||||
]);
|
||||
const follow = new Set(tracked);
|
||||
let list: AwardListItem[] = defs
|
||||
.map((d) => ({ code: d.code, name: d.name, valid: d.valid, bands: d.valid_bands ?? [], emission: d.emission ?? [] }))
|
||||
.sort((a, b) => a.code.localeCompare(b.code));
|
||||
if (follow.size > 0) list = list.filter((a) => follow.has(a.code));
|
||||
setAwardList(list);
|
||||
const first = list.find((a) => a.code === selected) ?? list[0];
|
||||
if (first) compute(first.code);
|
||||
@@ -152,6 +160,12 @@ export function AwardsPanel({ onEditQSO, onAwardsChanged }: { onEditQSO?: (id: n
|
||||
}
|
||||
}
|
||||
useEffect(() => { loadList(); }, []);
|
||||
// Re-filter when the operator changes their followed awards in Settings.
|
||||
useEffect(() => {
|
||||
const off = EventsOn('awards:tracked-changed', () => { loadList(); });
|
||||
return () => { off(); };
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
const current = byCode[`${selected}|${modeFilter}`];
|
||||
// Recompute when the mode class changes: the bands, counts and confirmations
|
||||
|
||||
Reference in New Issue
Block a user