From ec513fc362272cef660be7647ea675a91c1579b5 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Sat, 15 Nov 2025 09:13:37 +0200 Subject: [PATCH 01/25] Add basic filter --- frontend/src/html/popups.html | 7 ++++++ frontend/src/ts/modals/quote-filter.ts | 32 ++++++++++++++++++++++++++ frontend/src/ts/modals/quote-search.ts | 30 +++++++++++++++++++----- 3 files changed, 63 insertions(+), 6 deletions(-) create mode 100644 frontend/src/ts/modals/quote-filter.ts diff --git a/frontend/src/html/popups.html b/frontend/src/html/popups.html index 2b51f5751973..8e98fdd2101b 100644 --- a/frontend/src/html/popups.html +++ b/frontend/src/html/popups.html @@ -944,6 +944,13 @@ + + + Enter filter length + + submit + + Submit a quote diff --git a/frontend/src/ts/modals/quote-filter.ts b/frontend/src/ts/modals/quote-filter.ts new file mode 100644 index 000000000000..36a5cf1ac91c --- /dev/null +++ b/frontend/src/ts/modals/quote-filter.ts @@ -0,0 +1,32 @@ +import AnimatedModal from "../utils/animated-modal"; + +export let filterLength = 0; + +function handleLengthFilter(customFilterLength: number): void { + filterLength = customFilterLength; +} + +export function show(): void { + void modal.show(); +} + +function hide(clearModalChain: boolean): void { + void modal.hide({ + clearModalChain, + }); +} + +async function setup(modalEl: HTMLElement): Promise { + let submitButton = modalEl.querySelector("button"); + submitButton?.addEventListener("click", () => { + let inputEl = modalEl.querySelector(".filterLength") as HTMLInputElement; + let customFilterLength = +inputEl.value; + handleLengthFilter(customFilterLength); + hide(true); + }); +} + +const modal = new AnimatedModal({ + dialogId: "quoteFilterModal", + setup, +}); diff --git a/frontend/src/ts/modals/quote-search.ts b/frontend/src/ts/modals/quote-search.ts index 1d2c15df679d..cc442f3a93c1 100644 --- a/frontend/src/ts/modals/quote-search.ts +++ b/frontend/src/ts/modals/quote-search.ts @@ -4,6 +4,7 @@ import * as ManualRestart from "../test/manual-restart-tracker"; import * as Notifications from "../elements/notifications"; import * as QuoteSubmitPopup from "./quote-submit"; import * as QuoteApprovePopup from "./quote-approve"; +import * as QuoteFilterPopup from "./quote-filter"; import * as QuoteReportModal from "./quote-report"; import { buildSearchService, @@ -52,12 +53,25 @@ function applyQuoteLengthFilter(quotes: Quote[]): Quote[] { return quotes; } - const quoteLengthFilter = new Set( - quoteLengthFilterValue.map((filterValue) => parseInt(filterValue, 10)) - ); - const filteredQuotes = quotes.filter((quote) => - quoteLengthFilter.has(quote.group) - ); + let filterLength = QuoteFilterPopup.filterLength; + + if (quoteLengthFilterValue.includes("4")) { + QuoteFilterPopup.show(); + } else { + filterLength = 0; + } + + let filteredQuotes = quotes; + if (filterLength > 0) { + filteredQuotes = quotes.filter((quote) => quote.length <= filterLength); + } else { + const quoteLengthFilter = new Set( + quoteLengthFilterValue.map((filterValue) => parseInt(filterValue, 10)) + ); + filteredQuotes = quotes.filter((quote) => + quoteLengthFilter.has(quote.group) + ); + } return filteredQuotes; } @@ -281,6 +295,10 @@ export async function show(showOptions?: ShowOptions): Promise { text: "thicc", value: "3", }, + { + text: "custom", + value: "4", + }, ], }); }, From d7afb5aa38132bfc14c691036a9719400114b150 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Sat, 15 Nov 2025 11:30:13 +0200 Subject: [PATCH 02/25] Add refresh button --- frontend/src/html/popups.html | 4 ++++ frontend/src/ts/modals/quote-search.ts | 14 +++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/frontend/src/html/popups.html b/frontend/src/html/popups.html index 8e98fdd2101b..ffa88959aab2 100644 --- a/frontend/src/html/popups.html +++ b/frontend/src/html/popups.html @@ -915,6 +915,10 @@ Approve quotes + + + Refresh quotes + diff --git a/frontend/src/ts/modals/quote-search.ts b/frontend/src/ts/modals/quote-search.ts index cc442f3a93c1..829a0bad9667 100644 --- a/frontend/src/ts/modals/quote-search.ts +++ b/frontend/src/ts/modals/quote-search.ts @@ -27,6 +27,7 @@ const searchServiceCache: Record> = {}; const pageSize = 100; let currentPageNumber = 1; +let usingCustomLength = false; function getSearchService( language: string, @@ -56,7 +57,9 @@ function applyQuoteLengthFilter(quotes: Quote[]): Quote[] { let filterLength = QuoteFilterPopup.filterLength; if (quoteLengthFilterValue.includes("4")) { - QuoteFilterPopup.show(); + if (usingCustomLength) { + QuoteFilterPopup.show(); + } } else { filterLength = 0; } @@ -342,6 +345,7 @@ const searchForQuotes = debounce(250, (): void => { const searchText = (document.getElementById("searchBox") as HTMLInputElement) .value; currentPageNumber = 1; + usingCustomLength = true; void updateResults(searchText); }); @@ -455,6 +459,14 @@ async function setup(modalEl: HTMLElement): Promise { currentPageNumber--; void updateResults(searchText); }); + + modalEl.querySelector(".refreshQuotes")?.addEventListener("click", () => { + const searchText = ( + document.getElementById("searchBox") as HTMLInputElement + ).value; + usingCustomLength = false; + void updateResults(searchText); + }); } async function cleanup(): Promise { From e8e43011ba6457472a34ef70b2b089f5b92d50b9 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Sat, 15 Nov 2025 11:42:08 +0200 Subject: [PATCH 03/25] Refresh automatically --- frontend/src/ts/modals/quote-filter.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frontend/src/ts/modals/quote-filter.ts b/frontend/src/ts/modals/quote-filter.ts index 36a5cf1ac91c..e9fb3b969df7 100644 --- a/frontend/src/ts/modals/quote-filter.ts +++ b/frontend/src/ts/modals/quote-filter.ts @@ -23,6 +23,10 @@ async function setup(modalEl: HTMLElement): Promise { let customFilterLength = +inputEl.value; handleLengthFilter(customFilterLength); hide(true); + let refreshButton = document.querySelector( + ".refreshQuotes" + ) as HTMLButtonElement; + refreshButton.click(); }); } From 5e22606d3491e7f0a82b5f9b12ab9aad70133e6a Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Sat, 15 Nov 2025 12:35:07 +0200 Subject: [PATCH 04/25] Add min and max --- frontend/src/html/popups.html | 6 ++++-- frontend/src/ts/modals/quote-filter.ts | 14 ++++++-------- frontend/src/ts/modals/quote-search.ts | 13 +++++++++---- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/frontend/src/html/popups.html b/frontend/src/html/popups.html index ffa88959aab2..65d9f7f3e9ed 100644 --- a/frontend/src/html/popups.html +++ b/frontend/src/html/popups.html @@ -950,8 +950,10 @@ - Enter filter length - + Enter minimum length + + Enter maximum length + submit diff --git a/frontend/src/ts/modals/quote-filter.ts b/frontend/src/ts/modals/quote-filter.ts index e9fb3b969df7..9873f0814626 100644 --- a/frontend/src/ts/modals/quote-filter.ts +++ b/frontend/src/ts/modals/quote-filter.ts @@ -1,10 +1,7 @@ import AnimatedModal from "../utils/animated-modal"; -export let filterLength = 0; - -function handleLengthFilter(customFilterLength: number): void { - filterLength = customFilterLength; -} +export let minFilterLength: number = 0; +export let maxFilterLength: number = 0; export function show(): void { void modal.show(); @@ -19,9 +16,10 @@ function hide(clearModalChain: boolean): void { async function setup(modalEl: HTMLElement): Promise { let submitButton = modalEl.querySelector("button"); submitButton?.addEventListener("click", () => { - let inputEl = modalEl.querySelector(".filterLength") as HTMLInputElement; - let customFilterLength = +inputEl.value; - handleLengthFilter(customFilterLength); + let minEl = modalEl.querySelector(".minFilterLength") as HTMLInputElement; + let maxEl = modalEl.querySelector(".maxFilterLength") as HTMLInputElement; + minFilterLength = +minEl?.value; + maxFilterLength = +maxEl?.value; hide(true); let refreshButton = document.querySelector( ".refreshQuotes" diff --git a/frontend/src/ts/modals/quote-search.ts b/frontend/src/ts/modals/quote-search.ts index 829a0bad9667..99f30da55e44 100644 --- a/frontend/src/ts/modals/quote-search.ts +++ b/frontend/src/ts/modals/quote-search.ts @@ -54,19 +54,24 @@ function applyQuoteLengthFilter(quotes: Quote[]): Quote[] { return quotes; } - let filterLength = QuoteFilterPopup.filterLength; + let minFilterLength = QuoteFilterPopup.minFilterLength; + let maxFilterLength = QuoteFilterPopup.maxFilterLength; if (quoteLengthFilterValue.includes("4")) { if (usingCustomLength) { QuoteFilterPopup.show(); } } else { - filterLength = 0; + minFilterLength = 0; + maxFilterLength = 0; } let filteredQuotes = quotes; - if (filterLength > 0) { - filteredQuotes = quotes.filter((quote) => quote.length <= filterLength); + if (minFilterLength > 0) { + filteredQuotes = quotes.filter( + (quote) => + quote.length >= minFilterLength && quote.length <= maxFilterLength + ); } else { const quoteLengthFilter = new Set( quoteLengthFilterValue.map((filterValue) => parseInt(filterValue, 10)) From 52fd99dbc5df5e35e9ce187768449c55ab6efdd3 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Sat, 15 Nov 2025 12:40:45 +0200 Subject: [PATCH 05/25] refactor --- frontend/src/ts/modals/quote-filter.ts | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/frontend/src/ts/modals/quote-filter.ts b/frontend/src/ts/modals/quote-filter.ts index 9873f0814626..e9e91cc26f88 100644 --- a/frontend/src/ts/modals/quote-filter.ts +++ b/frontend/src/ts/modals/quote-filter.ts @@ -3,6 +3,13 @@ import AnimatedModal from "../utils/animated-modal"; export let minFilterLength: number = 0; export let maxFilterLength: number = 0; +function handleFilterLength(modalEl: HTMLElement): void { + let minEl = modalEl.querySelector(".minFilterLength") as HTMLInputElement; + let maxEl = modalEl.querySelector(".maxFilterLength") as HTMLInputElement; + minFilterLength = +minEl?.value; + maxFilterLength = +maxEl?.value; +} + export function show(): void { void modal.show(); } @@ -16,19 +23,20 @@ function hide(clearModalChain: boolean): void { async function setup(modalEl: HTMLElement): Promise { let submitButton = modalEl.querySelector("button"); submitButton?.addEventListener("click", () => { - let minEl = modalEl.querySelector(".minFilterLength") as HTMLInputElement; - let maxEl = modalEl.querySelector(".maxFilterLength") as HTMLInputElement; - minFilterLength = +minEl?.value; - maxFilterLength = +maxEl?.value; + handleFilterLength(modalEl); hide(true); - let refreshButton = document.querySelector( - ".refreshQuotes" - ) as HTMLButtonElement; - refreshButton.click(); }); } +async function cleanup(): Promise { + let refreshButton = document.querySelector( + ".refreshQuotes" + ) as HTMLButtonElement; + refreshButton.click(); +} + const modal = new AnimatedModal({ dialogId: "quoteFilterModal", setup, + cleanup, }); From 02754cdb126b20dace035948cf3e767da0cea992 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Sat, 15 Nov 2025 12:42:34 +0200 Subject: [PATCH 06/25] Remove unnecessary parameter --- frontend/src/ts/modals/quote-filter.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/frontend/src/ts/modals/quote-filter.ts b/frontend/src/ts/modals/quote-filter.ts index e9e91cc26f88..553f26938847 100644 --- a/frontend/src/ts/modals/quote-filter.ts +++ b/frontend/src/ts/modals/quote-filter.ts @@ -14,17 +14,15 @@ export function show(): void { void modal.show(); } -function hide(clearModalChain: boolean): void { - void modal.hide({ - clearModalChain, - }); +function hide(): void { + void modal.hide(); } async function setup(modalEl: HTMLElement): Promise { let submitButton = modalEl.querySelector("button"); submitButton?.addEventListener("click", () => { handleFilterLength(modalEl); - hide(true); + hide(); }); } From b40f0c320d3fc1cb5e08ebe30b3486dc7ffc4269 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Sat, 15 Nov 2025 12:47:31 +0200 Subject: [PATCH 07/25] Ignore custom when others are present --- frontend/src/ts/modals/quote-search.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/frontend/src/ts/modals/quote-search.ts b/frontend/src/ts/modals/quote-search.ts index 99f30da55e44..f7cfeb1cbe2b 100644 --- a/frontend/src/ts/modals/quote-search.ts +++ b/frontend/src/ts/modals/quote-search.ts @@ -57,13 +57,17 @@ function applyQuoteLengthFilter(quotes: Quote[]): Quote[] { let minFilterLength = QuoteFilterPopup.minFilterLength; let maxFilterLength = QuoteFilterPopup.maxFilterLength; - if (quoteLengthFilterValue.includes("4")) { + if ( + quoteLengthFilterValue[0] === "4" && + quoteLengthFilterValue.length === 1 + ) { if (usingCustomLength) { QuoteFilterPopup.show(); } } else { minFilterLength = 0; maxFilterLength = 0; + usingCustomLength = false; } let filteredQuotes = quotes; From a9a3a0e9a3ad8b0252da8697b067b024d54475b2 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Sat, 15 Nov 2025 15:07:36 +0200 Subject: [PATCH 08/25] Don't show popup when removing other filters --- frontend/src/ts/modals/quote-search.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/ts/modals/quote-search.ts b/frontend/src/ts/modals/quote-search.ts index f7cfeb1cbe2b..5b15d868d1f7 100644 --- a/frontend/src/ts/modals/quote-search.ts +++ b/frontend/src/ts/modals/quote-search.ts @@ -51,6 +51,7 @@ function applyQuoteLengthFilter(quotes: Quote[]): Quote[] { "#quoteSearchModal .quoteLengthFilter" ).val() as string[]; if (quoteLengthFilterValue.length === 0) { + usingCustomLength = true; return quotes; } @@ -354,7 +355,6 @@ const searchForQuotes = debounce(250, (): void => { const searchText = (document.getElementById("searchBox") as HTMLInputElement) .value; currentPageNumber = 1; - usingCustomLength = true; void updateResults(searchText); }); From 7b7422466cde2097511937ac48dc4b7635bc0449 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Sat, 15 Nov 2025 15:15:33 +0200 Subject: [PATCH 09/25] Make popup show when first option isn't custom --- frontend/src/ts/modals/quote-search.ts | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/frontend/src/ts/modals/quote-search.ts b/frontend/src/ts/modals/quote-search.ts index 5b15d868d1f7..94aa891b9e90 100644 --- a/frontend/src/ts/modals/quote-search.ts +++ b/frontend/src/ts/modals/quote-search.ts @@ -27,7 +27,7 @@ const searchServiceCache: Record> = {}; const pageSize = 100; let currentPageNumber = 1; -let usingCustomLength = false; +let usingCustomLength = true; function getSearchService( language: string, @@ -58,21 +58,18 @@ function applyQuoteLengthFilter(quotes: Quote[]): Quote[] { let minFilterLength = QuoteFilterPopup.minFilterLength; let maxFilterLength = QuoteFilterPopup.maxFilterLength; - if ( - quoteLengthFilterValue[0] === "4" && - quoteLengthFilterValue.length === 1 - ) { + if (quoteLengthFilterValue.includes("4")) { if (usingCustomLength) { QuoteFilterPopup.show(); } } else { minFilterLength = 0; maxFilterLength = 0; - usingCustomLength = false; + usingCustomLength = true; } let filteredQuotes = quotes; - if (minFilterLength > 0) { + if (minFilterLength > 0 && quoteLengthFilterValue.length === 1) { filteredQuotes = quotes.filter( (quote) => quote.length >= minFilterLength && quote.length <= maxFilterLength From 076da52de6021517c0d711486a35fb17ac8d3126 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Sat, 15 Nov 2025 15:35:36 +0200 Subject: [PATCH 10/25] Make quotes change after each input change --- frontend/src/ts/modals/quote-filter.ts | 30 ++++++++++++++++---------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/frontend/src/ts/modals/quote-filter.ts b/frontend/src/ts/modals/quote-filter.ts index 553f26938847..5cdf2f86482a 100644 --- a/frontend/src/ts/modals/quote-filter.ts +++ b/frontend/src/ts/modals/quote-filter.ts @@ -3,11 +3,17 @@ import AnimatedModal from "../utils/animated-modal"; export let minFilterLength: number = 0; export let maxFilterLength: number = 0; -function handleFilterLength(modalEl: HTMLElement): void { - let minEl = modalEl.querySelector(".minFilterLength") as HTMLInputElement; - let maxEl = modalEl.querySelector(".maxFilterLength") as HTMLInputElement; +function handleFilterLength( + modalEl: HTMLElement, + minEl: HTMLInputElement, + maxEl: HTMLInputElement +): void { minFilterLength = +minEl?.value; maxFilterLength = +maxEl?.value; + let refreshButton = document.querySelector( + ".refreshQuotes" + ) as HTMLButtonElement; + refreshButton.click(); } export function show(): void { @@ -20,21 +26,23 @@ function hide(): void { async function setup(modalEl: HTMLElement): Promise { let submitButton = modalEl.querySelector("button"); + let minEl = modalEl.querySelector(".minFilterLength") as HTMLInputElement; + let maxEl = modalEl.querySelector(".maxFilterLength") as HTMLInputElement; submitButton?.addEventListener("click", () => { - handleFilterLength(modalEl); + handleFilterLength(modalEl, minEl, maxEl); hide(); }); -} -async function cleanup(): Promise { - let refreshButton = document.querySelector( - ".refreshQuotes" - ) as HTMLButtonElement; - refreshButton.click(); + minEl?.addEventListener("input", function () { + handleFilterLength(modalEl, minEl, maxEl); + }); + + maxEl?.addEventListener("input", () => { + handleFilterLength(modalEl, minEl, maxEl); + }); } const modal = new AnimatedModal({ dialogId: "quoteFilterModal", setup, - cleanup, }); From 6edba5f24cdfe112039382a86f077e44d147949b Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Sat, 15 Nov 2025 15:59:02 +0200 Subject: [PATCH 11/25] refactor --- frontend/src/ts/modals/quote-filter.ts | 10 ++++++++++ frontend/src/ts/modals/quote-search.ts | 7 +++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/frontend/src/ts/modals/quote-filter.ts b/frontend/src/ts/modals/quote-filter.ts index 5cdf2f86482a..2d5479b22f0f 100644 --- a/frontend/src/ts/modals/quote-filter.ts +++ b/frontend/src/ts/modals/quote-filter.ts @@ -2,6 +2,7 @@ import AnimatedModal from "../utils/animated-modal"; export let minFilterLength: number = 0; export let maxFilterLength: number = 0; +export let usingCustomLength = true; function handleFilterLength( modalEl: HTMLElement, @@ -16,6 +17,10 @@ function handleFilterLength( refreshButton.click(); } +export function setUsingCustomLength(value: boolean): void { + usingCustomLength = value; +} + export function show(): void { void modal.show(); } @@ -42,7 +47,12 @@ async function setup(modalEl: HTMLElement): Promise { }); } +async function cleanup(): Promise { + setUsingCustomLength(false); +} + const modal = new AnimatedModal({ dialogId: "quoteFilterModal", setup, + cleanup, }); diff --git a/frontend/src/ts/modals/quote-search.ts b/frontend/src/ts/modals/quote-search.ts index 94aa891b9e90..927822ed46d4 100644 --- a/frontend/src/ts/modals/quote-search.ts +++ b/frontend/src/ts/modals/quote-search.ts @@ -27,7 +27,6 @@ const searchServiceCache: Record> = {}; const pageSize = 100; let currentPageNumber = 1; -let usingCustomLength = true; function getSearchService( language: string, @@ -50,8 +49,10 @@ function applyQuoteLengthFilter(quotes: Quote[]): Quote[] { const quoteLengthFilterValue = $( "#quoteSearchModal .quoteLengthFilter" ).val() as string[]; + + let usingCustomLength = QuoteFilterPopup.usingCustomLength; if (quoteLengthFilterValue.length === 0) { - usingCustomLength = true; + QuoteFilterPopup.setUsingCustomLength(true); return quotes; } @@ -65,7 +66,6 @@ function applyQuoteLengthFilter(quotes: Quote[]): Quote[] { } else { minFilterLength = 0; maxFilterLength = 0; - usingCustomLength = true; } let filteredQuotes = quotes; @@ -470,7 +470,6 @@ async function setup(modalEl: HTMLElement): Promise { const searchText = ( document.getElementById("searchBox") as HTMLInputElement ).value; - usingCustomLength = false; void updateResults(searchText); }); } From 8c44ed35bd9292d4a6798284e511334aef0a44f0 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Sat, 15 Nov 2025 16:08:31 +0200 Subject: [PATCH 12/25] Allow min to be 0 --- frontend/src/ts/modals/quote-search.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/frontend/src/ts/modals/quote-search.ts b/frontend/src/ts/modals/quote-search.ts index 927822ed46d4..288faa535657 100644 --- a/frontend/src/ts/modals/quote-search.ts +++ b/frontend/src/ts/modals/quote-search.ts @@ -50,7 +50,6 @@ function applyQuoteLengthFilter(quotes: Quote[]): Quote[] { "#quoteSearchModal .quoteLengthFilter" ).val() as string[]; - let usingCustomLength = QuoteFilterPopup.usingCustomLength; if (quoteLengthFilterValue.length === 0) { QuoteFilterPopup.setUsingCustomLength(true); return quotes; @@ -60,8 +59,9 @@ function applyQuoteLengthFilter(quotes: Quote[]): Quote[] { let maxFilterLength = QuoteFilterPopup.maxFilterLength; if (quoteLengthFilterValue.includes("4")) { - if (usingCustomLength) { + if (QuoteFilterPopup.usingCustomLength) { QuoteFilterPopup.show(); + QuoteFilterPopup.setUsingCustomLength(false); } } else { minFilterLength = 0; @@ -69,7 +69,10 @@ function applyQuoteLengthFilter(quotes: Quote[]): Quote[] { } let filteredQuotes = quotes; - if (minFilterLength > 0 && quoteLengthFilterValue.length === 1) { + if ( + !QuoteFilterPopup.usingCustomLength && + quoteLengthFilterValue.length === 1 + ) { filteredQuotes = quotes.filter( (quote) => quote.length >= minFilterLength && quote.length <= maxFilterLength From 5c0889d64658e558e55fd6e7b3e584f40d14ad34 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Sat, 15 Nov 2025 16:12:48 +0200 Subject: [PATCH 13/25] Remove else block --- frontend/src/ts/modals/quote-search.ts | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/frontend/src/ts/modals/quote-search.ts b/frontend/src/ts/modals/quote-search.ts index 288faa535657..f2a7d87f0f9d 100644 --- a/frontend/src/ts/modals/quote-search.ts +++ b/frontend/src/ts/modals/quote-search.ts @@ -55,17 +55,11 @@ function applyQuoteLengthFilter(quotes: Quote[]): Quote[] { return quotes; } - let minFilterLength = QuoteFilterPopup.minFilterLength; - let maxFilterLength = QuoteFilterPopup.maxFilterLength; - if (quoteLengthFilterValue.includes("4")) { if (QuoteFilterPopup.usingCustomLength) { QuoteFilterPopup.show(); QuoteFilterPopup.setUsingCustomLength(false); } - } else { - minFilterLength = 0; - maxFilterLength = 0; } let filteredQuotes = quotes; @@ -75,7 +69,8 @@ function applyQuoteLengthFilter(quotes: Quote[]): Quote[] { ) { filteredQuotes = quotes.filter( (quote) => - quote.length >= minFilterLength && quote.length <= maxFilterLength + quote.length >= QuoteFilterPopup.minFilterLength && + quote.length <= QuoteFilterPopup.maxFilterLength ); } else { const quoteLengthFilter = new Set( From a2805ee006770952bad201acdbdf3fa505a50b7a Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Sat, 15 Nov 2025 16:54:33 +0200 Subject: [PATCH 14/25] Make custom work with other filters --- frontend/src/ts/modals/quote-search.ts | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/frontend/src/ts/modals/quote-search.ts b/frontend/src/ts/modals/quote-search.ts index f2a7d87f0f9d..c3b484ae0fd8 100644 --- a/frontend/src/ts/modals/quote-search.ts +++ b/frontend/src/ts/modals/quote-search.ts @@ -55,27 +55,25 @@ function applyQuoteLengthFilter(quotes: Quote[]): Quote[] { return quotes; } + let filteredQuotes = quotes; + const quoteLengthFilter = new Set( + quoteLengthFilterValue.map((filterValue) => parseInt(filterValue, 10)) + ); + if (quoteLengthFilterValue.includes("4")) { if (QuoteFilterPopup.usingCustomLength) { QuoteFilterPopup.show(); QuoteFilterPopup.setUsingCustomLength(false); } - } - let filteredQuotes = quotes; - if ( - !QuoteFilterPopup.usingCustomLength && - quoteLengthFilterValue.length === 1 - ) { filteredQuotes = quotes.filter( (quote) => - quote.length >= QuoteFilterPopup.minFilterLength && - quote.length <= QuoteFilterPopup.maxFilterLength + (quote.length >= QuoteFilterPopup.minFilterLength && + quote.length <= QuoteFilterPopup.maxFilterLength) || + quoteLengthFilter.has(quote.group) ); } else { - const quoteLengthFilter = new Set( - quoteLengthFilterValue.map((filterValue) => parseInt(filterValue, 10)) - ); + QuoteFilterPopup.setUsingCustomLength(true); filteredQuotes = quotes.filter((quote) => quoteLengthFilter.has(quote.group) ); From cec251e618ab63bd136cc28a9e49ed073ee791f3 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Sat, 15 Nov 2025 17:53:52 +0200 Subject: [PATCH 15/25] convert to simple modal --- frontend/src/ts/modals/quote-filter.ts | 76 ++++++++++++-------------- frontend/src/ts/modals/quote-search.ts | 2 +- 2 files changed, 35 insertions(+), 43 deletions(-) diff --git a/frontend/src/ts/modals/quote-filter.ts b/frontend/src/ts/modals/quote-filter.ts index 2d5479b22f0f..3ef183ce0a2f 100644 --- a/frontend/src/ts/modals/quote-filter.ts +++ b/frontend/src/ts/modals/quote-filter.ts @@ -1,16 +1,10 @@ -import AnimatedModal from "../utils/animated-modal"; +import { SimpleModal } from "../utils/simple-modal"; export let minFilterLength: number = 0; export let maxFilterLength: number = 0; export let usingCustomLength = true; -function handleFilterLength( - modalEl: HTMLElement, - minEl: HTMLInputElement, - maxEl: HTMLInputElement -): void { - minFilterLength = +minEl?.value; - maxFilterLength = +maxEl?.value; +function refresh(): void { let refreshButton = document.querySelector( ".refreshQuotes" ) as HTMLButtonElement; @@ -21,38 +15,36 @@ export function setUsingCustomLength(value: boolean): void { usingCustomLength = value; } -export function show(): void { - void modal.show(); -} - -function hide(): void { - void modal.hide(); -} - -async function setup(modalEl: HTMLElement): Promise { - let submitButton = modalEl.querySelector("button"); - let minEl = modalEl.querySelector(".minFilterLength") as HTMLInputElement; - let maxEl = modalEl.querySelector(".maxFilterLength") as HTMLInputElement; - submitButton?.addEventListener("click", () => { - handleFilterLength(modalEl, minEl, maxEl); - hide(); - }); - - minEl?.addEventListener("input", function () { - handleFilterLength(modalEl, minEl, maxEl); - }); - - maxEl?.addEventListener("input", () => { - handleFilterLength(modalEl, minEl, maxEl); - }); -} - -async function cleanup(): Promise { - setUsingCustomLength(false); -} - -const modal = new AnimatedModal({ - dialogId: "quoteFilterModal", - setup, - cleanup, +export const quoteFilterModal = new SimpleModal({ + id: "quoteFilter", + title: "Enter minimum and maximum values", + inputs: [ + { + placeholder: "1", + type: "number", + }, + { + placeholder: "100", + type: "number", + }, + ], + buttonText: "save", + onlineOnly: true, + execFn: async (_thisPopup, min, max) => { + const minNum = parseInt(min, 10); + const maxNum = parseInt(max, 10); + if (isNaN(minNum) || isNaN(maxNum)) { + return { + status: 0, + message: "Invalid min/max values", + }; + } + + minFilterLength = minNum; + maxFilterLength = maxNum; + refresh(); + + let message: string = "saved custom filter"; + return { status: 1, message }; + }, }); diff --git a/frontend/src/ts/modals/quote-search.ts b/frontend/src/ts/modals/quote-search.ts index c3b484ae0fd8..56b94a6378bd 100644 --- a/frontend/src/ts/modals/quote-search.ts +++ b/frontend/src/ts/modals/quote-search.ts @@ -62,7 +62,7 @@ function applyQuoteLengthFilter(quotes: Quote[]): Quote[] { if (quoteLengthFilterValue.includes("4")) { if (QuoteFilterPopup.usingCustomLength) { - QuoteFilterPopup.show(); + QuoteFilterPopup.quoteFilterModal.show(undefined, {}); QuoteFilterPopup.setUsingCustomLength(false); } From 5778104d9320810f4b896ae4025bebdb7d7b3a87 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Sat, 15 Nov 2025 17:57:27 +0200 Subject: [PATCH 16/25] Move usingCustomLength to quote-search --- frontend/src/ts/modals/quote-filter.ts | 5 ----- frontend/src/ts/modals/quote-search.ts | 9 +++++---- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/frontend/src/ts/modals/quote-filter.ts b/frontend/src/ts/modals/quote-filter.ts index 3ef183ce0a2f..11df98fd4fec 100644 --- a/frontend/src/ts/modals/quote-filter.ts +++ b/frontend/src/ts/modals/quote-filter.ts @@ -2,7 +2,6 @@ import { SimpleModal } from "../utils/simple-modal"; export let minFilterLength: number = 0; export let maxFilterLength: number = 0; -export let usingCustomLength = true; function refresh(): void { let refreshButton = document.querySelector( @@ -11,10 +10,6 @@ function refresh(): void { refreshButton.click(); } -export function setUsingCustomLength(value: boolean): void { - usingCustomLength = value; -} - export const quoteFilterModal = new SimpleModal({ id: "quoteFilter", title: "Enter minimum and maximum values", diff --git a/frontend/src/ts/modals/quote-search.ts b/frontend/src/ts/modals/quote-search.ts index 56b94a6378bd..d1b215a36d27 100644 --- a/frontend/src/ts/modals/quote-search.ts +++ b/frontend/src/ts/modals/quote-search.ts @@ -27,6 +27,7 @@ const searchServiceCache: Record> = {}; const pageSize = 100; let currentPageNumber = 1; +let usingCustomLength = true; function getSearchService( language: string, @@ -51,7 +52,7 @@ function applyQuoteLengthFilter(quotes: Quote[]): Quote[] { ).val() as string[]; if (quoteLengthFilterValue.length === 0) { - QuoteFilterPopup.setUsingCustomLength(true); + usingCustomLength = true; return quotes; } @@ -61,9 +62,9 @@ function applyQuoteLengthFilter(quotes: Quote[]): Quote[] { ); if (quoteLengthFilterValue.includes("4")) { - if (QuoteFilterPopup.usingCustomLength) { + if (usingCustomLength) { QuoteFilterPopup.quoteFilterModal.show(undefined, {}); - QuoteFilterPopup.setUsingCustomLength(false); + usingCustomLength = false; } filteredQuotes = quotes.filter( @@ -73,7 +74,7 @@ function applyQuoteLengthFilter(quotes: Quote[]): Quote[] { quoteLengthFilter.has(quote.group) ); } else { - QuoteFilterPopup.setUsingCustomLength(true); + usingCustomLength = true; filteredQuotes = quotes.filter((quote) => quoteLengthFilter.has(quote.group) ); From 96eb8ea26980285b6073bdc3ddcdcf3aca2e2053 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Sat, 15 Nov 2025 18:00:33 +0200 Subject: [PATCH 17/25] Remove old modal --- frontend/src/html/popups.html | 9 --------- 1 file changed, 9 deletions(-) diff --git a/frontend/src/html/popups.html b/frontend/src/html/popups.html index 65d9f7f3e9ed..74f3aeda5222 100644 --- a/frontend/src/html/popups.html +++ b/frontend/src/html/popups.html @@ -948,15 +948,6 @@ - - - Enter minimum length - - Enter maximum length - - submit - - Submit a quote From 986dfd54e238cbce4e651e6ea6ab3aee83c3e295 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Sat, 15 Nov 2025 18:27:22 +0200 Subject: [PATCH 18/25] Remove onlineOnly --- frontend/src/ts/modals/quote-filter.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/ts/modals/quote-filter.ts b/frontend/src/ts/modals/quote-filter.ts index 11df98fd4fec..dc4992b1f534 100644 --- a/frontend/src/ts/modals/quote-filter.ts +++ b/frontend/src/ts/modals/quote-filter.ts @@ -24,7 +24,6 @@ export const quoteFilterModal = new SimpleModal({ }, ], buttonText: "save", - onlineOnly: true, execFn: async (_thisPopup, min, max) => { const minNum = parseInt(min, 10); const maxNum = parseInt(max, 10); From 3e4cbbe2297c9b84b25f4d34066fb4c564f5aec3 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Thu, 27 Nov 2025 17:24:57 +0200 Subject: [PATCH 19/25] Remove refresh button --- frontend/src/html/popups.html | 4 ---- frontend/src/ts/modals/quote-filter.ts | 6 ++---- frontend/src/ts/modals/quote-search.ts | 2 +- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/frontend/src/html/popups.html b/frontend/src/html/popups.html index 74f3aeda5222..2b51f5751973 100644 --- a/frontend/src/html/popups.html +++ b/frontend/src/html/popups.html @@ -915,10 +915,6 @@ Approve quotes - - - Refresh quotes - diff --git a/frontend/src/ts/modals/quote-filter.ts b/frontend/src/ts/modals/quote-filter.ts index dc4992b1f534..d86d5693bce7 100644 --- a/frontend/src/ts/modals/quote-filter.ts +++ b/frontend/src/ts/modals/quote-filter.ts @@ -4,10 +4,8 @@ export let minFilterLength: number = 0; export let maxFilterLength: number = 0; function refresh(): void { - let refreshButton = document.querySelector( - ".refreshQuotes" - ) as HTMLButtonElement; - refreshButton.click(); + const refreshEvent = new CustomEvent("refresh"); + document.dispatchEvent(refreshEvent); } export const quoteFilterModal = new SimpleModal({ diff --git a/frontend/src/ts/modals/quote-search.ts b/frontend/src/ts/modals/quote-search.ts index d1b215a36d27..e0baf4b97ce4 100644 --- a/frontend/src/ts/modals/quote-search.ts +++ b/frontend/src/ts/modals/quote-search.ts @@ -463,7 +463,7 @@ async function setup(modalEl: HTMLElement): Promise { void updateResults(searchText); }); - modalEl.querySelector(".refreshQuotes")?.addEventListener("click", () => { + document?.addEventListener("refresh", () => { const searchText = ( document.getElementById("searchBox") as HTMLInputElement ).value; From 8ad9addbd9069cadee50f76f6fc0e3e934e6b94c Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Thu, 27 Nov 2025 17:52:49 +0200 Subject: [PATCH 20/25] prettier --- frontend/src/ts/modals/quote-search.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/ts/modals/quote-search.ts b/frontend/src/ts/modals/quote-search.ts index 87a5c2f7d6ee..888f3ec6fe27 100644 --- a/frontend/src/ts/modals/quote-search.ts +++ b/frontend/src/ts/modals/quote-search.ts @@ -71,7 +71,7 @@ function applyQuoteLengthFilter(quotes: Quote[]): Quote[] { (quote) => (quote.length >= QuoteFilterPopup.minFilterLength && quote.length <= QuoteFilterPopup.maxFilterLength) || - quoteLengthFilter.has(quote.group) + quoteLengthFilter.has(quote.group), ); } else { usingCustomLength = true; From 468fcf04b2e2a8a8061f41c67baeee7a4cb67d0e Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Thu, 27 Nov 2025 22:11:16 +0200 Subject: [PATCH 21/25] Force users to enter min and max values --- frontend/src/ts/modals/quote-filter.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/ts/modals/quote-filter.ts b/frontend/src/ts/modals/quote-filter.ts index d86d5693bce7..f7df4a076ee9 100644 --- a/frontend/src/ts/modals/quote-filter.ts +++ b/frontend/src/ts/modals/quote-filter.ts @@ -22,6 +22,7 @@ export const quoteFilterModal = new SimpleModal({ }, ], buttonText: "save", + hideCallsExec: true, execFn: async (_thisPopup, min, max) => { const minNum = parseInt(min, 10); const maxNum = parseInt(max, 10); From 25c276265acae1fa14137034dc357f33ee832e66 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 28 Nov 2025 08:40:56 +0200 Subject: [PATCH 22/25] Add afterClick function --- frontend/src/ts/modals/quote-filter.ts | 7 ++++- frontend/src/ts/modals/quote-search.ts | 41 +++++++++++++++----------- frontend/src/ts/utils/simple-modal.ts | 4 +++ 3 files changed, 34 insertions(+), 18 deletions(-) diff --git a/frontend/src/ts/modals/quote-filter.ts b/frontend/src/ts/modals/quote-filter.ts index f7df4a076ee9..419ef957cc96 100644 --- a/frontend/src/ts/modals/quote-filter.ts +++ b/frontend/src/ts/modals/quote-filter.ts @@ -2,6 +2,7 @@ import { SimpleModal } from "../utils/simple-modal"; export let minFilterLength: number = 0; export let maxFilterLength: number = 0; +export let removeCustom: boolean = false; function refresh(): void { const refreshEvent = new CustomEvent("refresh"); @@ -22,7 +23,6 @@ export const quoteFilterModal = new SimpleModal({ }, ], buttonText: "save", - hideCallsExec: true, execFn: async (_thisPopup, min, max) => { const minNum = parseInt(min, 10); const maxNum = parseInt(max, 10); @@ -40,4 +40,9 @@ export const quoteFilterModal = new SimpleModal({ let message: string = "saved custom filter"; return { status: 1, message }; }, + afterClickAway: () => { + removeCustom = true; + refresh(); + removeCustom = false; + }, }); diff --git a/frontend/src/ts/modals/quote-search.ts b/frontend/src/ts/modals/quote-search.ts index 888f3ec6fe27..b7f0ea15ea5b 100644 --- a/frontend/src/ts/modals/quote-search.ts +++ b/frontend/src/ts/modals/quote-search.ts @@ -56,30 +56,37 @@ function applyQuoteLengthFilter(quotes: Quote[]): Quote[] { return quotes; } - let filteredQuotes = quotes; const quoteLengthFilter = new Set( quoteLengthFilterValue.map((filterValue) => parseInt(filterValue, 10)), ); - if (quoteLengthFilterValue.includes("4")) { - if (usingCustomLength) { - QuoteFilterPopup.quoteFilterModal.show(undefined, {}); - usingCustomLength = false; - } + const customFilterIndex = quoteLengthFilterValue.indexOf("4"); - filteredQuotes = quotes.filter( - (quote) => - (quote.length >= QuoteFilterPopup.minFilterLength && - quote.length <= QuoteFilterPopup.maxFilterLength) || - quoteLengthFilter.has(quote.group), - ); - } else { - usingCustomLength = true; - filteredQuotes = quotes.filter((quote) => - quoteLengthFilter.has(quote.group), - ); + if (customFilterIndex !== -1) { + if (QuoteFilterPopup.removeCustom) { + quoteLengthFilterValue.splice(customFilterIndex, 1); + } else { + if (usingCustomLength) { + QuoteFilterPopup.quoteFilterModal.show(undefined, {}); + usingCustomLength = false; + } + + const filteredQuotes = quotes.filter( + (quote) => + (quote.length >= QuoteFilterPopup.minFilterLength && + quote.length <= QuoteFilterPopup.maxFilterLength) || + quoteLengthFilter.has(quote.group), + ); + + return filteredQuotes; + } } + usingCustomLength = true; + const filteredQuotes = quotes.filter((quote) => + quoteLengthFilter.has(quote.group), + ); + return filteredQuotes; } diff --git a/frontend/src/ts/utils/simple-modal.ts b/frontend/src/ts/utils/simple-modal.ts index b1452dadf3e2..63364467637a 100644 --- a/frontend/src/ts/utils/simple-modal.ts +++ b/frontend/src/ts/utils/simple-modal.ts @@ -111,6 +111,7 @@ type SimpleModalOptions = { onlineOnly?: boolean; hideCallsExec?: boolean; showLabels?: boolean; + afterClickAway?: () => void; }; export class SimpleModal { @@ -131,6 +132,7 @@ export class SimpleModal { onlineOnly: boolean; hideCallsExec: boolean; showLabels: boolean; + afterClickAway: (() => void) | undefined; constructor(options: SimpleModalOptions) { this.parameters = []; this.id = options.id; @@ -149,6 +151,7 @@ export class SimpleModal { this.onlineOnly = options.onlineOnly ?? false; this.hideCallsExec = options.hideCallsExec ?? false; this.showLabels = options.showLabels ?? false; + this.afterClickAway = options.afterClickAway; } reset(): void { this.element.innerHTML = ` @@ -480,6 +483,7 @@ const modal = new AnimatedModal({ hide(); }, customWrapperClickHandler: (e): void => { + activePopup?.afterClickAway?.(); hide(); }, }); From 186092d0f4de720899383e8f1f3fc54affd538a3 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 28 Nov 2025 14:43:47 +0200 Subject: [PATCH 23/25] Remove custom selection after clicking out of modal --- frontend/src/ts/modals/quote-filter.ts | 7 +++++-- frontend/src/ts/modals/quote-search.ts | 28 ++++++++++++++++++++++---- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/frontend/src/ts/modals/quote-filter.ts b/frontend/src/ts/modals/quote-filter.ts index 419ef957cc96..d83fccce564f 100644 --- a/frontend/src/ts/modals/quote-filter.ts +++ b/frontend/src/ts/modals/quote-filter.ts @@ -4,6 +4,10 @@ export let minFilterLength: number = 0; export let maxFilterLength: number = 0; export let removeCustom: boolean = false; +export function setRemoveCustom(value: boolean): void { + removeCustom = value; +} + function refresh(): void { const refreshEvent = new CustomEvent("refresh"); document.dispatchEvent(refreshEvent); @@ -41,8 +45,7 @@ export const quoteFilterModal = new SimpleModal({ return { status: 1, message }; }, afterClickAway: () => { - removeCustom = true; + setRemoveCustom(true); refresh(); - removeCustom = false; }, }); diff --git a/frontend/src/ts/modals/quote-search.ts b/frontend/src/ts/modals/quote-search.ts index b7f0ea15ea5b..ca240d7861a0 100644 --- a/frontend/src/ts/modals/quote-search.ts +++ b/frontend/src/ts/modals/quote-search.ts @@ -47,9 +47,8 @@ function getSearchService( function applyQuoteLengthFilter(quotes: Quote[]): Quote[] { if (!modal.isOpen()) return []; - const quoteLengthFilterValue = $( - "#quoteSearchModal .quoteLengthFilter", - ).val() as string[]; + const quoteLengthDropdown = $("#quoteSearchModal .quoteLengthFilter"); + const quoteLengthFilterValue = quoteLengthDropdown.val() as string[]; if (quoteLengthFilterValue.length === 0) { usingCustomLength = true; @@ -64,7 +63,28 @@ function applyQuoteLengthFilter(quotes: Quote[]): Quote[] { if (customFilterIndex !== -1) { if (QuoteFilterPopup.removeCustom) { - quoteLengthFilterValue.splice(customFilterIndex, 1); + QuoteFilterPopup.setRemoveCustom(false); + const selectElement = quoteLengthDropdown.get(0) as + | HTMLSelectElement + | null + | undefined; + + if (!selectElement) { + return quotes; + } + + //@ts-expect-error SlimSelect adds slim to the element + const ss = selectElement.slim as SlimSelect | undefined; + + if (ss !== undefined) { + const currentSelected = ss.getSelected(); + + // remove custom selection + const withoutCustom = currentSelected.filter( + (selection) => selection !== "4", + ); + ss.setSelected(withoutCustom); + } } else { if (usingCustomLength) { QuoteFilterPopup.quoteFilterModal.show(undefined, {}); From 463d6d15887ac6d0dc5c521f736b4c0f44543a5a Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 28 Nov 2025 14:48:04 +0200 Subject: [PATCH 24/25] Use splice --- frontend/src/ts/modals/quote-search.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/frontend/src/ts/modals/quote-search.ts b/frontend/src/ts/modals/quote-search.ts index ca240d7861a0..12c6b729ad17 100644 --- a/frontend/src/ts/modals/quote-search.ts +++ b/frontend/src/ts/modals/quote-search.ts @@ -80,10 +80,12 @@ function applyQuoteLengthFilter(quotes: Quote[]): Quote[] { const currentSelected = ss.getSelected(); // remove custom selection - const withoutCustom = currentSelected.filter( - (selection) => selection !== "4", - ); - ss.setSelected(withoutCustom); + const customIndex = currentSelected.indexOf("4"); + if (customIndex > -1) { + currentSelected.splice(customIndex, 1); + } + + ss.setSelected(currentSelected); } } else { if (usingCustomLength) { From ddc7a5ec7274d34575baa96744397b2d31f054a1 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 28 Nov 2025 14:56:26 +0200 Subject: [PATCH 25/25] Only update results after submission --- frontend/src/ts/modals/quote-search.ts | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/frontend/src/ts/modals/quote-search.ts b/frontend/src/ts/modals/quote-search.ts index 12c6b729ad17..33f371384681 100644 --- a/frontend/src/ts/modals/quote-search.ts +++ b/frontend/src/ts/modals/quote-search.ts @@ -91,20 +91,21 @@ function applyQuoteLengthFilter(quotes: Quote[]): Quote[] { if (usingCustomLength) { QuoteFilterPopup.quoteFilterModal.show(undefined, {}); usingCustomLength = false; - } - - const filteredQuotes = quotes.filter( - (quote) => - (quote.length >= QuoteFilterPopup.minFilterLength && - quote.length <= QuoteFilterPopup.maxFilterLength) || - quoteLengthFilter.has(quote.group), - ); + } else { + const filteredQuotes = quotes.filter( + (quote) => + (quote.length >= QuoteFilterPopup.minFilterLength && + quote.length <= QuoteFilterPopup.maxFilterLength) || + quoteLengthFilter.has(quote.group), + ); - return filteredQuotes; + return filteredQuotes; + } } + } else { + usingCustomLength = true; } - usingCustomLength = true; const filteredQuotes = quotes.filter((quote) => quoteLengthFilter.has(quote.group), );