angular/projects/researchdatabox/portal-ng-common/src/lib/record-table.component.ts
This component displays records in a table.
Features:
Requires:
selector | record-table |
templateUrl | ./record-table.component.html |
Properties |
|
Methods |
|
Inputs |
constructor(loggerService: LoggerService, utilService: UtilityService, lodashTemplateUtilityService: LoDashTemplateUtilityService)
|
||||||||||||
Parameters :
|
columnConfig | |
Type : RecordPropViewMetaDto[]
|
|
Default value : null as any
|
|
dataSource | |
Type : RecordSource
|
|
Default value : null as any
|
|
enableActions | |
Type : boolean
|
|
Default value : false
|
|
enableSort | |
Type : boolean
|
|
Default value : false
|
|
optTemplateData | |
Type : any
|
|
Default value : {}
|
|
paginationBoundaryLinks | |
Type : boolean
|
|
Default value : true
|
|
paginationClass | |
Type : string
|
|
Default value : 'pagination-sm'
|
|
paginationDirectionLinks | |
Type : boolean
|
|
Default value : false
|
|
paginationItemsPerPage | |
Type : number
|
|
Default value : 10
|
|
paginationMaxSize | |
Type : number
|
|
Default value : 10
|
|
paginationRotate | |
Type : boolean
|
|
Default value : true
|
|
showActions | |
Type : literal type[]
|
|
Default value : []
|
|
getColValue | |||||||||
getColValue(row: any, col: RecordPropViewMetaDto)
|
|||||||||
Parameters :
Returns :
any
|
getEntryValue | ||||||||||||||||
getEntryValue(row: any, col: RecordPropViewMetaDto, val: any)
|
||||||||||||||||
Parameters :
Returns :
string
|
Async gotoPage | ||||||
gotoPage(event: any)
|
||||||
Parameters :
Returns :
any
|
Async headerSortChanged |
headerSortChanged(event: any, data: any)
|
Returns :
any
|
Protected Async initComponent |
initComponent()
|
Inherited from
BaseComponent
|
Defined in
BaseComponent:81
|
Returns :
Promise<void>
|
getInitSubject |
getInitSubject()
|
Inherited from
BaseComponent
|
Defined in
BaseComponent:71
|
For those interested in the init from RXJS-land. Note that it returns a BehaviorSubject instance, and will have an initial value of false, so process the return value as needed.
Returns :
Subject<any>
|
isInitializing |
isInitializing()
|
Inherited from
BaseComponent
|
Defined in
BaseComponent:95
|
Main flag to indicate the init status
Returns :
boolean
|
ngOnInit |
ngOnInit()
|
Inherited from
BaseComponent
|
Defined in
BaseComponent:50
|
Returns :
void
|
Async waitForDeps |
waitForDeps()
|
Inherited from
BaseComponent
|
Defined in
BaseComponent:78
|
Wait for dependencies to initialise
Returns :
Promise<any>
|
Async waitForInit |
waitForInit()
|
Inherited from
BaseComponent
|
Defined in
BaseComponent:89
|
For those interested in the init from the Promise-land
Returns :
Promise<any>
|
headerSortItems |
Type : QueryList<HeaderSortComponent> | undefined
|
Decorators :
@ViewChildren(HeaderSortComponent)
|
Protected brandingAndPortalUrl |
Type : string
|
Default value : ''
|
Inherited from
BaseComponent
|
Defined in
BaseComponent:42
|
Private filterFn |
Default value : function(initStat: boolean) { return initStat; }
|
Inherited from
BaseComponent
|
Defined in
BaseComponent:40
|
Protected initDependencies |
Type : Initable[]
|
Default value : []
|
Inherited from
BaseComponent
|
Defined in
BaseComponent:39
|
Protected initSubject |
Type : BehaviorSubject<any>
|
Default value : new BehaviorSubject(false)
|
Inherited from
BaseComponent
|
Defined in
BaseComponent:38
|
Protected isReady |
Type : boolean
|
Default value : false
|
Inherited from
BaseComponent
|
Defined in
BaseComponent:37
|
import {Component, Input, Inject, ViewChildren, QueryList} from '@angular/core';
import { BaseComponent } from './base.component';
import { LoggerService } from './logger.service';
import { UtilityService } from './utility.service';
import { isEmpty as _isEmpty, get as _get, merge as _merge } from 'lodash-es';
import { RecordSource } from './record.model';
import { RecordPropViewMetaDto } from '@researchdatabox/sails-ng-common';
import { LoDashTemplateUtilityService } from './lodash-template-utility.service';
import {HeaderSortComponent} from "./header-sort.component";
/**
* This component displays records in a table.
*
* Features:
* - Pagination
* - Sortable column headers (pending)
* - Group by workflow stages (pending)
*
* Requires:
* - Data source, with async support
* - Config block used to render the table
*
* * Author: <a href='https://github.com/shilob' target='_blank'>Shilo B</a>
*/
@Component({
selector: 'record-table',
templateUrl: './record-table.component.html'
})
export class RecordTableComponent extends BaseComponent {
// row/column config
@Input() columnConfig: RecordPropViewMetaDto[] = null as any;
// the data source
@Input() dataSource: RecordSource = null as any;
// additional binding data for templates
@Input() optTemplateData: any = {};
// pagination
@Input() paginationItemsPerPage: number = 10;
@Input() paginationDirectionLinks:boolean = false;
@Input() paginationBoundaryLinks: boolean = true;
@Input() paginationClass: string = 'pagination-sm';
@Input() paginationMaxSize:number = 10;
@Input() paginationRotate: boolean = true;
// which actions to show in the table
@Input() showActions: {name:string, classes: string, label:string}[] = [];
// whether to enable table sorting
@Input() enableSort: boolean = false;
// whether to enable actions column
@Input() enableActions: boolean = false;
// find the header sort elements and provide references to them
@ViewChildren(HeaderSortComponent) headerSortItems: QueryList<HeaderSortComponent> | undefined;
constructor(
@Inject(LoggerService) private loggerService: LoggerService,
@Inject(UtilityService) private utilService: UtilityService,
@Inject(LoDashTemplateUtilityService) private lodashTemplateUtilityService: LoDashTemplateUtilityService,
) {
super();
// no deps
this.initDependencies = [];
}
protected override async initComponent():Promise<void> {
if (_isEmpty(this.dataSource)) {
this.loggerService.error(`RecordTableComponent is missing a datasource parameter!`);
throw new Error(`RecordTableComponent is missing a datasource parameter!`);
}
}
getColValue(row: any, col: RecordPropViewMetaDto) {
if (col.multivalue) {
let retVal = [];
for (let val of _get(row, col.property)) {
retVal.push(this.getEntryValue(row, col, val));
}
return retVal.join('');
} else {
return this.getEntryValue(row, col);
}
}
getEntryValue(row: any, col: RecordPropViewMetaDto, val: any = undefined) {
let retVal = '';
if (!_isEmpty(col.template)) {
const data = _merge({}, row, {
recordTableMeta: {
col: col,
val: val
},
optTemplateData: this.optTemplateData
});
retVal = this.lodashTemplateUtilityService.runTemplate(data, {template: col.template});
} else {
retVal = _get(row, col.property, val);
}
return retVal;
}
async gotoPage(event: any) {
await this.dataSource.gotoPage(event.page);
}
async headerSortChanged(event: any, data: any) {
// Reset the sort order for all headers, except the header that was clicked.
this.headerSortItems?.forEach(item => {
if (item.step == event.step && item.variable == event.variable) {
return;
}
item.sort = '';
})
}
}
<ng-container *ngIf="isReady && dataSource">
<ng-container *ngIf="dataSource.getCurrentPage() as currentPage">
<div class="row">
<table class="table" *ngIf="columnConfig">
<thead>
<tr>
<ng-container *ngFor="let col of columnConfig">
<th *ngIf="!col.hide">
<header-sort
*ngIf="enableSort"
[title]="col.label | i18next"
[variable]="col.property"
(headerSortChanged)="dataSource.headerSortChanged($event, col); headerSortChanged($event, col);">
</header-sort>
<span
*ngIf="!enableSort"
class="record-table-heading-no-sort">
{{col.label | i18next}}
</span>
</th>
</ng-container>
<th *ngIf="enableActions && showActions.length > 0">{{'record-table-results-table-header-actions' | i18next}}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let row of currentPage.records">
<ng-container *ngFor="let col of columnConfig">
<td *ngIf="!col.hide" [innerHtml]="getColValue(row, col)"></td>
</ng-container>
<td *ngIf="enableActions && showActions.length > 0">
<ng-container *ngFor="let showAction of showActions">
<button
type="button"
class="btn {{showAction.classes}}"
(click)="dataSource.recordTableAction($event, row, showAction.name)">{{showAction.label | i18next}}</button>
</ng-container>
</td>
</tr>
</tbody>
</table>
</div>
<!-- Pagination -->
<div *ngIf="currentPage.total > 0" class="row">
<pagination [directionLinks]="paginationDirectionLinks" [boundaryLinks]="paginationBoundaryLinks"
[totalItems]="currentPage.total" [itemsPerPage]="paginationItemsPerPage" [(ngModel)]="currentPage.pageNum"
(pageChanged)="gotoPage($event)" [class]="paginationClass" [maxSize]="paginationMaxSize" [rotate]="paginationRotate"></pagination>
</div>
</ng-container>
</ng-container>