From 2f00391a84b3375d13aa6d5a03221d6b99515c9d Mon Sep 17 00:00:00 2001 From: Christian Fehmer Date: Tue, 5 May 2026 09:25:58 +0200 Subject: [PATCH 1/5] refactor(account): solid results, tags, account page, filter presets (@fehmer, @miodec) (#7854) Migrates - account page - results - filter presets - tags --------- Co-authored-by: Miodec --- backend/src/utils/result.ts | 9 + .../pages/account/utils.spec.ts} | 6 +- .../controllers/preset-controller.spec.ts | 55 +- frontend/package.json | 20 +- frontend/src/html/pages/account.html | 428 ---- frontend/src/html/popups.html | 6 - frontend/src/index.html | 5 +- frontend/src/styles/account.scss | 612 ------ frontend/src/styles/index.scss | 2 +- frontend/src/styles/media-queries-blue.scss | 38 - frontend/src/styles/media-queries-brown.scss | 8 - frontend/src/styles/media-queries-green.scss | 43 - frontend/src/styles/media-queries-purple.scss | 41 - frontend/src/styles/media-queries-yellow.scss | 9 +- frontend/src/styles/popups.scss | 10 - frontend/src/styles/test-activity.scss | 205 ++ frontend/src/ts/auth.tsx | 4 +- .../ts/collections/result-filter-presets.ts | 130 ++ frontend/src/ts/collections/results.ts | 610 ++++++ frontend/src/ts/collections/tags.ts | 488 +++++ frontend/src/ts/collections/utils/misc.ts | 5 + frontend/src/ts/commandline/lists/tags.ts | 40 +- .../ts/components/common/Advertisement.tsx | 36 + .../ts/components/common/AnimatedModal.tsx | 9 +- frontend/src/ts/components/common/Kbd.tsx | 6 +- frontend/src/ts/components/mount.tsx | 2 + .../src/ts/components/pages/AboutPage.tsx | 47 +- .../components/pages/account/AccountPage.tsx | 140 ++ .../ts/components/pages/account/Charts.tsx | 140 ++ .../pages/account/DailyActivityChart.tsx | 184 ++ .../ts/components/pages/account/Filters.tsx | 465 +++++ .../pages/account/HistogramChart.tsx | 109 + .../components/pages/account/HistoryChart.tsx | 406 ++++ .../pages/account/MiniResultChart.tsx | 155 ++ .../src/ts/components/pages/account/Table.tsx | 302 +++ .../ts/components/pages/account/TestStats.tsx | 185 ++ .../components/pages/account/VerifyNotice.tsx | 36 + .../src/ts/components/pages/account/utils.ts | 42 + .../src/ts/components/ui/table/DataTable.tsx | 22 +- frontend/src/ts/components/ui/table/Table.tsx | 8 +- frontend/src/ts/constants/default-snapshot.ts | 24 +- .../src/ts/controllers/chart-controller.ts | 842 +------- .../src/ts/controllers/page-controller.ts | 33 +- .../src/ts/controllers/preset-controller.ts | 14 +- frontend/src/ts/controllers/tag-controller.ts | 84 - frontend/src/ts/db.ts | 547 +---- .../src/ts/elements/account/result-filters.ts | 969 --------- frontend/src/ts/elements/last-10-average.ts | 16 +- frontend/src/ts/elements/modes-notice.ts | 7 +- frontend/src/ts/elements/result-batches.ts | 4 +- frontend/src/ts/elements/simple-modal.ts | 7 +- frontend/src/ts/event-handlers/account.ts | 60 - frontend/src/ts/event-handlers/settings.ts | 48 +- frontend/src/ts/event-handlers/test.ts | 4 +- frontend/src/ts/firebase.ts | 23 +- frontend/src/ts/index.ts | 3 - frontend/src/ts/modals/edit-preset.ts | 7 +- frontend/src/ts/modals/edit-result-tags.ts | 75 +- frontend/src/ts/modals/edit-tag.ts | 115 +- frontend/src/ts/modals/mini-result-chart.ts | 49 - frontend/src/ts/modals/new-filter-preset.ts | 45 - frontend/src/ts/pages/account.ts | 1246 ----------- frontend/src/ts/pages/settings.ts | 22 +- frontend/src/ts/states/core.ts | 1 + frontend/src/ts/states/modals.ts | 3 +- frontend/src/ts/states/result-filters.ts | 44 + frontend/src/ts/states/snapshot.ts | 2 +- frontend/src/ts/test/pace-caret.ts | 26 +- frontend/src/ts/test/result.ts | 35 +- frontend/src/ts/test/test-logic.ts | 10 +- frontend/src/ts/test/test-screenshot.ts | 1 + frontend/src/ts/test/today-tracker.ts | 10 +- .../src/ts/utils/local-storage-with-schema.ts | 4 +- frontend/src/ts/utils/strings.ts | 10 +- frontend/src/ts/utils/types.ts | 15 + frontend/src/ts/utils/typing-speed-units.ts | 2 +- frontend/static/contributors.json | 2 +- packages/schemas/src/users.ts | 5 +- pnpm-lock.yaml | 1831 +++++++++++++---- 79 files changed, 5413 insertions(+), 5900 deletions(-) rename frontend/__tests__/{elements/account/result-filters.spec.ts => components/pages/account/utils.spec.ts} (88%) delete mode 100644 frontend/src/html/pages/account.html delete mode 100644 frontend/src/styles/account.scss create mode 100644 frontend/src/styles/test-activity.scss create mode 100644 frontend/src/ts/collections/result-filter-presets.ts create mode 100644 frontend/src/ts/collections/results.ts create mode 100644 frontend/src/ts/collections/tags.ts create mode 100644 frontend/src/ts/collections/utils/misc.ts create mode 100644 frontend/src/ts/components/common/Advertisement.tsx create mode 100644 frontend/src/ts/components/pages/account/AccountPage.tsx create mode 100644 frontend/src/ts/components/pages/account/Charts.tsx create mode 100644 frontend/src/ts/components/pages/account/DailyActivityChart.tsx create mode 100644 frontend/src/ts/components/pages/account/Filters.tsx create mode 100644 frontend/src/ts/components/pages/account/HistogramChart.tsx create mode 100644 frontend/src/ts/components/pages/account/HistoryChart.tsx create mode 100644 frontend/src/ts/components/pages/account/MiniResultChart.tsx create mode 100644 frontend/src/ts/components/pages/account/Table.tsx create mode 100644 frontend/src/ts/components/pages/account/TestStats.tsx create mode 100644 frontend/src/ts/components/pages/account/VerifyNotice.tsx create mode 100644 frontend/src/ts/components/pages/account/utils.ts delete mode 100644 frontend/src/ts/controllers/tag-controller.ts delete mode 100644 frontend/src/ts/elements/account/result-filters.ts delete mode 100644 frontend/src/ts/event-handlers/account.ts delete mode 100644 frontend/src/ts/modals/mini-result-chart.ts delete mode 100644 frontend/src/ts/modals/new-filter-preset.ts delete mode 100644 frontend/src/ts/pages/account.ts create mode 100644 frontend/src/ts/states/result-filters.ts create mode 100644 frontend/src/ts/utils/types.ts diff --git a/backend/src/utils/result.ts b/backend/src/utils/result.ts index 2c79813f8b22..2e99fe2e4e87 100644 --- a/backend/src/utils/result.ts +++ b/backend/src/utils/result.ts @@ -122,5 +122,14 @@ export function replaceLegacyValues(result: DBResult): DBResult { }; } + if (typeof result.mode2 === "number") { + result.mode2 = (result.mode2 as number).toString(); + } + + //legacy value for english_1k + if ((result.language as string) === "english_expanded") { + result.language = "english_1k"; + } + return result; } diff --git a/frontend/__tests__/elements/account/result-filters.spec.ts b/frontend/__tests__/components/pages/account/utils.spec.ts similarity index 88% rename from frontend/__tests__/elements/account/result-filters.spec.ts rename to frontend/__tests__/components/pages/account/utils.spec.ts index 3403dda6b256..9ab523def755 100644 --- a/frontend/__tests__/elements/account/result-filters.spec.ts +++ b/frontend/__tests__/components/pages/account/utils.spec.ts @@ -1,8 +1,8 @@ import { describe, it, expect } from "vitest"; -import defaultResultFilters from "../../../src/ts/constants/default-result-filters"; -import { mergeWithDefaultFilters } from "../../../src/ts/elements/account/result-filters"; +import defaultResultFilters from "../../../../src/ts/constants/default-result-filters"; +import { mergeWithDefaultFilters } from "../../../../src/ts/components/pages/account/utils"; -describe("result-filters.ts", () => { +describe("utils.ts", () => { describe("mergeWithDefaultFilters", () => { it("should merge with default filters correctly", () => { const tests = [ diff --git a/frontend/__tests__/controllers/preset-controller.spec.ts b/frontend/__tests__/controllers/preset-controller.spec.ts index baef3596b82f..816e9edab7e3 100644 --- a/frontend/__tests__/controllers/preset-controller.spec.ts +++ b/frontend/__tests__/controllers/preset-controller.spec.ts @@ -9,7 +9,7 @@ import * as ConfigUtils from "../../src/ts/config/utils"; import * as Persistence from "../../src/ts/config/persistence"; import * as Notifications from "../../src/ts/states/notifications"; import * as TestLogic from "../../src/ts/test/test-logic"; -import * as TagController from "../../src/ts/controllers/tag-controller"; +import * as Tags from "../../src/ts/collections/tags"; describe("PresetController", () => { describe("apply", () => { @@ -34,12 +34,9 @@ describe("PresetController", () => { "showSuccessNotification", ); const testRestartMock = vi.spyOn(TestLogic, "restart"); - const tagControllerClearMock = vi.spyOn(TagController, "clear"); - const tagControllerSetMock = vi.spyOn(TagController, "set"); - const tagControllerSaveActiveMock = vi.spyOn( - TagController, - "saveActiveToLocalStorage", - ); + const tagsClearMock = vi.spyOn(Tags, "clearActiveTags"); + const tagsSetMock = vi.spyOn(Tags, "setTagActive"); + const tagsSaveActiveMock = vi.spyOn(Tags, "saveActiveToLocalStorage"); beforeEach(() => { [ @@ -49,9 +46,9 @@ describe("PresetController", () => { configGetConfigChangesMock, notificationAddMock, testRestartMock, - tagControllerClearMock, - tagControllerSetMock, - tagControllerSaveActiveMock, + tagsClearMock, + tagsSetMock, + tagsSaveActiveMock, ].forEach((it) => it.mockClear()); configApplyMock.mockResolvedValue(); @@ -66,7 +63,7 @@ describe("PresetController", () => { //THEN expect(configApplyMock).toHaveBeenCalledWith(preset.config); - expect(tagControllerClearMock).toHaveBeenCalled(); + expect(tagsClearMock).toHaveBeenCalled(); expect(testRestartMock).toHaveBeenCalled(); expect(notificationAddMock).toHaveBeenCalledWith("Preset applied", { durationMs: 2000, @@ -84,20 +81,10 @@ describe("PresetController", () => { await PresetController.apply(preset._id); //THEN - expect(tagControllerClearMock).toHaveBeenCalled(); - expect(tagControllerSetMock).toHaveBeenNthCalledWith( - 1, - "tagOne", - true, - false, - ); - expect(tagControllerSetMock).toHaveBeenNthCalledWith( - 2, - "tagTwo", - true, - false, - ); - expect(tagControllerSaveActiveMock).toHaveBeenCalled(); + expect(tagsClearMock).toHaveBeenCalled(); + expect(tagsSetMock).toHaveBeenNthCalledWith(1, "tagOne", true, false); + expect(tagsSetMock).toHaveBeenNthCalledWith(2, "tagTwo", true, false); + expect(tagsSaveActiveMock).toHaveBeenCalled(); }); it("should ignore unknown preset", async () => { @@ -145,20 +132,10 @@ describe("PresetController", () => { await PresetController.apply(preset._id); //THEN - expect(tagControllerClearMock).toHaveBeenCalled(); - expect(tagControllerSetMock).toHaveBeenNthCalledWith( - 1, - "tagOne", - true, - false, - ); - expect(tagControllerSetMock).toHaveBeenNthCalledWith( - 2, - "tagTwo", - true, - false, - ); - expect(tagControllerSaveActiveMock).toHaveBeenCalled(); + expect(tagsClearMock).toHaveBeenCalled(); + expect(tagsSetMock).toHaveBeenNthCalledWith(1, "tagOne", true, false); + expect(tagsSetMock).toHaveBeenNthCalledWith(2, "tagTwo", true, false); + expect(tagsSaveActiveMock).toHaveBeenCalled(); }); const givenPreset = (partialPreset: Partial): Preset => { diff --git a/frontend/package.json b/frontend/package.json index 38af68dbf817..e90f7a3721c0 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -39,14 +39,14 @@ "@solid-primitives/transition-group": "1.1.2", "@solidjs/meta": "0.29.4", "@tanstack/pacer-lite": "0.2.1", - "@tanstack/query-db-collection": "1.0.27", - "@tanstack/solid-db": "0.2.10", - "@tanstack/solid-devtools": "0.8.0", - "@tanstack/solid-form": "1.28.4", - "@tanstack/solid-hotkeys": "0.4.2", - "@tanstack/solid-hotkeys-devtools": "0.4.3", - "@tanstack/solid-query": "5.90.23", - "@tanstack/solid-query-devtools": "5.91.3", + "@tanstack/query-db-collection": "1.0.36", + "@tanstack/solid-db": "0.2.19", + "@tanstack/solid-devtools": "0.8.2", + "@tanstack/solid-form": "1.29.1", + "@tanstack/solid-hotkeys": "0.9.1", + "@tanstack/solid-hotkeys-devtools": "0.6.6", + "@tanstack/solid-query": "5.100.3", + "@tanstack/solid-query-devtools": "5.100.3", "@tanstack/solid-table": "8.21.3", "@ts-rest/core": "3.52.1", "animejs": "4.2.2", @@ -55,7 +55,7 @@ "chart.js": "3.7.1", "chartjs-adapter-date-fns": "3.0.0", "chartjs-plugin-annotation": "2.2.1", - "chartjs-plugin-trendline": "3.2.0", + "chartjs-plugin-trendline": "3.2.4", "clsx": "2.1.1", "color-blend": "4.0.0", "damerau-levenshtein": "1.0.8", @@ -82,7 +82,7 @@ "@monkeytype/typescript-config": "workspace:*", "@solidjs/testing-library": "0.8.10", "@tailwindcss/vite": "4.2.1", - "@tanstack/eslint-plugin-query": "5.91.4", + "@tanstack/eslint-plugin-query": "5.100.3", "@testing-library/dom": "10.4.1", "@testing-library/jest-dom": "6.9.1", "@testing-library/user-event": "14.6.1", diff --git a/frontend/src/html/pages/account.html b/frontend/src/html/pages/account.html deleted file mode 100644 index 0797dd993b28..000000000000 --- a/frontend/src/html/pages/account.html +++ /dev/null @@ -1,428 +0,0 @@ - diff --git a/frontend/src/html/popups.html b/frontend/src/html/popups.html index 4dd3c50507ed..0461edfa0343 100644 --- a/frontend/src/html/popups.html +++ b/frontend/src/html/popups.html @@ -7,12 +7,6 @@ - -