Skip to content

refactor: solid quote modals (@miodec)#7700

Open
Miodec wants to merge 15 commits intomasterfrom
solid-quote-search
Open

refactor: solid quote modals (@miodec)#7700
Miodec wants to merge 15 commits intomasterfrom
solid-quote-search

Conversation

@Miodec
Copy link
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
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.
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 waiting for review Pull requests that require a review before continuing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants