@@ -3,6 +3,8 @@ import { queryCollectionOptions } from "@tanstack/query-db-collection";
33import {
44 createCollection ,
55 createOptimisticAction ,
6+ eq ,
7+ queryOnce ,
68 useLiveQuery ,
79} from "@tanstack/solid-db" ;
810import { z } from "zod" ;
@@ -20,8 +22,9 @@ import {
2022} from "@monkeytype/schemas/shared" ;
2123import { Difficulty } from "@monkeytype/schemas/configs" ;
2224import { Language } from "@monkeytype/schemas/languages" ;
23- import { applyIdWorkaround , tempId } from "./utils/misc" ;
25+ import { applyIdWorkaround , isTempId , tempId } from "./utils/misc" ;
2426import { fetchUserFromApi } from "../ape/user" ;
27+ import { updateTagsInFilterStorage } from "../states/result-filters" ;
2528
2629export type TagItem = UserTag & { active : boolean } ;
2730
@@ -60,6 +63,16 @@ export function useTagsLiveQuery() {
6063 } ) ;
6164}
6265
66+ // oxlint-disable-next-line typescript/explicit-function-return-type
67+ export async function getActiveTagsOnce ( ) {
68+ return queryOnce ( ( q ) => {
69+ return q
70+ . from ( { tag : tagsCollection } )
71+ . where ( ( { tag } ) => eq ( tag . active , true ) )
72+ . orderBy ( ( { tag } ) => tag . name , "asc" ) ;
73+ } ) ;
74+ }
75+
6376type ActionType = {
6477 insertTag : {
6578 name : string ;
@@ -74,6 +87,18 @@ type ActionType = {
7487 deleteTag : {
7588 tagId : string ;
7689 } ;
90+ toggleTagActive : {
91+ tagId : string ;
92+ noSave ?: boolean ;
93+ } ;
94+ setTagActive : {
95+ tagId : string ;
96+ active : boolean ;
97+ noSave ?: boolean ;
98+ } ;
99+ clearActiveTags : {
100+ noSave ?: boolean ;
101+ } ;
77102} ;
78103
79104const actions = {
@@ -100,6 +125,11 @@ const actions = {
100125 } ;
101126
102127 tagsCollection . utils . writeInsert ( newTag ) ;
128+ updateTagsInFilterStorage (
129+ [ ...tagsCollection . values ( ) ]
130+ . filter ( ( it ) => ! isTempId ( it . _id ) )
131+ . map ( ( it ) => it . _id ) ,
132+ ) ;
103133 } ,
104134 } ) ,
105135 updateTagName : createOptimisticAction < ActionType [ "updateTagName" ] > ( {
@@ -166,6 +196,46 @@ const actions = {
166196 throw new Error ( `Failed to delete tag: ${ response . body . message } ` ) ;
167197 }
168198 tagsCollection . utils . writeDelete ( tagId ) ;
199+ updateTagsInFilterStorage (
200+ [ ...tagsCollection . values ( ) ] . map ( ( it ) => it . _id ) ,
201+ ) ;
202+ } ,
203+ } ) ,
204+ toggleTagActive : createOptimisticAction < ActionType [ "toggleTagActive" ] > ( {
205+ onMutate : ( { tagId, noSave } ) => {
206+ const tag = tagsCollection . get ( tagId ) ;
207+ if ( tag === undefined ) return ;
208+ tagsCollection . utils . writeUpdate ( { ...tag , active : ! tag . active } ) ;
209+ if ( ! noSave ) saveActiveToLocalStorage ( ) ;
210+ } ,
211+ mutationFn : async ( ) => {
212+ return ;
213+ } ,
214+ } ) ,
215+ setTagActive : createOptimisticAction < ActionType [ "setTagActive" ] > ( {
216+ onMutate : ( { tagId, active, noSave } ) => {
217+ const tag = tagsCollection . get ( tagId ) ;
218+ if ( tag === undefined ) return ;
219+ tagsCollection . utils . writeUpdate ( { ...tag , active } ) ;
220+ if ( ! noSave ) saveActiveToLocalStorage ( ) ;
221+ } ,
222+ mutationFn : async ( ) => {
223+ return ;
224+ } ,
225+ } ) ,
226+ clearActiveTags : createOptimisticAction < ActionType [ "clearActiveTags" ] > ( {
227+ onMutate : ( { noSave } ) => {
228+ tagsCollection . utils . writeBatch ( ( ) => {
229+ tagsCollection . forEach ( ( tag ) => {
230+ if ( tag . active ) {
231+ tagsCollection . utils . writeUpdate ( { ...tag , active : false } ) ;
232+ }
233+ } ) ;
234+ } ) ;
235+ if ( ! noSave ) saveActiveToLocalStorage ( ) ;
236+ } ,
237+ mutationFn : async ( ) => {
238+ return ;
169239 } ,
170240 } ) ,
171241} ;
@@ -200,6 +270,27 @@ export async function deleteTag(
200270 await transaction . isPersisted . promise ;
201271}
202272
273+ export async function toggleTagActive (
274+ params : ActionType [ "toggleTagActive" ] ,
275+ ) : Promise < void > {
276+ const transaction = actions . toggleTagActive ( params ) ;
277+ await transaction . isPersisted . promise ;
278+ }
279+
280+ export async function setTagActive (
281+ params : ActionType [ "setTagActive" ] ,
282+ ) : Promise < void > {
283+ const transaction = actions . setTagActive ( params ) ;
284+ await transaction . isPersisted . promise ;
285+ }
286+
287+ export async function clearActiveTags (
288+ params : ActionType [ "clearActiveTags" ] = { } ,
289+ ) : Promise < void > {
290+ const transaction = actions . clearActiveTags ( params ) ;
291+ await transaction . isPersisted . promise ;
292+ }
293+
203294function getTags ( ) : TagItem [ ] {
204295 return [ ...tagsCollection . values ( ) ] . sort ( ( a , b ) =>
205296 a . name . localeCompare ( b . name ) ,
@@ -230,35 +321,6 @@ export function saveActiveToLocalStorage(): void {
230321 activeTagsLS . set ( activeIds ) ;
231322}
232323
233- export function toggleTagActive ( tagId : string , nosave = false ) : void {
234- const tag = tagsCollection . get ( tagId ) ;
235- if ( tag === undefined ) return ;
236- tagsCollection . utils . writeUpdate ( { ...tag , active : ! tag . active } ) ;
237- if ( ! nosave ) saveActiveToLocalStorage ( ) ;
238- }
239-
240- export function setTagActive (
241- tagId : string ,
242- state : boolean ,
243- nosave = false ,
244- ) : void {
245- const tag = tagsCollection . get ( tagId ) ;
246- if ( tag === undefined ) return ;
247- tagsCollection . utils . writeUpdate ( { ...tag , active : state } ) ;
248- if ( ! nosave ) saveActiveToLocalStorage ( ) ;
249- }
250-
251- export function clearActiveTags ( nosave = false ) : void {
252- tagsCollection . utils . writeBatch ( ( ) => {
253- tagsCollection . forEach ( ( tag ) => {
254- if ( tag . active ) {
255- tagsCollection . utils . writeUpdate ( { ...tag , active : false } ) ;
256- }
257- } ) ;
258- } ) ;
259- if ( ! nosave ) saveActiveToLocalStorage ( ) ;
260- }
261-
262324// --- Personal bests ---
263325
264326export function getLocalTagPB < M extends Mode > (
0 commit comments