Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
c480e81
wip
fehmer Feb 12, 2026
1777458
wip
fehmer Feb 13, 2026
e059de8
wip
fehmer Feb 13, 2026
5b9a9b0
wip
fehmer Feb 13, 2026
7f7f5b4
working filter and sorting
fehmer Feb 13, 2026
0cae531
working filter and sorting
fehmer Feb 13, 2026
e6eb759
be migrate, move liveQuery and filters to collections/results
fehmer Feb 13, 2026
3cc6521
wip
fehmer Feb 16, 2026
a4ae35f
wip
fehmer Feb 17, 2026
dd708a5
complete filters?
fehmer Feb 17, 2026
9385711
forgot the quoteLength
fehmer Feb 17, 2026
7f55e67
simplify
fehmer Feb 17, 2026
003f571
styles
fehmer Feb 17, 2026
cdf66bf
buttons
fehmer Feb 17, 2026
58220bb
dropdowns. filter, funbox filter is missing
fehmer Feb 18, 2026
42ae60d
missing funbox filter
fehmer Feb 18, 2026
7a132ad
use store with localStorage
fehmer Feb 19, 2026
ac17b51
all option
Miodec Feb 18, 2026
7f67049
wip
Miodec Feb 18, 2026
df6c355
wip
Miodec Feb 19, 2026
eaf3bdc
wip
Miodec Feb 19, 2026
55cd549
memo
Miodec Feb 19, 2026
6ce8b79
wip
Miodec Feb 19, 2026
ef88310
wip
Miodec Feb 19, 2026
611c06d
fix tags
Miodec Feb 19, 2026
a82292c
better types, add charts filter summary
fehmer Feb 19, 2026
414e32a
wip
Miodec Feb 19, 2026
b7fb022
wip
Miodec Feb 19, 2026
8f4fdb7
settings
Miodec Feb 19, 2026
8ce62f7
simplify onChange
fehmer Feb 19, 2026
a748916
Merge branch 'feature/solid-results-select-all' into feature/solid-re…
fehmer Feb 19, 2026
f06cbd3
revert footer
fehmer Feb 19, 2026
08aed4d
add new results to collection
fehmer Feb 19, 2026
c00b6f2
debug
fehmer Feb 19, 2026
40d80e0
fix new results not available, cleanup
fehmer Feb 19, 2026
cdff534
get rid of fn.where
fehmer Feb 19, 2026
dfeb001
cleanup filters
fehmer Feb 19, 2026
6e61354
styles
fehmer Feb 20, 2026
ed1d739
miniResultChart
fehmer Feb 20, 2026
44ce83b
use asyncContent
fehmer Feb 20, 2026
488daaf
move miniResultChart, simplify chart
fehmer Feb 20, 2026
87a3615
some charts
fehmer Feb 20, 2026
822462f
add label, refactor, add trend
fehmer Feb 21, 2026
18a528e
fixes
fehmer Feb 21, 2026
24b5542
buttons
fehmer Feb 21, 2026
3a87665
fix grid colors not updating, extract history chart, fix about page c…
fehmer Feb 21, 2026
9fe9fbe
add histogramChart
fehmer Feb 21, 2026
9cb313e
add daily activity chart
fehmer Feb 21, 2026
7ffc204
Merge branch 'master' into feature/solid-results
fehmer Feb 26, 2026
b8ba5e7
clear filters button
fehmer Feb 27, 2026
1af312a
refactor filter callback, current settings button
fehmer Feb 27, 2026
87e30ff
filter presets
fehmer Feb 27, 2026
26db09c
fill filter presets collection from snapshot directly
fehmer Feb 27, 2026
84f30ed
Merge branch 'master' into feature/solid-results
fehmer Feb 27, 2026
62a6947
fix AnimatedModal test
fehmer Feb 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions backend/src/utils/result.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
9 changes: 6 additions & 3 deletions frontend/__tests__/components/common/AnimatedModal.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,12 @@ describe("AnimatedModal", () => {
modalDiv: HTMLDivElement;
} {
const { container } = render(() => (
<AnimatedModal id="Support" {...props}>
<div data-testid="modal-content">Test Content</div>
</AnimatedModal>
<>
<div id="solidmodals"></div>
<AnimatedModal id="Support" {...props}>
<div data-testid="modal-content">Test Content</div>
</AnimatedModal>
</>
));

return {
Expand Down
2 changes: 2 additions & 0 deletions frontend/__tests__/components/common/AsyncContent.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ describe("AsyncContent", () => {
}));

return (
//@ts-expect-error generic children, fine for tests
<AsyncContent
query={myQuery}
errorMessage={options?.errorMessage}
Expand Down Expand Up @@ -335,6 +336,7 @@ describe("AsyncContent", () => {
}));

return (
//@ts-expect-error generic children, fine for tests
<AsyncContent
queries={{ first: firstQuery, second: secondQuery }}
errorMessage={options?.errorMessage}
Expand Down
3 changes: 2 additions & 1 deletion frontend/__tests__/elements/account/result-filters.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
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 { __testing } from "../../../src/ts/elements/account/result-filters";
const mergeWithDefaultFilters = __testing.mergeWithDefaultFilters;

describe("result-filters.ts", () => {
describe("mergeWithDefaultFilters", () => {
Expand Down
4 changes: 3 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
"@sentry/browser": "9.14.0",
"@sentry/vite-plugin": "3.3.1",
"@solidjs/meta": "0.29.4",
"@tanstack/query-db-collection": "1.0.23",
"@tanstack/solid-db": "0.2.6",
"@tanstack/solid-query": "5.90.23",
"@tanstack/solid-query-devtools": "5.91.3",
"@tanstack/solid-table": "8.21.3",
Expand All @@ -40,7 +42,7 @@
"chart.js": "3.7.1",
"chartjs-adapter-date-fns": "3.0.0",
"chartjs-plugin-annotation": "2.2.1",
"chartjs-plugin-trendline": "1.0.2",
"chartjs-plugin-trendline": "3.2.0",
"clsx": "2.1.1",
"color-blend": "4.0.0",
"damerau-levenshtein": "1.0.8",
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@
<div id="ad-vertical-right"></div>
</div>
<load src="html/pages/loading.html" />
<div class="page pageAbout full-width hidden" id="pageAbout">
<!-- TODO: revert full-width -->
<div class="page pageAbout hidden" id="pageAbout">
<mount data-component="aboutpage"></mount>
</div>
<load src="html/pages/settings.html" />
Expand Down
79 changes: 79 additions & 0 deletions frontend/src/ts/collections/result-filter-presets.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { ResultFilters } from "@monkeytype/schemas/users";
import { queryCollectionOptions } from "@tanstack/query-db-collection";
import { createCollection } from "@tanstack/solid-db";
import Ape from "../ape";
import * as Notifications from "../elements/notifications";
import { queryClient } from "../queries";
import { baseKey } from "../queries/utils/keys";

const queryKeys = {
root: () => [...baseKey("resultFilterPresets", { isUserSpecific: true })],
};

export const resultFilterPresetsCollection = createCollection(
queryCollectionOptions({
staleTime: Infinity,
queryKey: queryKeys.root(),

queryClient,
getKey: (it) => it._id,
queryFn: async () => {
//return emtpy array. We load the user with the snapshot and fill the collection from there
return [] as ResultFilters[];
},
onInsert: async ({ transaction }) => {
const newItems = transaction.mutations.map((m) => m.modified);

const serverItems = await Promise.all(
newItems.map(async (it) => {
const response = await Ape.users.addResultFilterPreset({ body: it });
if (response.status !== 200) {
Notifications.add(
`Failed to insert result filter presets: ${response.body.message}`,
-1,
);
throw new Error(
`Failed to insert result filter presets: ${response.body.message}`,
);
}
return { ...it, _id: response.body.data };
}),
);

resultFilterPresetsCollection.utils.writeBatch(() => {
serverItems.forEach((it) =>
resultFilterPresetsCollection.utils.writeInsert(it),
);
});
return { refetch: false };
},
onDelete: async ({ transaction }) => {
const ids = transaction.mutations.map((it) => it.key as string);

await Promise.all(
ids.map(async (it) => {
const response = await Ape.users.removeResultFilterPreset({
params: { presetId: it },
});
if (response.status !== 200) {
Notifications.add(
`Failed to delete result filter presets: ${response.body.message}`,
-1,
);
throw new Error(
`Failed to delete result filter presets: ${response.body.message}`,
);
}
}),
);

resultFilterPresetsCollection.utils.writeBatch(() => {
ids.forEach((it) =>
resultFilterPresetsCollection.utils.writeDelete(it),
);
});
//don't refetch
return { refetch: false };
},
}),
);
Loading