import { OnInit, Component, OnDestroy, Inject } from '@angular/core';
import { SearchFactory, SearchService, SimpleSearchResult, HttpParams } from 'skf-search-angular-service';
import { UtilService } from 'src/app/core/services/util-service/util.service';
import { DOCUMENT } from '@angular/common';
import { ComponentLinkService } from 'src/app/core/services/component-link-service/component-link.service';
import { DataResolverService } from 'src/app/core/services/data-resolver/data-resolver.service';
import { PublicationService } from 'src/app/core/services/publication-service/publication.service';
import { ConstantsService } from 'src/app/shared/constants/constants.service';
import { RowResolverService } from 'src/app/core/services/row-resolver.service';
import { AppConfig } from '../../app.config';
import { LabelService } from 'src/app/core/services/label-service/label-service.service';
import { PdfDownloadService } from 'src/app/core/services/pdf-download-service/pdf-download.service';
import { LoadingIndicatorService } from 'src/app/core/services/loading-indicator.service';
import { ActivatedRoute } from '@angular/router';
interface AutomaticButton {
labelText: string;
onClick: () => void;
}
@Component({
selector: 'div[product-detail-page]',
templateUrl: './product-detail-page.component.html',
styleUrls: ['./product-detail-page.component.scss']
})
export class ProductDetailPageComponent implements OnInit, OnDestroy {
opcSearcher: SearchService;
imageUrls = [];
opcData;
opcDoc;
tridionPageData = [];
tridionData;
automaticButtons: AutomaticButton[];
page;
navigation;
subscriptions = [];
shortcuts = {
ShortcutLink: []
};
links = [];
information;
contentForPDPs = [];
noProductFound: boolean;
designation: string;
cadAvailable = true;
// Label
cadDownloadButtonTitle: string;
techSpecLabel: string;
whereToBuyLabel: string;
exportPDFLabel: string;
cadDownloadLabel: string;
constructor(
private searchFactory: SearchFactory,
private util: UtilService,
private linkService: ComponentLinkService,
private dataService: DataResolverService,
private pubService: PublicationService,
public constants: ConstantsService,
private rowResolver: RowResolverService,
private labelService: LabelService,
private pdfService: PdfDownloadService,
private loadingService: LoadingIndicatorService,
private activatedRoute: ActivatedRoute,
@Inject(DOCUMENT) private doc
) {
this.opcSearcher = this.searchFactory.get(`opc-${AppConfig.settings.searchEnvironment.name}`);
}
ngOnInit(): void {
this.labelService.getLabel('cadDownloadButtonTitle').then(label => this.cadDownloadButtonTitle = label);
this.labelService.getLabel('technicalSpecificationOnPDPs').then(label => {
this.techSpecLabel = label;
this.addShortcut({
Title: label,
LinkedComponentId: 'spec'
}, 0);
});
this.labelService.getLabel('prodSpecWhereToBuyButton').then(label => this.whereToBuyLabel = label);
this.labelService.getLabel('prodSpecExportPDFbutton').then(label => this.exportPDFLabel = label);
this.labelService.getLabel('prodSpecCadDownloadButton').then(label => this.cadDownloadLabel = label);
this.resultSubscription();
this.getPageData();
// Fetch navigation data for top menu and breadcrumb
this.dataService.getNavigationData().then(nav => this.navigation = nav);
}
ngOnDestroy(): void {
this.subscriptions.forEach(sub => {
if (sub) {
sub.unsubscribe();
}
});
}
/** Subscribe to search result */
private resultSubscription(): void {
/** Results from search are received here */
this.subscriptions.push(this.opcSearcher.result.subscribe(res => {
this.loadingService.loadingDone();
const result = res as SimpleSearchResult;
const documents = this.util.extract(result, 'documentList', 'documents') || [];
if (documents.length > 0) {
this.opcData = result;
this.opcDoc = documents[0];
this.imageUrls.push(this.opcDoc ? this.opcDoc['image_url'] : 'v2/assets/img/no-image.png');
/**
* Need to pass tabled Id since multiple product specs could have
* been placed on the parent page and we need to be able to find the correct product spec component
*/
const tableId = this.opcDoc.structure_group_id;
this.findTridionContent(tableId);
}
// Variable for showing 'no results' message.
this.noProductFound = documents.length <= 0;
}));
}
/** Fetch data from parent page */
private getPageData(): void {
this.loadingService.startLoading();
const url = this.activatedRoute.snapshot.url;
// Get url to fetch tridion content from parent page
const tridionUrl = url.splice(0, url.length - 1);
const path = tridionUrl.map(segment => segment.path).join('/');
this.dataService.getPageData(`/${path}`).then(res => {
this.page = res;
const mainReg = res['Regions'].find(region => region.Name === 'main');
this.tridionPageData = mainReg['Entities'];
this.getProductData();
});
}
/** Extract correct product spec based on tableId and setup the tridion content for the pdp */
private findTridionContent(tableId: string): void {
this.tridionPageData.forEach(element => {
const MvcData = element['MvcData'];
if (MvcData['ViewName'] === 'ProductSpecMain' && element['ProductTableID'] === tableId) {
this.tridionData = element;
}
// Product spec could be nested inside a tab
if (MvcData['ViewName'] === 'TabMain') {
const allTabs = this.util.extract(element, 'Entities');
const allTabedContent = allTabs.map(tab => this.util.extract(tab, 'TabContnetEntities')).flat();
const productSpec = allTabedContent.find(
entity => this.util.extract(entity, 'MvcData', 'ViewName') === 'ProductSpecMain'
&& this.util.extract(entity, 'ProductTableID') === tableId);
// If this is not undefined means we found a product spec that matches the desired tableID
if (productSpec) {
this.tridionData = productSpec;
}
}
});
const contentList = this.util.extract(this.tridionData, 'ContentForPDPs');
this.information = this.util.extract(this.tridionData, 'Information');
this.automaticButtons = this.resolveAutomaticLinks(this.util.extract(this.tridionData, 'AutoLinks') || []);
if (contentList) {
// Remove shortcuts from the contentForPDPs and add it to the shortcuts
const contentForPDPsTemp = [];
contentList.forEach(element => {
const MvcData = element['MvcData'];
if (MvcData['ViewName'] === 'ShortcutsMain') {
this.addShortcut(element['ShortcutLink'], 2);
} else {
contentForPDPsTemp.push(element);
}
});
this.contentForPDPs = this.rowResolver.transform(contentForPDPsTemp, 'MAIN');
}
const linkTargets = this.util.extract(this.tridionData, 'LinkTarget') || [];
this.links = linkTargets;
linkTargets.forEach(link => {
link['title'] = this.linkService.getTitle(link);
});
}
private resolveAutomaticLinks(automaticLinks): AutomaticButton[] {
// If the editors have included the 'None' value no automatic links should be added
if (automaticLinks.includes('None')) {
return [];
}
const autoLinks = [];
// Functionallity for the where to buy button is not yet specified
const whereToBuyOnClick: () => void = () => {
};
const exportPDFOnClick: () => void = () => {
this.pdfService.download();
};
// Functionallity for the cad download button is not yet specified
const cadDownloadOnClick: () => void = () => {
};
const whereToBuy: AutomaticButton = {
labelText: this.whereToBuyLabel,
onClick: whereToBuyOnClick
};
const exportPDF: AutomaticButton = {
labelText: this.exportPDFLabel,
onClick: exportPDFOnClick
};
const cadDownload: AutomaticButton = {
labelText: this.cadDownloadLabel,
onClick: cadDownloadOnClick
};
// Order here is important so that the where to buy is the leftmost button, CAD download is the second and export pdf the last
if (automaticLinks.includes('Where to buy')) {
autoLinks.push(whereToBuy);
}
if (automaticLinks.includes('CAD download')) {
autoLinks.push(cadDownload);
}
if (automaticLinks.includes('Export to PDF')) {
autoLinks.push(exportPDF);
}
return autoLinks;
}
/** Do a search with designation from URL */
private getProductData(): void {
const url = this.activatedRoute.snapshot.url;
this.designation = url[url.length - 1].path.replace('productid-', '');
const language = this.pubService.getLanguage();
const pubId = this.pubService.getPublicationId();
const system = this.activatedRoute.snapshot.queryParams['system'] || 'metric';
const opcString = `designation=${this.designation}&searcher=details&language=${language}&site=${pubId}&system=${system}`;
this.opcSearcher.doSearchWithParameters({
params: new HttpParams({ 'fromString': opcString }),
});
}
/** Scroll to CAD download component. */
public goToCadDownload() {
const cadComponent = this.doc.getElementById(this.constants.COMPONENT_ID_PREFIX + '-cad-download');
if (cadComponent) {
cadComponent.scrollIntoView(true);
}
}
/** Set CAD download variables */
public setCadDownloadVariables(available) {
this.cadAvailable = available;
if (this.cadAvailable) {
this.addShortcut({
Title: this.cadDownloadLabel,
LinkedComponentId: 'cad-download'
}, 1);
}
}
private addShortcut(shortcuts, position): void {
this.shortcuts['ShortcutLink'].splice(position, 0, ...shortcuts);
this.shortcuts = {
'ShortcutLink': [
...this.shortcuts['ShortcutLink']
]
};
}
}