mirror of
https://github.com/samsonjs/spirit-tracker.git
synced 2026-03-25 09:25:51 +00:00
feat: SMWS Search results
This commit is contained in:
parent
140b73af37
commit
13c82a74ba
2 changed files with 220 additions and 1 deletions
|
|
@ -3,6 +3,7 @@ import { tokenizeQuery, matchesAllTokens, displaySku, keySkuForRow, parsePriceTo
|
|||
import { loadIndex, loadRecent, loadSavedQuery, saveQuery } from "./state.js";
|
||||
import { aggregateBySku } from "./catalog.js";
|
||||
import { loadSkuRules } from "./mapping.js";
|
||||
import { smwsDistilleryCodesForQueryPrefix, smwsDistilleryCodeFromName } from "./smws.js";
|
||||
|
||||
export function renderSearch($app) {
|
||||
$app.innerHTML = `
|
||||
|
|
@ -387,7 +388,28 @@ export function renderSearch($app) {
|
|||
if (!tokens.length) return;
|
||||
|
||||
const matches = allAgg.filter((it) => matchesAllTokens(it.searchText, tokens));
|
||||
renderAggregates(matches);
|
||||
|
||||
// If query prefixes an SMWS distillery name, also surface SMWS bottles by code XXX.YYY where XXX matches.
|
||||
const wantCodes = new Set(smwsDistilleryCodesForQueryPrefix($q.value));
|
||||
if (!wantCodes.size) {
|
||||
renderAggregates(matches);
|
||||
return;
|
||||
}
|
||||
|
||||
const seen = new Set(matches.map((it) => String(it?.sku || "")));
|
||||
const extra = [];
|
||||
for (const it of allAgg) {
|
||||
const sku = String(it?.sku || "");
|
||||
if (!sku || seen.has(sku)) continue;
|
||||
const dCode = smwsDistilleryCodeFromName(it?.name || "");
|
||||
if (dCode && wantCodes.has(String(dCode))) {
|
||||
extra.push(it);
|
||||
seen.add(sku);
|
||||
}
|
||||
}
|
||||
|
||||
// Put SMWS distillery matches first, then normal search matches.
|
||||
renderAggregates([...extra, ...matches]);
|
||||
}
|
||||
|
||||
$results.innerHTML = `<div class="small">Loading index…</div>`;
|
||||
|
|
|
|||
197
viz/app/smws.js
Normal file
197
viz/app/smws.js
Normal file
|
|
@ -0,0 +1,197 @@
|
|||
// viz/app/smws.js
|
||||
import { normSearchText } from "./sku.js";
|
||||
|
||||
const DISTILLERIES = [
|
||||
{ code: "1", name: "Glenfarclas" },
|
||||
{ code: "2", name: "Glenlivet" },
|
||||
{ code: "3", name: "Bowmore" },
|
||||
{ code: "4", name: "Highland Park" },
|
||||
{ code: "5", name: "Auchentoshan" },
|
||||
{ code: "6", name: "Macduff" },
|
||||
{ code: "7", name: "Longmorn" },
|
||||
{ code: "8", name: "Tamdhu" },
|
||||
{ code: "9", name: "Glen Grant" },
|
||||
{ code: "10", name: "Bunnahabhain" },
|
||||
{ code: "11", name: "Tomatin" },
|
||||
{ code: "12", name: "BenRiach" },
|
||||
{ code: "13", name: "Dalmore" },
|
||||
{ code: "14", name: "Talisker" },
|
||||
{ code: "15", name: "Glenfiddich" },
|
||||
{ code: "16", name: "Glenturret" },
|
||||
{ code: "17", name: "Scapa" },
|
||||
{ code: "18", name: "Inchgower" },
|
||||
{ code: "19", name: "Glen Garioch" },
|
||||
{ code: "20", name: "Inverleven" },
|
||||
{ code: "21", name: "Glenglassaugh" },
|
||||
{ code: "22", name: "Glenkinchie" },
|
||||
{ code: "23", name: "Bruichladdich" },
|
||||
{ code: "24", name: "Macallan" },
|
||||
{ code: "25", name: "Rosebank" },
|
||||
{ code: "26", name: "Clynelish" },
|
||||
{ code: "27", name: "Springbank" },
|
||||
{ code: "28", name: "Tullibardine" },
|
||||
{ code: "29", name: "Laphroaig" },
|
||||
{ code: "30", name: "Glenrothes" },
|
||||
{ code: "31", name: "Isle of Jura" },
|
||||
{ code: "32", name: "Edradour" },
|
||||
{ code: "33", name: "Ardbeg" },
|
||||
{ code: "34", name: "Tamnavulin" },
|
||||
{ code: "35", name: "Glen Moray" },
|
||||
{ code: "36", name: "Benrinnes" },
|
||||
{ code: "37", name: "Cragganmore" },
|
||||
{ code: "38", name: "Caperdonich" },
|
||||
{ code: "39", name: "Linkwood" },
|
||||
{ code: "40", name: "Balvenie" },
|
||||
{ code: "41", name: "Dailuaine" },
|
||||
{ code: "42", name: "Tobermory" },
|
||||
{ code: "43", name: "Port Ellen" },
|
||||
{ code: "44", name: "Craigellachie" },
|
||||
{ code: "45", name: "Dallas Dhu" },
|
||||
{ code: "46", name: "Glenlossie" },
|
||||
{ code: "47", name: "Benromach" },
|
||||
{ code: "48", name: "Balmenach" },
|
||||
{ code: "49", name: "St. Magdalene" },
|
||||
{ code: "50", name: "Bladnoch" },
|
||||
{ code: "51", name: "Bushmills" },
|
||||
{ code: "52", name: "Old Pulteney" },
|
||||
{ code: "53", name: "Caol Ila" },
|
||||
{ code: "54", name: "Aberlour" },
|
||||
{ code: "55", name: "Royal Brackla" },
|
||||
{ code: "56", name: "Coleburn" },
|
||||
{ code: "57", name: "Glen Mhor" },
|
||||
{ code: "58", name: "Strathisla" },
|
||||
{ code: "59", name: "Teaninich" },
|
||||
{ code: "60", name: "Aberfeldy" },
|
||||
{ code: "61", name: "Brora" },
|
||||
{ code: "62", name: "Glenlochy" },
|
||||
{ code: "63", name: "Glentauchers" },
|
||||
{ code: "64", name: "Mannochmore" },
|
||||
{ code: "65", name: "Imperial" },
|
||||
{ code: "66", name: "Ardmore" },
|
||||
{ code: "67", name: "Banff" },
|
||||
{ code: "68", name: "Blair Athol" },
|
||||
{ code: "69", name: "Glen Albyn" },
|
||||
{ code: "70", name: "Balblair" },
|
||||
{ code: "71", name: "Glenburgie" },
|
||||
{ code: "72", name: "Miltonduff" },
|
||||
{ code: "73", name: "Aultmore" },
|
||||
{ code: "74", name: "North Port" },
|
||||
{ code: "75", name: "Glenury / Glenury Royal" },
|
||||
{ code: "76", name: "Mortlach" },
|
||||
{ code: "77", name: "Glen Ord" },
|
||||
{ code: "78", name: "Ben Nevis" },
|
||||
{ code: "79", name: "Deanston" },
|
||||
{ code: "80", name: "Glen Spey" },
|
||||
{ code: "81", name: "Glen Keith" },
|
||||
{ code: "82", name: "Glencadam" },
|
||||
{ code: "83", name: "Convalmore" },
|
||||
{ code: "84", name: "Glendullan" },
|
||||
{ code: "85", name: "Glen Elgin" },
|
||||
{ code: "86", name: "Glenesk" },
|
||||
{ code: "87", name: "Millburn" },
|
||||
{ code: "88", name: "Speyburn" },
|
||||
{ code: "89", name: "Tomintoul" },
|
||||
{ code: "90", name: "Pittyvaich" },
|
||||
{ code: "91", name: "Dufftown" },
|
||||
{ code: "92", name: "Lochside" },
|
||||
{ code: "93", name: "Glen Scotia" },
|
||||
{ code: "94", name: "Fettercairn" },
|
||||
{ code: "95", name: "Auchroisk" },
|
||||
{ code: "96", name: "GlenDronach" },
|
||||
{ code: "97", name: "Littlemill" },
|
||||
{ code: "98", name: "Inverleven" },
|
||||
{ code: "99", name: "Glenugie" },
|
||||
{ code: "100", name: "Strathmill" },
|
||||
{ code: "101", name: "Knockando" },
|
||||
{ code: "102", name: "Dalwhinnie" },
|
||||
{ code: "103", name: "Royal Lochnagar" },
|
||||
{ code: "104", name: "Glenburgie (Glencraig)" },
|
||||
{ code: "105", name: "Tormore" },
|
||||
{ code: "106", name: "Cardhu" },
|
||||
{ code: "107", name: "Glenallachie" },
|
||||
{ code: "108", name: "Allt-a-Bhainne" },
|
||||
{ code: "109", name: "Miltonduff (Mosstowie)" },
|
||||
{ code: "110", name: "Oban" },
|
||||
{ code: "111", name: "Lagavulin" },
|
||||
{ code: "112", name: "Loch Lomond (Inchmurrin / Inchmoan)" },
|
||||
{ code: "113", name: "Braeval (Braes of Glenlivet)" },
|
||||
{ code: "114", name: "Springbank (Longrow)" },
|
||||
{ code: "115", name: "Knockdhu (AnCnoc)" },
|
||||
{ code: "116", name: "Yoichi" },
|
||||
{ code: "117", name: "Cooley (Unpeated)" },
|
||||
{ code: "118", name: "Cooley / Connemara (Peated)" },
|
||||
{ code: "119", name: "Yamazaki" },
|
||||
{ code: "120", name: "Hakushu" },
|
||||
{ code: "121", name: "Isle of Arran" },
|
||||
{ code: "122", name: "Loch Lomond (Croftengea)" },
|
||||
{ code: "123", name: "Glengoyne" },
|
||||
{ code: "124", name: "Miyagikyo" },
|
||||
{ code: "125", name: "Glenmorangie" },
|
||||
{ code: "126", name: "Springbank (Hazelburn)" },
|
||||
{ code: "127", name: "Bruichladdich (Port Charlotte)" },
|
||||
{ code: "128", name: "Penderyn" },
|
||||
{ code: "129", name: "Kilchoman" },
|
||||
{ code: "130", name: "Chichibu" },
|
||||
{ code: "131", name: "Hanyu" },
|
||||
{ code: "132", name: "Karuizawa" },
|
||||
{ code: "133", name: "Westland" },
|
||||
{ code: "134", name: "Paul John" },
|
||||
{ code: "135", name: "Loch Lomond" },
|
||||
{ code: "136", name: "Eden Mill" },
|
||||
{ code: "137", name: "St. George’s (The English Whisky Co.)" },
|
||||
{ code: "138", name: "Nantou" },
|
||||
{ code: "139", name: "Kavalan" },
|
||||
{ code: "140", name: "Balcones" },
|
||||
{ code: "141", name: "Fary Lochan" },
|
||||
{ code: "142", name: "Breuckelen Distilling" },
|
||||
{ code: "143", name: "Copperworks Distilling Co." },
|
||||
{ code: "144", name: "High Coast Distillery" },
|
||||
{ code: "145", name: "Smögen Whisky" },
|
||||
{ code: "146", name: "Cotswolds" },
|
||||
{ code: "147", name: "Archie Rose" },
|
||||
{ code: "148", name: "Starward" },
|
||||
{ code: "149", name: "Ardnamurchan" },
|
||||
{ code: "150", name: "West Cork Distillers" },
|
||||
{ code: "151", name: "Mackmyra" },
|
||||
{ code: "152", name: "Shelter Point" },
|
||||
{ code: "153", name: "Thy Whisky" },
|
||||
{ code: "154", name: "Mosgaard Whisky" },
|
||||
{ code: "155", name: "Milk & Honey Distillery" },
|
||||
{ code: "156", name: "Glasgow Distillery" },
|
||||
{ code: "157", name: "Distillerie de Warenghem" },
|
||||
{ code: "158", name: "Yuza Distillery" },
|
||||
{ code: "159", name: "Mars Shinshu" },
|
||||
{ code: "160", name: "Mars Tsunuki" },
|
||||
{ code: "161", name: "Nc'nean Distillery" },
|
||||
{ code: "162", name: "Isle of Raasay" },
|
||||
{ code: "163", name: "Isle of Harris Distillery" },
|
||||
{ code: "164", name: "Penderyn" },
|
||||
{ code: "165", name: "Wolfburn" },
|
||||
];
|
||||
|
||||
const DIST = DISTILLERIES.map((d) => ({
|
||||
code: String(d.code),
|
||||
nameNorm: normSearchText(d.name),
|
||||
}));
|
||||
|
||||
const SMWS_WORD_RE = /\bsmws\b/i;
|
||||
const SMWS_CODE_RE = /\b(\d{1,3})\.(\d{1,4})\b/;
|
||||
|
||||
export function smwsDistilleryCodesForQueryPrefix(qRaw) {
|
||||
const q = normSearchText(qRaw);
|
||||
if (!q || q.length < 2) return [];
|
||||
|
||||
const out = new Set();
|
||||
for (const d of DIST) {
|
||||
if (d.nameNorm.startsWith(q)) out.add(d.code);
|
||||
}
|
||||
return Array.from(out);
|
||||
}
|
||||
|
||||
// If a listing name contains "SMWS" and an SMWS code like 35.123, returns "35" (distillery code).
|
||||
export function smwsDistilleryCodeFromName(name) {
|
||||
const s = String(name || "");
|
||||
if (!SMWS_WORD_RE.test(s)) return "";
|
||||
const m = s.match(SMWS_CODE_RE);
|
||||
return m ? String(m[1] || "") : "";
|
||||
}
|
||||
Loading…
Reference in a new issue