This commit is contained in:
sdarbinyan
2026-06-22 01:44:17 +04:00
parent fb570a32f5
commit 9038a1f782
5 changed files with 171 additions and 9 deletions

View File

@@ -1,7 +1,18 @@
import { Injectable, inject, signal } from '@angular/core';
import { HttpClient, HttpParams } from '@angular/common/http';
import { Observable, Subject, throwError } from 'rxjs';
import { debounceTime, retry, catchError, map, groupBy, mergeMap } from 'rxjs/operators';
import { EMPTY, Observable, Subject, from, of, throwError } from 'rxjs';
import {
catchError,
concatMap,
debounceTime,
expand,
groupBy,
map,
mergeMap,
reduce,
retry,
toArray,
} from 'rxjs/operators';
import { Project, Category, Subcategory, Item, ItemsListResponse } from '../models';
import { ItemName } from '../models/item.model';
import { MockDataService } from './mock-data.service';
@@ -302,6 +313,25 @@ export class ApiService {
);
}
setProjectVisibility(categories: Category[], visible: boolean): Observable<void> {
const { categoryIds, subcategoryIds } = this.collectVisibilityTargets(categories);
const requests = [
...categoryIds.map(id => () => this.updateCategory(id, { visible })),
...subcategoryIds.map(id => () => this.updateSubcategory(id, { visible })),
...subcategoryIds.map(id => () => this.updateSubcategoryItemsVisibility(id, visible)),
];
if (!requests.length) {
return of(void 0);
}
return from(requests).pipe(
concatMap(request => request()),
toArray(),
map(() => void 0)
);
}
// Image upload
uploadImage(file: File): Observable<{ url: string }> {
if (environment.useMockData) return this.mockService.uploadImage(file);
@@ -349,6 +379,47 @@ export class ApiService {
});
}
private updateSubcategoryItemsVisibility(subcategoryId: string, visible: boolean): Observable<void> {
return this.getAllSubcategoryItemIds(subcategoryId).pipe(
concatMap(itemIds => itemIds.length ? this.bulkUpdateItems(itemIds, { visible }) : of(void 0))
);
}
private getAllSubcategoryItemIds(subcategoryId: string): Observable<string[]> {
const pageSize = 100;
return this.getItems(subcategoryId, 1, pageSize).pipe(
expand(response =>
response.hasMore ? this.getItems(subcategoryId, response.page + 1, pageSize) : EMPTY
),
reduce((itemIds, response) => {
itemIds.push(...response.items.map(item => item.id));
return itemIds;
}, [] as string[])
);
}
private collectVisibilityTargets(categories: Category[]) {
const categoryIds = categories.map(category => category.id);
const subcategoryIds: string[] = [];
const visitSubcategories = (subcategories: Subcategory[]) => {
for (const subcategory of subcategories) {
subcategoryIds.push(subcategory.id);
if (subcategory.subcategories?.length) {
visitSubcategories(subcategory.subcategories);
}
}
};
for (const category of categories) {
visitSubcategories(category.subcategories || []);
}
return { categoryIds, subcategoryIds };
}
private handleError = (error: any): Observable<never> => {
let errorMessage = 'An unexpected error occurred';