autowp/autowp-frontend

View on GitHub
src/app/catalogue/engines/engines.component.ts

Summary

Maintainability
A
0 mins
Test Coverage
import {AsyncPipe} from '@angular/common';
import {ChangeDetectionStrategy, Component, inject} from '@angular/core';
import {ActivatedRoute, Router, RouterLink} from '@angular/router';
import {
ItemFields,
ItemListOptions,
ItemParentFields,
ItemParentListOptions,
ItemParentsRequest,
ItemsRequest,
ItemType,
Pages,
} from '@grpc/spec.pb';
import {ItemsClient} from '@grpc/spec.pbsc';
import {LanguageService} from '@services/language';
import {PageEnvService} from '@services/page-env.service';
import {
CatalogueListItem,
CatalogueListItemComponent,
CatalogueListItemPicture,
} from '@utils/list-item/list-item.component';
import {combineLatest, EMPTY, Observable, of} from 'rxjs';
import {debounceTime, distinctUntilChanged, map, shareReplay, switchMap, tap} from 'rxjs/operators';
 
import {PaginatorComponent} from '../../paginator/paginator/paginator.component';
import {convertChildsCounts} from '../catalogue-service';
 
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [RouterLink, PaginatorComponent, AsyncPipe, CatalogueListItemComponent],
selector: 'app-catalogue-engines',
templateUrl: './engines.component.html',
})
export class CatalogueEnginesComponent {
readonly #pageEnv = inject(PageEnvService);
readonly #route = inject(ActivatedRoute);
readonly #router = inject(Router);
readonly #itemsClient = inject(ItemsClient);
readonly #languageService = inject(LanguageService);
 
readonly #page$ = this.#route.queryParamMap.pipe(
map((params) => parseInt(params.get('page') ?? '', 10)),
distinctUntilChanged(),
debounceTime(10),
);
 
protected readonly brand$ = this.#route.paramMap.pipe(
map((params) => params.get('brand')),
distinctUntilChanged(),
debounceTime(10),
switchMap((catname) => {
if (!catname) {
return EMPTY;
}
return this.#itemsClient
.list(
new ItemsRequest({
fields: new ItemFields({
nameHtml: true,
nameOnly: true,
}),
language: this.#languageService.language,
limit: 1,
options: new ItemListOptions({
catname,
}),
}),
)
.pipe(
switchMap((response) => {
if (!response.items || response.items.length <= 0) {
this.#router.navigate(['/error-404'], {
skipLocationChange: true,
});
return EMPTY;
}
return of(response.items[0]);
}),
);
}),
tap((brand) => {
this.#pageEnv.set({
pageId: 208,
title: $localize`${brand.nameOnly} Engines`,
});
}),
shareReplay({bufferSize: 1, refCount: false}),
);
 
protected readonly data$: Observable<{items: CatalogueListItem[]; paginator: Pages | undefined}> = combineLatest([
this.brand$,
this.#page$,
]).pipe(
switchMap(([brand, page]) =>
combineLatest([
this.#itemsClient.getItemParents(
new ItemParentsRequest({
fields: new ItemParentFields({
item: new ItemFields({
acceptedPicturesCount: true,
canEditSpecs: true,
categories: new ItemsRequest({
fields: new ItemFields({nameHtml: true}),
}),
childsCount: true,
description: true,
engineVehicles: new ItemsRequest({
fields: new ItemFields({nameHtml: true, route: true}),
}),
hasChildSpecs: true,
hasText: true,
nameDefault: true,
nameHtml: true,
specsRoute: true,
twins: new ItemsRequest(),
}),
}),
language: this.#languageService.language,
limit: 7,
options: new ItemParentListOptions({
item: new ItemListOptions({
typeId: ItemType.ITEM_TYPE_ENGINE,
}),
parentId: brand.id,
}),
order: ItemParentsRequest.Order.AUTO,
page,
}),
),
of(brand),
]),
),
map(([response, brand]) => {
const items: CatalogueListItem[] = (response.items || []).map((item): CatalogueListItem => {
const largeFormat = !!item.item?.previewPictures?.largeFormat;
 
const routerLink = ['/', brand.catname, item.catname];
 
const pictures: CatalogueListItemPicture[] = (item.item?.previewPictures?.pictures || []).map(
(picture, idx) => {
let thumb = null;
if (picture.picture) {
thumb = largeFormat && idx == 0 ? picture.picture.thumbLarge : picture.picture.thumbMedium;
}
return {
picture: picture?.picture ? picture.picture : null,
routerLink: picture?.picture ? routerLink.concat(['pictures', picture.picture.identity]) : [],
thumb,
};
},
);
 
return {
acceptedPicturesCount: item.item?.acceptedPicturesCount,
canEditSpecs: !!item.item?.canEditSpecs,
categories: item.item?.categories || undefined,
childsCounts: item.item?.childsCounts ? convertChildsCounts(item.item.childsCounts) : null,
description: item.item?.description || null,
design: undefined,
details: {
count: item.item?.childsCount || 0,
routerLink,
},
engineVehicles: item.item?.engineVehicles,
hasText: !!item.item?.hasText,
id: item.item?.id || '',
itemTypeId: item.item?.itemTypeId || 0,
nameDefault: item.item?.nameDefault || '',
nameHtml: item.item?.nameHtml || '',
picturesRouterLink: routerLink.concat(['pictures']),
previewPictures: {
largeFormat: !!item.item?.previewPictures?.largeFormat,
pictures,
},
produced: item.item?.produced?.value,
producedExactly: item.item?.producedExactly || null,
specsRouterLink:
item.item?.hasSpecs || item.item?.hasChildSpecs ? routerLink.concat(['specifications']) : null,
};
});
 
return {
items,
paginator: response.paginator,
};
}),
);
 
protected readonly title$ = this.brand$.pipe(map((brand) => $localize`${brand.nameOnly} Engines`));
}