argos/dmp-frontend/src/app/ui/dmp/listing/dmp-listing.component.ts

387 lines
15 KiB
TypeScript

import { HttpClient } from '@angular/common/http';
import { Component, OnInit, ViewChild } from '@angular/core';
import { UntypedFormBuilder, UntypedFormControl } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { ActivatedRoute, Router } from '@angular/router';
import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order';
import { AuthService } from '@app/core/services/auth/auth.service';
import { DmpService } from '@app/core/services/dmp/dmp.service';
import { MatomoService } from '@app/core/services/matomo/matomo-service';
import { UiNotificationService } from '@app/core/services/notification/ui-notification-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 { IBreadCrumbComponent } from '@app/ui/misc/breadcrumb/definition/IBreadCrumbComponent';
// import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item';
import { IsActive } from '@app/core/common/enum/is-active.enum';
import { Description } from '@app/core/model/description/description';
import { DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
import { Dmp, DmpUser } from '@app/core/model/dmp/dmp';
import { DmpLookup } from '@app/core/query/dmp.lookup';
import { BaseComponent } from '@common/base/base.component';
import { Guid } from '@common/types/guid';
import { TranslateService } from '@ngx-translate/core';
import { NgDialogAnimationService } from "ng-dialog-animation";
import { debounceTime, takeUntil } from 'rxjs/operators';
import { nameof } from 'ts-simple-nameof';
import { DmpVersionStatus } from '@app/core/common/enum/dmp-version-status';
import { DmpReference } from '@app/core/model/dmp/dmp-reference';
import { Reference } from '@app/core/model/reference/reference';
import { ReferenceType } from '@app/core/model/reference-type/reference-type';
import { AppPermission } from '@app/core/common/enum/permission.enum';
import { DmpStatus } from '@app/core/common/enum/dmp-status';
import { DescriptionStatus } from '@app/core/common/enum/description-status';
@Component({
selector: 'app-dmp-listing-component',
templateUrl: 'dmp-listing.component.html',
styleUrls: ['./dmp-listing.component.scss'],
})
export class DmpListingComponent extends BaseComponent implements OnInit { //IBreadCrumbComponent
@ViewChild(MatPaginator, { static: true }) _paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort;
lookup: DmpLookup = new DmpLookup();
groupId: string;
totalCount: number;
listingItems: any[] = [];
isPublic: boolean = false;
hasListingItems = null;
pageSize: number = 5;
public formGroup = new UntypedFormBuilder().group({
like: new UntypedFormControl(),
order: new UntypedFormControl()
});
scrollbar: boolean;
order = RecentActivityOrder;
constructor(
private dmpService: DmpService,
private router: Router,
private route: ActivatedRoute,
public dialogAnimation: NgDialogAnimationService,
public dialog: MatDialog,
public enumUtils: EnumUtils,
private language: TranslateService,
private uiNotificationService: UiNotificationService,
private authService: AuthService,
private guidedTourService: GuidedTourService,
private httpClient: HttpClient,
private matomoService: MatomoService
) {
super();
}
ngOnInit() {
this.matomoService.trackPageView('DMPs');
this.isPublic = this.router.url.startsWith('/explore-plans');
if (this.isPublic) {
//TODO refactor
// this.formGroup.get('order').setValue(this.order.PUBLISHED);
} else {
this.formGroup.get('order').setValue(this.order.UpdatedAt);
}
if (!this.isPublic && !this.authService.currentAccountIsAuthenticated()) {
this.router.navigateByUrl("/explore-plans");
}
this.route.params
.pipe(takeUntil(this._destroyed))
.subscribe(async params => {
this.groupId = params['groupId'];
this.lookup.page = { size: this.pageSize, offset: 0 };
this.lookup.order = { items: ['-' + nameof<Dmp>(x => x.updatedAt)] };
this.lookup.metadata = { countAll: true };
this.lookup.isActive = [IsActive.Active];
if (this.groupId != null && Guid.isGuid(this.groupId)) {
this.lookup.groupIds = [Guid.parse(this.groupId)];
this.lookup.versionStatuses = null;
} else {
this.lookup.versionStatuses = [DmpVersionStatus.Current, DmpVersionStatus.NotFinalized];
}
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 => this.refresh(this.lookup));
}
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.authService.currentAccountIsAuthenticated();
}
ngAfterContentChecked(): void {
this.scrollbar = this.hasScrollbar();
}
openTour() {
this.language.get('DMP-LISTING.TEXT-INFO').pipe(takeUntil(this._destroyed)).subscribe((x: string) => {
this.dashboardTour.steps[0].title = x + '\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[1].title = 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.guidedTourService.startTour(this.dashboardTour);
});
}
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<Dmp>(x => x.status)] };
} else if(this.formGroup.get('order').value == RecentActivityOrder.Label){
this.lookup.order = { items: ['-' + nameof<Dmp>(x => x.label)] };
}else{
this.lookup.order = { items: ['-' + nameof<Dmp>(x => x.updatedAt)] };
}
this.refresh(this.lookup);
}
private refresh(lookup: DmpLookup) {
lookup.project = {
fields: [
nameof<Dmp>(x => x.id),
nameof<Dmp>(x => x.label),
nameof<Dmp>(x => x.description),
nameof<Dmp>(x => x.status),
nameof<Dmp>(x => x.accessType),
nameof<Dmp>(x => x.version),
nameof<Dmp>(x => x.groupId),
nameof<Dmp>(x => x.updatedAt),
nameof<Dmp>(x => x.hash),
[nameof<Dmp>(x => x.authorizationFlags), AppPermission.CreateNewVersionDmp].join('.'),
[nameof<Dmp>(x => x.authorizationFlags), AppPermission.DeleteDmp].join('.'),
[nameof<Dmp>(x => x.authorizationFlags), AppPermission.CloneDmp].join('.'),
[nameof<Dmp>(x => x.authorizationFlags), AppPermission.FinalizeDmp].join('.'),
[nameof<Dmp>(x => x.authorizationFlags), AppPermission.ExportDmp].join('.'),
[nameof<Dmp>(x => x.authorizationFlags), AppPermission.InviteDmpUsers].join('.'),
[nameof<Dmp>(x => x.authorizationFlags), AppPermission.AssignDmpUsers].join('.'),
[nameof<Dmp>(x => x.authorizationFlags), AppPermission.EditDmp].join('.'),
[nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.id)].join('.'),
[nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.label)].join('.'),
[nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.status)].join('.'),
[nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.isActive)].join('.'),
[nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.id)].join('.'),
[nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.label)].join('.'),
[nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.id)].join('.'),
[nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.label)].join('.'),
// [nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.label)].join('.'),
// [nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.id)].join('.'),
// [nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.label)].join('.'),
// [nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.accessType)].join('.'),
[nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.id)].join('.'),
[nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.user.id)].join('.'),
[nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.role)].join('.'),
[nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.dmp.id)].join('.'),
[nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.isActive)].join('.'),
[nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.id)].join('.'),
[nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.id)].join('.'),
[nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.label)].join('.'),
[nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.type), nameof<ReferenceType>(x => x.id)].join('.'),
[nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.isActive)].join('.'),
// [nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.reference)].join('.'),
]
};
if(this.isPublic){
this.dmpService.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.dmpService.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(x=> {
if (x.descriptions) {
if (x.status == DmpStatus.Finalized) {
x.descriptions = x.descriptions.filter(x => x.isActive === IsActive.Active && x.status === DescriptionStatus.Finalized);
} else {
x.descriptions = x.descriptions.filter(x => x.isActive === IsActive.Active && x.status !== DescriptionStatus.Canceled);
}
}
x.dmpUsers = x.dmpUsers.filter(x=> x.isActive === IsActive.Active);
this.listingItems.push(x);
})
// this.listingItems.push(...result.items);
this.hasListingItems = true;
});
}
}
controlModified(): void {
this.lookup.like = this.formGroup.get("like").value;
this.lookup.page = { size: this.pageSize, offset: 0 };
this.refresh(this.lookup);
}
openShareDialog(rowId: any, rowName: any) {
//TODO: add this
// const dialogRef = this.dialog.open(DmpInvitationDialogComponent, {
// autoFocus: false,
// data: {
// dmpId: rowId,
// dmpName: rowName
// }
// });
}
openFiltersDialog(): void {
//TODO: Add filters dialog
// const dialogRef = this.dialog.open(DmpCriteriaDialogComponent, {
// width: '456px',
// height: '100%',
// id: 'filters',
// restoreFocus: false,
// data: {
// showGrant: this.showGrant,
// isPublic: this.isPublic,
// 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',
// // may remove NgDialogAnimationService package
// // animation: {
// // to: "left",
// // incomingOptions: {
// // keyframeAnimationOptions: { duration: 300, easing: "ease-in-out" }
// // }
// // }
// });
// dialogRef.afterClosed().subscribe(result => {
// });
}
// updateDataFn(criteria: DmpCriteriaComponent): void {
// this.criteriaFormGroup = criteria.formGroup;
// this.toDmpCriteria(criteria);
// this.refresh();
// }
// toDmpCriteria(criteria: DmpCriteriaComponent): void {
// let formGroup = criteria.formGroup;
// this.criteria = {
// like: formGroup.get('like').value,
// grants: formGroup.get('grants').value,
// role: formGroup.get('role').value
// }
// this.criteria.status = formGroup.get('status').value;
// this.setPublicCriteria(formGroup);
// if (formGroup.get('datasetTemplates').value)
// this.criteria.datasetTemplates = formGroup.get('datasetTemplates').value.map(x => x.id);
// if (formGroup.get('collaborators').value)
// this.criteria.collaborators = formGroup.get('collaborators').value.map(x => x.id);
// if (formGroup.get('organisations').value)
// this.criteria.organisations = formGroup.get('organisations').value.map(x => x.id);
// if (this.itemId) {
// this.criteria.groupIds = [this.itemId];
// this.criteria.allVersions = true;
// }
// this.criteria.grantStatus = formGroup.get('grantStatus').value;
// }
// setPublicCriteria(formGroup?: UntypedFormGroup): void {
// if (!isNullOrUndefined(formGroup)) {
// if (formGroup.get('status').value == 2) {
// this.criteria.status = 1;
// this.criteria.isPublic = true;
// } else {
// this.criteria.isPublic = false;
// }
// }
// this.criteria.onlyPublic = this.isPublic;
// if (this.isPublic) {
// this.criteria.isPublic = true;
// }
// // } else {
// // this.criteria.isPublic = false;
// // }
// }
hasScrollbar(): boolean {
return document.getElementById("main-page").scrollHeight > document.documentElement.clientHeight
}
public setDashboardTourDmpText(): void {
const 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 = dmpText;
}
public setDashboardTourDatasetText(): void {
const 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 = datasetText;
}
public restartTour(): void {
this.setDashboardTourDmpText();
this.setDashboardTourDatasetText();
this.guidedTourService.startTour(this.dashboardTour);
}
public hasLikeCriteria(): boolean {
return this.lookup.like !== undefined && this.lookup.like !== null;
}
}