Newer
Older
import {
ChangeDetectionStrategy,
Component,
Input,
Output,
ViewChild,
ViewEncapsulation,
} from "@angular/core";
import {SharedAbstractPresentational} from "@app/shared/components/presentationals/shared-abstract/shared-abstract.presentational";
import {SharedPaginatorPresentational} from "@app/shared/components/presentationals/shared-paginator/shared-paginator.presentational";
import {FieldTypeEnum} from "@app/shared/enums/field-type.enum";
import {DataTableColumns} from "@app/shared/models/data-table-columns.model";
import {environment} from "@environments/environment";
import {DataTableComponentEnum} from "@shared/enums/data-table-component.enum";
import {DataTableActions} from "@shared/models/data-table-actions.model";
import {LazyLoadEvent} from "primeng/api";
import {
BehaviorSubject,
Observable,
} from "rxjs";

Florent Poittevin
committed
DateUtil,
isEmptyString,
isNullOrUndefined,

Florent Poittevin
committed
isObservable,
MappingObjectUtil,
ObjectUtil,
ObservableUtil,
OrderEnum,
Paging,
QueryParameters,
QueryParametersUtil,
Sort,
selector: "dlcm-shared-data-table",
templateUrl: "./shared-data-table.presentational.html",
styleUrls: ["./shared-data-table.presentational.scss"],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class SharedDataTablePresentational<TResource extends BaseResource> extends SharedAbstractPresentational {
readonly TIME_BEFORE_DISPLAY_TOOLTIP: number = environment.timeBeforeDisplayTooltipOnDataTable;
defaultSortColumn: DataTableColumns;
this._datas = value;
this.computeIsDatasPresent();
}
@Input()
skipInitialQuery: boolean = false;
@Input()
isLoading: boolean = false;
private _queryParameters: QueryParameters;
@Input()
columnsSkippedToClear: string[];
set queryParameters(value: QueryParameters) {
this._queryParameters = QueryParametersUtil.clone(value);
if (isNullOrUndefined(value.paging)) {
this._queryParameters.paging = new Paging(environment.defaultPageSize);
}
}
get queryParameters(): QueryParameters {
return this._queryParameters;
}
private _columns: DataTableColumns[];
set columns(value: DataTableColumns[]) {
this._columns = value;
this.defaultSortColumn = this._columns.find(c => isTrue(c.isSortable) && c.order !== 0);
}
get columns(): DataTableColumns[] {
return this._columns;
}
private _actions: DataTableActions[] = [];
@Input()
set actions(value: DataTableActions[]) {
this._actions = value;
}
get actions(): DataTableActions[] {
return this._actions;
}
private _listNewId: string[] = [];
@Input()
set listNewId(value: string[]) {
this._listNewId = value;
}
get listNewId(): string[] {
return this._listNewId;
}
@Input()
scrollHeight: string | undefined = undefined;
private readonly _selectBS: BehaviorSubject<TResource | undefined> = new BehaviorSubject<TResource | undefined>(undefined);
private readonly _queryParametersBS: BehaviorSubject<QueryParameters | undefined> = new BehaviorSubject<QueryParameters | undefined>(undefined);
@Output("selectChange")
readonly selectObs: Observable<TResource | undefined> = ObservableUtil.asObservable(this._selectBS);
@Output("queryParametersChange")
readonly queryParametersObs: Observable<QueryParameters | undefined> = ObservableUtil.asObservable(this._queryParametersBS);
paginator: SharedPaginatorPresentational;
get fieldTypeEnum(): typeof FieldTypeEnum {
return FieldTypeEnum;
}
get dataTableComponentEnum(): typeof DataTableComponentEnum {
return DataTableComponentEnum;
}
private readonly _SEPARATOR: string = ".";
let isDatasPresent = false;
if (!isNullOrUndefined(this.datas) && this.datas.length > 0) {
isDatasPresent = true;
}
this.isDatasPresent = isDatasPresent;
this._selectBS.next(row);
getCellData(row: TResource, column: DataTableColumns): any {
const data = this.getData(row, column);
if (column.translate && column.filterEnum) {
const enumValue = column.filterEnum.find(f => f.key === data + "");
if (enumValue) {
return enumValue.value;
}
return data;
}
return this.applyTypeToData(data, column.type);
getData(row: TResource, column: DataTableColumns): any {
const field = column.field;
if (field.includes(this._SEPARATOR)) {
return ObjectUtil.getNestedValue(row as any, column.field);
private applyTypeToData(data: any, type: FieldTypeEnum): any {
if (isNullOrUndefined(data)) {
return StringUtil.stringEmpty;
}
if (type === FieldTypeEnum.date) {

Florent Poittevin
committed
return DateUtil.convertDateToDateString(data);
}
if (type === FieldTypeEnum.datetime) {

Florent Poittevin
committed
return DateUtil.convertDateToDateTimeString(data);
backendSort($event: LazyLoadEvent): void {
if (isTrue(this.skipInitialQuery)) {
this.skipInitialQuery = false;
return;
}
const queryParameters = ObjectUtil.clone(this.queryParameters);
if (!isNullOrUndefined($event.sortField)) {
const sort = this.adaptLazyLoadEventToSortModel($event);
queryParameters.sort = sort;
}
this._queryParametersBS.next(queryParameters);
private adaptLazyLoadEventToSortModel($event: LazyLoadEvent): Sort {

Florent Poittevin
committed
field: this.getSortableFieldByFieldName($event.sortField),
order: $event.sortOrder === -1 ? OrderEnum.descending : OrderEnum.ascending,
} as Sort;
pageChange($event: Paging): void {
const queryParameters = ObjectUtil.clone(this.queryParameters);
queryParameters.paging = $event;
this._queryParametersBS.next(queryParameters);
onValueChange(col: DataTableColumns, value: string): void {
const fieldName = this.getFilterableField(col);
let queryParameters = ObjectUtil.clone(this.queryParameters);
queryParameters.search = ObjectUtil.clone(queryParameters.search);
queryParameters.search.searchItems = ObjectUtil.clone(queryParameters.search.searchItems);
if (isEmptyString(value) || isNullOrUndefined(value)) {
MappingObjectUtil.delete(queryParameters.search.searchItems, fieldName);
MappingObjectUtil.set(queryParameters.search.searchItems, fieldName, value);
queryParameters = QueryParametersUtil.resetToFirstPage(queryParameters);
this._queryParametersBS.next(queryParameters);
getValue(col: DataTableColumns): string | null {
const value = MappingObjectUtil.get(this.queryParameters.search.searchItems, this.getFilterableField(col));
if (value === null || value === undefined || value === StringUtil.stringEmpty) {
private getFilterableField(col: DataTableColumns): string {
return isNullOrUndefined(col.filterableField) ? col.field : col.filterableField;
}

Florent Poittevin
committed
private getSortableField(col: DataTableColumns): string {
return isNullOrUndefined(col.sortableField) ? col.field : col.sortableField;
}
getSortableFieldByFieldName(fieldName: string): string {
const column = this.columns.find(col => col.field === fieldName);
return this.getSortableField(column);
}
isFilterApplied(): boolean {
let toSkip: boolean = false;
if (MappingObjectUtil.size(QueryParametersUtil.getSearchItems(this.queryParameters)) > 0) {
if (this.columnsSkippedToClear === undefined || isEmptyArray(this.columnsSkippedToClear)) {
return true;
}
const searchItems: Map<string, string> = MappingObjectUtil.toMap(this.queryParameters.search.searchItems);
searchItems.forEach((value: string, key: string) => {
if (this.columnsSkippedToClear.some(c => c.includes(key)) === false) {
}
clearFilters(): void {
let queryParameters = QueryParametersUtil.clone(this.queryParameters);
const searchItems = QueryParametersUtil.getSearchItems(queryParameters);
if (this.columnsSkippedToClear === undefined || isEmptyArray(this.columnsSkippedToClear)) {
MappingObjectUtil.clear(searchItems);
MappingObjectUtil.forEach(searchItems, (value: string, key: string) => {
if (this.columnsSkippedToClear.some(c => c.includes(key)) === false) {
MappingObjectUtil.delete(searchItems, key);
}
});
}
queryParameters = QueryParametersUtil.resetToFirstPage(queryParameters);
this._queryParametersBS.next(queryParameters);
}
callCallback($event: MouseEvent, callback: (current: TResource) => void, rowData: TResource): void {
$event.stopPropagation();
callback(rowData);
}
if (isNullOrUndefined(this.listNewId) || isEmptyArray(this.listNewId)) {
return false;
}
return this.listNewId.includes(rowData.resId);
}

Florent Poittevin
committed
displayActionOnCondition(action: DataTableActions<TResource>, resource: TResource = undefined): boolean | Observable<boolean> {
if (isNullOrUndefined(resource) || isNullOrUndefined(action.displayOnCondition)) {
return this.atLeastOneActionRowDisplayed(action);
}
return action.displayOnCondition(resource);
}

Florent Poittevin
committed
private atLeastOneActionRowDisplayed(action: DataTableActions<TResource>): boolean | Observable<boolean> {
if (isNullOrUndefined(this._datas) || isEmptyArray(this._datas)) {
return false;
}
if (isNullOrUndefined(action.displayOnCondition)) {
return true;
}

Florent Poittevin
committed
if (this._datas.some(data => !isObservable(action.displayOnCondition(data)) && isTrue(action.displayOnCondition(data)))) {
return true;
}
// TODO Find a way to merge all observable
return action.displayOnCondition(this._datas[0]);
getWidth(column: DataTableColumns<TResource>): string {
if (!isNullOrUndefined(column.width)) {
return column.width;
}
if (column.component === DataTableComponentEnum.conformityLevelStar) {
return "100px";
}
if (column.type === FieldTypeEnum.datetime) {
return "145px";
}
if (column.type === FieldTypeEnum.date) {
return "90px";
}
return undefined;
}
isColumnFilterable(): boolean {
return !isNullOrUndefined(this.columns.find(c => isTrue(c.isFilterable)));
}