changes are done

This commit is contained in:
sdarbinyan
2026-03-01 02:40:42 +04:00
parent ffde301181
commit e32ee998c1
16 changed files with 246 additions and 184 deletions

View File

@@ -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 {