import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute, Router } from '@angular/router'; import { IsActive } from '@app/core/common/enum/is-active.enum'; import { DescriptionTemplate } from '@app/core/model/description-template/description-template'; import { AuthService } from '@app/core/services/auth/auth.service'; import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; import { FileUtils } from '@app/core/services/utilities/file-utils.service'; import { QueryParamsService } from '@app/core/services/utilities/query-params.service'; import { BaseListingComponent } from '@common/base/base-listing-component'; import { PipeService } from '@common/formatting/pipe.service'; import { DataTableDateTimeFormatPipe } from '@common/formatting/pipes/date-time-format.pipe'; import { QueryResult } from '@common/model/query-result'; import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service'; import { ColumnDefinition, ColumnsChangedEvent, HybridListingComponent, PageLoadEvent } from '@common/modules/hybrid-listing/hybrid-listing.component'; import { Guid } from '@common/types/guid'; import { TranslateService } from '@ngx-translate/core'; import * as FileSaver from 'file-saver'; import { Observable } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { nameof } from 'ts-simple-nameof'; import { ImportDescriptionTemplateDialogComponent } from './import-description-template/import-description-template.dialog.component'; import { DescriptionTemplateService } from '@app/core/services/description-template/description-template.service'; import { DescriptionTemplateStatus } from '@app/core/common/enum/description-template-status'; import { DescriptionTemplateLookup } from '@app/core/query/description-template.lookup'; import { IsActiveTypePipe } from '@common/formatting/pipes/is-active-type.pipe'; import { DescriptionTemplateVersionStatus } from '@app/core/common/enum/description-template-version-status'; @Component({ selector: 'app-description-template-listing-component', templateUrl: './description-template-listing.component.html', styleUrls: ['./description-template-listing.component.scss'] }) export class DescriptionTemplateListingComponent extends BaseListingComponent implements OnInit { publish = false; userSettingsKey = { key: 'DescriptionTemplateListingUserSettings' }; propertiesAvailableForOrder: ColumnDefinition[]; descriptionTemplateStatuses = DescriptionTemplateStatus; mode; @ViewChild('descriptionTemplateStatus', { static: true }) descriptionTemplateStatus?: TemplateRef; @ViewChild('actions', { static: true }) actions?: TemplateRef; @ViewChild(HybridListingComponent, { static: true }) hybridListingComponent: HybridListingComponent; private readonly lookupFields: string[] = [ nameof(x => x.id), nameof(x => x.label), nameof(x => x.description), nameof(x => x.status), nameof(x => x.version), nameof(x => x.groupId), nameof(x => x.updatedAt), nameof(x => x.createdAt), nameof(x => x.hash), nameof(x => x.belongsToCurrentTenant), nameof(x => x.isActive) ]; rowIdentity = x => x.id; constructor( protected router: Router, protected route: ActivatedRoute, protected uiNotificationService: UiNotificationService, protected httpErrorHandlingService: HttpErrorHandlingService, protected queryParamsService: QueryParamsService, private descriptionTemplateService: DescriptionTemplateService, public authService: AuthService, private matomoService: MatomoService, private pipeService: PipeService, public enumUtils: EnumUtils, private language: TranslateService, private dialog: MatDialog, private fileUtils: FileUtils ) { super(router, route, uiNotificationService, httpErrorHandlingService, queryParamsService); // Lookup setup // Default lookup values are defined in the user settings class. this.mode = this.route.snapshot?.data['mode']; this.lookup = this.initializeLookup(); } ngOnInit() { this.matomoService.trackPageView('Admin: DMP Templates'); super.ngOnInit(); } protected initializeLookup(): DescriptionTemplateLookup { const lookup = new DescriptionTemplateLookup(); lookup.metadata = { countAll: true }; lookup.page = { offset: 0, size: this.ITEMS_PER_PAGE }; lookup.isActive = [IsActive.Active]; lookup.order = { items: [this.toDescSortField(nameof(x => x.createdAt))] }; if (this.mode && this.mode == 'versions-listing') { lookup.groupIds = [Guid.parse(this.route.snapshot.paramMap.get('groupid'))]; lookup.versionStatuses = null; }else{ lookup.versionStatuses = [DescriptionTemplateVersionStatus.Current, DescriptionTemplateVersionStatus.NotFinalized]; } this.updateOrderUiFields(lookup.order); lookup.project = { fields: this.lookupFields }; return lookup; } protected setupColumns() { this.gridColumns.push(...[{ prop: nameof(x => x.label), sortable: true, languageName: 'DESCRIPTION-TEMPLATE-LISTING.FIELDS.NAME' }, { prop: nameof(x => x.description), sortable: true, languageName: 'DESCRIPTION-TEMPLATE-LISTING.FIELDS.DESCRIPTION' }, { prop: nameof(x => x.status), sortable: true, languageName: 'DESCRIPTION-TEMPLATE-LISTING.FIELDS.STATUS', cellTemplate: this.descriptionTemplateStatus }, { prop: nameof(x => x.version), sortable: true, languageName: 'DESCRIPTION-TEMPLATE-LISTING.FIELDS.VERSION' }, { prop: nameof(x => x.createdAt), sortable: true, languageName: 'DESCRIPTION-TEMPLATE-LISTING.FIELDS.CREATED-AT', pipe: this.pipeService.getPipe(DataTableDateTimeFormatPipe).withFormat('short') }, { prop: nameof(x => x.updatedAt), sortable: true, languageName: 'DESCRIPTION-TEMPLATE-LISTING.FIELDS.UPDATED-AT', pipe: this.pipeService.getPipe(DataTableDateTimeFormatPipe).withFormat('short') }, { prop: nameof(x => x.isActive), sortable: true, languageName: 'DESCRIPTION-TEMPLATE-LISTING.FIELDS.IS-ACTIVE', pipe: this.pipeService.getPipe(IsActiveTypePipe) }, { alwaysShown: true, cellTemplate: this.actions, maxWidth: 120 } ]); this.propertiesAvailableForOrder = this.gridColumns.filter(x => x.sortable); } // // Listing Component functions // onColumnsChanged(event: ColumnsChangedEvent) { super.onColumnsChanged(event); this.onColumnsChangedInternal(event.properties.map(x => x.toString())); } private onColumnsChangedInternal(columns: string[]) { // Here are defined the projection fields that always requested from the api. const fields = new Set(this.lookupFields); this.gridColumns.map(x => x.prop) .filter(x => !columns?.includes(x as string)) .forEach(item => { fields.delete(item as string) }); this.lookup.project = { fields: [...fields] }; this.onPageLoad({ offset: 0 } as PageLoadEvent); } protected loadListing(): Observable> { return this.descriptionTemplateService.query(this.lookup); } public delete(id: Guid) { if (id) { const dialogRef = this.dialog.open(ConfirmationDialogComponent, { data: { isDeleteConfirmation: true, message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'), confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'), cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL') } }); dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { if (result) { this.descriptionTemplateService.delete(id).pipe(takeUntil(this._destroyed)) .subscribe( complete => this.onCallbackSuccess(), error => this.onCallbackError(error) ); } }); } } onCallbackSuccess(): void { this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-DELETE'), SnackBarNotificationLevel.Success); this.refresh(); } export(id: Guid): void { this.descriptionTemplateService.downloadXML(id) .pipe(takeUntil(this._destroyed)) .subscribe(response => { const blob = new Blob([response.body], { type: 'application/xml' }); const filename = this.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); FileSaver.saveAs(blob, filename); }); } import(): void { const dialogRef = this.dialog.open(ImportDescriptionTemplateDialogComponent, { restoreFocus: false, data: { message: this.language.instant('DESCRIPTION-TEMPLATE-LISTING.IMPORT.UPLOAD-XML-FILE-TITLE'), confirmButton: this.language.instant('DESCRIPTION-TEMPLATE-LISTING.IMPORT.UPLOAD-XML'), cancelButton: this.language.instant('DESCRIPTION-TEMPLATE-LISTING.IMPORT.UPLOAD-XML-FILE-CANCEL'), name: '', file: FileList, sucsess: false } }); dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(data => { if (data && data.sucsess && data.name != null && data.file != null) { this.descriptionTemplateService.uploadFile(data.file, data.name) .pipe(takeUntil(this._destroyed)) .subscribe(_ => { this.uiNotificationService.snackBarNotification(this.language.instant('DESCRIPTION-TEMPLATE-LISTING.MESSAGES.TEMPLATE-UPLOAD-SUCCESS'), SnackBarNotificationLevel.Success); this.refresh(); }, error => { this.uiNotificationService.snackBarNotification(error.message, SnackBarNotificationLevel.Error); }); } }); } } // ngOnInit() { // refresh() { // this.dataSource = new DatasetDataSource(this.descriptionTemplateService, this._paginator, this.sort, this.criteria); // } // clone(id: string) { // this.router.navigate(['description-templates/clone/' + id]); // } // rowClick(rowId: String) { // this.router.navigate(['description-templates/' + rowId]); // } // downloadXML(descriptionTemplateId: string): void { // this.descriptionTemplateService.downloadXML(descriptionTemplateId) // .pipe(takeUntil(this._destroyed)) // .subscribe(response => { // const blob = new Blob([response.body], { type: 'application/xml' }); // const filename = this.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); // FileSaver.saveAs(blob, filename); // }); // } // deleteTemplate(id: string) { // if (id) { // this.dialog.open(ConfirmationDialogComponent, { // data: { // isDeleteConfirmation: true, // confirmButton: this.languageService.instant('DESCRIPTION-TEMPLATE-EDITOR.CONFIRM-DELETE-DIALOG.CONFIRM-BUTTON'), // cancelButton: this.languageService.instant("DESCRIPTION-TEMPLATE-EDITOR.CONFIRM-DELETE-DIALOG.CANCEL-BUTTON"), // message: this.languageService.instant("DESCRIPTION-TEMPLATE-EDITOR.CONFIRM-DELETE-DIALOG.MESSAGE") // } // }) // .afterClosed() // .subscribe( // confirmed => { // if (confirmed) { // this.descriptionTemplateService.delete(id) // .pipe(takeUntil(this._destroyed)) // .subscribe( // complete => { // this.uiNotificationService.snackBarNotification(this.languageService.instant('GENERAL.SNACK-BAR.SUCCESSFUL-DESCRIPTION-TEMPLATE-DELETE'), SnackBarNotificationLevel.Success); // this.refresh(); // }, // error => { // this.onCallbackError(error); // if (error.error.statusCode == 674) { // this.uiNotificationService.snackBarNotification(this.languageService.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DESCRIPTION-TEMPLATE-DELETE'), SnackBarNotificationLevel.Error); // } else { // this.uiNotificationService.snackBarNotification(this.languageService.instant(error.message), SnackBarNotificationLevel.Error); // } // } // ); // } // } // ) // } // } // onCallbackError(errorResponse: HttpErrorResponse) { // this.uiNotificationService.snackBarNotification(errorResponse.message, SnackBarNotificationLevel.Warning); // } // getDefaultCriteria(): DescriptionTemplateCriteria { // const defaultCriteria = new DescriptionTemplateCriteria(); // return defaultCriteria; // } // // makeItPublic(id: String) { // // debugger; // // this.datasetService.makeDatasetPublic(id).pipe(takeUntil(this._destroyed)).subscribe(); // // } // parseStatus(value: number): string { // const stringVal = value.toString() // try { // return this.statuses.find(status => status.value === stringVal).viewValue; // } catch { // return stringVal; // } // } // openDialog(): void { // const dialogRef = this.dialog.open(DialodConfirmationUploadDescriptionTemplates, { // restoreFocus: false, // data: { // message: this.languageService.instant('DESCRIPTION-TEMPLATE-LISTING.IMPORT.UPLOAD-XML-FILE-TITLE'), // confirmButton: this.languageService.instant('DESCRIPTION-TEMPLATE-LISTING.IMPORT.UPLOAD-XML'), // cancelButton: this.languageService.instant('DESCRIPTION-TEMPLATE-LISTING.IMPORT.UPLOAD-XML-FILE-CANCEL'), // name: '', // file: FileList, // sucsess: false // } // }); // dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(data => { // if (data && data.sucsess && data.name != null && data.file != null) { // this.descriptionTemplateService.uploadFile(data.file, data.name) // .pipe(takeUntil(this._destroyed)) // .subscribe(_ => { // this.uiNotificationService.snackBarNotification(this.languageService.instant('DESCRIPTION-TEMPLATE-LISTING.MESSAGES.TEMPLATE-UPLOAD-SUCCESS'), SnackBarNotificationLevel.Success); // this.refresh(); // }, // error => { // this.uiNotificationService.snackBarNotification(error.message, SnackBarNotificationLevel.Error); // }); // } // }); // } // getStatusClass(status: number): string { // if (status === 1) {//finalized // return 'status-chip-finalized' // } // if (status === 0) { // return 'status-chip-draft'; // } // return ''; // } // } // export class DatasetDataSource extends DataSource { // totalCount = 0; // constructor( // private _service: descriptionTemplateService, // private _paginator: MatPaginator, // private _sort: MatSort, // private _criteria: DescriptionTemplateCriteriaComponent // ) { // super(); // } // connect(): Observable { // const displayDataChanges = [ // this._paginator.page // //this._sort.matSortChange // ]; // return observableMerge(...displayDataChanges).pipe( // startWith(null), // switchMap(() => { // const startIndex = this._paginator.pageIndex * this._paginator.pageSize; // let fields: Array = new Array(); // if (this._sort.active) { fields = this._sort.direction === 'asc' ? ['+' + this._sort.active] : ['-' + this._sort.active]; } // const request = new DataTableRequest(startIndex, this._paginator.pageSize, { fields: fields }); // request.criteria = this._criteria.criteria; // return this._service.getPagedBlueprint(request); // }), // /*.catch((error: any) => { // this._snackBar.openFromComponent(SnackBarNotificationComponent, { // data: { message: 'GENERAL.SNACK-BAR.FORMS-BAD-REQUEST', language: this._languageService }, // duration: 3000, // extraClasses: ['snackbar-warning'] // }); // //this._criteria.criteria.onCallbackError(error); // return Observable.of(null); // })*/ // map(result => { // return result; // }), // map(result => { // if (!result) { return []; } // if (this._paginator.pageIndex === 0) { this.totalCount = result.totalCount; } // return result.data; // })); // } // disconnect() { // // No-op // }