mirror of
				https://github.com/mealie-recipes/mealie.git
				synced 2025-10-30 17:53:31 -04:00 
			
		
		
		
	* added normalization to foods and units
* changed search to reference new normalized fields
* fix tests
* added parsed food matching to backend
* prevent pagination from ordering when searching
* added extra fuzzy matching to sqlite ing matching
* added tests
* only apply search ordering when order_by is null
* enabled post-search fuzzy matching for postgres
* fixed postgres fuzzy search test
* idk why this is failing
* 🤦
* simplified frontend ing matching
and restored automatic unit creation
* tightened food fuzzy threshold
* change to rapidfuzz
* sped up fuzzy matching with process
* fixed units not matching by abbreviation
* fast return for exact matches
* replace db searching with pure fuzz
* added fuzzy normalization
* tightened unit fuzzy matching thresh
* cleaned up comments/var names
* ran matching logic through the dryer
* oops
* simplified order by application logic
		
	
		
			
				
	
	
		
			162 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			162 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| import { Ref, useAsync } from "@nuxtjs/composition-api";
 | |
| import { useAsyncKey } from "../use-utils";
 | |
| import { BaseCRUDAPI, BaseCRUDAPIReadOnly } from "~/lib/api/base/base-clients";
 | |
| import { QueryValue } from "~/lib/api/base/route";
 | |
| 
 | |
| type BoundT = {
 | |
|   id?: string | number;
 | |
| };
 | |
| 
 | |
| interface PublicStoreActions<T extends BoundT> {
 | |
|   getAll(page?: number, perPage?: number, params?: any): Ref<T[] | null>;
 | |
|   refresh(): Promise<void>;
 | |
| }
 | |
| 
 | |
| interface StoreActions<T extends BoundT> extends PublicStoreActions<T> {
 | |
|   createOne(createData: T): Promise<T | null>;
 | |
|   updateOne(updateData: T): Promise<T | null>;
 | |
|   deleteOne(id: string | number): Promise<T | null>;
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|  * usePublicStoreActions is a factory function that returns a set of methods
 | |
|  * that can be reused to manage the state of a data store without using
 | |
|  * Vuex. This is primarily used for basic GET/GETALL operations that required
 | |
|  * a lot of refreshing hooks to be called on operations
 | |
|  */
 | |
| export function usePublicStoreActions<T extends BoundT>(
 | |
|   api: BaseCRUDAPIReadOnly<T>,
 | |
|   allRef: Ref<T[] | null> | null,
 | |
|   loading: Ref<boolean>
 | |
| ): PublicStoreActions<T> {
 | |
|   function getAll(page = 1, perPage = -1, params = {} as Record<string, QueryValue>) {
 | |
|     params.orderBy ??= "name";
 | |
|     params.orderDirection ??= "asc";
 | |
| 
 | |
|     loading.value = true;
 | |
|     const allItems = useAsync(async () => {
 | |
|       const { data } = await api.getAll(page, perPage, params);
 | |
| 
 | |
|       if (data && allRef) {
 | |
|         allRef.value = data.items;
 | |
|       }
 | |
| 
 | |
|       if (data) {
 | |
|         return data.items ?? [];
 | |
|       } else {
 | |
|         return [];
 | |
|       }
 | |
|     }, useAsyncKey());
 | |
| 
 | |
|     loading.value = false;
 | |
|     return allItems;
 | |
|   }
 | |
| 
 | |
|   async function refresh() {
 | |
|     loading.value = true;
 | |
|     const { data } = await api.getAll();
 | |
| 
 | |
|     if (data && data.items && allRef) {
 | |
|       allRef.value = data.items;
 | |
|     }
 | |
| 
 | |
|     loading.value = false;
 | |
|   }
 | |
| 
 | |
|   return {
 | |
|     getAll,
 | |
|     refresh,
 | |
|   };
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * useStoreActions is a factory function that returns a set of methods
 | |
|  * that can be reused to manage the state of a data store without using
 | |
|  * Vuex. This is primarily used for basic CRUD operations that required
 | |
|  * a lot of refreshing hooks to be called on operations
 | |
|  */
 | |
| export function useStoreActions<T extends BoundT>(
 | |
|   api: BaseCRUDAPI<unknown, T, unknown>,
 | |
|   allRef: Ref<T[] | null> | null,
 | |
|   loading: Ref<boolean>
 | |
| ): StoreActions<T> {
 | |
|   function getAll(page = 1, perPage = -1, params = {} as Record<string, QueryValue>) {
 | |
|     params.orderBy ??= "name";
 | |
|     params.orderDirection ??= "asc";
 | |
| 
 | |
|     loading.value = true;
 | |
|     const allItems = useAsync(async () => {
 | |
|       const { data } = await api.getAll(page, perPage, params);
 | |
| 
 | |
|       if (data && allRef) {
 | |
|         allRef.value = data.items;
 | |
|       }
 | |
| 
 | |
|       if (data) {
 | |
|         return data.items ?? [];
 | |
|       } else {
 | |
|         return [];
 | |
|       }
 | |
|     }, useAsyncKey());
 | |
| 
 | |
|     loading.value = false;
 | |
|     return allItems;
 | |
|   }
 | |
| 
 | |
|   async function refresh() {
 | |
|     loading.value = true;
 | |
|     const { data } = await api.getAll();
 | |
| 
 | |
|     if (data && data.items && allRef) {
 | |
|       allRef.value = data.items;
 | |
|     }
 | |
| 
 | |
|     loading.value = false;
 | |
|   }
 | |
| 
 | |
|   async function createOne(createData: T) {
 | |
|     loading.value = true;
 | |
|     const { data } = await api.createOne(createData);
 | |
|     if (data && allRef?.value) {
 | |
|       allRef.value.push(data);
 | |
|     } else {
 | |
|       await refresh();
 | |
|     }
 | |
|     loading.value = false;
 | |
|     return data;
 | |
|   }
 | |
| 
 | |
|   async function updateOne(updateData: T) {
 | |
|     if (!updateData.id) {
 | |
|       return null;
 | |
|     }
 | |
| 
 | |
|     loading.value = true;
 | |
|     const { data } = await api.updateOne(updateData.id, updateData);
 | |
|     if (data && allRef?.value) {
 | |
|       await refresh();
 | |
|     }
 | |
|     loading.value = false;
 | |
|     return data;
 | |
|   }
 | |
| 
 | |
|   async function deleteOne(id: string | number) {
 | |
|     loading.value = true;
 | |
|     const { response } = await api.deleteOne(id);
 | |
|     if (response && allRef?.value) {
 | |
|       await refresh();
 | |
|     }
 | |
|     loading.value = false;
 | |
|     return response?.data || null;
 | |
|   }
 | |
| 
 | |
|   return {
 | |
|     getAll,
 | |
|     refresh,
 | |
|     createOne,
 | |
|     updateOne,
 | |
|     deleteOne,
 | |
|   };
 | |
| }
 |