nm-list
src/app/shared/widgets/list/list.component.ts
host | { |
selector | nm-list |
styleUrls | list.component.scss |
templateUrl | ./list.component.html |
constructor(listService: ListService, router: Router, route: ActivatedRoute, _scrollService: ScrollService, _progressbarService: ProgressbarService, _shopCategoryService: ShopCategoryService, localStorageService: LocalStorageService, _notificationService: CustomNotificationService)
|
|||||||||||||||||||||||||||
Parameters :
|
Private addRowIndexToSelectedItem | ||||||
addRowIndexToSelectedItem(item: any)
|
||||||
Parameters :
Returns :
any
|
Protected configureWidget | ||||||
configureWidget(configuration: WidgetConfig)
|
||||||
Decorators : WidgetConfigure
|
||||||
Available json configurations: isListviewEnabled, cssClass, header, hideOnEmpty, default-profile, profiles, dataType, infoText, title, wikiLink, selectionMode
Parameters :
Returns :
void
|
dropdownValueChanged | ||||||
dropdownValueChanged(object: , rowIndex: )
|
||||||
Parameters :
Returns :
void
|
Private emitResults | ||||
emitResults(object: )
|
||||
Parameters :
Returns :
void
|
Private filterKey |
filterKey(field: string, value: string)
|
Returns :
string
|
getSortOrder | ||||
getSortOrder(col: )
|
||||
Parameters :
Returns :
any
|
keydown | ||||||
keydown(event: any)
|
||||||
Parameters :
Returns :
void
|
keyup | ||||||
keyup(event: any)
|
||||||
Parameters :
Returns :
void
|
Public loadData | ||||||
loadData(event: LazyLoadEvent)
|
||||||
Parameters :
Returns :
void
|
Private mapField |
mapField(value: any, type: string)
|
Returns :
any
|
Private mapResult | ||||||
mapResult(data: ResultResource)
|
||||||
Parameters :
Returns :
void
|
ngOnDestroy |
ngOnDestroy()
|
Returns :
void
|
ngOnInit |
ngOnInit()
|
Returns :
void
|
onBlur | ||||
onBlur(data: )
|
||||
Parameters :
Returns :
void
|
onChangeNumberField | ||||||
onChangeNumberField(object: , rowIndex: )
|
||||||
Parameters :
Returns :
void
|
onChangeViewMode | ||||
onChangeViewMode(event: )
|
||||
Parameters :
Returns :
void
|
onEnter | ||||
onEnter(event: )
|
||||
Parameters :
Returns :
void
|
onFilterKeyup | ||||||
onFilterKeyup(value: , field: )
|
||||||
Parameters :
Returns :
void
|
onFilterKeyupCustom | ||||||||
onFilterKeyupCustom(value: , field: , filterMatchMode: )
|
||||||||
Parameters :
Returns :
void
|
onFocus | ||||
onFocus(data: )
|
||||
Parameters :
Returns :
void
|
onPage | ||||
onPage(event: )
|
||||
Parameters :
Returns :
void
|
onRowSelectChange | ||||
onRowSelectChange(event: )
|
||||
Parameters :
Returns :
void
|
onSelect | ||||
onSelect(event: )
|
||||
Parameters :
Returns :
void
|
onSelectionChange | ||||
onSelectionChange(event: )
|
||||
Parameters :
Returns :
void
|
onSortingChanged | ||||||
onSortingChanged(event: , col: )
|
||||||
Parameters :
Returns :
void
|
openLink | ||||||||
openLink(data: , column: , event: )
|
||||||||
Parameters :
Returns :
boolean
|
openRelation | ||||
openRelation(contentNo: )
|
||||
Parameters :
Returns :
void
|
openRoute | ||||||||
openRoute(data: , column: , event: )
|
||||||||
Parameters :
Returns :
boolean
|
Public reload | ||||||||
reload(force: boolean)
|
||||||||
Parameters :
Returns :
void
|
Private restoreState | ||||
restoreState(lasturi: )
|
||||
Parameters :
Returns :
void
|
Private restoreStateForListview | ||||
restoreStateForListview(lasturi: )
|
||||
Parameters :
Returns :
void
|
selectors |
selectors()
|
Returns :
{ content: string; target: string; }
|
showDetails | ||||
showDetails(path: )
|
||||
Parameters :
Returns :
void
|
Public slideChange | ||||
slideChange(event: )
|
||||
Parameters :
Returns :
void
|
toogleContentVisibility |
toogleContentVisibility()
|
Returns :
void
|
Private _uriParams |
_uriParams:
|
Type : UriParams
|
Public autoexpand |
autoexpand:
|
Type : boolean
|
Default value : false
|
Private autoSearchLocalStorage |
autoSearchLocalStorage:
|
Type : LocalStorageEntry
|
Public boxHeight |
boxHeight:
|
Type : string
|
Default value : "220px"
|
Public boxWidth |
boxWidth:
|
Type : string
|
Default value : "33%"
|
Private clearSelectionChannel |
clearSelectionChannel:
|
Type : Subject<any>
|
Default value : new Subject<any>()
|
Decorators : WidgetInput
|
Resets all selected rows |
Public clientPaging |
clientPaging:
|
Type : boolean
|
Default value : false
|
Public cols |
cols:
|
Type : Subject<any[]>
|
Default value : new BehaviorSubject([])
|
Public columns |
columns:
|
Type : literal type
|
Default value : {}
|
Public configuration |
configuration:
|
Type : WidgetConfig
|
Decorators : WidgetConfiguration
|
Private contentNoLocalStorage |
contentNoLocalStorage:
|
Type : LocalStorageEntry
|
Public contentVisible |
contentVisible:
|
Type : boolean
|
Default value : true
|
Public cssClass |
cssClass:
|
Type : string
|
Private currentLink |
currentLink:
|
Type : string
|
datatable |
datatable:
|
Type : any
|
Decorators : ViewChild
|
Private dateOptions |
dateOptions:
|
Default value : {
year: "numeric",
month: "numeric",
day: "numeric",
hour: "numeric",
minute: "numeric",
} as const
|
Public debounceTime |
debounceTime:
|
Type : number
|
Default value : 500
|
Public dropdownData |
dropdownData:
|
Type : Subject<any[]>
|
Default value : new BehaviorSubject([])
|
Decorators : WidgetInput
|
Public dropdownsData |
dropdownsData:
|
Type : literal type
|
Default value : {}
|
Public editedRow |
editedRow:
|
Type : any
|
Default value : {}
|
Public expandedRows |
expandedRows:
|
Type : any[]
|
Default value : []
|
Public externalResource |
externalResource:
|
Type : boolean
|
Default value : false
|
Private filter |
filter:
|
Type : string[]
|
Public filterChanged |
filterChanged:
|
Type : boolean
|
Default value : false
|
Public filterOnBlur |
filterOnBlur:
|
Type : boolean
|
Default value : false
|
Public firstLoad |
firstLoad:
|
Type : boolean
|
Default value : true
|
Public header |
header:
|
Type : string
|
Public hideOnEmpty |
hideOnEmpty:
|
Type : boolean
|
Default value : false
|
Public hideTable |
hideTable:
|
Type : Subject<any>
|
Default value : new ReplaySubject<any>()
|
Decorators : WidgetInput
|
Public input |
input:
|
Default value : new Subject<any>()
|
Decorators : WidgetInput
|
Private inputChannel |
inputChannel:
|
Type : ReplaySubject<any>
|
Default value : new ReplaySubject<any>()
|
Decorators : WidgetInput
|
The uri that should be used to fetch the data |
Public isMultiselectActionNeeded |
isMultiselectActionNeeded:
|
Type : boolean
|
Default value : false
|
Public isViewmodeList |
isViewmodeList:
|
Type : boolean
|
Default value : false
|
Private isViewmodeListKey |
isViewmodeListKey:
|
Type : string
|
Private isViewmodeListLocalStorage |
isViewmodeListLocalStorage:
|
Type : LocalStorageEntry
|
Public keepSettingsAfterChangeViewMode |
keepSettingsAfterChangeViewMode:
|
Type : boolean
|
Default value : false
|
Public lastPrimeNGEvent |
lastPrimeNGEvent:
|
Type : LazyLoadEvent
|
Default value : {}
|
Public lasttotalresults |
lasttotalresults:
|
Type : Result[]
|
Default value : []
|
Private lastUriLocalStorage |
lastUriLocalStorage:
|
Type : LocalStorageEntry
|
Public limit |
limit:
|
Type : number
|
Default value : 10
|
Public lookups |
lookups:
|
Type : any
|
Public mappedResults |
mappedResults:
|
Type : Observable<Result[]>
|
Private modeIsChangedChannel |
modeIsChangedChannel:
|
Type : Subject<any>
|
Default value : new Subject<any>()
|
Decorators : WidgetInput
|
Public multiselectaction |
multiselectaction:
|
Type : Subject<any>
|
Default value : new BehaviorSubject({})
|
Public multiselectpayload |
multiselectpayload:
|
Type : Subject<any>
|
Default value : new BehaviorSubject({})
|
Private offset |
offset:
|
Type : number
|
Private onChange |
onChange:
|
Type : Subject<any>
|
Default value : new Subject<any>()
|
Public onEdit |
onEdit:
|
Default value : new Subject<any>()
|
Decorators : WidgetOutput
|
Emits each time a row is inline editted, payload is the editted row |
Public profile |
profile:
|
Type : string
|
Private profileChannel |
profileChannel:
|
Type : Subject<any>
|
Default value : new Subject<any>()
|
Decorators : WidgetInput
|
Set the profile the table is using |
Static QUERY_PARAMS_CONTD |
QUERY_PARAMS_CONTD:
|
Type : string
|
Default value : "{&page,offset,limit,filter*,sort,data-locale,locale,cache,attributes,force-reload}"
|
Static QUERY_PARAMS_PAGING_CONTD |
QUERY_PARAMS_PAGING_CONTD:
|
Type : string
|
Default value : "{&page,offset,limit}"
|
Static QUERY_PARAMS_PAGING_START |
QUERY_PARAMS_PAGING_START:
|
Type : string
|
Default value : "{?page,offset,limit}"
|
Static QUERY_PARAMS_START |
QUERY_PARAMS_START:
|
Type : string
|
Default value : "{?page,offset,limit,filter*,sort,data-locale,locale,cache,attributes,force-reload}"
|
Public refresh |
refresh:
|
Type : any
|
Public relation |
relation:
|
Type : Subject<any>
|
Default value : new ReplaySubject<any>()
|
Decorators : WidgetOutput
|
Public relationURL |
relationURL:
|
Type : string
|
Private reloadChannel |
reloadChannel:
|
Type : Subject<any>
|
Default value : new Subject<any>()
|
Decorators : WidgetInput
|
Force a reload of the table on input |
Private requestRunning |
requestRunning:
|
Default value : false
|
Public requestStarted |
requestStarted:
|
Type : boolean
|
Default value : false
|
Public resetChannel |
resetChannel:
|
Default value : new Subject<any>()
|
Decorators : WidgetInput
|
Reset the sort, filter and paginator// Emits all selected items whenever they change |
Public results |
results:
|
Type : Subject<Result[]>
|
Default value : new BehaviorSubject([])
|
Decorators : WidgetOutput
|
Private selectedItems |
selectedItems:
|
Type : Subject<any>
|
Default value : new Subject<any>()
|
Decorators : WidgetOutput
|
Emits all selected items whenever they change |
Public selectedLocale |
selectedLocale:
|
Default value : new ReplaySubject<any>()
|
Decorators : WidgetInput
|
Input for the current locale (of ipim) |
Private selectedLocaleString |
selectedLocaleString:
|
Type : string
|
Default value : ""
|
Public selectedRows |
selectedRows:
|
Type : Result[]
|
Default value : []
|
Public selectedRowsOnShift |
selectedRowsOnShift:
|
Type : Result[]
|
Default value : []
|
Public selectedUiLocale |
selectedUiLocale:
|
Default value : new ReplaySubject<any>()
|
Decorators : WidgetInput
|
Input for the current locale (of the ui) |
Private selectedUiLocaleString |
selectedUiLocaleString:
|
Type : string
|
Default value : ""
|
Public selectedViewmode |
selectedViewmode:
|
Type : string
|
Default value : "table"
|
Public selectionMode |
selectionMode:
|
Type : string
|
Default value : "multiple"
|
Public shiftIsPressed |
shiftIsPressed:
|
Type : boolean
|
Public showProgressBar |
showProgressBar:
|
Default value : new BehaviorSubject<boolean>(true)
|
Decorators : WidgetInput
|
Flag to toggle progress bar during request |
Public slidevalue |
slidevalue:
|
Type : number
|
Default value : 3
|
Private sort |
sort:
|
Type : string
|
Private style |
style:
|
Type : string
|
Public template |
template:
|
Type : any
|
Public title |
title:
|
Type : string
|
Public total |
total:
|
Type : BehaviorSubject<number>
|
Default value : new BehaviorSubject(0)
|
Decorators : WidgetOutput
|
Public totalresults |
totalresults:
|
Type : Result[]
|
Default value : []
|
Private unsubscribe |
unsubscribe:
|
Default value : NgUnsubscribe.create()
|
Public wikiLink |
wikiLink:
|
Type : string
|
Public withFooter |
withFooter:
|
Type : boolean
|
Default value : false
|
Public withHeader |
withHeader:
|
Type : boolean
|
Default value : true
|
uriParams | ||||||
geturiParams()
|
||||||
seturiParams(params: any)
|
||||||
Parameters :
Returns :
void
|
import {
BehaviorSubject,
empty as observableEmpty,
Observable,
of as observableOf,
ReplaySubject,
Subject,
timer as observableTimer,
} from "rxjs";
import {
catchError,
debounceTime,
distinctUntilChanged,
map,
mergeMap,
switchMap,
take,
takeUntil,
withLatestFrom,
} from "rxjs/operators";
import { Component, Input, OnDestroy, OnInit, ViewChild } from "@angular/core";
import { ActivatedRoute, Router } from "@angular/router";
import { Table } from "../../components/primeng/table/table";
import { LazyLoadEvent } from "../../components/primeng/common/lazyloadevent";
import { ListService } from "./list.service";
import { ScrollService } from "../../components/scroll/scroll.service";
import { ProgressbarService } from "../../components/progressbar/progressbar.service";
import { WidgetConfig } from "../widget.configuration";
import { ShopCategoryService } from "../apps/my-shop-md/shop-category/shop-category.service";
import { CustomNotificationService } from "../../components/notification/customnotification.service";
import { UtilService } from "../../components/util/util.service";
import {
WidgetComponent,
WidgetConfiguration,
WidgetConfigure,
WidgetInput,
WidgetOutput,
} from "../widget.metadata";
import { Result, ResultResource } from "../interfaces/list.interfaces";
import { NgUnsubscribe } from "../../ng-unsubscribe";
import * as uriTemplates_ from "uri-templates";
import {
DeletionMode,
Scope,
} from "../../components/local-storage/local-storage-constants";
import {
LocalStorageEntry,
LocalStorageService,
} from "../../components/local-storage/local-storage.service";
const uriTemplates = uriTemplates_;
declare var $;
declare var jQuery: any;
interface UriParams {
timestamp?: number;
template?: any;
offset?: number;
limit?: number;
sort?: string;
filter?: string[];
[key: string]: any;
}
@WidgetComponent("nm-list")
@Component({
selector: "nm-list",
templateUrl: "./list.component.html",
styleUrls: ["./list.component.scss"],
host: {
"(window:keydown.passive)": "keydown($event)",
"(window:keyup.passive)": "keyup($event)",
},
})
export class ListComponentWidget implements OnInit, OnDestroy {
@ViewChild("dt") datatable: any;
static QUERY_PARAMS_CONTD =
"{&page,offset,limit,filter*,sort,data-locale,locale,cache,attributes,force-reload}";
static QUERY_PARAMS_START =
"{?page,offset,limit,filter*,sort,data-locale,locale,cache,attributes,force-reload}";
static QUERY_PARAMS_PAGING_CONTD = "{&page,offset,limit}";
static QUERY_PARAMS_PAGING_START = "{?page,offset,limit}";
public selectedViewmode: string = "table";
public isViewmodeList: boolean = false;
public mappedResults: Observable<Result[]>;
public multiselectaction: Subject<any> = new BehaviorSubject({});
public multiselectpayload: Subject<any> = new BehaviorSubject({});
public isMultiselectActionNeeded: boolean = false;
public cols: Subject<any[]> = new BehaviorSubject([]);
public lookups: any;
public slidevalue: number = 3;
public boxWidth: string = "33%";
public boxHeight: string = "220px";
public contentVisible: boolean = true;
public totalresults: Result[] = [];
public lasttotalresults: Result[] = [];
public selectedRows: Result[] = [];
public selectedRowsOnShift: Result[] = [];
public expandedRows: any[] = [];
public shiftIsPressed: boolean;
public firstLoad: boolean = true;
public externalResource: boolean = false;
public clientPaging: boolean = false;
public template: any;
public profile: string;
public hideOnEmpty: boolean = false;
public autoexpand: boolean = false;
public cssClass: string;
public header: string;
public filterChanged: boolean = false;
public keepSettingsAfterChangeViewMode: boolean = false;
public lastPrimeNGEvent: LazyLoadEvent = {};
public refresh: any;
public debounceTime: number = 500;
public editedRow: any = {};
public selectionMode = "multiple";
public columns: { [key: string]: any } = {};
public requestStarted: boolean = false;
private requestRunning = false;
public filterOnBlur: boolean = false;
public withFooter: boolean = false;
@WidgetInput()
public dropdownData: Subject<any[]> = new BehaviorSubject([]);
public dropdownsData: { [key: string]: any } = {};
//Emits currently visible data
@WidgetOutput("results")
public results: Subject<Result[]> = new BehaviorSubject([]);
@Input("widgetId") widgetId: string;
@WidgetOutput("total")
public total: BehaviorSubject<number> = new BehaviorSubject(0);
@Input("info-text")
public infoText: string = "list.results";
public wikiLink: string;
public title: string;
@Input("inputLink") inputLink: string;
@Input("dataType") dataType: string = "products";
// Deprecated
@WidgetInput()
public input = new Subject<any>();
/**
* Emits each time a row is inline editted, payload is the editted row
*/
@WidgetOutput("onEdit")
public onEdit = new Subject<any>();
@WidgetConfiguration()
public configuration: WidgetConfig;
/**
* Emits the link the list is searching for, each time a search is triggered
*/
@WidgetOutput("searchLink")
public searchLink: BehaviorSubject<string> = new BehaviorSubject<string>(
null
);
private _uriParams: UriParams;
@Input("uriParams")
public set uriParams(params: any) {
this._uriParams = <UriParams>params;
}
public get uriParams(): any {
return this._uriParams;
}
/**
* The uri that should be used to fetch the data
*/
@WidgetInput("uri")
private inputChannel: ReplaySubject<any> = new ReplaySubject<any>();
@WidgetInput("modeischanged")
private modeIsChangedChannel: Subject<any> = new Subject<any>();
/**
* Force a reload of the table on input
*/
@WidgetInput("reload")
private reloadChannel: Subject<any> = new Subject<any>();
/**
* Reset the sort, filter and paginator// Emits all selected items whenever they change
*/
@WidgetInput("reset")
public resetChannel = new Subject<any>();
/**
*Resets all selected rows
*/
@WidgetInput("clearSelection")
private clearSelectionChannel: Subject<any> = new Subject<any>();
/**
*Set the profile the table is using
*/
@WidgetInput("profile")
private profileChannel: Subject<any> = new Subject<any>();
/**
*Emits all selected items whenever they change
*/
@WidgetOutput("selectedItems")
private selectedItems: Subject<any> = new Subject<any>();
/**
*Input for the current locale (of ipim)
*/
@WidgetInput()
public selectedLocale = new ReplaySubject<any>();
/**
*Input for the current locale (of the ui)
*/
@WidgetInput()
public selectedUiLocale = new ReplaySubject<any>();
/**
*Flag to toggle progress bar during request
*/
@WidgetInput()
public showProgressBar = new BehaviorSubject<boolean>(true);
@WidgetOutput()
public relation: Subject<any> = new ReplaySubject<any>();
// hide table
@WidgetInput("hide")
public hideTable: Subject<any> = new ReplaySubject<any>();
private currentLink: string;
private onChange: Subject<any> = new Subject<any>();
private offset: number;
public limit: number = 10;
private sort: string;
private filter: string[];
private style: string;
private isViewmodeListKey: string;
public withHeader: boolean = true;
private selectedLocaleString: string = "";
private selectedUiLocaleString: string = "";
private dateOptions = {
year: "numeric",
month: "numeric",
day: "numeric",
hour: "numeric",
minute: "numeric",
} as const;
public relationURL: string;
private isViewmodeListLocalStorage: LocalStorageEntry;
private lastUriLocalStorage: LocalStorageEntry;
private autoSearchLocalStorage: LocalStorageEntry;
private contentNoLocalStorage: LocalStorageEntry;
private unsubscribe = NgUnsubscribe.create();
constructor(
private listService: ListService,
private router: Router,
private route: ActivatedRoute,
private _scrollService: ScrollService,
private _progressbarService: ProgressbarService,
private _shopCategoryService: ShopCategoryService,
private localStorageService: LocalStorageService,
private _notificationService: CustomNotificationService
) {
//In case a former call was aborted
this._progressbarService.requestFinished();
this.selectedViewmode = "table";
this.mappedResults = this.results.pipe(
withLatestFrom(this.cols),
map((data) => {
const rows = data[0];
const cols = data[1];
if (cols.length == 0 || rows.length == 0) {
return [];
} else {
return rows.map((input) => {
const row = Object.assign({}, input);
for (let i = 0; i < cols.length; i++) {
const col = cols[i];
const field = row[col.field];
if (field == undefined) {
continue;
}
if (col.type) {
row[col.field] = this.mapField(field, col.type);
}
}
return row;
});
}
})
);
}
/**
*Available json configurations:
*
* isListviewEnabled, cssClass, header, hideOnEmpty, default-profile, profiles, dataType, infoText, title, wikiLink, selectionMode
*
*/
@WidgetConfigure()
protected configureWidget(configuration: WidgetConfig) {
this.title = this.configuration.configuration["title"];
this.slidevalue = this.configuration.configuration["slidevalue"];
this.lastUriLocalStorage = this.localStorageService.getLocalStorageEntry(
"last-uri" + this.title,
Scope.GLOBAL,
DeletionMode.RESET
);
this.isViewmodeListKey =
this.configuration.configuration["isViewmodeListKey"];
this.isViewmodeListLocalStorage = this.isViewmodeListKey
? this.localStorageService.getLocalStorageEntry(
this.isViewmodeListKey,
Scope.GLOBAL,
DeletionMode.LOGIN
)
: null;
if (configuration.configuration["isListviewEnabled"]) {
if (this.isViewmodeListLocalStorage.value) {
this.isViewmodeList = this.isViewmodeListLocalStorage.value === "true";
} else {
this.isViewmodeList =
this.configuration.configuration["isViewmodeListActive"];
}
}
this.cssClass = configuration.configuration["cssClass"] || "";
this.header = configuration.configuration["header"] || "primary";
this.hideOnEmpty = configuration.configuration["hideOnEmpty"] || false;
this.profile = configuration.configuration["default-profile"];
this.cols.next(
configuration.configuration["profiles"][
configuration.configuration["default-profile"]
]
);
this.dataType = configuration.configuration["dataType"];
this.infoText = configuration.configuration["infoText"];
if (this.configuration.configuration["withHeader"] != undefined) {
this.withHeader = this.configuration.configuration["withHeader"];
}
this.wikiLink = this.configuration.configuration["wikiLink"];
const selectionMode = this.configuration.configuration["selectionMode"];
if (selectionMode) {
this.selectionMode = selectionMode;
}
this.dropdownData.next(
configuration.configuration["dropdownConfigs"]
? configuration.configuration["dropdownConfigs"]
: null
);
this.filterOnBlur = configuration.configuration["filterOnBlur"]
? configuration.configuration["filterOnBlur"]
: false;
this.withFooter = configuration.configuration["withFooter"]
? configuration.configuration["withFooter"]
: false;
this.externalResource = configuration.configuration["externalResource"];
this.clientPaging =
configuration.configuration["clientPaging"] !== undefined
? configuration.configuration["clientPaging"]
: false;
this.debounceTime =
configuration.configuration["debounceTime"] !== undefined
? parseInt(configuration.configuration["debounceTime"])
: 500;
this.limit =
this.configuration.configuration["defaultPageSize"] !== undefined
? parseInt(this.configuration.configuration["defaultPageSize"])
: 10;
this.autoexpand = configuration.configuration["autoexpand"]
? configuration.configuration["autoexpand"]
: false;
this.refresh = configuration.configuration["refresh"];
this.relationURL = configuration.configuration["relationURL"]
? configuration.configuration["relationURL"]
: "";
if (this.refresh) {
let timer = observableTimer(this.refresh, this.refresh);
timer.pipe(takeUntil(this.unsubscribe)).subscribe((t) => {
this.expandedRows = [].concat(this.datatable.expandedRows);
// this.reload(true);
});
}
this.hideTable
.asObservable()
.pipe(takeUntil(this.unsubscribe))
.subscribe((hide) => {
this.hideOnEmpty = true;
this.results.next([]);
});
this.selectedLocale
.asObservable()
.pipe(takeUntil(this.unsubscribe))
.subscribe((selectedLocale) => {
this.selectedLocaleString = selectedLocale;
this.reload();
});
this.selectedUiLocale
.asObservable()
.pipe(takeUntil(this.unsubscribe))
.subscribe((selectedUiLocale) => {
this.selectedUiLocaleString = selectedUiLocale;
this.reload();
});
this.profileChannel
.asObservable()
.pipe(takeUntil(this.unsubscribe))
.subscribe((profile) => {
this.profile = profile;
this.cols.next(configuration.configuration["profiles"][profile]);
});
this.clearSelectionChannel
.asObservable()
.pipe(takeUntil(this.unsubscribe))
.subscribe((reload) => {
this.selectedRows = [];
this.isMultiselectActionNeeded = false;
});
this.reloadChannel
.asObservable()
.pipe(takeUntil(this.unsubscribe))
.subscribe((reload) => {
this.reload(true);
});
this.resetChannel
.asObservable()
.pipe(takeUntil(this.unsubscribe))
.subscribe((reset) => {
this.lastUriLocalStorage.clear();
this.currentLink = null;
this.lastPrimeNGEvent = {};
this.lastPrimeNGEvent.filters = {};
this.sort = "";
this.filter = [];
if (this.datatable) {
this.datatable.reset();
}
this.inputChannel.next(null);
});
this.modeIsChangedChannel
.asObservable()
.pipe(takeUntil(this.unsubscribe))
.subscribe((isChanged) => {
if (this.datatable) {
this.datatable.reset();
}
this.reload();
});
this.inputChannel
.asObservable()
.pipe(takeUntil(this.unsubscribe))
.subscribe((link) => {
console.log("input link", link);
this.clearSelectionChannel.next();
if (link === null || link === undefined) {
this.total.next(null);
this.results.next([]);
} else {
this._progressbarService.requestFinished();
this.total.next(null);
this.currentLink = link;
let queryParams =
link.indexOf("?") >= 0
? ListComponentWidget.QUERY_PARAMS_CONTD
: ListComponentWidget.QUERY_PARAMS_START;
this.currentLink =
link.indexOf("filter*") >= 0 ? link : link + queryParams;
this.offset = 0;
this.totalresults = [];
if (this.datatable) {
this.datatable.reset();
}
this.lastPrimeNGEvent = {};
this.lastPrimeNGEvent.filters = {};
this.sort = "";
this.filter = [];
if (this.isViewmodeList) {
this.results.next([]);
}
if (this.lastUriLocalStorage.exists() && this.firstLoad) {
let lasturi = this.lastUriLocalStorage.value;
let timer = observableTimer(1);
timer.subscribe((t) => {
if (this.datatable) {
this.restoreState(lasturi);
} else {
this.restoreStateForListview(lasturi);
}
this.firstLoad = false;
});
} else {
this.reload();
}
}
});
this.onChange
.pipe(
debounceTime(this.debounceTime),
map((trigger) => {
let input = this.currentLink;
let offset = this.offset || 0;
let limit = this.limit || 10;
let sort = this.sort || "";
let filter = this.filter || [];
if (!input) {
return null;
}
let uriParams = Object.assign({});
if (!this.clientPaging) {
uriParams.offset = offset;
uriParams.limit = limit;
uriParams.sort = sort;
uriParams.filter = filter;
}
if (
this.selectedLocaleString &&
this.selectedLocaleString.length > 0
) {
uriParams["data-locale"] = this.selectedLocaleString;
this.dropdownData
.pipe(takeUntil(this.unsubscribe), debounceTime(1), take(1))
.subscribe((dropdownConfigs) => {
if (dropdownConfigs != null) {
let dropdownData = {};
for (let dropdownConfig of dropdownConfigs) {
let template = uriTemplates(dropdownConfig.url).fill({
locale: this.selectedUiLocaleString
? this.selectedUiLocaleString
: this.selectedLocaleString,
});
this.listService.getActions(template).subscribe((data) => {
let values = [];
let receivedValues: any[] =
data["_embedded"][dropdownConfig.dataType];
receivedValues.forEach((row) => {
values.push({
id: row.identifier,
description: row.description,
});
});
dropdownData[dropdownConfig.field] = values;
this.dropdownsData = dropdownData;
});
}
}
});
}
if (
this.selectedUiLocaleString &&
this.selectedUiLocaleString.length > 0
) {
uriParams.locale = this.selectedUiLocaleString;
}
if (trigger !== undefined) {
uriParams.cache = (<Date>trigger).getTime();
}
uriParams.template = input;
return uriParams;
}),
map((uriParams) => {
if (!uriParams) {
return null;
}
this.template = uriTemplates((<any>uriParams).template);
return this.template.fill(uriParams);
}),
switchMap((uri) => {
this.requestRunning = true;
if (this.requestStarted) {
this.requestStarted = false;
this._progressbarService.requestFinished();
}
this.searchLink.next(uri);
return observableOf(uri).pipe(
withLatestFrom(this.showProgressBar),
mergeMap(([uri, showProgressBar]) => {
if (uri && !uri.startsWith("undefined")) {
this.lastUriLocalStorage.value = uri;
if (this.externalResource) {
return this.listService.getTemplatedFilteredResults(uri);
} else {
this.requestStarted = true;
return this.listService.getTemplatedFilteredResults(
uri,
showProgressBar
);
}
} else {
return observableEmpty();
}
}),
catchError((err) => {
this._notificationService.fromResponse(err);
this.requestRunning = false;
return observableEmpty();
})
);
}),
takeUntil(this.unsubscribe)
)
.subscribe(
(data) => {
this.requestRunning = false;
this.mapResult(data);
},
(err) => {
this._progressbarService.requestFinished();
}
);
this.cols
.pipe(
takeUntil(this.unsubscribe),
map((cols) => {
for (let col of cols) {
if (!col.sortable && !col.filter) {
if (col.style) {
col.style += " noFilter";
} else {
col.style = "noFilter";
}
}
}
return cols;
})
)
.subscribe((cols) => {
let columns = {};
for (let col of cols) {
columns[col.field] = col;
}
this.columns = columns;
});
this.slideChange(null);
}
private restoreState(lasturi) {
let params;
if (!this.template) {
params = UtilService.getAllUrlParams(lasturi);
} else {
params = this.template.fromUri(lasturi);
}
if (params === undefined) {
return;
}
if (params.filter !== undefined) {
for (var item of params.filter) {
let filterIdentifier = item.substring(0, item.indexOf(":"));
let filter = item.substring(
item.indexOf('"') + 1,
item.lastIndexOf('"')
);
this.datatable.filter(filter, filterIdentifier, "startsWith");
var filterItem = this.filterKey(filterIdentifier, filter);
this.lastPrimeNGEvent.filters[filterIdentifier] = {};
this.lastPrimeNGEvent.filters[filterIdentifier].value = filter;
this.filter.push(filterItem);
}
}
if (params.sort !== undefined) {
let item = params.sort;
let sortIdentifier = item.substring(0, item.indexOf(":"));
let sortValue = item.substring(item.indexOf(":") + 1, item.length);
this.datatable.sortField = sortIdentifier;
this.datatable.sortOrder = sortValue === "asc" ? 1 : -1;
this.datatable.sortSingle();
this.lastPrimeNGEvent.sortOrder = sortValue === "asc" ? 1 : -1;
this.lastPrimeNGEvent.sortField = sortIdentifier;
this.sort = params.sort;
}
if (params.offset !== undefined && params.offset != 0) {
let paging = {
first: parseInt(params.offset),
rows: parseInt(params.limit),
};
}
this.keepSettingsAfterChangeViewMode = true;
this.reload();
}
private restoreStateForListview(lasturi) {
this.lastPrimeNGEvent.filters = {};
let params;
if (!this.template) {
params = UtilService.getAllUrlParams(lasturi);
} else {
params = this.template.fromUri(lasturi);
}
if (params === undefined) {
return;
}
if (params.filter !== undefined) {
for (var item of params.filter) {
let filterIdentifier = item.substring(0, item.indexOf(":"));
let filter = item.substring(
item.indexOf('"') + 1,
item.lastIndexOf('"')
);
var filterItem = this.filterKey(filterIdentifier, filter);
this.lastPrimeNGEvent.filters[filterIdentifier] = {};
this.lastPrimeNGEvent.filters[filterIdentifier].value = filter;
this.filter.push(filterItem);
}
}
if (params.sort !== undefined) {
let item = params.sort;
let sortIdentifier = item.substring(0, item.indexOf(":"));
let sortValue = item.substring(item.indexOf(":") + 1, item.length);
this.lastPrimeNGEvent.sortOrder = sortValue === "asc" ? 1 : -1;
this.lastPrimeNGEvent.sortField = sortIdentifier;
this.sort = params.sort;
}
this.keepSettingsAfterChangeViewMode = true;
this.limit = 10;
this.offset = 0;
this.results.next([]);
this.reload();
}
onFilterKeyupCustom(value, field, filterMatchMode) {
let changed: boolean = false;
for (let i = this.filter.length - 1; i >= 0; i--) {
let item = this.filter[i];
let split = item.split(":");
if (split[0] && split[1] && split[0] === field && split[1] != value) {
changed = true;
if (!value) {
this.filter.splice(i, 1);
} else {
split[1] = value;
let join = split.join(":");
this.filter[i] = join;
}
}
}
if (this.filter.length === 0 && field && value) {
changed = true;
this.filter.push(field + ":" + value);
}
if (changed) {
this.lastUriLocalStorage.clear();
this.firstLoad = false;
this.reload();
}
}
onFilterKeyup(value, field) {
this.lastPrimeNGEvent.filters[field] = {};
this.lastPrimeNGEvent.filters[field].value = value;
let duplicate = this.filter.filter((item) => item.startsWith(field));
if (duplicate.length > 0) {
this.filter.splice(this.filter.indexOf(duplicate[0]), 1);
}
this.filter.push(this.filterKey(field, value));
this.results.next([]);
this.limit = 10;
this.offset = 0;
this.filterChanged = true;
this.reload();
}
getSortOrder(col) {
if (this.lastPrimeNGEvent.sortField == col.field) {
return this.lastPrimeNGEvent.sortOrder;
}
}
onSortingChanged(event, col) {
if (event.target.classList.contains("fa-sort-desc")) {
event.target.classList.remove("fa-sort-desc");
event.target.classList.add("fa-sort-asc");
this.lastPrimeNGEvent.sortOrder = 1;
} else if (event.target.classList.contains("fa-sort-asc")) {
event.target.classList.remove("fa-sort-asc");
event.target.classList.add("fa-sort-desc");
this.lastPrimeNGEvent.sortOrder = -1;
} else {
event.target.classList.add("fa-sort-desc");
this.lastPrimeNGEvent.sortOrder = -1;
}
this.lastPrimeNGEvent.sortField = col.field;
this.keepSettingsAfterChangeViewMode = true;
var order = this.lastPrimeNGEvent.sortOrder === 1 ? "asc" : "desc";
this.sort = this.lastPrimeNGEvent.sortField.toString() + ":" + order;
this.limit = 10;
this.offset = 0;
this.results.next([]);
this.reload();
}
ngOnInit() {
this.lastPrimeNGEvent = {};
this.lastPrimeNGEvent.filters = {};
this._scrollService
.getOnScroll()
.pipe(debounceTime(200), takeUntil(this.unsubscribe))
.subscribe((data) => {
if (this._progressbarService.hasOpenRequests()) {
return;
}
if (!this.isViewmodeList) {
return;
}
let total = this.total.getValue();
if (total < 10 || this.offset > total) {
return;
}
this.offset = this.offset + 10;
this.reload();
});
}
ngOnDestroy(): void {
this.unsubscribe.destroy();
this._progressbarService.requestFinished();
}
onChangeViewMode(event) {
this.totalresults = [];
this.isViewmodeList = event.checked;
this.isViewmodeListLocalStorage.value =
this.isViewmodeList === true ? "true" : "false";
this.keepSettingsAfterChangeViewMode = true;
this.offset = 0;
if (!this.isViewmodeList) {
this.limit =
this.configuration.configuration["defaultPageSize"] !== undefined
? parseInt(this.configuration.configuration["defaultPageSize"])
: 10;
let timer = observableTimer(1);
timer.subscribe((t) => {
if (this.lastUriLocalStorage.value) {
this.restoreState(this.lastUriLocalStorage.value);
}
});
} else {
this.results.next([]);
this.limit = 10;
this.offset = 0;
this.reload();
}
}
private filterKey(field: string, value: string) {
let filterType = this.columns[field]["filter-type"] || "";
return (
field + ":" + (filterType ? `${filterType}:` : "") + '"' + value + '"'
);
}
public loadData(event: LazyLoadEvent) {
var _sort: string = "";
var _filter: string[] = [];
if (!this.isViewmodeList) {
this.lastPrimeNGEvent = event;
}
if (typeof event.sortField !== "undefined" && event.sortField !== null) {
var order = event.sortOrder === 1 ? "asc" : "desc";
_sort = event.sortField.toString() + ":" + order;
}
if (typeof event.filters !== "undefined" && event.filters !== null) {
for (let field in event.filters) {
_filter.push(this.filterKey(field, event.filters[field].value));
}
}
if (!this.keepSettingsAfterChangeViewMode) {
this.sort = _sort;
this.filter = _filter;
this.offset = event.first;
this.limit = event.rows;
}
this.keepSettingsAfterChangeViewMode = false;
this.reload();
}
public reload(force: boolean = false) {
if (force) {
this.onChange.next(new Date());
} else {
this.onChange.next();
}
}
private mapResult(data: ResultResource) {
//if there are additional attributes
if (data._embedded[this.dataType][0]) {
if (data._embedded[this.dataType][0].hasOwnProperty("attributes")) {
for (var result of data._embedded[this.dataType]) {
for (var attribute of result.attributes) {
result[attribute.identifier] = attribute.value;
}
}
}
if (data._embedded[this.dataType][0].hasOwnProperty("properties")) {
for (var result of data._embedded[this.dataType]) {
for (var property of result.properties) {
result[property.identifier] = property.value;
}
}
}
}
this.lookups = data["lookups"];
this.multiselectaction.next(data._actions);
if (data._embedded[this.dataType].length > 0) {
if (this.isViewmodeList) {
if (this.slidevalue > 3) {
if (this.offset === 0) {
this.offset += 10;
this.reload();
} else if (this.slidevalue > 4 && this.offset < 20) {
this.offset += 10;
this.reload();
}
}
if (this.filterChanged) {
this.results.next(data._embedded[this.dataType]);
this.filterChanged = false;
} else {
if (this.totalresults.length === 0) {
this.results.subscribe((data) => {
this.totalresults = data;
});
}
this.totalresults = this.totalresults.concat(
data._embedded[this.dataType]
);
this.results.next(this.totalresults);
}
} else {
this.totalresults = data._embedded[this.dataType];
this.results.next(data._embedded[this.dataType]);
}
} else if (!this.isViewmodeList) {
this.results.next([]);
}
this.total.next(data.total);
if (this.clientPaging) {
this.total.next(data._embedded[this.dataType].length);
}
if (this.refresh) {
this.datatable.expandedRows = [];
if (this.autoexpand) {
for (let index = 0; index < this.totalresults.length; index++) {
if (
this.lasttotalresults.length > 0 &&
this.lasttotalresults[index]
) {
if (
this.lasttotalresults[index]["status"] !==
this.totalresults[index]["status"]
) {
this.expandedRows.push(this.totalresults[index]);
}
}
}
if (this.totalresults[0]) {
if (
this.totalresults[0]["status"] === "COMPLETED" &&
this.offset === 0 &&
this.filter.length === 0
) {
this.expandedRows.push(this.totalresults[0]);
}
}
}
for (const row of this.expandedRows) {
let rowtoAdd = this.totalresults.filter(
(item) => item.identifier === row.identifier
);
if (rowtoAdd.length > 0) {
this.datatable.expandedRows.push(rowtoAdd[0]);
}
}
}
// TODO: This leads to lost parameters
// this.currentLink = data._links["custom"].href;
this.lasttotalresults = this.totalresults;
}
onPage(event) {
this.limit = event.rows;
this.offset = event.first;
}
showDetails(path) {
this.router.navigate(path, { relativeTo: this.route });
}
openLink(data, column, event) {
event.stopPropagation();
const template = uriTemplates(column.linkTemplate);
const url = template.fill(data);
if (column.openLinkInSameTab) {
window.location.href = url;
} else {
window.open(url);
}
return false;
}
openRoute(data, column, event) {
event.stopPropagation();
const template = uriTemplates(column.linkTemplate);
const url = template.fill(data);
this.router.navigate([url]);
return false;
}
openRelation(contentNo) {
this.autoSearchLocalStorage = this.localStorageService.getLocalStorageEntry(
"autoSearch",
Scope.GLOBAL,
DeletionMode.LOGIN
);
this.contentNoLocalStorage = this.localStorageService.getLocalStorageEntry(
"content-searchInput",
Scope.GLOBAL,
DeletionMode.LOGIN
);
this.autoSearchLocalStorage.value = "true";
this.contentNoLocalStorage.value = contentNo;
this.showDetails([this.relationURL]);
this.relation.next(contentNo);
}
onSelect(event) {}
keydown(event: any) {
if (event.keyCode === 16) {
this.shiftIsPressed = true;
this.selectedRowsOnShift = this.selectedRows;
}
}
keyup(event: any) {
if (event.keyCode === 16) {
this.shiftIsPressed = false;
}
}
onSelectionChange(event) {
if (Array.isArray(event)) {
this.selectedRows = event;
} else {
event = this.addRowIndexToSelectedItem(event);
this.selectedRows = [event];
}
}
onRowSelectChange(event) {
this.selectedItems.next(this.selectedRows);
let selectedRowsOnShiftIndexes = [];
let selectedRowsIndex;
let selectedRowsOnShiftIndexesMin;
let selectedRowsOnShiftIndexesMax;
let fromIndex;
let toIndex;
if (this.shiftIsPressed) {
this.results.subscribe((allrows) => {
allrows.forEach((row, index) => {
this.selectedRowsOnShift.forEach((selectedRow, selectedRowindex) => {
if (row.identifier === selectedRow.identifier) {
selectedRowsOnShiftIndexes.push(index);
}
});
if (row.identifier === this.selectedRows[0].identifier) {
selectedRowsIndex = index;
}
});
selectedRowsOnShiftIndexesMin = Math.min.apply(
Math,
selectedRowsOnShiftIndexes
);
selectedRowsOnShiftIndexesMax = Math.max.apply(
Math,
selectedRowsOnShiftIndexes
);
if (selectedRowsIndex < selectedRowsOnShiftIndexesMin) {
fromIndex = selectedRowsIndex;
toIndex = selectedRowsOnShiftIndexesMax;
} else if (selectedRowsIndex > selectedRowsOnShiftIndexesMax) {
fromIndex = selectedRowsOnShiftIndexesMin;
toIndex = selectedRowsIndex;
}
allrows.forEach((row, index) => {
if (fromIndex <= index && toIndex >= index) {
this.selectedRows.push(row);
this.selectedItems.next(this.selectedRows);
}
});
});
}
if (this.selectedRows.length > 1) {
this.isMultiselectActionNeeded = true;
}
let payload = [];
this.selectedRows.forEach((row) => {
if (row) {
payload.push(row.identifier);
}
});
this.multiselectpayload.next(payload);
}
toogleContentVisibility() {
this.contentVisible = !this.contentVisible;
}
public slideChange(event) {
if (this.slidevalue == 1) {
this.boxWidth = "100%";
this.boxHeight = "600px";
} else if (this.slidevalue == 2) {
this.boxWidth = "47%";
this.boxHeight = "350px";
} else if (this.slidevalue == 3) {
this.boxWidth = "30%";
this.boxHeight = "220px";
} else if (this.slidevalue == 4) {
this.boxWidth = "23%";
this.boxHeight = "190px";
} else if (this.slidevalue == 5) {
this.boxWidth = "19%";
this.boxHeight = "130px";
}
// Prevent reload if a request is already started, map result will handle reloading if the slide value is high enough
if (this.slidevalue > 3 && !this.requestRunning) {
if (this.offset === 0) {
this.offset += 10;
this.reload();
} else if (this.slidevalue === 5 && this.offset === 10) {
this.offset += 10;
this.reload();
}
}
}
private mapField(value: any, type: string): any {
switch (type) {
case "date":
return value.substring(0, 10);
case "datetime":
if (!value) {
return;
}
const date = new Date(value);
return date.toLocaleDateString(
this.selectedLocaleString,
this.dateOptions
);
default:
return value;
}
}
private addRowIndexToSelectedItem(item: any) {
this.results.subscribe((allRows) => {
allRows.forEach((row, index) => {
if (item && row.identifier === item.identifier) {
item["rowIndex"] = index;
}
});
});
return item;
}
onBlur(data) {
this.editedRow["value"] = data;
this.onEdit.next(this.editedRow);
}
onEnter(event) {
event.target.blur();
}
onFocus(data) {
this.editedRow = {};
this.editedRow["originalValue"] = jQuery.extend(true, {}, data);
}
selectors() {
return { content: this.dataType, target: "nm-list-row" };
}
dropdownValueChanged(object, rowIndex) {
object["rowIndex"] = rowIndex;
this.onEdit.next(object);
this.emitResults(object);
}
onChangeNumberField(object, rowIndex) {
object["rowIndex"] = rowIndex;
this.onEdit.next(object);
this.emitResults(object);
}
private emitResults(object) {
let currentResults = [];
this.results
.pipe(
map((data) => {
data[object["rowIndex"]] = object;
return data;
})
)
.subscribe((data) => (currentResults = data));
if (this.selectedRows.length > 0) {
this.selectedItems.next(this.selectedRows);
}
}
}
<nm-widgetframe
[configuration]="configuration"
[infoText]="infoText"
[infoTitle]="title"
[wikiLink]="wikiLink"
[visible]="!(hideOnEmpty && (results | async)?.length == 0)"
>
<div slot="title" class="nm-widgetframe__title">
<span>{{ title | translate }}</span>
<span *ngIf="total | async as totalValue"> ({{ totalValue }}) </span>
<!-- This fills the remaining space of the current row -->
<div class="u-flex-1"></div>
<mat-slider
class="nm-button__slider"
color="primary"
min="1"
max="5"
*ngIf="isViewmodeList"
slidevalue
[(ngModel)]="slidevalue"
(change)="slideChange($event)"
></mat-slider>
<p-toggleButton
*ngIf="configuration.configuration['isListviewEnabled']"
[(ngModel)]="isViewmodeList"
(onChange)="onChangeViewMode($event)"
offIcon="fa fa-table"
onIcon="fa fa-list"
popover="{{ 'table.switchview' | translate }}"
offLabel=""
onLabel=""
></p-toggleButton>
</div>
<div slot="content" class="nm-widgetframe__content">
<div class="nm-list {{ dataType }} {{ cssClass }}">
<p-dataTable
(selectionChange)="onSelectionChange($event)"
[value]="mappedResults | async"
expandableRows="configuration.configuration['expandableRows']"
emptyMessage="{{ 'table.emptytext.product' | translate }}"
(onPage)="onPage($event)"
(onLazyLoad)="loadData($event)"
[paginator]="(mappedResults | async).length > 0"
[rows]="limit"
[pageLinks]="5"
[lazy]="!clientPaging"
[totalRecords]="total | async"
[rowsPerPageOptions]="[5, 10, 25, 50, 100]"
*ngIf="!isViewmodeList"
[selectionMode]="selectionMode"
(onRowSelect)="onRowSelectChange($event)"
(onRowUnselect)="onRowSelectChange($event)"
#dt
>
<ng-template let-result pTemplate="rowexpansion">
<div class="nm-downloadlist">
<nm-action-link-list [actions]="result._actions.download">
</nm-action-link-list>
</div>
</ng-template>
<p-column
expander="true"
*ngIf="configuration.configuration['expandableRows']"
>
</p-column>
<p-column
*ngFor="let column of cols | async"
[sortable]="column.sortable"
[filter]="column.filter"
[field]="column.field"
[header]="column.header | translate"
[styleClass]="column.style"
[editable]="column.editable"
filterMatchMode="contains"
>
<ng-template pTemplate="editor" let-col let-data="rowData">
<input
type="text"
[(ngModel)]="data[col.field]"
(focus)="onFocus(data)"
(blur)="onBlur(data)"
(keydown.enter)="onEnter($event)"
class="input-editor"
/>
</ng-template>
<ng-template pTemplate="filter" let-col *ngIf="column.filter">
<mat-form-field *ngIf="filterOnBlur == false">
<input
pinputtext
matInput
placeholder="{{ col.header }}"
[value]="
dt.filters[col.field] ? dt.filters[col.field].value : ''
"
type="text"
class="ui-column-filter"
*ngIf="col.filter == true"
(click)="dt.onFilterInputClick($event)"
(input)="
dt.onFilterKeyup(
$event.target.value,
col.field,
col.filterMatchMode
);
onFilterKeyupCustom(
$event.target.value,
col.field,
col.filterMatchMode
)
"
/>
</mat-form-field>
<mat-form-field *ngIf="filterOnBlur == true">
<input
pinputtext
matInput
placeholder="{{ col.header }}"
[value]="
dt.filters[col.field] ? dt.filters[col.field].value : ''
"
type="text"
class="ui-column-filter"
*ngIf="col.filter == true"
(click)="dt.onFilterInputClick($event)"
(blur)="
dt.onFilterKeyup(
$event.target.value,
col.field,
col.filterMatchMode
)
"
/>
</mat-form-field>
</ng-template>
<ng-template
*ngIf="!externalResource"
let-col
let-results="rowData"
let-rowIndex="rowIndex"
pTemplate="body"
>
<ng-container [ngSwitch]="column.dataType">
<div
*ngSwitchCase="'route'"
(id)="(results[col.field])"
style="width: 100%"
class="table-content"
>
<a (click)="openRoute(results, column, $event)">
<nm-ellipsis [content]="results[col.field]"></nm-ellipsis>
</a>
</div>
<div
*ngSwitchCase="'link'"
(id)="(results[col.field])"
style="width: 100%"
class="table-content"
>
<a (click)="openLink(results, column, $event)">
<nm-ellipsis [content]="results[col.field]"></nm-ellipsis>
</a>
</div>
<div
*ngSwitchCase="'traffic-light'"
(id)="(results[col.field])"
style="width: 100%"
class="table-content"
>
<div
class="traffic_light_single_container"
matTooltip="{{
column['tooltip-prefix'] + results[col.field] | translate
}}"
>
<div class="traffic_light traffic_light_grid single">
<span class="active" [ngClass]="results[col.field]"></span>
</div>
</div>
</div>
<div
*ngSwitchDefault
(id)="(results[col.field])"
style="width: 100%"
class="table-content"
>
<div
(id)="(results[col.field])"
style="width: 100%"
class="table-content"
>
<div [ngSwitch]="col.field">
<div *ngSwitchCase="'main-asset'">
<nm-image
[container]="results"
asset="main-asset"
size="thumbnail"
width="auto"
height="auto"
max-width="48px"
max-height="48px"
tooltip="true"
></nm-image>
</div>
<div *ngSwitchCase="'identifier'">
<div
class="nm-break"
*ngIf="
dataType != 'products' &&
dataType != 'assets' &&
dataType != 'variants' &&
dataType != 'content-text' &&
dataType != 'content-relations'
"
>
<nm-ellipsis
[content]="results[col.field]"
></nm-ellipsis>
</div>
<div
*ngIf="dataType == 'products' || dataType == 'assets'"
>
<a
*ngIf="profile !== 'content-assets'"
[routerLink]="[
this.dataType.substring(
0,
this.dataType.length - 1
),
results.identifier
]"
>
<nm-ellipsis
[content]="results[col.field]"
></nm-ellipsis>
</a>
<nm-ellipsis
*ngIf="profile === 'content-assets'"
[content]="results[col.field]"
></nm-ellipsis>
</div>
<div *ngIf="dataType == 'variants'">
<a
(click)="
showDetails([this.dataType, results.identifier])
"
>
<nm-ellipsis
[content]="results[col.field]"
></nm-ellipsis>
</a>
</div>
<div *ngIf="dataType == 'content-relations'">
<a (click)="openRelation(results.identifier)">
<nm-ellipsis
[content]="results[col.field]"
></nm-ellipsis>
</a>
</div>
<div *ngIf="dataType == 'content-text'">
<mat-form-field class="editable-field">
<mat-select
[value]="results[col.field]"
name="editable-type"
[(ngModel)]="results[col.field]"
(selectionChange)="
dropdownValueChanged(results, rowIndex)
"
>
<mat-option
*ngFor="let data of dropdownsData[col.field]"
[value]="data.id"
>
{{ data.description }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
<div *ngSwitchCase="'link'" class="nm-actions">
<ng-container
*ngFor="let act of results._actions | iterable"
>
<nm-action-icon
*ngIf="act.key != 'download'"
[action]="act.value"
[name]="act.key"
>
</nm-action-icon>
</ng-container>
</div>
<div *ngSwitchCase="'status'">
<div
*ngIf="results[col.field] == 'PROCESSING'"
class="nm-download-result-processing"
>
{{ results[col.field] | translate }}
</div>
<div
*ngIf="results[col.field] == 'COMPLETED'"
class="nm-download-result-completed"
>
{{ results[col.field] | translate }}
</div>
<div
*ngIf="results[col.field] == 'FAILED'"
class="nm-download-result-failed"
>
{{ results[col.field] | translate }}
</div>
<div
*ngIf="results[col.field] == 'TIMEOUT'"
class="nm-download-result-timeout"
>
{{ results[col.field] | translate }}
</div>
</div>
<div *ngSwitchCase="'status1'">
<div class="traffic_light traffic_light_grid single">
<span class="{{ results[col.field] }} active"></span>
</div>
</div>
<div *ngSwitchCase="'status2'">
<div class="traffic_light traffic_light_grid single">
<span class="{{ results[col.field] }} active"></span>
</div>
</div>
<div *ngSwitchCase="'status3'">
<div class="traffic_light traffic_light_grid single">
<span class="{{ results[col.field] }} active"></span>
</div>
</div>
<div *ngSwitchCase="'status4'">
<div class="traffic_light traffic_light_grid single">
<span class="{{ results[col.field] }} active"></span>
</div>
</div>
<!--[popover]="popTemplateTranslation" popoverTitle="{{'app.ipim-mytextedit.trafficlight.popover.title' | translate}}"
placement="top" container="body" triggers="mouseenter:mouseleave"-->
<div *ngSwitchCase="'channels'">
<div
*ngFor="let channel of results[col.field]"
class="nm-inline-images"
>
<ng-template #popTemplateTranslation>
<div class="translation-status-list">
<div
*ngFor="let marketplace of channel.marketplaces"
class="translation-status"
>
<div>Name: {{ marketplace.name }}</div>
<div>Identifer: {{ marketplace.identifier }}</div>
<div>Sprache: {{ marketplace.language }}</div>
</div>
</div>
</ng-template>
<div
[popover]="popTemplateTranslation"
popoverTitle="{{ 'table.head.channels' | translate }}"
placement="right"
container="body"
triggers="mouseenter:mouseleave"
>
<!-- TODO fix array channel.marketplaces[0] -->
<a
(click)="
showDetails([
this.dataType.substring(
0,
this.dataType.length - 1
),
results.identifier,
channel.marketplaces[0].identifier
])
"
>
<nm-image
[container]="channel.image"
asset="image"
size="preview"
width="auto"
height="auto"
max-width="58px"
max-height="58px"
></nm-image>
</a>
</div>
</div>
</div>
<div *ngSwitchCase="'created'">
{{ results[col.field] | date: "medium" }}
</div>
<div *ngSwitchCase="'articleNo'">
<a
(click)="showDetails(['articles', results.identifier])"
>
<nm-ellipsis
[content]="results.identifier"
></nm-ellipsis>
</a>
</div>
<div *ngSwitchCase="'variants'">
<div *ngFor="let variant of results.variants">
<a
(click)="
showDetails([
'articles',
results.identifier,
variant.sku
])
"
>
{{ variant.identifier }}
</a>
</div>
</div>
<div *ngSwitchCase="'customer'">
<div>{{ results[col.field] | customerDetails }}</div>
</div>
<div *ngSwitchCase="'marektplace'">
<div>{{ results[col.field].name }}</div>
</div>
<div *ngSwitchCase="'interactions'">
<nm-interactions
[param]="results"
[selectors]="selectors()"
></nm-interactions>
</div>
<div *ngSwitchCase="'type'">
<div
*ngIf="
dataType == 'content-assets' ||
dataType == 'content-relations'
"
>
<mat-form-field class="editable-field">
<mat-select
[value]="results[col.field]"
name="editable-type"
[(ngModel)]="results[col.field]"
(selectionChange)="
dropdownValueChanged(results, rowIndex)
"
>
<mat-option
*ngFor="let data of dropdownsData[col.field]"
[value]="data.id"
>
{{ data.description }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div
*ngIf="
dataType != 'content-assets' &&
dataType != 'content-relations'
"
>
<nm-ellipsis
[content]="results[col.field]"
></nm-ellipsis>
</div>
</div>
<div *ngSwitchCase="'asset-type'">
<div *ngIf="dataType == 'assets'">
<mat-form-field class="editable-field">
<mat-select
#model="ngModel"
[value]="results[col.field]"
name="editable-type"
[(ngModel)]="results[col.field]"
(selectionChange)="
dropdownValueChanged(results, rowIndex)
"
>
<mat-option (click)="model.reset()"></mat-option>
<mat-option
*ngFor="let data of dropdownsData[col.field]"
[value]="data.id"
>
{{ data.description }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div *ngIf="dataType != 'assets'">
<nm-ellipsis
[content]="results[col.field]"
></nm-ellipsis>
</div>
</div>
<div *ngSwitchCase="'rel-type'">
<div *ngIf="dataType == 'content'">
<mat-form-field class="editable-field">
<mat-select
#model="ngModel"
[value]="results[col.field]"
name="editable-type"
[(ngModel)]="results[col.field]"
(selectionChange)="
dropdownValueChanged(results, rowIndex)
"
>
<mat-option (click)="model.reset()"></mat-option>
<mat-option
*ngFor="let data of dropdownsData[col.field]"
[value]="data.id"
>
{{ data.description }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div *ngIf="dataType != 'content'">
<nm-ellipsis
[content]="results[col.field]"
></nm-ellipsis>
</div>
</div>
<div *ngSwitchCase="'direction'">
<div
*ngIf="
dataType == 'content-relations' ||
dataType == 'content'
"
>
<mat-form-field class="editable-field">
<mat-select
#model="ngModel"
[value]="results[col.field]"
name="editable-type"
[(ngModel)]="results[col.field]"
(selectionChange)="
dropdownValueChanged(results, rowIndex)
"
>
<mat-option (click)="model.reset()"></mat-option>
<mat-option
*ngFor="let data of dropdownsData[col.field]"
[value]="data.id"
>
{{ data.description }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
<div *ngSwitchDefault class="nm-break">
<div
*ngIf="col.field != 'order' && col.field != 'sequence'"
>
<nm-ellipsis
[content]="results[col.field]"
></nm-ellipsis>
</div>
<div
*ngIf="col.field == 'order' || col.field == 'sequence'"
>
<mat-form-field class="editable-field">
<input
(input)="onChangeNumberField(results, rowIndex)"
matInput
type="number"
min="0"
maxlength="10"
oninput="javascript: if (this.value.length > this.maxLength) this.value = this.value.slice(0, this.maxLength);"
[(ngModel)]="results[col.field]"
[readonly]="false"
/>
</mat-form-field>
</div>
</div>
</div>
</div>
</div>
</ng-container>
</ng-template>
</p-column>
<footer>
<div class="ui-helper-clearfix" style="width: 100%"></div>
</footer>
</p-dataTable>
<div class="viewmodeList" *ngIf="isViewmodeList">
<p-dataGrid
[value]="results | async"
(onLazyLoad)="loadData($event)"
[paginator]="false"
[rows]="limit"
[lazy]="true"
[totalRecords]="total | async"
class="wrap"
emptyMessage=""
#dg
>
<p-header>
<div *ngFor="let col of cols | async" class="nm-sort-header">
<span
class="ui-sortable-column-icon fa fa-fw fa-sort"
(click)="onSortingChanged($event, col)"
*ngIf="col.sortable"
[ngClass]="{
'fa-sort-desc': getSortOrder(col) == -1,
'fa-sort-asc': getSortOrder(col) == 1
}"
></span>
<mat-form-field *ngIf="col.filter">
<input
matInput
placeholder="{{ col.header | translate }}"
[value]="
lastPrimeNGEvent?.filters[col.field]
? lastPrimeNGEvent?.filters[col.field]?.value
: ''
"
type="text"
class="ui-column-filter"
(input)="onFilterKeyup($event.target.value, col.field)"
/>
</mat-form-field>
</div>
</p-header>
<ng-template let-entry pTemplate="item">
<p-panel
class="nm-gridlist-box"
[style.width]="boxWidth"
[style.padding-bottom]="boxHeight"
>
<div class="nm-gridlist-boxInner">
<div class="nm-gridlist-actionBox">
<nm-action-icon
*ngIf="entry._actions"
[action]="entry._actions['add-to-cart']"
[name]="'add-to-cart'"
>
</nm-action-icon>
</div>
<nm-image
[container]="entry"
asset="main-asset"
size="preview"
width="auto"
height="auto"
alt="{{ entry.identifier }}"
></nm-image>
<div
class="nm-gridlist-titleBox"
(click)="
showDetails([
this.dataType.substring(0, this.dataType.length - 1),
entry.identifier
])
"
>
<span> {{ entry.identifier }}</span>
<div>{{ entry.description }}</div>
</div>
</div>
</p-panel>
</ng-template>
</p-dataGrid>
</div>
</div>
</div>
</nm-widgetframe>
<!-- TODO: Make it more generic -->
<button
mat-mini-fab
color="primary"
mat-elevation-z0
*ngFor="let act of multiselectaction | async | iterable"
[nm-action]="act.value"
[action-name]="act.key"
[action-payload]="multiselectpayload | async"
matTooltip="{{ 'infotext.addselectiontocart' | translate }}"
class="mat-icon-button mat-elevation-z0 nm-button__addSelction"
[class.nm-fadein]="isMultiselectActionNeeded"
>
<div
class="material-icons nm-svg-icon"
[ngStyle]="{ fill: 'rgb(255,153,0)' }"
>
<mat-icon>add_shopping_cart</mat-icon>
</div>
</button>