feat(catalog): implement sprint 10 advanced search experience
Some checks failed
Architecture Governance / architecture (push) Has been cancelled

This commit is contained in:
sdarbinyan
2026-07-09 00:55:50 +04:00
parent 3ef0bd711d
commit 1a8f916942
40 changed files with 1917 additions and 70 deletions

View File

@@ -9,6 +9,7 @@ import {
ProductSearchQuery,
RelatedProductsQuery,
} from '../../core/products/models/product-domain.model';
import { SearchCriteria } from '../../core/products/models/catalog-experience.model';
import { EngagementListQuery, EngagementListResult, Question, RatingSummary, Review, SubmitQuestionInput, SubmitReviewInput } from '../../core/products/models/product-engagement.model';
@Injectable({ providedIn: 'root' })
@@ -66,4 +67,58 @@ export class ProductFacade {
submitQuestion(productID: number, input: SubmitQuestionInput): Observable<void> {
return this.productData.submitQuestion(productID, input);
}
search(criteria: SearchCriteria): Observable<ProductListResult> {
const pageSize = Math.max(1, criteria.pageSize ?? 24);
const page = Math.max(1, criteria.page ?? 1);
const skip = (page - 1) * pageSize;
return this.searchProducts({
search: criteria.keyword ?? '',
count: pageSize,
skip,
categoryIDs: criteria.categoryIDs,
minPrice: criteria.minPrice,
maxPrice: criteria.maxPrice,
sort: criteria.sort === 'discount' ? 'price_desc' : criteria.sort
});
}
filter(criteria: SearchCriteria): Observable<ProductListResult> {
return this.search(criteria);
}
sort(criteria: SearchCriteria): Observable<ProductListResult> {
return this.search({ ...criteria, sort: criteria.sort ?? 'relevance' });
}
loadCatalog(criteria: SearchCriteria): Observable<ProductListResult> {
const hasKeyword = (criteria.keyword ?? '').trim().length > 0;
if (hasKeyword) {
return this.search(criteria);
}
const categoryID = criteria.categoryIDs?.[0];
if (categoryID != null) {
const pageSize = Math.max(1, criteria.pageSize ?? 24);
const page = Math.max(1, criteria.page ?? 1);
const skip = (page - 1) * pageSize;
return this.getProductsByCategory(categoryID, {
count: pageSize,
skip,
sort: criteria.sort === 'discount' ? 'price_desc' : criteria.sort
});
}
const pageSize = Math.max(1, criteria.pageSize ?? 24);
const page = Math.max(1, criteria.page ?? 1);
const skip = (page - 1) * pageSize;
return this.getProducts({
count: pageSize,
skip,
sort: criteria.sort === 'discount' ? 'price_desc' : criteria.sort
});
}
}