import { Component, OnInit, ViewChild } from '@angular/core'; import { MatPaginator } from '@angular/material/paginator'; import { MatSort } from '@angular/material/sort'; import { ActivatedRoute, Params, Router } from '@angular/router'; import { DatasetStatus } from '@app/core/common/enum/dataset-status'; import { DataTableRequest } from '@app/core/model/data-table/data-table-request'; import { DatasetListingModel } from '@app/core/model/dataset/dataset-listing'; import { DatasetCriteria } from '@app/core/query/dataset/dataset-criteria'; import { DatasetService } from '@app/core/services/dataset/dataset.service'; import { DmpService } from '@app/core/services/dmp/dmp.service'; import { DatasetCriteriaComponent } from '@app/ui/dataset/listing/criteria/dataset-criteria.component'; import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item'; import { IBreadCrumbComponent } from '@app/ui/misc/breadcrumb/definition/IBreadCrumbComponent'; import { BaseComponent } from '@common/base/base.component'; import { TranslateService } from '@ngx-translate/core'; import { Observable, of as observableOf } from 'rxjs'; import { debounceTime, takeUntil } from 'rxjs/operators'; import { ExternalTagEditorModel, DatasetWizardEditorModel } from '../dataset-wizard/dataset-wizard-editor.model'; import { AuthService } from '@app/core/services/auth/auth.service'; import { isNullOrUndefined } from 'util'; import { DatasetCriteriaDialogComponent } from './criteria/dataset-criteria-dialogue/dataset-criteria-dialog.component'; import { MatDialog } from '@angular/material'; import { FormGroup, FormBuilder, FormControl } from '@angular/forms'; import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order'; import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; import { GuidedTourService } from '@app/library/guided-tour/guided-tour.service'; import { GuidedTour, Orientation } from '@app/library/guided-tour/guided-tour.constants'; import { StartNewDatasetDialogComponent } from '@app/ui/dmp/start-new-dataset-dialogue/start-new-dataset-dialog.component'; import { StartNewDmpDialogComponent } from '@app/ui/dmp/start-new-dmp-dialogue/start-new-dmp-dialog.component'; @Component({ selector: 'app-dataset-listing-component', templateUrl: 'dataset-listing.component.html', styleUrls: ['./dataset-listing.component.scss'] }) export class DatasetListingComponent extends BaseComponent implements OnInit, IBreadCrumbComponent { @ViewChild(MatPaginator, { static: true }) _paginator: MatPaginator; @ViewChild(MatSort, { static: false }) sort: MatSort; // @ViewChild(DatasetCriteriaComponent, { static: true }) criteria: DatasetCriteriaComponent; breadCrumbs: Observable; titlePrefix: String; dmpId: string; status: Number; totalCount: number; dmpSearchEnabled = true; listingItems: DatasetListingModel[] = []; hasListingItems = null; isPublic: boolean = false; public isVisible = true startIndex: number = 0; pageSize: number = 5; criteria: DatasetCriteria; criteriaFormGroup: FormGroup; public formGroup = new FormBuilder().group({ like: new FormControl(), order: new FormControl() }); scrollbar: boolean; order = RecentActivityOrder; dmpText: string; datasetText: string; constructor( private datasetService: DatasetService, private router: Router, private route: ActivatedRoute, public dialog: MatDialog, private dmpService: DmpService, private language: TranslateService, private authService: AuthService, public enumUtils: EnumUtils, private authentication: AuthService, private guidedTourService: GuidedTourService ) { super(); } ngOnInit() { this.isPublic = this.router.url === '/explore'; if (this.isPublic) { this.formGroup.get('order').setValue(this.order.DATASETPUBLISHED); } else { this.formGroup.get('order').setValue(this.order.MODIFIED); } if (!this.isPublic && isNullOrUndefined(this.authService.current())) { 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']; // Makes multiple post requests // this.criteria.setRefreshCallback(() => this.refresh()); if (this.dmpId != null) { this.dmpSearchEnabled = false; const dmp = await this.dmpService.getSingle(this.dmpId).toPromise(); this.criteria = this.getDefaultCriteria(dmp); // this.criteria.setCriteria(this.getDefaultCriteria(dmp)); this.refresh(); // this.criteria.setRefreshCallback((resetPages) => this.refresh(resetPages)); this.breadCrumbs = observableOf([{ parentComponentName: 'DmpEditorComponent', label: dmp.label, url: '/plans/edit/' + this.dmpId }]); if (params['dmpLabel'] !== undefined) { this.titlePrefix = 'for ' + params['dmpLabel']; } } else { this.criteria = this.getDefaultCriteria(); // this.criteria.setCriteria(this.getDefaultCriteria()); this.refresh(); // this.criteria.setRefreshCallback((resetPages) => this.refresh(resetPages)); this.breadCrumbs = observableOf([{ parentComponentName: null, label: this.language.instant('NAV-BAR.MY-DATASET-DESCRIPTIONS'), url: this.isPublic ? "/explore" : "/datasets" }]); } if (this.status != null && this.status == DatasetStatus.Draft) { this.criteria = this.getDraftCriteria(); // this.criteria.setRefreshCallback((resetPages) => this.refresh(resetPages)); this.refresh(); } }); 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 => this.refresh()); } ngAfterContentChecked(): void { this.scrollbar = this.hasScrollbar(); } public dashboardTour: GuidedTour = { tourId: 'dmp-dataset-tour', useOrb: true, steps: [ { selector: '.dmp-tour', content: 'Step 1', orientation: Orientation.Right, isStepUnique: false }, { selector: '.dataset-tour', content: 'Step 2', orientation: Orientation.Right, isStepUnique: false } ] }; public isAuthenticated(): boolean { return !(!this.authentication.current()); } controlModified(): void { // this.clearErrorModel(); // if (this.refreshCallback != null && // (this.formGroup.get('like').value == null || this.formGroup.get('like').value.length === 0 || this.formGroup.get('like').value.length > 2) // ) { // setTimeout(() => this.refreshCallback(true)); // } this.criteria.like = this.formGroup.get("like").value; this.startIndex = 0; this.refresh(); } refresh(resetPages = false) { // if (this._paginator.pageSize === undefined) this._paginator.pageSize = 10; // if (resetPages) this._paginator.pageIndex = 0; // const startIndex = this._paginator.pageIndex * this._paginator.pageSize; // let fields: Array = new Array(); // fields.push('-modified'); //if (this.sort && this.sort.active) { fields = this.sort.direction === 'asc' ? ['+' + this.sort.active] : ['-' + this.sort.active]; } const fields: Array = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value]; const request = new DataTableRequest(this.startIndex, this.pageSize, { fields: fields }); this.criteria.isPublic = this.isPublic; request.criteria = this.criteria; this.datasetService.getPaged(request).pipe(takeUntil(this._destroyed)).subscribe(result => { if (!result) { return []; } // if (this._paginator.pageIndex === 0) { this.totalCount = result.totalCount; } this.totalCount = result.totalCount; this.listingItems = result.data; this.hasListingItems = true; }); } public loadMore() { this.startIndex = this.startIndex + this.pageSize; // const fields: Array = ["-modified"]; const fields: Array = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value]; const request = new DataTableRequest(this.startIndex, this.pageSize, { fields: fields }); this.criteria.isPublic = this.isPublic; request.criteria = this.criteria; this.datasetService.getPaged(request).pipe(takeUntil(this._destroyed)).subscribe(result => { if (!result) { return []; } // if (this._paginator.pageIndex === 0) { this.totalCount = result.totalCount; } // this.listingItems = this.listingItems.concat(result.data); this.listingItems = this.listingItems.length > 0 ? this.mergeTwoSortedLists(this.listingItems, result.data, this.formGroup.get('order').value) : result.data; this.hasListingItems = true; }); } pageThisEvent(event) { this.refresh(); } getDefaultCriteria(dmp: any = null): DatasetCriteria { const defaultCriteria = new DatasetCriteria(); if (dmp != null) { defaultCriteria.dmpIds.push(dmp); } return defaultCriteria; } getDraftCriteria(): DatasetCriteria { const draftCriteria = new DatasetCriteria(); draftCriteria.status = DatasetStatus.Draft; return draftCriteria; } makeItPublic(id: String) { this.datasetService.makeDatasetPublic(id) .pipe(takeUntil(this._destroyed)) .subscribe(); } openFiltersDialog(): void { const dialogRef = this.dialog.open(DatasetCriteriaDialogComponent, { 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;' } }); dialogRef.afterClosed().subscribe(result => { }); } updateDataFn(criteria: DatasetCriteriaComponent): void { this.criteriaFormGroup = criteria.formGroup; this.toDatasetCriteria(criteria); this.refresh(); } toDatasetCriteria(criteria: DatasetCriteriaComponent) { 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("datasetTemplates") && formGroup.get("datasetTemplates").value) { this.criteria.datasetTemplates = formGroup.get("datasetTemplates").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; // if (this.itemId) { // // this.criteria.groupIds = [this.itemId]; // this.criteria.allVersions = true; // } } public closeCard(): void { this.isVisible = false; } hasScrollbar(): boolean { return document.getElementById("main-page").scrollHeight > document.documentElement.clientHeight } private mergeTwoSortedLists(arr1: DatasetListingModel[], arr2: DatasetListingModel[], order: string): DatasetListingModel[] { let merged = []; let index1 = 0; let index2 = 0; let current = 0; while (current < (arr1.length + arr2.length)) { let isArr1Depleted = index1 >= arr1.length; let isArr2Depleted = index2 >= arr2.length; if (order === 'modified') { if (!isArr1Depleted && (isArr2Depleted || (new Date(arr1[index1].modified) > new Date(arr2[index2].modified)))) { merged[current] = arr1[index1]; index1++; } else { merged[current] = arr2[index2]; index2++; } } else if (order === 'created') { if (!isArr1Depleted && (isArr2Depleted || (new Date(arr1[index1].created) > new Date(arr2[index2].created)))) { merged[current] = arr1[index1]; index1++; } else { merged[current] = arr2[index2]; index2++; } } else if (order === 'label') { if (!isArr1Depleted && (isArr2Depleted || (arr1[index1].label.localeCompare(arr2[index2].label)))) { merged[current] = arr1[index1]; index1++; } else { merged[current] = arr2[index2]; index2++; } } else if (order === 'status') { if (!isArr1Depleted && (isArr2Depleted || (arr1[index1].status < arr2[index2].status))) { merged[current] = arr1[index1]; index1++; } else { merged[current] = arr2[index2]; index2++; } } else if (order === 'dmp:publishedAt|join|') { if (!isArr1Depleted && (isArr2Depleted || (new Date(arr1[index1].dmpPublishedAt) > new Date(arr2[index2].dmpPublishedAt)))) { merged[current] = arr1[index1]; index1++; } else { merged[current] = arr2[index2]; index2++; } } current++; } return merged; } public setDashboardTourDmpText(): void { this.dmpText = this.language.instant('DMP-LISTING.TEXT-INFO') + '\n\n' + this.language.instant('DMP-LISTING.TEXT-INFO-QUESTION') + ' ' + this.language.instant('DMP-LISTING.LINK-ZENODO') + ' ' + this.language.instant('DMP-LISTING.GET-IDEA'); this.dashboardTour.steps[0].title = this.dmpText; } public setDashboardTourDatasetText(): void { this.datasetText = this.language.instant('DATASET-LISTING.TEXT-INFO') + this.language.instant('DATASET-LISTING.LINK-PUBLIC-DATASETS') + ' ' + this.language.instant('DATASET-LISTING.TEXT-INFO-REST') + '\n\n' + this.language.instant('DATASET-LISTING.TEXT-INFO-PAR'); this.dashboardTour.steps[1].title = this.datasetText; } public restartTour(): void { this.setDashboardTourDmpText(); this.setDashboardTourDatasetText(); this.guidedTourService.startTour(this.dashboardTour); } openNewDmpDialog() { if (this.dialog.openDialogs.length > 0) { this.dialog.closeAll(); } else { const dialogRef = this.dialog.open(StartNewDmpDialogComponent, { disableClose: false, data: { isDialog: true } }); } } addNewDataset() { const dialogRef = this.dialog.open(StartNewDatasetDialogComponent, { disableClose: false, restoreFocus: false, data: { startNewDmp: false, formGroup: new DatasetWizardEditorModel().buildForm() } }); dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { if (result) { if (result.startNewDmp) { this.openNewDmpDialog(); } else { this.router.navigate(['/datasets', 'new', result.formGroup.get('dmp').value.id]); } } }); } // rowClicked(dataset: DatasetListingModel) { // this.router.navigate(['/datasets/edit/' + dataset.id]); // } }