mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-07-22 22:59:41 +02:00
Feature: Global Timeline (#2265)
* extended query filter to accept nested tables * decoupled timeline api from recipe slug * modified frontend to use simplified events api * fixed nested loop index ghosting * updated existing tests * gave mypy a snack * added tests for nested queries * fixed "last made" render error * decoupled recipe timeline from dialog * removed unused props * tweaked recipe get_all to accept ids * created group global timeline added new timeline page to sidebar reformatted the recipe timeline added vertical option to recipe card mobile * extracted timeline item into its own component * fixed apploader centering * added paginated scrolling to recipe timeline * added sort direction config fixed infinite scroll on dialog fixed hasMore var not resetting during instantiation * added sort direction to user preferences * updated API docs with new query filter feature * better error tracing * fix for recipe not found response * simplified recipe crud route for slug/id added test for fetching by slug/id * made query filter UUID validation clearer * moved timeline menu option below shopping lists --------- Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com>
This commit is contained in:
parent
0e397b34fd
commit
fe17922bb8
28 changed files with 871 additions and 506 deletions
|
@ -355,6 +355,7 @@ export interface RecipeTimelineEventIn {
|
|||
eventMessage?: string;
|
||||
image?: string;
|
||||
timestamp?: string;
|
||||
recipeId: string;
|
||||
}
|
||||
export interface RecipeTimelineEventOut {
|
||||
userId: string;
|
||||
|
|
|
@ -39,6 +39,7 @@ const routes = {
|
|||
recipesParseIngredient: `${prefix}/parser/ingredient`,
|
||||
recipesParseIngredients: `${prefix}/parser/ingredients`,
|
||||
recipesCreateFromOcr: `${prefix}/recipes/create-ocr`,
|
||||
recipesTimelineEvent: `${prefix}/recipes/timeline/events`,
|
||||
|
||||
recipesRecipeSlug: (recipe_slug: string) => `${prefix}/recipes/${recipe_slug}`,
|
||||
recipesRecipeSlugExport: (recipe_slug: string) => `${prefix}/recipes/${recipe_slug}/exports`,
|
||||
|
@ -50,9 +51,7 @@ const routes = {
|
|||
recipesSlugCommentsId: (slug: string, id: number) => `${prefix}/recipes/${slug}/comments/${id}`,
|
||||
|
||||
recipesSlugLastMade: (slug: string) => `${prefix}/recipes/${slug}/last-made`,
|
||||
|
||||
recipesSlugTimelineEvent: (slug: string) => `${prefix}/recipes/${slug}/timeline/events`,
|
||||
recipesSlugTimelineEventId: (slug: string, id: string) => `${prefix}/recipes/${slug}/timeline/events/${id}`,
|
||||
recipesTimelineEventId: (id: string) => `${prefix}/recipes/timeline/events/${id}`,
|
||||
};
|
||||
|
||||
export type RecipeSearchQuery = {
|
||||
|
@ -170,24 +169,24 @@ export class RecipeAPI extends BaseCRUDAPI<CreateRecipe, Recipe, Recipe> {
|
|||
return await this.requests.patch<Recipe, RecipeLastMade>(routes.recipesSlugLastMade(recipeSlug), { timestamp })
|
||||
}
|
||||
|
||||
async createTimelineEvent(recipeSlug: string, payload: RecipeTimelineEventIn) {
|
||||
return await this.requests.post<RecipeTimelineEventOut>(routes.recipesSlugTimelineEvent(recipeSlug), payload);
|
||||
async createTimelineEvent(payload: RecipeTimelineEventIn) {
|
||||
return await this.requests.post<RecipeTimelineEventOut>(routes.recipesTimelineEvent, payload);
|
||||
}
|
||||
|
||||
async updateTimelineEvent(recipeSlug: string, eventId: string, payload: RecipeTimelineEventUpdate) {
|
||||
async updateTimelineEvent(eventId: string, payload: RecipeTimelineEventUpdate) {
|
||||
return await this.requests.put<RecipeTimelineEventOut, RecipeTimelineEventUpdate>(
|
||||
routes.recipesSlugTimelineEventId(recipeSlug, eventId),
|
||||
routes.recipesTimelineEventId(eventId),
|
||||
payload
|
||||
);
|
||||
}
|
||||
|
||||
async deleteTimelineEvent(recipeSlug: string, eventId: string) {
|
||||
return await this.requests.delete<RecipeTimelineEventOut>(routes.recipesSlugTimelineEventId(recipeSlug, eventId));
|
||||
async deleteTimelineEvent(eventId: string) {
|
||||
return await this.requests.delete<RecipeTimelineEventOut>(routes.recipesTimelineEventId(eventId));
|
||||
}
|
||||
|
||||
async getAllTimelineEvents(recipeSlug: string, page = 1, perPage = -1, params = {} as any) {
|
||||
async getAllTimelineEvents(page = 1, perPage = -1, params = {} as any) {
|
||||
return await this.requests.get<PaginationData<RecipeTimelineEventOut>>(
|
||||
routes.recipesSlugTimelineEvent(recipeSlug),
|
||||
routes.recipesTimelineEvent,
|
||||
{
|
||||
params: { page, perPage, ...params },
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue