File
Implements
Metadata
changeDetection |
ChangeDetectionStrategy.OnPush |
selector |
hierarchy-facet |
styleUrls |
./facet-hierarchy.component.scss |
templateUrl |
./facet-hierarchy.component.html |
Index
Properties
|
|
Methods
|
|
Inputs
|
|
Methods
Public
buildBreadcrumb
|
buildBreadcrumb(filters)
|
|
|
Public
findLowestBranch
|
findLowestBranch(cat)
|
|
Recursively go through category tree and find lowest
first node which has more than 1 child.
If you've gone through the whole tree without finding one (no children left), select lowest branch.
|
Public
findSelectedCat
|
findSelectedCat(filters)
|
|
Recursively find selected filter
|
ngOnDestroy
|
ngOnDestroy()
|
|
|
Public
selectFilter
|
selectFilter(filter)
|
|
|
Public
toggleFacet
|
toggleFacet()
|
|
|
Public
trackFilters
|
trackFilters(index, filter)
|
|
Parameters :
Name |
Optional |
index |
No
|
filter |
No
|
|
breadcrumb
|
Type : []
|
Default value : []
|
|
filterList
|
Type : []
|
Default value : []
|
|
open
|
Default value : true
|
|
resolvedFilters
|
Type : []
|
Default value : []
|
|
tcmIds
|
Type : []
|
Default value : []
|
|
import { Component, OnInit, Input, ChangeDetectionStrategy, SimpleChanges, ChangeDetectorRef, OnChanges, OnDestroy } from '@angular/core';
import { LabelService } from 'src/app/core/services/label-service/label-service.service';
import { TcmResolverService } from 'src/app/core/services/tcmResolver.service';
import { LoadingIndicatorService } from 'src/app/core/services/loading-indicator.service';
@Component ({
selector: 'hierarchy-facet',
templateUrl: './facet-hierarchy.component.html',
styleUrls: ['./facet-hierarchy.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class HierarchyFacetComponent implements OnInit, OnChanges, OnDestroy {
@Input() facet;
@Input() stats;
open = true;
filterList = [];
resolvedFilters = [];
parent;
resolvedIds;
tcmIds = [];
breadcrumb = [];
selectedCategory;
subscription: any;
// Label
facetNameLabel: string;
constructor(
public loadingService: LoadingIndicatorService,
public changeRef: ChangeDetectorRef,
public labelService: LabelService,
private tcmResolver: TcmResolverService
) { }
ngOnInit() {
this.labelService.getLabel(this.facet.displayName).then(res => {
this.facetNameLabel = res;
this.changeRef.markForCheck();
});
}
ngOnChanges(changes: SimpleChanges): void {
if (changes) {
this.tcmIds = [];
this.buildBreadcrumb(this.facet.filters);
// If a category has been selected, show its children.
// Otherwise, find the lowest node which has more than 1 child, and show that instead.
if (this.selectedCategory) {
this.filterList = this.selectedCategory.children;
const isTcm = this.selectedCategory.displayName.match(/\d+-\d+/);
if (isTcm) { this.tcmIds.push(isTcm.input); }
} else {
this.parent = undefined;
// if (this.facet.filters.length > 1) { this.filterList = this.facet.filters; }
this.filterList = this.facet.filters;
// else {
// this.findLowestBranch(this.facet.filters[0]);
// }
}
// Translate displayName of filters if they are tcm-ids.
this.filterList.forEach(filter => {
const isTcm = filter.displayName.match(/\d+-\d+/);
if (isTcm) { this.tcmIds.push(isTcm.input); }
});
// If tcm-id was found in filter names, get their real value from tcmResolver.
if (this.tcmIds.length > 0) {
const resolver = this.tcmResolver.resolveTcmIds(this.tcmIds);
this.subscription = resolver.subscribe(ids => {
this.resolvedIds = ids;
this.resolvedFilters = this.filterList.map(filter => {
if (filter.displayName in this.resolvedIds) { filter.resolvedName = this.resolvedIds[filter.displayName]; }
else { filter.resolvedName = filter.displayName; }
return filter;
});
if (this.selectedCategory) { this.selectedCategory.resolvedName = this.resolvedIds[this.selectedCategory.displayName]; }
this.changeRef.detectChanges(); // Needed for updating view after names have been resolved.
});
} else { // If no tcm-id was found, use filters as they are.
this.resolvedFilters = this.filterList;
}
}
}
ngOnDestroy(): void {
if (this.subscription) { this.subscription.unsubscribe(); }
}
public trackFilters(index, filter) {
return filter ? filter.displayName : {};
}
/** Toggle facet div */
public toggleFacet() {
this.open = !this.open;
}
/** Recursively find selected filter */
public findSelectedCat(filters) {
let foundFilter;
filters.forEach(filter => {
if (filter.selected) {
this.breadcrumb.push(filter);
foundFilter = filter;
} else {
const crumb = this.findSelectedCat(filter.children);
if (crumb) {
this.breadcrumb.push(filter);
foundFilter = filter;
}
}
});
return foundFilter;
}
/** Builds breadcrumb */
public buildBreadcrumb(filters) {
this.breadcrumb = [];
this.findSelectedCat(filters);
// Breadcrumb is built backwards, revers to get right order
this.breadcrumb.reverse();
if (this.breadcrumb.length > 0) {
this.selectedCategory = this.breadcrumb[this.breadcrumb.length - 1];
}
// If no parent, set parent to self
if (this.breadcrumb.length === 1) {
this.parent = this.selectedCategory;
}
else if (this.breadcrumb.length > 1) {
this.parent = this.breadcrumb[this.breadcrumb.length - 2];
} else {
this.parent = undefined;
this.selectedCategory = undefined;
}
}
/** Recursively go through category tree and find lowest
* first node which has more than 1 child.
*
* If you've gone through the whole tree without finding one (no children left), select lowest branch.
*/
public findLowestBranch(cat) {
if (cat) {
const list = cat.children;
if (list.length > 1 || cat.count !== this.stats.totalHits) {
this.filterList = cat.children;
}
else if (list.length === 0) {
cat.select();
}
else { this.findLowestBranch(list[0]); }
}
}
public selectFilter(filter) {
this.loadingService.show();
if (filter === this.selectedCategory) { this.facet.deselect(); }
else { filter.select(); }
}
}
<div class="card">
<div class="card-header" (click)="parent && selectFilter(parent)">
<i class="icon-chevronPrev back-parent" [hidden]="!parent"></i>
<div class="title" *ngIf="selectedCategory">
{{selectedCategory.resolvedName || selectedCategory.displayName || facetNameLabel}}
</div>
<div class="title" *ngIf="!selectedCategory">
{{ facetNameLabel }}
</div>
</div>
<div class="card-body" *ngIf="resolvedFilters.length > 0">
<ul class="list-group list-group-flush">
<li class="list-group-item" *ngFor="let filter of resolvedFilters; let i=index; trackBy: trackFilters" (click)="selectFilter(filter)">
<label class="list-group-item-name">
{{filter.resolvedName || filter.displayName}}
</label>
<i class="icon-chevronNext"></i>
</li>
</ul>
</div>
</div>
@import "src/app/styles/helpers";
.card {
margin-bottom: calc-rem(15);
color: $light-blue;
border: none;
&-header {
background-color: $cool-grey;
display: flex;
flex-direction: row;
align-items: center;
padding: calc-rem(20);
margin-bottom: calc-rem(2);
@include font-scale(14, uppercase);
letter-spacing: calc-rem(2);
border: none;
cursor: pointer;
.title {
text-transform: uppercase;
}
.back-parent {
display: inline-block;
@include font-size(12);
margin-right: calc-rem(10);
margin-top: calc-rem(2);
}
}
&-body {
background-color: $cool-grey;
.list-group {
&-item {
background-color: transparent;
color: $light-blue;
display: flex;
justify-content: space-between;
@include font-scale(14, uppercase);
letter-spacing: calc-rem(2);
padding: calc-rem(10) 0;
align-items: center;
border-color: rgba($light-blue, 0.5);
cursor: pointer;
&-name {
display: flex;
flex-grow: 1;
margin: 0;
cursor: pointer;
}
i {
color: $light-blue;
@include font-size(14);
}
}
}
}
}
Legend
Html element with directive