File
Implements
Metadata
selector |
product-table |
styleUrls |
./product-table.component.scss |
templateUrl |
./product-table.component.html |
Index
Properties
|
|
Methods
|
|
Inputs
|
|
Methods
Public
getColLength
|
getColLength(tableCell)
|
|
Counts number of object in given object
Used to get number of columns that table header should span over
Parameters :
Name |
Optional |
tableCell |
No
|
|
Private
getColumnSortOrder
|
getColumnSortOrder()
|
|
|
Public
getPdpLink
|
getPdpLink(product)
|
|
|
Public
isDesCol
|
isDesCol(header, index)
|
|
Checks if column is the designation column, used to highlight the column
Parameters :
Name |
Optional |
header |
No
|
index |
No
|
|
Private
renderTableHeaders
|
renderTableHeaders()
|
|
|
Public
sortColumn
|
sortColumn(name)
|
|
Sort column on click, ascending and descending
Parameters :
Name |
Optional |
Description |
name |
No
|
Name of clicked column
|
|
calculateProductLabel
|
Type : string
|
|
mountDismountLabel
|
Type : string
|
|
popularItemLabel
|
Type : string
|
|
showAction
|
Default value : false
|
|
tableHeaderFirstRow
|
Type : []
|
Default value : []
|
|
tableHeaderSecondRow
|
Type : []
|
Default value : []
|
|
viewProductLabel
|
Type : string
|
|
import { Component, OnInit, Input, SimpleChanges, OnChanges } from '@angular/core';
import { LabelService } from 'src/app/core/services/label-service/label-service.service';
import { LoadingIndicatorService } from 'src/app/core/services/loading-indicator.service';
import { Router } from '@angular/router';
import { UtilService } from 'src/app/core/services/util-service/util.service';
import { PublicationService } from 'src/app/core/services/publication-service/publication.service';
import { OpcService } from 'src/app/core/services/opc-service/opc-service.service';
@Component({
selector: 'product-table',
templateUrl: './product-table.component.html',
styleUrls: ['./product-table.component.scss']
})
export class ProductTableComponent implements OnInit, OnChanges {
@Input() documentList;
@Input() tableId: string;
showAction = false;
sortedColumn: number;
sortDir: string;
lang: string;
pgpURL: string;
tableHeader;
tableHeaderFirstRow = [];
tableHeaderSecondRow = [];
// Labels
viewProductLabel: string;
calculateProductLabel: string;
mountDismountLabel: string;
popularItemLabel: string;
explorerLabel: string;
constructor(
public loadingService: LoadingIndicatorService,
public pubService: PublicationService,
private labelService: LabelService,
private router: Router,
private util: UtilService,
private opcService: OpcService
) { }
ngOnInit() {
this.lang = this.pubService.getLanguage();
// Fetch labels
this.labelService.getLabel('view_product').then(res => this.viewProductLabel = res);
this.labelService.getLabel('calculate_product').then(res => this.calculateProductLabel = res);
this.labelService.getLabel('mount_dismount_product').then(res => this.mountDismountLabel = res);
// If table ID has been given, all products on the table belongs to the same product category.
if (this.tableId) {
this.opcService.getPGPUrl(this.tableId).then(res => this.pgpURL = res);
}
}
ngOnChanges(changes: SimpleChanges): void {
// Check if sort option is selected, to update GUI
if (changes && this.documentList) {
// Get labels from search result.
if (!this.popularItemLabel) {
this.popularItemLabel = this.util.extract(this.documentList, 'documents', x => x.popular_item_label, 'popular_item_label');
}
if (!this.explorerLabel) {
this.explorerLabel = this.util.extract(this.documentList, 'documents', x => x.performance_class, 'performance_class');
}
this.renderTableHeaders();
}
}
private renderTableHeaders() {
this.tableHeader = this.util.extract(this.documentList, 'documents', [0], 'table_header');
if (this.tableHeader) {
this.tableHeaderFirstRow = [];
this.tableHeaderSecondRow = [];
this.tableHeader.forEach(row => {
this.tableHeaderFirstRow.push(row.category);
row.subcategories.forEach(subCategory => {
subCategory.entries.forEach(entry => {
if (!entry.symbol) {
this.tableHeaderSecondRow.push({
name: entry.name,
symbol: subCategory.subcategory === '' ? entry.name : subCategory.subcategory,
unit: entry.unit,
popular_item: entry.popular_item,
explorer: entry.explorer
});
}
else {
this.tableHeaderSecondRow.push(entry);
}
});
});
});
this.getColumnSortOrder();
}
}
private getColumnSortOrder() {
const selectedColumn = this.documentList.sortOptions.find(column => column.selected);
if (selectedColumn) {
for (let i = 0; i < this.tableHeaderSecondRow.length; i++) {
if (selectedColumn.displayName === this.tableHeaderSecondRow[i].name) {
this.sortedColumn = i;
}
}
this.sortDir = selectedColumn.properties.order;
}
}
/** Counts number of object in given object
* Used to get number of columns that table header should span over
*/
public getColLength(tableCell): number {
let length: number;
this.tableHeader.forEach(row => {
if (row.category === tableCell) {
row.subcategories.forEach(subCategory => {
length = subCategory.entries[0].popular_item ? 1 : 0;
if (subCategory.subcategory === '') {
length += subCategory.entries.length;
} else {
length += row.subcategories.length;
}
});
}
});
return length;
}
public getPdpLink(product) {
const des = encodeURIComponent(product.designation);
return this.pgpURL ? `${this.pgpURL}/productid-${des}` : null;
}
/**
* Sort column on click, ascending and descending
* @param name Name of clicked column
*/
public sortColumn(name) {
let columnSorts = [];
if (this.documentList) {
// Find the sort options for the clicked column
columnSorts = this.documentList.sortOptions.filter(sort => {
if (sort.displayName.toLowerCase() === name.toLowerCase()) { return sort; }
});
// If Ascending sort is selected, switch to descending. If descending is selected, swith to ascending.
// If none i selected, select ascending.
if (columnSorts[0].selected) {
columnSorts[1].select();
} else {
columnSorts[0].select();
}
}
}
/**
* Checks if column is the designation column, used to highlight the column
*/
public isDesCol(header, index) {
return header.toLowerCase().indexOf('designation') > -1;
}
}
<div class="table-responsive">
<table class="table-sm table-striped table-bordered">
<thead class="table-head" *ngIf="tableHeader">
<tr class="table-row">
<th class="column-name upper-row" [colSpan]="getColLength(tabledata)" scope="colgroup"
*ngFor="let tabledata of tableHeaderFirstRow" [innerHTML]="tabledata">
</th>
</tr>
<tr class="table-row">
<ng-container *ngFor="let tabledata of tableHeaderSecondRow; let i=index">
<th class="column-name bottom-row" scope="col" (click)="sortColumn(tabledata.name)"
[ngClass]="{'selected-col': i==sortedColumn}">
<div class="col-sortable">
<div class="col-value" [title]="tabledata.name">
<span class="header-symbol" [innerHTML]="tabledata.symbol"
*ngIf="tabledata.symbol"></span>
<span *ngIf="tabledata.unit">[<span [innerHTML]="tabledata.unit"></span>]</span>
</div>
<div class="sort-direction" *ngIf="sortDir=='DESCENDING' && sortedColumn==i"><i
class="fas fa-chevron-up"></i></div>
<div class="sort-direction" *ngIf="sortDir=='ASCENDING' && sortedColumn==i"><i
class="fas fa-chevron-down"></i></div>
</div>
</th>
</ng-container>
</tr>
</thead>
<tbody class="table-body">
<tr class="table-row" *ngFor="let document of documentList.documents" [routerLink]="getPdpLink(document)" [ngClass]="{'disabled-link': !getPdpLink(document)}">
<ng-container *ngFor="let cellData of document.table_values; let i=index">
<td [ngClass]="{'column-value': true,
'selected-col': i==sortedColumn,
'column-value--bold': i==0 }">
<span class="column-value--triangle" *ngIf="tableHeaderSecondRow[i].popular_item"
[ngClass]="{'invisible': !document.popular_item}"><i class="fas fa-play"></i></span>
<span [ngClass]="{'column-value--blue': tableHeaderSecondRow[i].explorer && document.explorer}">
{{cellData}}
</span>
</td>
</ng-container>
</tr>
</tbody>
</table>
</div>
<div class="legend">
<ul class="list-group list-group-horizontal legend-labels">
<li class="list-group-item label blue" *ngIf="explorerLabel">
<i class="fas fa-square-full"></i>
{{explorerLabel}}
</li>
<li class="list-group-item label triangle" *ngIf="popularItemLabel">
<i class="fas fa-play popular-item"></i>
{{popularItemLabel}}
</li>
</ul>
</div>
@import "src/app/styles/helpers";
.table-sm {
width: 100%;
@include media-breakpoint-up(sd) {
.table-head .column-name { @include font-size(14); }
.table-body .column-value {
@include font-size(12);
line-height: 20px;
}
}
@include media-breakpoint-down(sd) {
.table-head .column-name { @include font-size(16); }
.table-body .column-value {
@include font-size(12);
line-height: 25px;
}
}
.no-border-left {
padding: 0px;
border-left: none;
}
.no-border-right {
border-right: none;
}
.table-head {
background-color: $blue;
color: white;
.column-name {
vertical-align: middle;
font-weight: normal;
&.bottom-row {
cursor: pointer;
&:hover {
background-color: $dark-blue;
}
}
&.selected-col {
background-color: $dark-blue;
}
.header-symbol {
margin-right: 5px;
}
.sort-direction {
margin-left: 3px;
}
.col-sortable {
display: flex;
flex-direction: row;
justify-content: space-between;
width: 100%;
height: 100%;
align-items: center;
@include font-size(14);
.col-value {
width: calc(100% - 13px);
}
}
}
}
.table-body {
.table-row {
cursor: pointer;
&:nth-child(odd) .selected-col {
background-color: $light-green;
}
&:nth-child(even) .selected-col {
background-color: $off-white;
}
&:hover {
.column-value {
background-color: $light-blue !important;
}
}
.column-value {
@include font-size(12);
color: $cool-grey;
&--blue {
color: $dark-blue;
}
&--triangle {
@include font-size(8);
margin-right: calc-rem(3);
}
&--bold {
font-weight: bold;
}
.popular-item {
width: calc-rem(20);
}
}
}
}
}
.legend {
position: absolute;
top: calc-rem(-30);
right: calc-rem(15);
&-labels {
@include font-size(14);
.label {
padding: 0 calc-rem(15);
border: none;
&:last-child {
padding-right: 0;
}
}
.blue {
i {
margin-right: calc-rem(3);
color: $dark-blue;
}
}
.popular-item {
@include font-size(10);
margin-right: calc-rem(3);
}
}
}
Legend
Html element with directive