import { HttpClient } from '@angular/common/http'; import { Component, OnInit, ViewChild } from '@angular/core'; import { UntypedFormBuilder, UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; import { MatPaginator } from '@angular/material/paginator'; import { MatSort } from '@angular/material/sort'; import { ActivatedRoute, Params, Router } from '@angular/router'; import { DescriptionStatus } from '@app/core/common/enum/description-status'; import { IsActive } from '@app/core/common/enum/is-active.enum'; import { AppPermission } from '@app/core/common/enum/permission.enum'; import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order'; import { DescriptionTemplate } from '@app/core/model/description-template/description-template'; import { Description } from '@app/core/model/description/description'; import { Dmp, DmpDescriptionTemplate, DmpUser } from '@app/core/model/dmp/dmp'; import { DmpReference } from '@app/core/model/dmp/dmp-reference'; import { FileFormat } from '@app/core/model/file/file-format.model'; import { ReferenceType } from '@app/core/model/reference-type/reference-type'; import { Reference } from '@app/core/model/reference/reference'; import { DescriptionLookup } from '@app/core/query/description.lookup'; import { DmpLookup } from '@app/core/query/dmp.lookup'; import { AuthService } from '@app/core/services/auth/auth.service'; import { DescriptionService } from '@app/core/services/description/description.service'; import { DmpService } from '@app/core/services/dmp/dmp.service'; import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; import { GuidedTour, Orientation } from '@app/library/guided-tour/guided-tour.constants'; import { GuidedTourService } from '@app/library/guided-tour/guided-tour.service'; import { StartNewDmpDialogComponent } from '@app/ui/dmp/new/start-new-dmp-dialogue/start-new-dmp-dialog.component'; // import { IBreadCrumbComponent } from '@app/ui/misc/breadcrumb/definition/IBreadCrumbComponent'; // import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item'; import { BaseComponent } from '@common/base/base.component'; import { Guid } from '@common/types/guid'; import { TranslateService } from '@ngx-translate/core'; import { debounceTime, takeUntil } from 'rxjs/operators'; import { nameof } from 'ts-simple-nameof'; import { StartNewDescriptionDialogComponent } from '../start-new-description-dialog/start-new-description-dialog.component'; @Component({ selector: 'app-description-listing-component', templateUrl: 'description-listing.component.html', styleUrls: ['./description-listing.component.scss'] }) export class DescriptionListingComponent extends BaseComponent implements OnInit {//IBreadCrumbComponent @ViewChild(MatPaginator, { static: true }) _paginator: MatPaginator; @ViewChild(MatSort) sort: MatSort; // @ViewChild(DescriptionCriteriaComponent, { static: true }) criteria: DescriptionCriteriaComponent; // breadCrumbs: Observable; titlePrefix: String; dmpId: string; status: Number; totalCount: number; dmpSearchEnabled = true; listingItems: any[] = []; hasListingItems = null; isPublic: boolean = false; public isVisible = true pageSize: number = 5; lookup: DescriptionLookup = new DescriptionLookup(); criteriaFormGroup: UntypedFormGroup; public formGroup = new UntypedFormBuilder().group({ like: new UntypedFormControl(), order: new UntypedFormControl() }); scrollbar: boolean; order = RecentActivityOrder; dmpText: string; descriptionText: string; constructor( private descriptionService: DescriptionService, private router: Router, private route: ActivatedRoute, public dialog: MatDialog, private language: TranslateService, private authService: AuthService, public enumUtils: EnumUtils, private authentication: AuthService, private guidedTourService: GuidedTourService, private httpClient: HttpClient, private matomoService: MatomoService, private fb: UntypedFormBuilder, ) { super(); } ngOnInit() { this.matomoService.trackPageView('Descriptions'); this.isPublic = this.router.url === '/explore-descriptions'; if (this.isPublic) { //TODO: refactor // this.formGroup.get('order').setValue(this.order.DATASETPUBLISHED); } else { this.formGroup.get('order').setValue(this.order.UpdatedAt); } if (!this.isPublic && !this.authService.currentAccountIsAuthenticated()) { this.router.navigateByUrl("/explore"); } this.route.params .pipe(takeUntil(this._destroyed)) .subscribe(async (params: Params) => { const queryParams = this.route.snapshot.queryParams; this.dmpId = queryParams['dmpId']; this.status = queryParams['status']; this.lookup.page = { size: this.pageSize, offset: 0 }; this.lookup.order = { items: ['-' + nameof(x => x.updatedAt)] }; this.lookup.metadata = { countAll: true }; this.lookup.isActive = [IsActive.Active]; if (this.dmpId != null && Guid.isGuid(this.dmpId)) { this.dmpSearchEnabled = false; //const dmp = await this.dmpService.getSingle(this.dmpId).toPromise(); this.lookup.dmpSubQuery = new DmpLookup(); this.lookup.dmpSubQuery.ids = [Guid.parse(this.dmpId)]; if (params['dmpLabel'] !== undefined) { this.titlePrefix = 'for ' + params['dmpLabel']; } } if (this.status != null && this.status == DescriptionStatus.Draft) { //TODO: chack if actually used this.lookup.statuses = [DescriptionStatus.Draft] } this.refresh(this.lookup); }); this.formGroup.get('like').valueChanges .pipe(takeUntil(this._destroyed), debounceTime(500)) .subscribe(x => this.controlModified()); this.formGroup.get('order').valueChanges .pipe(takeUntil(this._destroyed)) .subscribe(x => { const fields: Array = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '' : "-") + this.formGroup.get('order').value]; this.lookup.order = { items: fields }; this.lookup.page = { size: this.pageSize, offset: 0 }; this.refresh(this.lookup); }); } ngAfterContentChecked(): void { this.scrollbar = this.hasScrollbar(); } public dashboardTour: GuidedTour = { tourId: 'dmp-description-tour', useOrb: true, steps: [ { selector: '.dmp-tour', content: 'Step 1', orientation: Orientation.Right, isStepUnique: false }, { selector: '.description-tour', content: 'Step 2', orientation: Orientation.Right, isStepUnique: false } ] }; public isAuthenticated(): boolean { return this.authService.currentAccountIsAuthenticated(); } controlModified(): void { this.lookup.like = this.formGroup.get("like").value; this.lookup.page = { size: this.pageSize, offset: 0 }; this.refresh(this.lookup); } loadMore() { this.lookup.page = { size: this.pageSize, offset: this.lookup.page.offset + this.pageSize }; this.refresh(this.lookup); } orderByChanged(){ if (this.formGroup.get('order').value == RecentActivityOrder.Status){ this.lookup.order = { items: ['-' + nameof(x => x.status)] }; } else if(this.formGroup.get('order').value == RecentActivityOrder.Label){ this.lookup.order = { items: ['-' + nameof(x => x.label)] }; }else{ this.lookup.order = { items: ['-' + nameof(x => x.updatedAt)] }; } this.refresh(this.lookup); } private refresh(lookup: DescriptionLookup) { lookup.project = { fields: [ nameof(x => x.id), nameof(x => x.label), nameof(x => x.status), nameof(x => x.updatedAt), [nameof(x => x.authorizationFlags), AppPermission.EditDescription].join('.'), [nameof(x => x.authorizationFlags), AppPermission.DeleteDescription].join('.'), [nameof(x => x.descriptionTemplate), nameof(x => x.id)].join('.'), [nameof(x => x.descriptionTemplate), nameof(x => x.label)].join('.'), [nameof(x => x.descriptionTemplate), nameof(x => x.groupId)].join('.'), [nameof(x => x.dmp), nameof(x => x.id)].join('.'), [nameof(x => x.dmp), nameof(x => x.label)].join('.'), [nameof(x => x.dmp), nameof(x => x.status)].join('.'), [nameof(x => x.dmp), nameof(x => x.accessType)].join('.'), [nameof(x => x.dmp), nameof(x => x.dmpUsers), nameof(x => x.id)].join('.'), [nameof(x => x.dmp), nameof(x => x.dmpUsers), nameof(x => x.user.id)].join('.'), [nameof(x => x.dmp), nameof(x => x.dmpUsers), nameof(x => x.role)].join('.'), [nameof(x => x.dmp), nameof(x => x.dmpReferences), nameof(x => x.id)].join('.'), [nameof(x => x.dmp), nameof(x => x.dmpReferences), nameof(x => x.reference), nameof(x => x.id)].join('.'), [nameof(x => x.dmp), nameof(x => x.dmpReferences), nameof(x => x.reference), nameof(x => x.label)].join('.'), [nameof(x => x.dmp), nameof(x => x.dmpReferences), nameof(x => x.reference), nameof(x => x.type), nameof(x => x.id)].join('.'), [nameof(x => x.dmp), nameof(x => x.dmpReferences), nameof(x => x.reference), nameof(x => x.reference)].join('.'), [nameof(x => x.dmp), nameof(x => x.dmpReferences), nameof(x => x.isActive)].join('.'), [nameof(x => x.dmpDescriptionTemplate), nameof(x => x.id)].join('.'), [nameof(x => x.dmpDescriptionTemplate), nameof(x => x.dmp), nameof(x => x.id)].join('.'), [nameof(x => x.dmpDescriptionTemplate), nameof(x => x.descriptionTemplateGroupId)].join('.'), [nameof(x => x.dmpDescriptionTemplate), nameof(x => x.sectionId)].join('.'), ] }; if(this.isPublic){ this.descriptionService.publicQuery(lookup).pipe(takeUntil(this._destroyed)) .subscribe(result => { if (!result) { return []; } this.totalCount = result.count; if (lookup?.page?.offset === 0) this.listingItems = []; this.listingItems.push(...result.items); this.hasListingItems = true; }); }else{ this.descriptionService.query(lookup).pipe(takeUntil(this._destroyed)) .subscribe(result => { if (!result) { return []; } this.totalCount = result.count; if (lookup?.page?.offset === 0) this.listingItems = []; result.items.forEach(description => { if (description.status != DescriptionStatus.Canceled) this.listingItems.push(description); }) this.hasListingItems = true; }); } } openFiltersDialog(): void { //TODO: Add filters dialog // const dialogRef = this.dialog.open(DescriptionCriteriaDialogComponent, { // width: '456px', // height: '100%', // id: 'filters', // restoreFocus: false, // data: { // isPublic: this.isPublic, // status: this.status, // criteria: this.criteria, // formGroup: this.criteriaFormGroup, // // criteria: this.grantId ? this.criteria : this.getDefaultCriteria(), // updateDataFn: this.updateDataFn.bind(this) // }, // position: { right: '0px;' }, // panelClass: 'dialog-side-panel' // }); // dialogRef.afterClosed().subscribe(result => { // }); } // updateDataFn(criteria: DescriptionCriteriaComponent): void { // this.criteriaFormGroup = criteria.formGroup; // this.toDescriptionCriteria(criteria); // this.refresh(); // } // toDescriptionCriteria(criteria: DescriptionCriteriaComponent) { // let formGroup = criteria.formGroup; // this.criteria = { // like: formGroup.get("like").value, // status: formGroup.get("status").value, // allVersions: formGroup.get("allVersions").value, // role: formGroup.get("role").value // } // if (formGroup.get("tags") && formGroup.get("tags").value) { // this.criteria.tags = formGroup.get("tags").value.map(x => (x)); // } // if (formGroup.get("collaborators") && formGroup.get("collaborators").value) { // this.criteria.collaborators = formGroup.get("collaborators").value.map(x => x.id); // } // if (formGroup.get("dmpIds") && formGroup.get("dmpIds").value) { // this.criteria.dmpIds = formGroup.get("dmpIds").value.map(x => x.id); // } // if (formGroup.get("groupIds") && formGroup.get("groupIds").value) { // this.criteria.groupIds = formGroup.get("groupIds").value.map(x => x.groupId); // } // if (formGroup.get("grants") && formGroup.get("grants").value) { // this.criteria.grants = formGroup.get("grants").value.map(x => x.id); // } // if (formGroup.get("organisations") && formGroup.get("organisations").value) { // this.criteria.organisations = formGroup.get("organisations").value.map(x => x.id); // } // if (formGroup.get("descriptionTemplates") && formGroup.get("descriptionTemplates").value) { // this.criteria.descriptionTemplates = formGroup.get("descriptionTemplates").value.map(x => x.id) // } // if (formGroup.get("grantStatus") && formGroup.get("grantStatus").value) { // this.criteria.grantStatus = formGroup.get("grantStatus").value; // } // this.criteria.isPublic = this.isPublic; // } hasScrollbar(): boolean { return document.getElementById("main-page").scrollHeight > document.documentElement.clientHeight } public restartTour(): void { this.setDashboardTourDmpText(); this.setDashboardTourDescriptionText(); this.guidedTourService.startTour(this.dashboardTour); } public setDashboardTourDmpText(): void { this.dmpText = this.language.instant('DESCRIPTION-LISTING.TEXT-INFO') + '\n\n' + this.language.instant('DESCRIPTION-LISTING.TEXT-INFO-QUESTION') + ' ' + this.language.instant('DESCRIPTION-LISTING.LINK-ZENODO') + ' ' + this.language.instant('DESCRIPTION-LISTING.GET-IDEA'); this.dashboardTour.steps[0].title = this.dmpText; } public setDashboardTourDescriptionText(): void { this.descriptionText = this.language.instant('DESCRIPTION-LISTING.TEXT-INFO') + this.language.instant('DESCRIPTION-LISTING.LINK-PUBLIC-DATASETS') + ' ' + this.language.instant('DESCRIPTION-LISTING.TEXT-INFO-REST') + '\n\n' + this.language.instant('DESCRIPTION-LISTING.TEXT-INFO-PAR'); this.dashboardTour.steps[1].title = this.descriptionText; } openNewDmpDialog() { if (this.dialog.openDialogs.length > 0) { this.dialog.closeAll(); } else { const dialogRef = this.dialog.open(StartNewDmpDialogComponent, { disableClose: false, data: { isDialog: true } }); } } addNewDescription() { const formGroup = this.fb.group({ dmpId: this.fb.control(null, Validators.required), sectionId: this.fb.control(null, Validators.required), }) const dialogRef = this.dialog.open(StartNewDescriptionDialogComponent, { disableClose: false, restoreFocus: false, data: { startNewDmp: false, formGroup: formGroup, } }); dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { if (result) { if (result.startNewDmp) { this.openNewDmpDialog(); } else { this.router.navigate(['/descriptions', 'edit', result.formGroup.get('dmpId').value, result.formGroup.get('sectionId').value]); } } }); } hasLikeCriteria(): boolean { return this.lookup.like !== undefined && this.lookup.like !== null; } }