File

app/shared/product-table/product-table.component.ts

Implements

OnInit OnChanges

Metadata

selector product-table
styleUrls ./product-table.component.scss
templateUrl ./product-table.component.html

Index

Properties
Methods
Inputs

Constructor

constructor(loadingService: LoadingIndicatorService, pubService: PublicationService, labelService: LabelService, router: Router, util: UtilService, opcService: OpcService)
Parameters :
Name Type Optional
loadingService LoadingIndicatorService No
pubService PublicationService No
labelService LabelService No
router Router No
util UtilService No
opcService OpcService No

Inputs

documentList
tableId
Type : string

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
Returns : number
Private getColumnSortOrder
getColumnSortOrder()
Returns : void
Public getPdpLink
getPdpLink(product)
Parameters :
Name Optional
product No
Returns : string
Public isDesCol
isDesCol(header, index)

Checks if column is the designation column, used to highlight the column

Parameters :
Name Optional
header No
index No
Returns : boolean
ngOnChanges
ngOnChanges(changes: SimpleChanges)
Parameters :
Name Type Optional
changes SimpleChanges No
Returns : void
ngOnInit
ngOnInit()
Returns : void
Private renderTableHeaders
renderTableHeaders()
Returns : void
Public sortColumn
sortColumn(name)

Sort column on click, ascending and descending

Parameters :
Name Optional Description
name No

Name of clicked column

Returns : void

Properties

calculateProductLabel
Type : string
explorerLabel
Type : string
lang
Type : string
Public loadingService
Type : LoadingIndicatorService
mountDismountLabel
Type : string
pgpURL
Type : string
popularItemLabel
Type : string
Public pubService
Type : PublicationService
showAction
Default value : false
sortDir
Type : string
sortedColumn
Type : number
tableHeader
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>

./product-table.component.scss

@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
Component
Html element with directive

result-matching ""

    No results matching ""