meals-made-easy-app/src/app/shared/services/RecipeDraftService.ts
2026-01-28 18:17:31 -06:00

115 lines
4.1 KiB
TypeScript

import { inject, Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { delay, firstValueFrom, map, Observable, of } from 'rxjs';
import { RecipeUploadClientModel } from '../client-models/RecipeUploadClientModel';
import { RecipeUploadStep } from '../client-models/RecipeUploadStep';
import { RecipeDraftViewModel } from '../models/RecipeDraftView.model';
import { EndpointService } from './EndpointService';
import { WithStringDates } from '../util';
import { Recipe } from '../models/Recipe.model';
@Injectable({
providedIn: 'root',
})
export class RecipeDraftService {
private readonly http = inject(HttpClient);
private readonly endpointService = inject(EndpointService);
private hydrateView(rawView: WithStringDates<RecipeDraftViewModel>): RecipeDraftViewModel {
return {
...rawView,
created: new Date(rawView.created),
modified: rawView.modified ? new Date(rawView.modified) : undefined,
lastInference: rawView.lastInference
? {
...rawView.lastInference,
inferredAt: new Date(rawView.lastInference.inferredAt),
}
: undefined,
};
}
public getInProgressDrafts(): Promise<RecipeDraftViewModel[]> {
return firstValueFrom(
this.http.get<WithStringDates<RecipeDraftViewModel>[]>(this.endpointService.getUrl('recipeDrafts')).pipe(
map((rawViews) => {
return rawViews.map((rawView) => this.hydrateView(rawView));
}),
),
);
}
public getRecipeUploadClientModel(draftId: string): Observable<RecipeUploadClientModel> {
return this.http
.get<WithStringDates<RecipeDraftViewModel>>(this.endpointService.getUrl('recipeDrafts', [draftId]))
.pipe(
map((rawDraft) => {
return this.hydrateView(rawDraft);
}),
map((draft) => {
return {
draft,
inProgressStep:
draft.state === 'ENTER_DATA' ? RecipeUploadStep.ENTER_DATA : RecipeUploadStep.INFER,
};
}),
);
}
public createManualDraft(): Promise<RecipeUploadClientModel> {
return firstValueFrom(
this.http
.post<
WithStringDates<RecipeDraftViewModel>
>(this.endpointService.getUrl('recipeDrafts', ['manual']), null)
.pipe(
map((rawDraft) => this.hydrateView(rawDraft)),
map((draft) => ({
draft,
inProgressStep: RecipeUploadStep.ENTER_DATA,
})),
),
);
}
public updateDraft(id: string, data: {
title?: string | null;
slug?: string | null;
rawText?: string | null;
}): Promise<RecipeUploadClientModel> {
return firstValueFrom(
this.http.put<WithStringDates<RecipeDraftViewModel>>(
this.endpointService.getUrl('recipeDrafts', [id]),
data
)
.pipe(
map(rawView => this.hydrateView(rawView)),
map(draft => ({
draft,
inProgressStep: RecipeUploadStep.ENTER_DATA,
}))
)
);
}
public publish(id: string): Promise<Recipe> {
return firstValueFrom(
this.http.post<Recipe>(
this.endpointService.getUrl('recipeDrafts', [id, 'publish']),
null
)
);
}
public doInference(model: RecipeUploadClientModel): Observable<RecipeUploadClientModel> {
return of({
inProgressStep: RecipeUploadStep.ENTER_DATA,
id: 16,
inferredTitle: 'Some recipe',
inferredSlug: 'some-recipe',
inferredText: 'Some text.',
inferredIngredients: [],
}).pipe(delay(5_000));
}
}