|
- import {AfterViewInit, Component, Input, OnDestroy, OnInit, Type, ViewChild} from '@angular/core';
- import {MatSort, Sort} from "@angular/material/sort";
- import {PagingComponent} from "@app/_components/paging/paging.component";
- import {MatTableDataSource} from "@angular/material/table";
- import {ListColDefinition} from "@app/_components/list/list-col-definition";
- import {AppHelperService} from "@app/_helpers/app-helper.service";
- import {ListGetDataFunctionType} from "@app/_components/list/list-get-data-function-type";
- import {ListUpdateElementFunctionType} from "@app/_components/list/list-update-element-function-type";
- import {FilterBarComponent} from "@app/_components/filter-bar/filter-bar.component";
- import { Router } from '@angular/router';
- import {interval, Subscription} from "rxjs";
- import {AbstractCreateDataComponent} from "@app/_interfaces/AbstractCreateDataComponent";
-
- @Component({
- selector: 'app-list',
- templateUrl: './list.component.html',
- styleUrl: './list.component.scss'
- })
-
- export class ListComponent implements OnInit, AfterViewInit, OnDestroy {
- @Input() public listId!: string;
- @Input() public getDataFunction!: ListGetDataFunctionType;
- @Input() public onSortFunction!: Function;
- @Input() public onNavigateToDetailsFunction!: Function;
- @Input() public onRemoveItemFunction!: Function;
- @Input() public onEditFunction!: Function;
- @Input() public onDownloadFunction!: Function;
- @Input() public onRowSelectedFunction!: Function;
- @Input() public onUpdateBooleanStateFunction!: ListUpdateElementFunctionType;
- @Input() public createDataComponent!: Type<AbstractCreateDataComponent<any>>;
- @Input() public searchable: boolean;
- @Input() public showDetailButton: boolean;
- @Input() public showPosition: boolean;
- @Input() public showFilterBar: boolean;
- @Input() public listColDefinitions!: ListColDefinition[];
- @Input() public hidePageSize: boolean;
- @Input() public displayOptions!: { [key: string]: string };
- @Input() public defaultDisplayOption!: string;
- @Input() public refreshIntervalSeconds?: number;
- @ViewChild(MatSort) sort;
- @ViewChild("pagingComponent", {static: false}) protected pagingComponent!: PagingComponent;
- @ViewChild("filterBarComponent", {static: false}) protected filterBarComponent!: FilterBarComponent;
-
- public static COLUMN_TYPE_ADDRESS: string = 'address';
- public static COLUMN_TYPE_BOOLEAN: string = 'boolean';
- public static COLUMN_TYPE_BTN_DOWNLOAD: string = 'btn_download';
- public static COLUMN_TYPE_BTN_EDIT: string = 'btn_edit';
- public static COLUMN_TYPE_BTN_REMOVE: string = 'btn_remove';
- public static COLUMN_TYPE_CURRENCY: string = 'euro';
- public static COLUMN_TYPE_DATE: string = 'date';
- public static COLUMN_TYPE_DETAIL: string = 'detail';
- public static COLUMN_TYPE_DETAIL_LINK: string = 'detail_link';
- public static COLUMN_TYPE_EMAIL: string = 'email';
- public static COLUMN_TYPE_IMAGE: string = 'image';
- public static COLUMN_TYPE_COMBINED_IMAGES: string = 'combined_images';
- public static COLUMN_TYPE_NUMBER: string = 'number';
- public static COLUMN_TYPE_NUMBER_UNFORMATTED: string = 'number_unformatted';
- public static COLUMN_TYPE_NUMBER_BOLD: string = 'number_bold';
- public static COLUMN_TYPE_POSITION: string = 'position';
- public static COLUMN_TYPE_TEXT: string = 'text';
- public static COLUMN_TYPE_TEXT_BOLD: string = 'text_bold';
- public static COLUMN_TYPE_TEXT_LINKED: string = 'text_linked';
- public static COLUMN_TYPE_WEBSITE: string = 'website';
-
- public activeFilterCount: number = 0;
-
- protected displayedColumns!: string[];
- protected selectedRowIndex: number | null = null;
- protected dataSource;
- protected currentGroup!: string;
- protected filterExists!: boolean;
- protected sortObj!: any;
- protected filterObj!: any;
- protected listColDefinitionsByField!: any;
- protected filterConfig: string | null;
- private refreshSubscription?: Subscription;
-
- constructor(
- protected appHelperService: AppHelperService,
- private router: Router,
- ) {
- this.searchable = true;
- this.showDetailButton = true;
- this.showPosition = true;
- this.showFilterBar = true;
- this.filterExists = false;
- this.filterObj = {};
- this.sort = new MatSort();
- this.hidePageSize = false;
- this.dataSource = new MatTableDataSource<any>();
- this.filterConfig = null;
-
- }
-
- ngOnInit(): void {
- this.loadColumnConfig();
- if (this.showPosition) {
- this.listColDefinitions.unshift(ListComponent.getDefaultColPosition());
- }
- if (this.showDetailButton) {
- // this.listColDefinitions.unshift(ListComponent.getDefaultColDetailBtn());
- this.listColDefinitions.unshift(ListComponent.getDefaultColDetailBtnLink(this.router.routerState.snapshot.url));
- }
- if (this.displayOptions !== undefined) {
- this.currentGroup = this.defaultDisplayOption || Object.keys(this.displayOptions)[0] || '';
- }
-
- this.listColDefinitionsByField = {};
- this.listColDefinitions.forEach((value, index) => {
- if (value.visible === undefined) {
- value.visible = true;
- }
- this.listColDefinitionsByField[value['name']] = value;
- if (value.filterType !== undefined) {
- this.filterExists = true;
- }
- })
- this.updateDisplayedColumns();
- this.filterConfig = this.loadFilterConfig();
- this.setupAutoRefresh();
- }
-
- private setupAutoRefresh(): void {
- this.clearAutoRefresh();
- if (this.refreshIntervalSeconds && this.refreshIntervalSeconds > 0) {
- this.refreshSubscription = interval(this.refreshIntervalSeconds * 1000).subscribe(() => {
- this.getData();
- });
- }
- }
-
- private clearAutoRefresh(): void {
- if (this.refreshSubscription) {
- this.refreshSubscription.unsubscribe();
- }
- }
-
- saveFilterConfig(): void {
- localStorage.setItem(`filterConfig_${this.listId}`, this.getFilterJsonString());
- }
-
- loadFilterConfig(): string | null {
- return localStorage.getItem(`filterConfig_${this.listId}`);
- }
-
- saveColumnConfig(): void {
- const config = this.listColDefinitions.map(col => ({
- name: col.name,
- visible: col.visible
- }));
- localStorage.setItem(`listConfig_${this.listId}`, JSON.stringify(config));
- }
-
- loadColumnConfig(): void {
- const savedConfig = localStorage.getItem(`listConfig_${this.listId}`);
- if (savedConfig) {
- const config = JSON.parse(savedConfig);
- this.listColDefinitions.forEach(col => {
- const savedCol = config.find((c: any) => c.name === col.name);
- if (savedCol) {
- col.visible = savedCol.visible;
- }
- });
- this.updateDisplayedColumns();
- }
- }
-
- updateDisplayedColumns(): void {
- this.displayedColumns = this.listColDefinitions
- .filter(col => col.visible !== false &&
- (this.displayOptions === undefined ||
- col.groups?.includes(this.currentGroup) ||
- col.type === ListComponent.COLUMN_TYPE_DETAIL ||
- col.type === ListComponent.COLUMN_TYPE_POSITION))
- .map(col => col.name);
- }
-
- onDisplayOptionChange(option: string): void {
- this.currentGroup = option;
- this.updateDisplayedColumns();
- }
-
- onToggleColumnVisibility(columnName: string): void {
- const column = this.listColDefinitions.find(col => col.name === columnName);
- if (column) {
- column.visible = !column.visible;
- this.updateDisplayedColumns();
- }
- }
-
- showAllColumns() {
- this.listColDefinitions.forEach((value, index) => {
- value.visible = true;
- });
- this.updateDisplayedColumns();
- }
-
- getColumnVisibility(): { [key: string]: boolean } {
- const visibility: { [key: string]: boolean } = {};
- this.listColDefinitions.forEach(col => {
- visibility[col.name] = col.visible !== false;
- });
- return visibility;
- }
-
- ngAfterViewInit(): void {
- }
-
- getData = (): void => {
- this.getDataFunction(
- this.pagingComponent.getPageIndex(),
- this.pagingComponent.getPageSize(),
- this.pagingComponent.getSearchValue()
- ).subscribe(
- data => {
- this.dataSource = new MatTableDataSource<any>(data['member']);
- this.pagingComponent.setDataLength(data["totalItems"]);
- }
- )
- }
-
- onSortChange = (sortState: Sort) => {
- let listColDefinition: any = this.listColDefinitionsByField[sortState.active];
- this.sortObj = sortState;
- this.sortObj['listColDefinition'] = listColDefinition;
- this.pagingComponent.resetPageIndex();
- this.onSortFunction(sortState);
- this.getData();
- }
-
- onRowSelected(row: any, index: number) {
- this.selectedRowIndex = index;
- if (this.onRowSelectedFunction !== undefined) {
- this.onRowSelectedFunction(row, index);
- }
- }
-
- getElementValue(element: any, column: ListColDefinition, multipleFieldIndex?: number): any | null {
- element = column.subResource !== undefined ? element[column.subResource] : element;
- if (element === undefined) {
- return null;
- }
- if (column.field !== undefined) {
- if (
- column.displayedLength !== undefined &&
- element[column.field] !== undefined &&
- element[column.field].length > column.displayedLength
- ) {
- return element[column.field]?.slice(0, column.displayedLength) + '...';
- }
- return element[column.field];
- }
- if (column.multipleFields !== undefined) {
- if (multipleFieldIndex !== undefined) {
- return element[column.multipleFields[multipleFieldIndex]];
- }
- let res: any[] = [];
- column.multipleFields.forEach((field, index) => {
- res.push(element[field]);
- })
- return res;
- }
- if (column.address !== undefined) {
- const field = column.address;
- let addressString = '';
- if (element[field.street] !== undefined && element[field.street] !== null) {
- addressString += `${element[field.street].trim()} `;
- }
- if (element[field.streetNo] !== undefined && element[field.streetNo] !== null) {
- addressString += `${element[field.streetNo].trim()} `;
- }
- addressString += ' <br/> ';
- if (element[field.zip] !== undefined && element[field.zip] !== null) {
- addressString += `${element[field.zip].trim()} `;
- }
- if (element[field.city] !== undefined && element[field.city] !== null) {
- addressString += `${element[field.city].trim()}`;
- }
- addressString += ' <br/> ';
-
- if (element[field.country] !== undefined && element[field.country] !== null) {
- addressString += `${element[field.country].trim()}`;
- }
- return addressString;
- }
- return element;
- }
-
- getElementImage(element: any, column: ListColDefinition): any {
- let elementValue = this.getElementValue(element, column);
- if (elementValue !== undefined && elementValue !== null) {
- return elementValue;
- }
- return "/assets/images/icons/dummy-product.png"
- }
-
-
- getColCssClass(column: ListColDefinition): string {
- switch (column.type) {
- case ListComponent.COLUMN_TYPE_DETAIL:
- return "spt-button-td";
- case ListComponent.COLUMN_TYPE_BTN_REMOVE:
- return "spt-button-td text-end";
- case ListComponent.COLUMN_TYPE_TEXT:
- return "spt-version-td";
- default:
- return "";
- }
- }
-
- public getPageIndex() {
- return this.pagingComponent.getPageIndex();
- }
-
- public getPageSize() {
- return this.pagingComponent.getPageSize();
- }
-
- public static getDefaultColDetailBtn(): ListColDefinition {
- return {
- name: 'detail',
- text: '',
- type: ListComponent.COLUMN_TYPE_DETAIL
- } as ListColDefinition;
- }
-
- public static getDefaultColDetailBtnLink(currentUrl: string): ListColDefinition {
- return {
- name: 'detaillink',
- text: '',
- url: currentUrl,
- type: ListComponent.COLUMN_TYPE_DETAIL_LINK
- } as ListColDefinition;
- }
-
- public static getDefaultColPosition(): ListColDefinition {
- return {
- name: 'pos',
- text: 'basic.number',
- type: ListComponent.COLUMN_TYPE_POSITION
- } as ListColDefinition;
- }
-
- public getSortingJsonString(): any
- {
- return JSON.stringify(this.sortObj);
- }
-
- public updateBooleanState = (element: any, index: number, column: ListColDefinition) => {
- if (this.onUpdateBooleanStateFunction === undefined) {
- throw new Error('no onUpdateBooleanStateFunction given');
- }
- if (column.field !== undefined) {
- element[column.field] = !element[column.field];
- } else {
- throw new Error('column.field is undefined');
- }
- this.onUpdateBooleanStateFunction(element).subscribe(
- data => {
- this.updateRow(data, index);
- }
- )
- }
-
- public updateRow(element: any, index: number) {
- const data = this.dataSource.data as any;
- data[index] = element;
- this.dataSource.data = data;
- }
-
- public onFilterInit(filterData: {filters: any, activeCount: number}) {
- this.filterObj = filterData.filters;
- this.activeFilterCount = filterData.activeCount;
- }
-
- public onFilterChanged(filterData: {filters: any, activeCount: number}) {
- console.log(filterData);
- const filterJson = JSON.stringify(filterData.filters);
- const currentFilterJson = JSON.stringify(this.filterObj);
-
- if (filterJson !== currentFilterJson) {
- this.filterObj = filterData.filters;
- this.activeFilterCount = filterData.activeCount;
- this.getData();
- }
- }
-
- public onCreateData() {
- this.appHelperService.openModal(
- this.createDataComponent,
- null,
- this.getData
- );
- }
-
- public getFilterJsonString(): any {
- return JSON.stringify(this.filterObj);
- }
-
- get COLUMN_TYPE_ADDRESS(): string {
- return ListComponent.COLUMN_TYPE_ADDRESS;
- }
-
- get COLUMN_TYPE_BOOLEAN(): string {
- return ListComponent.COLUMN_TYPE_BOOLEAN;
- }
-
- get COLUMN_TYPE_BTN_DOWNLOAD(): string {
- return ListComponent.COLUMN_TYPE_BTN_DOWNLOAD;
- }
-
- get COLUMN_TYPE_BTN_EDIT(): string {
- return ListComponent.COLUMN_TYPE_BTN_EDIT;
- }
-
- get COLUMN_TYPE_BTN_REMOVE(): string {
- return ListComponent.COLUMN_TYPE_BTN_REMOVE;
- }
-
- get COLUMN_TYPE_CURRENCY(): string {
- return ListComponent.COLUMN_TYPE_CURRENCY;
- }
-
- get COLUMN_TYPE_DATE(): string {
- return ListComponent.COLUMN_TYPE_DATE;
- }
-
- get COLUMN_TYPE_DETAIL(): string {
- return ListComponent.COLUMN_TYPE_DETAIL;
- }
-
- get COLUMN_TYPE_DETAIL_LINK(): string {
- return ListComponent.COLUMN_TYPE_DETAIL_LINK;
- }
-
- get COLUMN_TYPE_EMAIL(): string {
- return ListComponent.COLUMN_TYPE_EMAIL;
- }
-
- get COLUMN_TYPE_POSITION(): string {
- return ListComponent.COLUMN_TYPE_POSITION;
- }
-
- get COLUMN_TYPE_IMAGE(): string {
- return ListComponent.COLUMN_TYPE_IMAGE;
- }
-
- get COLUMN_TYPE_COMBINED_IMAGES(): string {
- return ListComponent.COLUMN_TYPE_COMBINED_IMAGES;
- }
-
- get COLUMN_TYPE_TEXT(): string {
- return ListComponent.COLUMN_TYPE_TEXT;
- }
-
- get COLUMN_TYPE_NUMBER(): string {
- return ListComponent.COLUMN_TYPE_NUMBER;
- }
-
- get COLUMN_TYPE_NUMBER_UNFORMATTED(): string {
- return ListComponent.COLUMN_TYPE_NUMBER_UNFORMATTED;
- }
-
- get COLUMN_TYPE_NUMBER_BOLD(): string {
- return ListComponent.COLUMN_TYPE_NUMBER_BOLD;
- }
-
- get COLUMN_TYPE_TEXT_BOLD(): string {
- return ListComponent.COLUMN_TYPE_TEXT_BOLD;
- }
-
- get COLUMN_TYPE_TEXT_LINKED(): string {
- return ListComponent.COLUMN_TYPE_TEXT_LINKED;
- }
-
- get COLUMN_TYPE_WEBSITE(): string {
- return ListComponent.COLUMN_TYPE_WEBSITE;
- }
-
- ngOnDestroy(): void {
- this.clearAutoRefresh();
- }
- }
|