feat: filter cluster spots on new POTA and new county
The grid already badges them; only the filter was missing. They are not entity statuses — a new park or county is another dimension of the same spot — so the filter key is now a superset of the status, and matching is an OR across all of them, as it already was for a previously-worked callsign. The chips carry the colours their badges use in the grid: a filter that does not look like what it selects has to be learned twice.
This commit is contained in:
@@ -1,4 +1,14 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"version": "0.22.5",
|
||||||
|
"date": "",
|
||||||
|
"en": [
|
||||||
|
"Cluster filters gain NEW POTA and NEW COUNTY, alongside the existing status chips."
|
||||||
|
],
|
||||||
|
"fr": [
|
||||||
|
"Les filtres du cluster gagnent NEW POTA et NEW COUNTY, à côté des pastilles de statut existantes."
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"version": "0.22.4",
|
"version": "0.22.4",
|
||||||
"date": "",
|
"date": "",
|
||||||
|
|||||||
+18
-6
@@ -1323,7 +1323,12 @@ export default function App() {
|
|||||||
// Status filter chips. Empty set = show every status (including
|
// Status filter chips. Empty set = show every status (including
|
||||||
// already-worked). Otherwise only matching spots pass.
|
// already-worked). Otherwise only matching spots pass.
|
||||||
type SpotStatusKey = 'new' | 'new-band' | 'new-mode' | 'new-slot' | 'worked';
|
type SpotStatusKey = 'new' | 'new-band' | 'new-mode' | 'new-slot' | 'worked';
|
||||||
const [clusterStatusFilter, setClusterStatusFilter] = useState<Set<SpotStatusKey>>(() => lsSet<SpotStatusKey>('opslog.clusterStatusFilter'));
|
// What the cluster can be FILTERED on. A superset of the entity status: a new
|
||||||
|
// county or a new park is not a DXCC state, it is another dimension of the
|
||||||
|
// same spot — which is why the grid shows them as separate badges. Filtering
|
||||||
|
// is an OR across all of them, as it already was for a worked callsign.
|
||||||
|
type SpotFilterKey = SpotStatusKey | 'new-pota' | 'new-county';
|
||||||
|
const [clusterStatusFilter, setClusterStatusFilter] = useState<Set<SpotFilterKey>>(() => lsSet<SpotFilterKey>('opslog.clusterStatusFilter'));
|
||||||
// Mode filter chips. Empty set = show every mode. Categories map the
|
// Mode filter chips. Empty set = show every mode. Categories map the
|
||||||
// inferred per-spot mode onto SSB (phone) / CW / DATA (digital).
|
// inferred per-spot mode onto SSB (phone) / CW / DATA (digital).
|
||||||
type SpotModeCat = 'SSB' | 'CW' | 'DATA';
|
type SpotModeCat = 'SSB' | 'CW' | 'DATA';
|
||||||
@@ -4269,7 +4274,10 @@ export default function App() {
|
|||||||
// entity status is still new-band/new-slot (the grid flags it WKD CALL),
|
// entity status is still new-band/new-slot (the grid flags it WKD CALL),
|
||||||
// matching the "Hide worked" toggle. Additive: it still matches its own
|
// matching the "Hide worked" toggle. Additive: it still matches its own
|
||||||
// entity status too, so it stays visible under NEW BAND / NEW SLOT.
|
// entity status too, so it stays visible under NEW BAND / NEW SLOT.
|
||||||
const matches = clusterStatusFilter.has(st) || (!!e?.worked_call && clusterStatusFilter.has('worked'));
|
const matches = clusterStatusFilter.has(st)
|
||||||
|
|| (!!e?.worked_call && clusterStatusFilter.has('worked'))
|
||||||
|
|| (!!e?.new_pota && clusterStatusFilter.has('new-pota'))
|
||||||
|
|| (!!e?.new_county && clusterStatusFilter.has('new-county'));
|
||||||
if (!matches) return false;
|
if (!matches) return false;
|
||||||
}
|
}
|
||||||
if (clusterHideWorked) {
|
if (clusterHideWorked) {
|
||||||
@@ -4381,10 +4389,14 @@ export default function App() {
|
|||||||
<div className="text-[10px] uppercase tracking-wider text-muted-foreground mb-1">Status</div>
|
<div className="text-[10px] uppercase tracking-wider text-muted-foreground mb-1">Status</div>
|
||||||
<div className="flex flex-wrap gap-1">
|
<div className="flex flex-wrap gap-1">
|
||||||
{([
|
{([
|
||||||
{ k: 'new' as SpotStatusKey, label: 'NEW', cls: 'bg-danger-muted text-danger-muted-foreground border-danger-border' },
|
{ k: 'new' as SpotFilterKey, label: 'NEW', cls: 'bg-danger-muted text-danger-muted-foreground border-danger-border' },
|
||||||
{ k: 'new-band' as SpotStatusKey, label: 'NEW BAND', cls: 'bg-warning-muted text-warning-muted-foreground border-warning-border' },
|
{ k: 'new-band' as SpotFilterKey, label: 'NEW BAND', cls: 'bg-warning-muted text-warning-muted-foreground border-warning-border' },
|
||||||
{ k: 'new-mode' as SpotStatusKey, label: 'NEW MODE', cls: 'bg-caution-muted text-caution-muted-foreground border-caution-border' },
|
{ k: 'new-mode' as SpotFilterKey, label: 'NEW MODE', cls: 'bg-caution-muted text-caution-muted-foreground border-caution-border' },
|
||||||
{ k: 'new-slot' as SpotStatusKey, label: 'NEW SLOT', cls: 'bg-caution-muted text-caution-muted-foreground border-caution-border' },
|
{ k: 'new-slot' as SpotFilterKey, label: 'NEW SLOT', cls: 'bg-caution-muted text-caution-muted-foreground border-caution-border' },
|
||||||
|
// Same colours as the badges in the grid — a filter that does not
|
||||||
|
// look like what it selects has to be learned twice.
|
||||||
|
{ k: 'new-pota' as SpotFilterKey, label: 'NEW POTA', cls: 'bg-success-muted text-success-muted-foreground border-success-border' },
|
||||||
|
{ k: 'new-county' as SpotFilterKey, label: 'NEW COUNTY', cls: 'bg-info-muted text-info-muted-foreground border-info-border' },
|
||||||
// (no WORKED chip — use the "Hide worked" checkbox to drop dupes.)
|
// (no WORKED chip — use the "Hide worked" checkbox to drop dupes.)
|
||||||
]).map((s) => {
|
]).map((s) => {
|
||||||
const on = clusterStatusFilter.has(s.k);
|
const on = clusterStatusFilter.has(s.k);
|
||||||
|
|||||||
Reference in New Issue
Block a user