changes are done
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { Injectable, inject, signal } from '@angular/core';
|
||||
import { HttpClient, HttpParams } from '@angular/common/http';
|
||||
import { Observable, Subject, timer } from 'rxjs';
|
||||
import { debounce, retry, catchError, tap, map } from 'rxjs/operators';
|
||||
import { Observable, Subject, throwError } from 'rxjs';
|
||||
import { debounceTime, retry, catchError, map, groupBy, mergeMap } from 'rxjs/operators';
|
||||
import { Project, Category, Subcategory, Item, ItemsListResponse } from '../models';
|
||||
import { MockDataService } from './mock-data.service';
|
||||
import { ToastService } from './toast.service';
|
||||
import { environment } from '../../environments/environment';
|
||||
|
||||
@Injectable({
|
||||
@@ -12,15 +13,22 @@ import { environment } from '../../environments/environment';
|
||||
export class ApiService {
|
||||
private http = inject(HttpClient);
|
||||
private mockService = inject(MockDataService);
|
||||
private toast = inject(ToastService);
|
||||
private readonly API_BASE = environment.apiUrl;
|
||||
|
||||
|
||||
/** Whether a debounced save is in-flight */
|
||||
saving = signal(false);
|
||||
|
||||
// Debounced save queue
|
||||
private saveQueue$ = new Subject<SaveOperation>();
|
||||
|
||||
constructor() {
|
||||
// Set up auto-save with 500ms debounce
|
||||
// Debounce per unique type+id+field so independent fields don't clobber each other
|
||||
this.saveQueue$
|
||||
.pipe(debounce(() => timer(500)))
|
||||
.pipe(
|
||||
groupBy(op => `${op.type}:${op.id}:${op.field}`),
|
||||
mergeMap(group$ => group$.pipe(debounceTime(500)))
|
||||
)
|
||||
.subscribe(operation => {
|
||||
this.executeSave(operation);
|
||||
});
|
||||
@@ -198,7 +206,8 @@ export class ApiService {
|
||||
}
|
||||
|
||||
// Debounced auto-save
|
||||
queueSave(type: 'category' | 'subcategory' | 'item', id: string, field: string, value: any) {
|
||||
queueSave(type: 'category' | 'subcategory' | 'item', id: string, field: string, value: unknown) {
|
||||
this.saving.set(true);
|
||||
this.saveQueue$.next({ type, id, field, value });
|
||||
}
|
||||
|
||||
@@ -219,12 +228,18 @@ export class ApiService {
|
||||
}
|
||||
|
||||
request.subscribe({
|
||||
next: () => console.log(`Saved ${operation.type} ${operation.id} - ${operation.field}`),
|
||||
error: (err) => console.error(`Failed to save ${operation.type}`, err)
|
||||
next: () => {
|
||||
this.saving.set(false);
|
||||
this.toast.success('Saved');
|
||||
},
|
||||
error: (err) => {
|
||||
this.saving.set(false);
|
||||
this.toast.error(err.message || 'Failed to save');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private handleError(error: any): Observable<never> {
|
||||
private handleError = (error: any): Observable<never> => {
|
||||
let errorMessage = 'An unexpected error occurred';
|
||||
|
||||
if (error.error instanceof ErrorEvent) {
|
||||
@@ -269,15 +284,15 @@ export class ApiService {
|
||||
url: error.url
|
||||
});
|
||||
|
||||
throw { message: errorMessage, status: error.status, originalError: error };
|
||||
}
|
||||
return throwError(() => ({ message: errorMessage, status: error.status, originalError: error }));
|
||||
};
|
||||
}
|
||||
|
||||
interface SaveOperation {
|
||||
type: 'category' | 'subcategory' | 'item';
|
||||
id: string;
|
||||
field: string;
|
||||
value: any;
|
||||
value: unknown;
|
||||
}
|
||||
|
||||
interface ItemFilters {
|
||||
|
||||
Reference in New Issue
Block a user