Skip to content

refactor: solid quote modals (@miodec)#7700

Merged
Miodec merged 20 commits intomasterfrom
solid-quote-search
Mar 24, 2026
Merged

refactor: solid quote modals (@miodec)#7700
Miodec merged 20 commits intomasterfrom
solid-quote-search

Conversation

@Miodec
Copy link
Copy Markdown
Member

@Miodec Miodec commented Mar 22, 2026

No description provided.

Copilot AI review requested due to automatic review settings March 22, 2026 13:34
@monkeytypegeorge monkeytypegeorge added the frontend User interface or web stuff label Mar 22, 2026
@github-actions github-actions bot added the waiting for review Pull requests that require a review before continuing label Mar 22, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors the quote-related modals (search/rate/report/submit/approve) from legacy DOM-driven modal implementations to SolidJS modal components backed by centralized modal/state stores.

Changes:

  • Added SolidJS modal components for quote workflows and registered them in the global modals mount.
  • Introduced new Solid state modules for quote rating/reporting and rewired callers to use them.
  • Removed legacy quote modal TS modules + corresponding HTML dialog markup and SCSS styling; adjusted shared UI components (Button, SlimSelect) to support the new modal UX.

Reviewed changes

Copilot reviewed 24 out of 24 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
frontend/src/ts/test/test-logic.ts Switches quote-rate reset to new state module.
frontend/src/ts/test/result.ts Uses new getQuoteStats from quote-rate state.
frontend/src/ts/states/quote-report.ts New state + entrypoint to open QuoteReport modal.
frontend/src/ts/states/quote-rate.ts New state + API helpers for quote rating/stats and opening QuoteRate modal.
frontend/src/ts/states/modals.ts Extends ModalId union to include quote modal IDs.
frontend/src/ts/modals/quote-submit.ts Removes legacy quote submit modal implementation.
frontend/src/ts/modals/quote-search.ts Removes legacy quote search modal implementation.
frontend/src/ts/modals/quote-report.ts Removes legacy quote report modal implementation.
frontend/src/ts/modals/quote-rate.ts Removes legacy quote rate modal implementation.
frontend/src/ts/modals/quote-filter.ts Removes legacy quote filter modal implementation (replaced by SimpleModal usage).
frontend/src/ts/modals/quote-approve.ts Removes legacy quote approve modal implementation.
frontend/src/ts/modals/mobile-test-config.ts Opens new QuoteSearch modal from mobile test config.
frontend/src/ts/event-handlers/test.ts Rewires quote search/rate/report button handlers to new modal/state APIs.
frontend/src/ts/components/ui/SlimSelect.tsx Ensures SlimSelect dropdown renders within a local container (contentLocation).
frontend/src/ts/components/modals/QuoteSubmitModal.tsx New Solid QuoteSubmit modal.
frontend/src/ts/components/modals/QuoteSearchModal.tsx New Solid QuoteSearch modal (includes submit/approve modals).
frontend/src/ts/components/modals/QuoteReportModal.tsx New Solid QuoteReport modal.
frontend/src/ts/components/modals/QuoteRateModal.tsx New Solid QuoteRate modal.
frontend/src/ts/components/modals/QuoteApproveModal.tsx New Solid QuoteApprove modal.
frontend/src/ts/components/modals/Modals.tsx Mounts the new quote modal components.
frontend/src/ts/components/common/Button.tsx Updates event handler typings to receive the MouseEvent (enables stopPropagation usage).
frontend/src/ts/commandline/lists.ts Rewires quote search command to open new QuoteSearch modal.
frontend/src/styles/popups.scss Removes legacy quote modal styles.
frontend/src/html/popups.html Removes legacy quote modal dialog markup.

return;
}
void QuoteReportModal.show(TestWords.currentQuote?.id);
showQuoteReportModal(TestWords.currentQuote?.id);
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TestWords.currentQuote is already null-checked above, but optional chaining makes the arg type number | undefined, which fails under strictNullChecks and can break compilation. Pass TestWords.currentQuote.id (or change showQuoteReportModal to accept/guard undefined).

