Add a Circuit filter to the filter bar
Buttons are generated from CONFIG.circuits (not hand-written in index.html), so adding a circuit to the config still only takes one line — its filter button appears automatically. Uses accent color to match the circuit badges on the cards, same active/dimmed styling as Format/Scope. An event matches the circuit filter if it belongs to any active circuit (OR within the group), not all of them, since an event can legitimately carry more than one circuit tag. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SBzcNkW7JcYipnAX6HfgmK
This commit is contained in:
@@ -215,25 +215,42 @@ function scopeOf(ev) {
|
||||
/* ---- Filters ---- */
|
||||
const activeFormats = new Set(["Singles", "Team Event"]);
|
||||
const activeScopes = new Set(["RTT", "GT"]);
|
||||
const activeCircuits = new Set(CONFIG.circuits.map(c => c.id));
|
||||
|
||||
function passesFilter(ev) {
|
||||
// An event passes the circuit filter if it belongs to at least one
|
||||
// active circuit — it's an OR within the group, same as Format/Scope,
|
||||
// not "must match every circuit it happens to also belong to".
|
||||
function passesFilter(ev, circuits) {
|
||||
const scope = scopeOf(ev);
|
||||
return activeFormats.has(formatOf(ev)) && (scope === null || activeScopes.has(scope));
|
||||
return activeFormats.has(formatOf(ev))
|
||||
&& (scope === null || activeScopes.has(scope))
|
||||
&& circuits.some(c => activeCircuits.has(c.id));
|
||||
}
|
||||
|
||||
// Filter buttons use the same color as the badge they control (warning
|
||||
// for Format, info for Scope) when active, so it's obvious at a glance
|
||||
// which is which — and switch to a dimmed outline when off, since
|
||||
// btn-outline alone reads too similarly to its own active state in dark
|
||||
// mode to tell the two apart at a glance.
|
||||
const FILTER_GROUP_COLOR = { format: "btn-warning", scope: "btn-info" };
|
||||
// for Format, info for Scope, accent for Circuit — matching the badge
|
||||
// colors on the cards) when active, so it's obvious at a glance which is
|
||||
// which — and switch to a dimmed outline when off, since btn-outline
|
||||
// alone reads too similarly to its own active state in dark mode to
|
||||
// tell the two apart at a glance.
|
||||
const FILTER_GROUP_COLOR = { format: "btn-warning", scope: "btn-info", circuit: "btn-accent" };
|
||||
const FILTER_SET = { format: activeFormats, scope: activeScopes, circuit: activeCircuits };
|
||||
|
||||
// Circuit buttons are generated from CONFIG rather than hand-written in
|
||||
// index.html, so adding a circuit there is still a one-line change.
|
||||
function renderCircuitFilterButtons() {
|
||||
$("circuit-filters").innerHTML = CONFIG.circuits.map(c =>
|
||||
`<button type="button" class="btn btn-sm btn-accent" data-filter-group="circuit" data-filter-value="${esc(c.id)}">${esc(c.name)}</button>`
|
||||
).join("");
|
||||
}
|
||||
|
||||
function setupFilters() {
|
||||
renderCircuitFilterButtons();
|
||||
document.querySelectorAll("#filters button[data-filter-group]").forEach(btn => {
|
||||
const group = btn.dataset.filterGroup;
|
||||
const onClass = FILTER_GROUP_COLOR[group];
|
||||
btn.addEventListener("click", () => {
|
||||
const set = group === "format" ? activeFormats : activeScopes;
|
||||
const set = FILTER_SET[group];
|
||||
const nowActive = !btn.classList.contains(onClass);
|
||||
btn.classList.toggle(onClass, nowActive);
|
||||
btn.classList.toggle("btn-outline", !nowActive);
|
||||
@@ -297,7 +314,7 @@ let allResults = [];
|
||||
|
||||
function renderEvents() {
|
||||
const merged = mergeEvents(allResults);
|
||||
const filtered = merged.filter(({ event }) => passesFilter(event));
|
||||
const filtered = merged.filter(({ event, circuits }) => passesFilter(event, circuits));
|
||||
|
||||
const failed = allResults.filter(r => r.error).map(r => r.circuit.name);
|
||||
const errorBanner = failed.length
|
||||
|
||||
Reference in New Issue
Block a user