Suggested change
showQuoteReportModal(TestWords.currentQuote?.id);
showQuoteReportModal(TestWords.currentQuote.id);

Copilot uses AI. Check for mistakes.
@@ -126,9 +126,7 @@ async function setup(modalEl: ElementWithUtils): Promise<void> {
TestLogic.restart();
}
} else if (lenAttr === "-2") {
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This opens the new Solid modal via states/modals, but mobile-test-config is still a legacy utils/animated-modal dialog, so it won't be hidden/"chained" and you can end up with multiple dialogs open/stacked. Hide/close the legacy modal before showing QuoteSearch (or provide a bridge that restores the previous modal on close).

Suggested change
} else if (lenAttr === "-2") {
} else if (lenAttr === "-2") {
void modal.hide();

Copilot uses AI. Check for mistakes.
};

const applyQuote = (quoteId: number): void => {
if (isNaN(quoteId) || quoteId < 0) {
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Validation allows quoteId === 0 but the error text says "at least 1". This should reject 0 as well (and ideally align with the legacy behavior everywhere quote IDs are accepted).

Suggested change
if (isNaN(quoteId) || quoteId < 0) {
if (isNaN(quoteId) || quoteId < 1) {

Copilot uses AI. Check for mistakes.
Comment on lines +341 to +364
createEffect(
on(lengthFilter, (lengths) => {
if (lengths.includes("4") && !hasCustomFilter()) {
showSimpleModal({
title: "Enter minimum and maximum number of words",
inputs: [
{ type: "number", placeholder: "1" },
{ type: "number", placeholder: "100" },
],
buttonText: "save",
execFn: async (min: string, max: string) => {
const minNum = parseInt(min, 10);
const maxNum = parseInt(max, 10);
if (isNaN(minNum) || isNaN(maxNum)) {
return { status: "notice", message: "Invalid min/max values" };
}
setCustomFilterMin(minNum);
setCustomFilterMax(maxNum);
setHasCustomFilter(true);
return { status: "success", message: "Saved custom filter" };
},
});
}
}),
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the user selects the "custom" length filter, a SimpleModal is shown, but there's no handling for dismiss/backdrop/escape. If the modal is closed without saving, lengthFilter can keep "4" selected while hasCustomFilter stays false, so the UI shows custom selected but it has no effect. Consider clearing "custom" from lengthFilter on cancel/dismiss, or track a pending custom config and only add "4" after successful save.

Copilot uses AI. Check for mistakes.
Comment on lines +43 to +54
const handleBeforeShow = (): void => {
const quote = currentQuote();
if (!quote) return;
setRating(0);
setHoverRating(0);
const snapshot = DB.getSnapshot();
const alreadyRated = snapshot?.quoteRatings?.[quote.language]?.[quote.id];
if (isSafeNumber(alreadyRated)) {
setRating(alreadyRated);
}
void getQuoteStats(quote);
};
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getQuoteStats(quote) is fired-and-forgotten. If the user submits quickly (esp. when updating an existing rating), quoteStats() may still be null/{}, causing incorrect ratings/totalRating/average calculations and displaying "0" ratings. Consider awaiting the fetch in beforeShow, or disabling submit until stats are loaded (or ensure the submit path fetches stats if missing).

Copilot uses AI. Check for mistakes.
@github-actions github-actions bot removed the waiting for review Pull requests that require a review before continuing label Mar 24, 2026
setDisabled(true);

showLoaderBar();
const response = await Ape.quotes.approveSubmission({
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could use tanstack query and mutate around the api calls. this would centralize the error handling and we can show the loader bar just based on query/mutation in progress instead of manually setting show/hide loaderBar.

fehmer
fehmer previously approved these changes Mar 24, 2026
@Miodec Miodec merged commit 37d8846 into master Mar 24, 2026
16 checks passed
@Miodec Miodec deleted the solid-quote-search branch March 24, 2026 11:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

frontend User interface or web stuff

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants