diff --git a/dmp-backend/web/src/main/java/eu/eudat/interceptors/UserInterceptor.java b/dmp-backend/web/src/main/java/eu/eudat/interceptors/UserInterceptor.java index 815b27f97..b81759a38 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/interceptors/UserInterceptor.java +++ b/dmp-backend/web/src/main/java/eu/eudat/interceptors/UserInterceptor.java @@ -265,8 +265,10 @@ public class UserInterceptor implements WebRequestInterceptor { user.setId(UUID.randomUUID()); user.setName(name); user.setCreatedAt(Instant.now()); + user.setUpdatedAt(Instant.now()); user.setIsActive(IsActive.Active); user.setAdditionalInfo(this.jsonHandlingService.toJsonSafe(new AdditionalInfoEntity())); + this.entityManager.persist(user); UserCredentialEntity credential = this.buildCredential(user.getId(), subjectId); this.entityManager.persist(credential); @@ -275,7 +277,6 @@ public class UserInterceptor implements WebRequestInterceptor { UserContactInfoEntity contactInfo = this.buildEmailContact(user.getId(), email); this.entityManager.persist(contactInfo); } - this.entityManager.persist(user); if (roles != null) { for (String role: roles) { UserRoleEntity roleEntity = this.buildRole(user.getId(), role); diff --git a/dmp-frontend/src/app/app-routing.module.ts b/dmp-frontend/src/app/app-routing.module.ts index 33dc5520a..e5bb184f8 100644 --- a/dmp-frontend/src/app/app-routing.module.ts +++ b/dmp-frontend/src/app/app-routing.module.ts @@ -27,24 +27,6 @@ const appRoutes: Routes = [ title: 'GENERAL.TITLES.DATASETCREATEWIZARD' } }, - { - path: 'explore', - // loadChildren: () => import('./ui/explore-dataset/explore-dataset.module').then(m => m.ExploreDatasetModule), - loadChildren: () => import('./ui/dataset/dataset.module').then(m => m.DatasetModule), - data: { - breadcrumb: true, - title: 'GENERAL.TITLES.EXPLORE' - } - }, - { - path: 'explore-plans', - // loadChildren: () => import('./ui/explore-dmp/explore-dmp.module').then(m => m.ExploreDmpModule), - loadChildren: () => import('./ui/dmp/dmp.module').then(m => m.DmpModule), - data: { - breadcrumb: true, - title: 'GENERAL.TITLES.EXPLORE-PLANS' - } - }, { path: 'descriptions', loadChildren: () => import('./ui/description/description.module').then(m => m.DescriptionModule), @@ -53,6 +35,14 @@ const appRoutes: Routes = [ title: 'GENERAL.TITLES.DESCRIPTIONS' } }, + { + path: 'explore-descriptions', + loadChildren: () => import('./ui/description/description.module').then(m => m.DescriptionModule), + data: { + breadcrumb: true, + title: 'GENERAL.TITLES.EXPLORE' + } + }, { path: 'about', loadChildren: () => import('./ui/about/about.module').then(m => m.AboutModule), @@ -78,6 +68,14 @@ const appRoutes: Routes = [ title: 'GENERAL.TITLES.PLANS' } }, + { + path: 'explore-plans', + loadChildren: () => import('./ui/dmp/dmp.module').then(m => m.DmpModule), + data: { + breadcrumb: true, + title: 'GENERAL.TITLES.EXPLORE-PLANS' + } + }, { path: 'dmp-blueprints', loadChildren: () => import('./ui/admin/dmp-blueprint/dmp-blueprint.module').then(m => m.DmpBlueprintModule), diff --git a/dmp-frontend/src/app/core/model/description/description.ts b/dmp-frontend/src/app/core/model/description/description.ts index a28bc8b7c..522385e32 100644 --- a/dmp-frontend/src/app/core/model/description/description.ts +++ b/dmp-frontend/src/app/core/model/description/description.ts @@ -1,7 +1,7 @@ import { DescriptionStatus } from "@app/core/common/enum/description-status"; import { BaseEntity, BaseEntityPersist } from "@common/base/base-entity.model"; import { Guid } from "@common/types/guid"; -import { Dmp } from "../dmp/dmp"; +import { Dmp, DmpDescriptionTemplatePersist } from "../dmp/dmp"; import { DescriptionTemplate } from "../description-template/description-template"; import { User } from "../user/user"; import { Reference, ReferencePersist } from "../reference/reference"; @@ -18,7 +18,8 @@ export interface Description extends BaseEntity { finalizedAt: Date; descriptionReferences: DescriptionReference[]; descriptionTags: DescriptionTag[]; - template: DescriptionTemplate; + descriptionTemplate: DescriptionTemplate; + dmpDescriptionTemplate: DmpDescriptionTemplatePersist; dmp: Dmp; } diff --git a/dmp-frontend/src/app/core/model/dmp/dmp.ts b/dmp-frontend/src/app/core/model/dmp/dmp.ts index 9b4ff57c4..71623e7b6 100644 --- a/dmp-frontend/src/app/core/model/dmp/dmp.ts +++ b/dmp-frontend/src/app/core/model/dmp/dmp.ts @@ -17,6 +17,7 @@ import { DmpVersionStatus } from '@app/core/common/enum/dmp-version-status'; import { DmpAccessType } from '@app/core/common/enum/dmp-access-type'; import { DmpUserRole } from '@app/core/common/enum/dmp-user-role'; import { Guid } from '@common/types/guid'; +import { DescriptionTemplate } from '../description-template/description-template'; export interface DmpModel { //TODO: Delete id: string; @@ -99,6 +100,14 @@ export interface DmpUser extends BaseEntity { role: DmpUserRole; } +export interface DmpDescriptionTemplate extends BaseEntity { + dmp: Dmp; + currentDescriptionTemplate: DescriptionTemplate; //TODO: what is this? + descriptionTemplates: DescriptionTemplate[]; //TODO: why it is array? + descriptionTemplateGroupId: Guid; + sectionId: Guid; +} + // // Persist // diff --git a/dmp-frontend/src/app/core/query/dmp.lookup.ts b/dmp-frontend/src/app/core/query/dmp.lookup.ts index 72d341a5e..536318b00 100644 --- a/dmp-frontend/src/app/core/query/dmp.lookup.ts +++ b/dmp-frontend/src/app/core/query/dmp.lookup.ts @@ -13,7 +13,8 @@ export class DmpLookup extends Lookup implements DmpFilter { versionStatuses: DmpVersionStatus[]; statuses: DmpStatus[]; accessTypes: DmpAccessType[]; - versions: Number[] + versions: Number[]; + constructor() { super(); diff --git a/dmp-frontend/src/app/core/services/dmp/dmp.service.ts b/dmp-frontend/src/app/core/services/dmp/dmp.service.ts index 4d215065b..95543b769 100644 --- a/dmp-frontend/src/app/core/services/dmp/dmp.service.ts +++ b/dmp-frontend/src/app/core/services/dmp/dmp.service.ts @@ -1,5 +1,6 @@ import { HttpClient, HttpHeaders, HttpResponse } from '@angular/common/http'; import { Injectable } from '@angular/core'; +import { DmpUserRole } from '@app/core/common/enum/dmp-user-role'; import { IsActive } from '@app/core/common/enum/is-active.enum'; import { UserInfoListingModel } from '@app/core/model/user/user-info-listing'; import { VersionListingModel } from '@app/core/model/version/version-listing.model'; @@ -27,16 +28,24 @@ import { DatasetProfileCriteria } from '../../query/dataset-profile/dataset-prof import { DmpCriteria } from '../../query/dmp/dmp-criteria'; import { ExploreDmpCriteriaModel } from '../../query/explore-dmp/explore-dmp-criteria'; import { RequestItem } from '../../query/request-item'; +import { AuthService } from '../auth/auth.service'; import { ConfigurationService } from '../configuration/configuration.service'; import { BaseHttpV2Service } from '../http/base-http-v2.service'; import { BaseHttpService } from '../http/base-http.service'; +import { DmpStatus } from '@app/core/common/enum/dmp-status'; @Injectable() export class DmpServiceNew { private headers = new HttpHeaders(); - constructor(private http: BaseHttpV2Service, private httpClient: HttpClient, private configurationService: ConfigurationService, private filterService: FilterService) { + constructor( + private http: BaseHttpV2Service, + private httpClient: HttpClient, + private configurationService: ConfigurationService, + private filterService: FilterService, + private authService: AuthService + ) { } private get apiBase(): string { return `${this.configurationService.server}dmp`; } @@ -142,12 +151,13 @@ export class DmpServiceNew { valueAssign: (item: Dmp) => item.id, }; - private buildAutocompleteLookup(like?: string, excludedIds?: Guid[], ids?: Guid[]): DmpLookup { + public buildAutocompleteLookup(like?: string, excludedIds?: Guid[], ids?: Guid[], statuses?: DmpStatus[]): DmpLookup { const lookup: DmpLookup = new DmpLookup(); lookup.page = { size: 100, offset: 0 }; if (excludedIds && excludedIds.length > 0) { lookup.excludedIds = excludedIds; } if (ids && ids.length > 0) { lookup.ids = ids; } lookup.isActive = [IsActive.Active]; + lookup.statuses = statuses; lookup.project = { fields: [ nameof(x => x.id), @@ -158,6 +168,25 @@ export class DmpServiceNew { if (like) { lookup.like = this.filterService.transformLike(like); } return lookup; } + + // + // + // UI Helpers + // + // + + getCurrentUserRolesInDmp(dmpUsers: DmpUser[]): DmpUserRole[] { + const principalId: Guid = this.authService.userId(); + let dmpUserRoles: DmpUserRole[] = null; + if (principalId) { + dmpUserRoles = dmpUsers.filter(element => element?.user?.id === principalId).map(x => x.role); + } + return dmpUserRoles; + } + + isDmpOwner(dmpUsers: DmpUser[]): Boolean { + return this.getCurrentUserRolesInDmp(dmpUsers).includes(DmpUserRole.Owner); + } } diff --git a/dmp-frontend/src/app/core/services/reference/reference.service.ts b/dmp-frontend/src/app/core/services/reference/reference.service.ts index 1d00d6e5d..53354fe39 100644 --- a/dmp-frontend/src/app/core/services/reference/reference.service.ts +++ b/dmp-frontend/src/app/core/services/reference/reference.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { IsActive } from '@app/core/common/enum/is-active.enum'; import { ReferenceType } from '@app/core/common/enum/reference-type'; -import { Reference, ReferencePersist } from '@app/core/model/reference/reference'; +import { DmpReference, Reference, ReferencePersist } from '@app/core/model/reference/reference'; import { ReferenceLookup } from '@app/core/query/reference.lookup'; import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration'; import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration'; @@ -15,6 +15,7 @@ import { ConfigurationService } from '../configuration/configuration.service'; import { BaseHttpV2Service } from '../http/base-http-v2.service'; import { ReferenceSourceType } from '@app/core/common/enum/reference-source-type'; import { ReferenceSearchDefinitionLookup, ReferenceSearchLookup } from '@app/core/query/reference-search.lookup'; +import { Dmp } from '@app/core/model/dmp/dmp'; @Injectable() export class ReferenceService { @@ -111,4 +112,18 @@ export class ReferenceService { if (like) { lookup.like = this.filterService.transformLike(like); } return lookup; } + + // + // + // UI Helpers + // + // + + getReferencesForTypes(dmpReferences: DmpReference[], referenceTypes: ReferenceType[]): DmpReference[] { + return dmpReferences?.filter(x => referenceTypes?.includes(x?.reference?.type)); + } + + getReferencesForTypesFirstSafe(dmpReferences: DmpReference[], referenceTypes: ReferenceType[]): DmpReference { + return this.getReferencesForTypes(dmpReferences, referenceTypes)?.find(Boolean); + } } diff --git a/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts b/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts index 83c39c266..19573da24 100644 --- a/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts +++ b/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts @@ -27,6 +27,7 @@ import { DmpBlueprintType } from '../../common/enum/dmp-blueprint-type'; import { DmpStatus } from '../../common/enum/dmp-status'; import { ValidationType } from '../../common/enum/validation-type'; import { IsActive } from '@app/core/common/enum/is-active.enum'; +import { DmpUserRole } from '@app/core/common/enum/dmp-user-role'; @Injectable() export class EnumUtils { @@ -368,4 +369,11 @@ export class EnumUtils { } } + toDmpUserRolesString(roles: DmpUserRole[]): string { return roles.map(x => this.toDmpUserRoleString(x)).join(', ') } + toDmpUserRoleString(role: DmpUserRole): string { + switch (role) { + case DmpUserRole.Owner: return this.language.instant('TYPES.DMP-USER-ROLE.OWNER'); + case DmpUserRole.User: return this.language.instant('TYPES.DMP-USER-ROLE.USER'); + } + } } diff --git a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.ts b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.ts index 0907aa039..baec1c2d3 100644 --- a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.ts +++ b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.ts @@ -426,7 +426,7 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme breadcrumbs.push({ parentComponentName: null, label: this.language.instant('NAV-BAR.PUBLIC DATASETS'), - url: '/explore' + url: '/explore-descriptions' }); breadcrumbs.push({ parentComponentName: null, @@ -612,7 +612,7 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme if (!isNullOrUndefined(this.lock)) { this.lockService.unlockTarget(this.datasetWizardModel.id).pipe(takeUntil(this._destroyed)).subscribe( complete => { - this.publicMode ? this.router.navigate(['/explore']) : this.router.navigate(['/datasets']); + this.publicMode ? this.router.navigate(['/explore-descriptions']) : this.router.navigate(['/datasets']); }, error => { this.formGroup.get('status').setValue(DmpStatus.Draft); @@ -620,7 +620,7 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme } ) } else { - this.publicMode ? this.router.navigate(['/explore']) : this.router.navigate(['/datasets']); + this.publicMode ? this.router.navigate(['/explore-descriptions']) : this.router.navigate(['/datasets']); } } diff --git a/dmp-frontend/src/app/ui/dataset/listing/dataset-listing.component.html b/dmp-frontend/src/app/ui/dataset/listing/dataset-listing.component.html index 03f10f4e4..632807de0 100644 --- a/dmp-frontend/src/app/ui/dataset/listing/dataset-listing.component.html +++ b/dmp-frontend/src/app/ui/dataset/listing/dataset-listing.component.html @@ -5,7 +5,7 @@
-

{{'DATASET-LISTING.TEXT-INFO' | translate}} {{'DATASET-LISTING.LINK-PUBLIC-DATASETS' | translate}} {{'DATASET-LISTING.TEXT-INFO-REST' | translate}}

+

{{'DATASET-LISTING.TEXT-INFO' | translate}} {{'DATASET-LISTING.LINK-PUBLIC-DATASETS' | translate}} {{'DATASET-LISTING.TEXT-INFO-REST' | translate}}

{{'DATASET-LISTING.TEXT-INFO-PAR' | translate}}

-
+
diff --git a/dmp-frontend/src/app/ui/description/dataset-wizard/dataset-copy-dialogue/dataset-copy-dialogue.component.scss b/dmp-frontend/src/app/ui/description/description-copy-dialog/description-copy-dialog.component.scss similarity index 100% rename from dmp-frontend/src/app/ui/description/dataset-wizard/dataset-copy-dialogue/dataset-copy-dialogue.component.scss rename to dmp-frontend/src/app/ui/description/description-copy-dialog/description-copy-dialog.component.scss diff --git a/dmp-frontend/src/app/ui/description/description-copy-dialog/description-copy-dialog.component.ts b/dmp-frontend/src/app/ui/description/description-copy-dialog/description-copy-dialog.component.ts new file mode 100644 index 000000000..f021937d1 --- /dev/null +++ b/dmp-frontend/src/app/ui/description/description-copy-dialog/description-copy-dialog.component.ts @@ -0,0 +1,61 @@ + +import { map, filter } from 'rxjs/operators'; +import { Component } from "@angular/core"; +import { MatDialogRef, MAT_DIALOG_DATA } from "@angular/material/dialog"; +import { Observable } from "rxjs"; +import { Inject } from "@angular/core"; +import { TranslateService } from "@ngx-translate/core"; +import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration'; +import { Dmp } from '@app/core/model/dmp/dmp'; +import { DmpServiceNew } from '@app/core/services/dmp/dmp.service'; +import { DescriptionService } from '@app/core/services/description/description.service'; + +@Component({ + selector: 'description-copy-dialog-component', + templateUrl: 'description-copy-dialog.component.html', + styleUrls: ['./description-copy-dialog.component.scss'], +}) +export class DescriptionCopyDialogComponent { + + dmpModel: Dmp; + descriptionDescriptionTemplateLabel: String; + dmpAutoCompleteConfiguration: SingleAutoCompleteConfiguration = { //TODO: add filter to only get DMPs that have connection with the same Description Template group. + initialItems: (data?: any) => this.dmpService.query(this.dmpService.buildAutocompleteLookup()).pipe(map(x => x.items)), + filterFn: (searchQuery: string, data?: any) => this.dmpService.query(this.dmpService.buildAutocompleteLookup(searchQuery)).pipe(map(x => x.items)), + getSelectedItem: (selectedItem: any) => this.dmpService.query(this.dmpService.buildAutocompleteLookup(null, null, [selectedItem])).pipe(map(x => x.items[0])), + displayFn: (item: Dmp) => item.label, + titleFn: (item: Dmp) => item.label, + valueAssign: (item: Dmp) => item.id, + }; + + + constructor( + public dialogRef: MatDialogRef, + public dmpService: DmpServiceNew, + public descriptionService: DescriptionService, + public language: TranslateService, + @Inject(MAT_DIALOG_DATA) public data: any + ) { } + + ngOnInit() { + + } + + cancel() { + this.dialogRef.close(this.data); + } + + confirm() { + // TODO: create a backend service to copy the description + const newDmpId = this.data.formControl.value; + this.dialogRef.close(newDmpId); + } + + getErrorMessage() { + return this.language.instant('DESCRIPTION-COPY-DIALOG.ERROR-MESSAGE'); + } + + close() { + this.dialogRef.close(false); + } +} diff --git a/dmp-frontend/src/app/ui/description/description-copy-dialog/description-copy-dialog.module.ts b/dmp-frontend/src/app/ui/description/description-copy-dialog/description-copy-dialog.module.ts new file mode 100644 index 000000000..776628c63 --- /dev/null +++ b/dmp-frontend/src/app/ui/description/description-copy-dialog/description-copy-dialog.module.ts @@ -0,0 +1,18 @@ +import { NgModule } from '@angular/core'; +import { CommonUiModule } from '@common/ui/common-ui.module'; + +import { AutoCompleteModule } from '@app/library/auto-complete/auto-complete.module'; +import { CommonFormsModule } from '@common/forms/common-forms.module'; +import { DescriptionCopyDialogComponent } from './description-copy-dialog.component'; + +@NgModule({ + imports: [ + CommonUiModule, + CommonFormsModule, + AutoCompleteModule + ], + declarations: [ + DescriptionCopyDialogComponent + ] +}) +export class DescriptionCopyDialogModule { } diff --git a/dmp-frontend/src/app/ui/description/description.module.ts b/dmp-frontend/src/app/ui/description/description.module.ts index e2dba3e3e..de71c24eb 100644 --- a/dmp-frontend/src/app/ui/description/description.module.ts +++ b/dmp-frontend/src/app/ui/description/description.module.ts @@ -25,6 +25,8 @@ import { FormValidationErrorsDialogModule } from '@common/forms/form-validation- import { ConfirmationDialogModule } from '@common/modules/confirmation-dialog/confirmation-dialog.module'; import { CommonUiModule } from '@common/ui/common-ui.module'; import { AngularStickyThingsModule } from '@w11k/angular-sticky-things'; +import { DescriptionCopyDialogModule } from './description-copy-dialog/description-copy-dialog.module'; +import { DescriptionOverviewModule } from './overview/description-overview.module'; // import { FormProgressIndicationModule } from '../misc/description-description-form/components/form-progress-indication/form-progress-indication.module'; // import { DescriptionCopyDialogModule } from './description-wizard/description-copy-dialogue/description-copy-dialogue.module'; // import { DescriptionCriteriaDialogComponent } from './listing/criteria/description-criteria-dialogue/description-criteria-dialog.component'; @@ -48,7 +50,10 @@ import { AngularStickyThingsModule } from '@w11k/angular-sticky-things'; // DescriptionCopyDialogModule, // DescriptionOverviewModule, // FormProgressIndicationModule, - RichTextEditorModule + RichTextEditorModule, + + DescriptionCopyDialogModule, + DescriptionOverviewModule ], declarations: [ DescriptionListingComponent, diff --git a/dmp-frontend/src/app/ui/description/description.routing.ts b/dmp-frontend/src/app/ui/description/description.routing.ts index 9d2b4ecdb..11f55612f 100644 --- a/dmp-frontend/src/app/ui/description/description.routing.ts +++ b/dmp-frontend/src/app/ui/description/description.routing.ts @@ -1,9 +1,9 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; -import { CanDeactivateGuard } from '@app/library/deactivate/can-deactivate.guard'; import { AuthGuard } from '../../core/auth-guard.service'; // import { DescriptionWizardComponent } from './description-wizard/description-wizard.component'; import { DescriptionListingComponent } from './listing/description-listing.component'; +import { DescriptionOverviewComponent } from './overview/description-overview.component'; // import { DescriptionOverviewComponent } from './overview/description-overview.component'; const routes: Routes = [ @@ -23,6 +23,22 @@ const routes: Routes = [ breadcrumb: true }, }, + { + path: 'overview/:id', + component: DescriptionOverviewComponent, + data: { + breadcrumb: true, + title: 'GENERAL.TITLES.DATASET-OVERVIEW' + }, + }, + { + path: 'publicOverview/:publicId', + component: DescriptionOverviewComponent, + data: { + breadcrumb: true, + title: 'GENERAL.TITLES.DATASET-OVERVIEW' + }, + } // { // path: 'new/:dmpId/:dmpSectionIndex', // component: DescriptionWizardComponent, @@ -76,14 +92,6 @@ const routes: Routes = [ // }, // canDeactivate:[CanDeactivateGuard] // }, - { - path: 'dmp/:dmpId', - component: DescriptionListingComponent, - canActivate: [AuthGuard], - data: { - breadcrumb: true - }, - }, // { // path: 'copy/:id', // component: DescriptionWizardComponent, @@ -104,22 +112,7 @@ const routes: Routes = [ // }, // canDeactivate:[CanDeactivateGuard] // }, - // { - // path: 'overview/:id', - // component: DescriptionOverviewComponent, - // data: { - // breadcrumb: true, - // title: 'GENERAL.TITLES.DATASET-OVERVIEW' - // }, - // }, - // { - // path: 'publicOverview/:publicId', - // component: DescriptionOverviewComponent, - // data: { - // breadcrumb: true, - // title: 'GENERAL.TITLES.DATASET-OVERVIEW' - // }, - // } + ]; @NgModule({ diff --git a/dmp-frontend/src/app/ui/description/listing/description-listing.component.html b/dmp-frontend/src/app/ui/description/listing/description-listing.component.html index 6c094d9bc..d618fa4a5 100644 --- a/dmp-frontend/src/app/ui/description/listing/description-listing.component.html +++ b/dmp-frontend/src/app/ui/description/listing/description-listing.component.html @@ -5,21 +5,21 @@
-

{{'DATASET-LISTING.TEXT-INFO' | translate}} {{'DATASET-LISTING.LINK-PUBLIC-DATASETS' | translate}} {{'DATASET-LISTING.TEXT-INFO-REST' | translate}}

-

{{'DATASET-LISTING.TEXT-INFO-PAR' | translate}} +

{{'DESCRIPTION-LISTING.TEXT-INFO' | translate}} {{'DESCRIPTION-LISTING.LINK-PUBLIC-DATASETS' | translate}} {{'DESCRIPTION-LISTING.TEXT-INFO-REST' | translate}}

+

{{'DESCRIPTION-LISTING.TEXT-INFO-PAR' | translate}}

-

{{(isPublic ? 'GENERAL.TITLES.EXPLORE' : 'GENERAL.TITLES.DESCRIPTIONS') | translate}}

+

{{(isPublic ? 'DESCRIPTION-LISTING.TITLE-EXPLORE' : 'DESCRIPTION-LISTING.TITLE') | translate}}

@@ -48,7 +48,7 @@
- {{ 'GENERAL.ACTIONS.TAKE-A-TOUR'| translate }} + {{ 'DESCRIPTION-LISTING.ACTIONS.TAKE-A-TOUR'| translate }}
@@ -66,11 +66,11 @@
- +
- {{'DATASET-LISTING.EMPTY-LIST' | translate}} + {{'DESCRIPTION-LISTING.EMPTY-LIST' | translate}}
diff --git a/dmp-frontend/src/app/ui/description/listing/description-listing.component.ts b/dmp-frontend/src/app/ui/description/listing/description-listing.component.ts index 02f861856..9bb492566 100644 --- a/dmp-frontend/src/app/ui/description/listing/description-listing.component.ts +++ b/dmp-frontend/src/app/ui/description/listing/description-listing.component.ts @@ -7,11 +7,13 @@ 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 { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order'; import { DataTableRequest } from '@app/core/model/data-table/data-table-request'; +import { DescriptionTemplate } from '@app/core/model/description-template/description-template'; import { Description, DescriptionReference } from '@app/core/model/description/description'; import { Dmp, DmpUser } from '@app/core/model/dmp/dmp'; -import { Reference } from '@app/core/model/reference/reference'; +import { DmpReference, 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'; @@ -88,7 +90,7 @@ export class DescriptionListingComponent extends BaseComponent implements OnInit ngOnInit() { this.matomoService.trackPageView('Descriptions'); - this.isPublic = this.router.url === '/explore'; + this.isPublic = this.router.url === '/explore-descriptions'; if (this.isPublic) { this.formGroup.get('order').setValue(this.order.DATASETPUBLISHED); } else { @@ -106,12 +108,13 @@ export class DescriptionListingComponent extends BaseComponent implements OnInit 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)]; - this.refresh(this.lookup); if (params['dmpLabel'] !== undefined) { this.titlePrefix = 'for ' + params['dmpLabel']; } @@ -170,33 +173,39 @@ export class DescriptionListingComponent extends BaseComponent implements OnInit this.refresh(this.lookup); } - refresh(lookup: DescriptionLookup) { + loadMore() { + this.lookup.page = { size: this.pageSize, offset: this.lookup.page.offset + this.pageSize }; + 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.descriptionTemplate), nameof(x => x.id)].join('.'), + [nameof(x => x.descriptionTemplate), nameof(x => x.label)].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.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.user.roles)].join('.'), - [nameof(x => x.descriptionReferences), nameof(x => x.id)].join('.'), - [nameof(x => x.descriptionReferences), nameof(x => x.reference), nameof(x => x.id)].join('.'), - [nameof(x => x.descriptionReferences), nameof(x => x.reference), nameof(x => x.label)].join('.'), - [nameof(x => x.descriptionReferences), nameof(x => x.reference), nameof(x => x.type)].join('.'), - [nameof(x => x.descriptionReferences), nameof(x => x.reference), nameof(x => x.reference)].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)].join('.'), + [nameof(x => x.dmp), nameof(x => x.dmpReferences), nameof(x => x.reference), nameof(x => x.reference)].join('.'), ] }; this.descriptionService.query(lookup).pipe(takeUntil(this._destroyed)) .subscribe(result => { if (!result) { return []; } - // if (this._paginator.pageIndex === 0) { this.totalCount = result.totalCount; } this.totalCount = result.count; if (lookup?.page?.offset === 0) this.listingItems = []; - this.listingItems = result.items; + this.listingItems.push(...result.items); this.hasListingItems = true; }); } @@ -278,18 +287,18 @@ export class DescriptionListingComponent extends BaseComponent implements OnInit } 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.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('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.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; } diff --git a/dmp-frontend/src/app/ui/description/listing/listing-item/description-listing-item.component.html b/dmp-frontend/src/app/ui/description/listing/listing-item/description-listing-item.component.html index b8e8d4f46..7522be842 100644 --- a/dmp-frontend/src/app/ui/description/listing/listing-item/description-listing-item.component.html +++ b/dmp-frontend/src/app/ui/description/listing/listing-item/description-listing-item.component.html @@ -1,40 +1,40 @@
-
{{'DATASET-LISTING.DESCRIPTION' | translate}}
-
{{'DATASET-LISTING.STATES.EDITED' | translate}}: {{description.updatedAt | dateTimeCultureFormatter: "d MMMM y"}}
-
{{'DATASET-LISTING.STATES.PUBLISHED' | translate}}: {{description.dmpPublishedAt | dateTimeCultureFormatter: "d MMMM y"}}
+
{{'DESCRIPTION-LISTING.DESCRIPTION' | translate}}
+
{{'DESCRIPTION-LISTING.STATES.EDITED' | translate}}: {{description.updatedAt | dateTimeCultureFormatter: "d MMMM y"}}
+
{{'DESCRIPTION-LISTING.STATES.PUBLISHED' | translate}}: {{description.dmpPublishedAt | dateTimeCultureFormatter: "d MMMM y"}}
{{description.label}}
{{description.label}}
- {{ roleDisplay(description.users) }} + {{ enumUtils.toDmpUserRolesString(dmpService.getCurrentUserRolesInDmp(description?.dmp?.dmpUsers)) }} . - public{{'DATASET-LISTING.STATES.PUBLIC' | translate}} + public{{'DESCRIPTION-LISTING.STATES.PUBLIC' | translate}} done{{ enumUtils.toDescriptionStatusString(description.status) }} create{{ enumUtils.toDescriptionStatusString(description.status) }} . - + {{'DESCRIPTION-LISTING.GRANT' | translate}}: {{referenceService.getReferencesForTypesFirstSafe(description?.dmp?.dmpReferences, [referenceTypeEnum.Grants])?.reference?.label}}
-
{{'DATASET-LISTING.TOOLTIP.PART-OF' | translate}} -
{{'DATASET-LISTING.TOOLTIP.DMP' | translate}}
+
{{'DESCRIPTION-LISTING.PART-OF' | translate}} +
{{'DESCRIPTION-LISTING.DMP' | translate}}
{{description.dmp?.label}}
- diff --git a/dmp-frontend/src/app/ui/description/listing/listing-item/description-listing-item.component.ts b/dmp-frontend/src/app/ui/description/listing/listing-item/description-listing-item.component.ts index 5d80d74ef..5757b8c7b 100644 --- a/dmp-frontend/src/app/ui/description/listing/listing-item/description-listing-item.component.ts +++ b/dmp-frontend/src/app/ui/description/listing/listing-item/description-listing-item.component.ts @@ -23,6 +23,11 @@ import { DescriptionService } from '@app/core/services/description/description.s import { IsActive } from '@app/core/common/enum/is-active.enum'; import { Guid } from '@common/types/guid'; import { DmpAccessType } from '@app/core/common/enum/dmp-access-type'; +import { DmpUser } from '@app/core/model/dmp/dmp'; +import { DmpService, DmpServiceNew } from '@app/core/services/dmp/dmp.service'; +import { ReferenceService } from '@app/core/services/reference/reference.service'; +import { ReferenceType } from '@app/core/common/enum/reference-type'; +import { DescriptionCopyDialogComponent } from '../../description-copy-dialog/description-copy-dialog.component'; @Component({ selector: 'app-description-listing-item-component', @@ -41,6 +46,7 @@ export class DescriptionListingItemComponent extends BaseComponent implements On isUserOwner: boolean; descriptionStatusEnum = DescriptionStatus; dmpAccessTypeEnum = DmpAccessType; + referenceTypeEnum = ReferenceType; constructor( private router: Router, @@ -54,7 +60,9 @@ export class DescriptionListingItemComponent extends BaseComponent implements On private location: Location, private httpClient: HttpClient, private matomoService: MatomoService, - private fileUtils: FileUtils + private fileUtils: FileUtils, + public dmpService: DmpServiceNew, + public referenceService: ReferenceService ) { super(); } @@ -149,29 +157,27 @@ export class DescriptionListingItemComponent extends BaseComponent implements On }); } - openDmpSearchDialogue(description: Description) { - // TODO: add this. - // const formControl = new UntypedFormControl(); - // const dialogRef = this.dialog.open(DescriptionCopyDialogueComponent, { - // width: '500px', - // restoreFocus: false, - // data: { - // formControl: formControl, - // descriptionId: description.id, - // descriptionProfileId: description.profile.id, - // descriptionProfileExist: false, - // confirmButton: this.language.instant('DATASET-WIZARD.DIALOGUE.COPY'), - // cancelButton: this.language.instant('DATASET-WIZARD.DIALOGUE.CANCEL') - // } - // }); + copyToDmp(description: Description) { + const formControl = new UntypedFormControl(); + const dialogRef = this.dialog.open(DescriptionCopyDialogComponent, { + width: '500px', + restoreFocus: false, + data: { + formControl: formControl, + descriptionId: description.id, + descriptionProfileId: description.descriptionTemplate.id, + descriptionProfileExist: false, + confirmButton: this.language.instant('DESCRIPTION-LISTING.COPY-DIALOG.COPY'), + cancelButton: this.language.instant('DESCRIPTION-LISTING.COPY-DIALOG.CANCEL') + } + }); - // dialogRef.afterClosed().pipe(takeUntil(this._destroyed)) - // .subscribe(result => { - // if (result && result.descriptionProfileExist) { - // const newDmpId = result.formControl.value.id; - // this.router.navigate(['/descriptions/copy/' + result.descriptionId], { queryParams: { newDmpId: newDmpId } }); - // } - // }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)) + .subscribe(newDmpId => { + if (newDmpId) { + this.router.navigate(['/descriptions/copy/' + description.id], { queryParams: { newDmpId: newDmpId } }); + } + }); } deleteClicked(id: Guid) { @@ -213,7 +219,7 @@ export class DescriptionListingItemComponent extends BaseComponent implements On maxWidth: '400px', restoreFocus: false, data: { - message: this.language.instant('DATASET-WIZARD.ACTIONS.LOCK') + message: this.language.instant('DESCRIPTION-LISTING.LOCKED') } }); } @@ -234,38 +240,10 @@ export class DescriptionListingItemComponent extends BaseComponent implements On this.uiNotificationService.snackBarNotification(error.error.message ? error.error.message : this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DELETE'), SnackBarNotificationLevel.Error); } - roleDisplay(value: any) { - const principalId: string = this.authService.userId()?.toString(); - let role: number; - if (principalId) { - value.forEach(element => { - if (principalId === element.id) { - role = element.role; - } - }); - } - if (role === 0) { - return this.language.instant('DMP-LISTING.OWNER'); - } - else if (role === 1) { - return this.language.instant('DMP-LISTING.MEMBER'); - } - else { - return this.language.instant('DMP-LISTING.OWNER'); - } - } + - isUserDescriptionRelated() { - //TODO: add user to description objects - const principalId: string = this.authService.userId()?.toString(); - let isRelated: boolean = false; - // if (this.description && principalId) { - // this.description.users.forEach(element => { - // if (element.id === principalId) { - // isRelated = true; - // } - // }) - // } - return isRelated; + isUserDescriptionRelated(): boolean { + const principalId: Guid = this.authService.userId(); + return this.description.dmp.dmpUsers.some(x => (x.user.id === principalId)); } } diff --git a/dmp-frontend/src/app/ui/description/overview/dataset-overview.component.html b/dmp-frontend/src/app/ui/description/overview/dataset-overview.component.html deleted file mode 100644 index 92c068c65..000000000 --- a/dmp-frontend/src/app/ui/description/overview/dataset-overview.component.html +++ /dev/null @@ -1,186 +0,0 @@ -
-
-
- - chevron_left -

{{'DMP-WIZARD.ACTIONS.BACK' | translate}}

-
-
-
-
- -

{{ dataset.label }}

-
-
-
-

- {{ roleDisplayFromList(dataset.users) }} -

-
- . - - -
- public - {{'DMP-OVERVIEW.PUBLIC' | translate}} -
- . - - -
- lock_outline - {{'DMP-OVERVIEW.LOCKED' | translate}} -
- . -
{{'GENERAL.STATUSES.EDIT' | translate}} : - - {{dataset.modified | dateTimeCultureFormatter: "d MMMM y"}} -
-
-
- check - {{'TYPES.DATASET-STATUS.FINALISED' | translate}} -
-
-
-
- - - -
-
{{'DATASET-LISTING.TOOLTIP.PART-OF' | translate}}
-
- -
- -
-
{{'DMP-OVERVIEW.GRANT' | translate}}
-
{{ dataset.grant.label }}
-
- -
{{'DMP-OVERVIEW.RESEARCHERS' | translate}}
-
-
- - -
 
-
{{ researcher.name }},
-
{{ researcher.name }}
-
-
- -
{{ researcher.name }},
-
{{ researcher.name }}
-
-
- horizontal_rule -
- -
{{'DATASET-LISTING.COLUMNS.DESCRIPTION' | translate}}
-
-

-
-
- horizontal_rule -
-
-
-
-
-
- -

{{ 'DMP-LISTING.ACTIONS.FINALIZE' | translate }}

-
-
-
-
-
-
- -

{{ 'DATASET-WIZARD.ACTIONS.REVERSE' | translate }}

-
-
- -

- {{ 'DMP-LISTING.ACTIONS.EXPORT' | translate }}

-
- - - - - - - - -
-
-
-

{{ 'DATASET-OVERVIEW.DESCRIPTION-AUTHORS' | translate }}

-
-
-
-
- -
-

{{ user.name }} - - ({{ 'DMP-OVERVIEW.YOU' | translate }}) -

-

{{ roleDisplay(user) }}

-
-
- -
-
-
- -
-
-
-
-
-
-
diff --git a/dmp-frontend/src/app/ui/description/overview/dataset-overview.component.ts b/dmp-frontend/src/app/ui/description/overview/dataset-overview.component.ts deleted file mode 100644 index 9c372d3ab..000000000 --- a/dmp-frontend/src/app/ui/description/overview/dataset-overview.component.ts +++ /dev/null @@ -1,549 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { DatasetOverviewModel } from '@app/core/model/dataset/dataset-overview'; -import { BaseComponent } from '@common/base/base.component'; -// import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item'; -import { Location } from '@angular/common'; -import { HttpClient } from '@angular/common/http'; -import { UntypedFormControl } from '@angular/forms'; -import { MatDialog } from '@angular/material/dialog'; -import { ActivatedRoute, Params, Router } from '@angular/router'; -import { DatasetStatus } from '@app/core/common/enum/dataset-status'; -import { DmpStatus } from '@app/core/common/enum/dmp-status'; -import { Role } from '@app/core/common/enum/role'; -import { DatasetWizardModel } from '@app/core/model/dataset/dataset-wizard'; -import { DmpOverviewModel } from '@app/core/model/dmp/dmp-overview'; -import { ResearcherModel } from '@app/core/model/researcher/researcher'; -import { UserInfoListingModel } from '@app/core/model/user/user-info-listing'; -import { AuthService } from '@app/core/services/auth/auth.service'; -import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; -import { DatasetWizardService } from '@app/core/services/dataset-wizard/dataset-wizard.service'; -import { DatasetService } from '@app/core/services/dataset/dataset.service'; -import { DmpService } from '@app/core/services/dmp/dmp.service'; -import { LockService } from '@app/core/services/lock/lock.service'; -import { MatomoService } from '@app/core/services/matomo/matomo-service'; -import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; -import { UserServiceOld } from '@app/core/services/user/user.service-old'; -import { FileUtils } from '@app/core/services/utilities/file-utils.service'; -import { PopupNotificationDialogComponent } from '@app/library/notification/popup/popup-notification.component'; -import { DmpInvitationDialogComponent } from '@app/ui/dmp/invitation/dmp-invitation-dialog.component'; -import { Oauth2DialogService } from '@app/ui/misc/oauth2-dialog/service/oauth2-dialog.service'; -import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; -import { TranslateService } from '@ngx-translate/core'; -import * as FileSaver from 'file-saver'; -import { filter, takeUntil } from 'rxjs/operators'; -import { DatasetCopyDialogueComponent } from '../dataset-wizard/dataset-copy-dialogue/dataset-copy-dialogue.component'; - - -@Component({ - selector: 'app-dataset-overview', - templateUrl: './dataset-overview.component.html', - styleUrls: ['./dataset-overview.component.scss'] -}) -export class DatasetOverviewComponent extends BaseComponent implements OnInit { - - dataset: DatasetOverviewModel; - // datasetWizardEditorModel: DatasetWizardEditorModel; - datasetWizardModel: DatasetWizardModel; - isNew = true; - isFinalized = false; - isPublicView = true; - hasPublishButton: boolean = true; - // breadCrumbs: Observable = observableOf(); - isUserOwner: boolean; - expand = false; - researchers: ResearcherModel[]; - users: UserInfoListingModel[]; - lockStatus: Boolean; - - constructor( - private route: ActivatedRoute, - private router: Router, - private datasetService: DatasetService, - private translate: TranslateService, - private authentication: AuthService, - private dialog: MatDialog, - private language: TranslateService, - private uiNotificationService: UiNotificationService, - private configurationService: ConfigurationService, - private oauth2DialogService: Oauth2DialogService, - private userService: UserServiceOld, - private dmpService: DmpService, - private location: Location, - private datasetWizardService: DatasetWizardService, - private lockService: LockService, - private httpClient: HttpClient, - private matomoService: MatomoService, - private fileUtils: FileUtils - ) { - super(); - } - - ngOnInit() { - this.matomoService.trackPageView('Dataset Overview'); - // Gets dataset data using parameter id - this.route.params - .pipe(takeUntil(this._destroyed)) - .subscribe((params: Params) => { - const itemId = params['id']; - const publicId = params['publicId']; - if (itemId != null) { - this.isNew = false; - this.isPublicView = false; - this.datasetService.getOverviewSingle(itemId) - .pipe(takeUntil(this._destroyed)) - .subscribe(data => { - this.dataset = data; - this.researchers = this.dataset.dmp.researchers; - this.users = this.dataset.dmp.users; - this.checkLockStatus(this.dataset.id); - this.setIsUserOwner(); - // const breadCrumbs = []; - // breadCrumbs.push({ parentComponentName: null, label: this.language.instant('NAV-BAR.MY-DATASET-DESCRIPTIONS'), url: "/datasets" }); - // breadCrumbs.push({ parentComponentName: 'DatasetListingComponent', label: this.dataset.label, url: '/datasets/overview/' + this.dataset.id }); - // this.breadCrumbs = observableOf(breadCrumbs); - }, (error: any) => { - if (error.status === 404) { - return this.onFetchingDeletedCallbackError('/datasets/'); - } - if (error.status === 403) { - return this.onFetchingForbiddenCallbackError('/datasets/'); - } - }); - } - else if (publicId != null) { - this.isNew = false; - this.isFinalized = true; - this.isPublicView = true; - this.datasetService.getOverviewSinglePublic(publicId) - .pipe(takeUntil(this._destroyed)) - .subscribe(data => { - this.dataset = data; - this.researchers = this.dataset.dmp.researchers; - this.users = this.dataset.dmp.users; - // const breadCrumbs = []; - // breadCrumbs.push({ parentComponentName: null, label: this.language.instant('NAV-BAR.PUBLIC DATASETS'), url: "/explore" }); - // breadCrumbs.push({ parentComponentName: 'DatasetListingComponent', label: this.dataset.label, url: '/datasets/publicOverview/' + this.dataset.id }); - // this.breadCrumbs = observableOf(breadCrumbs); - }, (error: any) => { - if (error.status === 404) { - return this.onFetchingDeletedCallbackError('/explore'); - } - if (error.status === 403) { - return this.onFetchingForbiddenCallbackError('/explore'); - } - }); - } - }); - } - - checkLockStatus(id: string) { - this.lockService.checkLockStatus(id).pipe(takeUntil(this._destroyed)) - .subscribe(lockStatus => { - this.lockStatus = lockStatus - if (lockStatus) { - this.dialog.open(PopupNotificationDialogComponent, { - data: { - title: this.language.instant('DATASET-OVERVIEW.LOCKED.TITLE'), - message: this.language.instant('DATASET-OVERVIEW.LOCKED.MESSAGE') - }, maxWidth: '30em' - }); - } - }); - } - - onFetchingDeletedCallbackError(redirectRoot: string) { - this.uiNotificationService.snackBarNotification(this.language.instant('DATASET-OVERVIEW.ERROR.DELETED-DATASET'), SnackBarNotificationLevel.Error); - this.router.navigate([redirectRoot]); - } - - onFetchingForbiddenCallbackError(redirectRoot: string) { - this.uiNotificationService.snackBarNotification(this.language.instant('DATASET-OVERVIEW.ERROR.FORBIDEN-DATASET'), SnackBarNotificationLevel.Error); - this.router.navigate([redirectRoot]); - } - - goBack(): void { - this.location.back(); - } - - reloadPage(): void { - const path = this.location.path(); - this.router.navigateByUrl('/reload', { skipLocationChange: true }).then(() => this.router.navigate([path])); - } - - setIsUserOwner() { - if (this.dataset) { - const principalId: string = this.authentication.userId()?.toString(); - if (principalId) this.isUserOwner = !!this.dataset.users.find(x => (x.role === Role.Owner) && (principalId === x.id)); - } - } - - isUserAuthor(userId: string): boolean { - if (this.isAuthenticated()) { - const principalId: string = this.authentication.userId()?.toString(); - return userId === principalId; - } else return false; - } - - isUserDatasetRelated() { - const principalId: string = this.authentication.userId()?.toString(); - let isRelated: boolean = false; - if (this.dataset && principalId) { - this.dataset.users.forEach(element => { - if (element.id === principalId) { - isRelated = true; - } - }) - } - return isRelated; - } - - roleDisplay(value: UserInfoListingModel) { - if (value.role === Role.Owner) { - return this.translate.instant('DMP-LISTING.OWNER'); - } else if (value.role === Role.Member) { - return this.translate.instant('DMP-LISTING.MEMBER'); - } else { - return this.translate.instant('DMP-LISTING.OWNER'); - } - } - - - roleDisplayFromList(value: UserInfoListingModel[]) { - const principalId: string = this.authentication.userId()?.toString(); - let role: number; - if (principalId) { - value.forEach(element => { - if (principalId === element.id) { - role = element.role; - } - }); - } - if (role === Role.Owner) { - return this.translate.instant('DMP-LISTING.OWNER'); - } else if (role === Role.Member) { - return this.translate.instant('DMP-LISTING.MEMBER'); - } else { - return this.translate.instant('DMP-LISTING.OWNER'); - } - } - - openShareDialog(rowId: any, rowName: any) { - const dialogRef = this.dialog.open(DmpInvitationDialogComponent, { - autoFocus: false, - restoreFocus: false, - data: { - dmpId: rowId, - dmpName: rowName - } - }); - } - - public isAuthenticated(): boolean { - return this.authentication.currentAccountIsAuthenticated(); - } - - isDraftDataset(dataset: DatasetOverviewModel) { - return dataset.status == DatasetStatus.Draft; - } - - isFinalizedDataset(dataset: DatasetOverviewModel) { - return dataset.status == DatasetStatus.Finalized; - } - - editClicked(dataset: DatasetOverviewModel) { - if (dataset.public) { - this.router.navigate(['/datasets/publicEdit/', dataset.id]); - // let url = this.router.createUrlTree(['/datasets/publicEdit/', dataset.id]); - // window.open(url.toString(), '_blank'); - } else { - this.router.navigate(['/datasets/edit/', dataset.id]); - // let url = this.router.createUrlTree(['/datasets/edit/', dataset.id]); - // let url = this.router.createUrlTree(['/plans/edit/', dataset.dmp.id], { queryParams: { dataset: dataset.id } }); - // window.open(url.toString(), '_blank'); - } - } - - deleteClicked() { - const dialogRef = this.dialog.open(ConfirmationDialogComponent, { - maxWidth: '300px', - data: { - message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'), - confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.DELETE'), - cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'), - isDeleteConfirmation: true - } - }); - dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { - if (result) { - this.datasetService.delete(this.dataset.id) - .pipe(takeUntil(this._destroyed)) - .subscribe( - complete => { - this.onDeleteCallbackSuccess(); - }, - error => this.onDeleteCallbackError(error) - ); - } - }); - } - - dmpClicked(dmp: DmpOverviewModel) { - if (this.isPublicView) { - this.router.navigate(['/explore-plans/publicOverview/' + dmp.id]); - } else { - this.router.navigate(['/plans/overview/' + dmp.id]); - } - } - - onDeleteCallbackSuccess(): void { - this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-DELETE'), SnackBarNotificationLevel.Success); - this.router.navigate(['/datasets']); - } - - onDeleteCallbackError(error) { - this.uiNotificationService.snackBarNotification(error.error.message ? error.error.message : this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DELETE'), SnackBarNotificationLevel.Error); - } - - onUpdateCallbackSuccess(): void { - this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success); - this.reloadPage(); - } - - onUpdateCallbackError(error) { - this.uiNotificationService.snackBarNotification(error.error.message ? this.tryTranslate(error.error.message) : this.language.instant('DATASET-UPLOAD.SNACK-BAR.UNSUCCESSFUL'), SnackBarNotificationLevel.Error); - } - tryTranslate(errorMessage: string): string { - return errorMessage.replace('Field value of', this.language.instant('Field value of')) - .replace('must be filled', this.language.instant('must be filled')); - } - - public getOrcidPath(): string { - return this.configurationService.orcidPath; - } - - isOrcid(reference: string) { - const head = reference.split(':')[0]; - return head === 'orcid'; - } - - getOrcidPathForResearcher(reference: string): string { - const path = this.getOrcidPath(); - const userId = reference.split(':')[1]; - return path + userId; - } - - downloadPDF(id: string) { - this.datasetService.downloadPDF(id) - .pipe(takeUntil(this._destroyed)) - .subscribe(response => { - const blob = new Blob([response.body], { type: 'application/pdf' }); - const filename = this.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); - - FileSaver.saveAs(blob, filename); - this.matomoService.trackDownload('datasets', "pdf", id); - }); - } - - downloadDocx(id: string) { - this.datasetService.downloadDocx(id) - .pipe(takeUntil(this._destroyed)) - .subscribe(response => { - const blob = new Blob([response.body], { type: 'application/msword' }); - const filename = this.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); - - FileSaver.saveAs(blob, filename); - this.matomoService.trackDownload('datasets', "docx", id); - }); - } - - downloadXml(id: string) { - this.datasetService.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); - this.matomoService.trackDownload('datasets', "xml", id); - }); - } - - //GK: NO - // downloadJson(id: string) { - // this.datasetService.downloadJson(id) - // .pipe(takeUntil(this._destroyed)) - // .subscribe(response => { - // const blob = new Blob([response.body], { type: 'application/json' }); - // const filename = this.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); - // FileSaver.saveAs(blob, filename); - // }) - // } - - openDmpSearchDialogue() { - const formControl = new UntypedFormControl(); - const dialogRef = this.dialog.open(DatasetCopyDialogueComponent, { - width: '500px', - restoreFocus: false, - data: { - formControl: formControl, - datasetId: this.dataset.id, - datasetProfileId: this.dataset.datasetTemplate.id, - datasetProfileExist: false, - confirmButton: this.language.instant('DATASET-WIZARD.DIALOGUE.COPY'), - cancelButton: this.language.instant('DATASET-WIZARD.DIALOGUE.CANCEL') - } - }); - - dialogRef.afterClosed().pipe(takeUntil(this._destroyed)) - .subscribe(result => { - if (result && result.datasetProfileExist) { - const newDmpId = result.formControl.value.id; - this.router.navigate(['/datasets/copy/' + result.datasetId], { queryParams: { newDmpId: newDmpId } }); - // let url = this.router.createUrlTree(['/datasets/copy/', result.datasetId, { newDmpId: newDmpId }]) - // window.open(url.toString(), '_blank') - } - }); - } - - updateUsers() { - return this.dmpService.updateUsers(this.dataset.dmp.id, this.users).pipe(takeUntil(this._destroyed)) - .subscribe( - complete => { - this.onUpdateCallbackSuccess(); - }, - error => this.onUpdateCallbackError(error) - ); - } - - removeUserFromDmp(user: UserInfoListingModel) { - const dialogRef = this.dialog.open(ConfirmationDialogComponent, { - data: { - message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-USER'), - confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.REMOVE'), - cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'), - isDeleteConfirmation: false - } - }); - dialogRef.afterClosed().subscribe(result => { - if (result) { - const index = this.users.findIndex(x => x.id === user.id); - if (index > -1) { - this.users.splice(index, 1); - } - this.updateUsers(); - } - }); - } - - showPublishButton(dataset: DatasetOverviewModel) { - return this.isFinalizedDataset(dataset) && !dataset.public && this.hasPublishButton; - } - - // publish(id: String) { - // const dialogRef = this.dialog.open(ConfirmationDialogComponent, { - // maxWidth: '500px', - // restoreFocus: false, - // data: { - // message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.PUBLISH-ITEM'), - // privacyPolicyNames: this.language.instant('GENERAL.CONFIRMATION-DIALOG.PRIVACY-POLICY-NAMES'), - // confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'), - // cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'), - // isDeleteConfirmation: false - // } - // }); - // dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { - // if (result) { - // this.datasetService.publish(id) - // .pipe(takeUntil(this._destroyed)) - // .subscribe(() => { - // this.hasPublishButton = false; - // this.reloadPage(); - // }); - // } - // }); - // } - - finalize(dataset: DatasetOverviewModel) { - - - this.dialog.open(ConfirmationDialogComponent, { - data: { - message: this.language.instant('DATASET-OVERVIEW.FINALISE-POPUP.MESSAGE'), - confirmButton: this.language.instant('DATASET-OVERVIEW.FINALISE-POPUP.CONFIRM'), - cancelButton: this.language.instant('DATASET-OVERVIEW.FINALISE-POPUP.CANCEL'), - }, - maxWidth: '30em' - }) - .afterClosed() - .pipe( - filter(x => x), - takeUntil(this._destroyed) - ) - .subscribe(_ => { - this.router.navigate(['datasets', 'edit', dataset.id, 'finalize']); - }) - - - - - - // const dialogRef = this.dialog.open(ConfirmationDialogComponent, { - // restoreFocus: false, - // data: { - // message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.FINALIZE-ITEM'), - // confirmButton: this.language.instant('QUICKWIZARD.SAVE-DIALOG.ACTIONS.AFFIRMATIVE'), - // cancelButton: this.language.instant('QUICKWIZARD.SAVE-DIALOG.ACTIONS.NEGATIVE'), - // isDeleteConfirmation: false - // } - // }); - // dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { - // if (result) { - // this.datasetWizardService.getSingle(dataset.id) - // .pipe(takeUntil(this._destroyed)) - // .subscribe(data => { - // this.datasetWizardModel = data; - // this.datasetWizardModel.status = DatasetStatus.Finalized; - // this.datasetWizardService.createDataset(this.datasetWizardModel) - // .pipe(takeUntil(this._destroyed)) - // .subscribe( - // data => this.onUpdateCallbackSuccess(), - // error => this.onUpdateCallbackError(error) - // ); - // }); - // } - // }); - } - - hasReversableStatus(dataset: DatasetOverviewModel): boolean { - return dataset.dmp.status == DmpStatus.Draft && dataset.status == DatasetStatus.Finalized - } - - reverse(dataset: DatasetOverviewModel) { - const dialogRef = this.dialog.open(ConfirmationDialogComponent, { - restoreFocus: false, - data: { - message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.UNFINALIZE-ITEM'), - confirmButton: this.language.instant('QUICKWIZARD.SAVE-DIALOG.ACTIONS.AFFIRMATIVE'), - cancelButton: this.language.instant('QUICKWIZARD.SAVE-DIALOG.ACTIONS.NEGATIVE'), - isDeleteConfirmation: false - } - }); - dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { - if (result) { - this.datasetWizardService.getSingle(dataset.id) - .pipe(takeUntil(this._destroyed)) - .subscribe(data => { - this.datasetWizardModel = data; - this.datasetWizardModel.status = DatasetStatus.Draft; - this.datasetWizardService.createDataset(this.datasetWizardModel) - .pipe(takeUntil(this._destroyed)) - .subscribe( - data => this.onUpdateCallbackSuccess(), - error => this.onUpdateCallbackError(error) - ); - }); - } - }); - } - -} diff --git a/dmp-frontend/src/app/ui/description/overview/description-overview.component.html b/dmp-frontend/src/app/ui/description/overview/description-overview.component.html new file mode 100644 index 000000000..e6d3ea297 --- /dev/null +++ b/dmp-frontend/src/app/ui/description/overview/description-overview.component.html @@ -0,0 +1,166 @@ +
+
+
+ + chevron_left +

{{'DESCRIPTION-OVERVIEW.ACTIONS.BACK' | translate}}

+
+
+
+
+ +

{{ description.label }}

+
+
+
+

+ {{ enumUtils.toDmpUserRolesString(dmpService.getCurrentUserRolesInDmp(description?.dmp?.dmpUsers)) }} +

+
+ . +
+ public + {{'DESCRIPTION-OVERVIEW.PUBLIC' | translate}} +
+ . +
+ lock_outline + {{'DESCRIPTION-OVERVIEW.LOCKED' | translate}} +
+ . +
{{'DESCRIPTION-OVERVIEW.EDITED' | translate}} : + {{description.modified | dateTimeCultureFormatter: "d MMMM y"}} +
+
+
+ check + {{'DESCRIPTION-OVERVIEW.FINALISED' | translate}} +
+
+
+
+ + + +
+
{{'DESCRIPTION-OVERVIEW.PART-OF' | translate}}
+
+ +
+ +
+
{{'DESCRIPTION-OVERVIEW.GRANT' | translate}}
+
{{referenceService.getReferencesForTypesFirstSafe(description?.dmp?.dmpReferences, [referenceTypeEnum.Grants])?.reference?.label}}
+
+ +
{{'DESCRIPTION-OVERVIEW.RESEARCHERS' | translate}}
+
+
+ + +
 
+
{{ dmpReference.reference?.data?.name }},
+
{{ dmpReference.reference?.data?.name }}
+
+
+ +
{{ dmpReference.reference?.data?.name }},
+
{{ dmpReference.reference?.data?.name }}
+
+
+ horizontal_rule +
+ +
{{'DESCRIPTION-OVERVIEW.DESCRIPTION' | translate}}
+
+

+
+
+ horizontal_rule +
+
+
+
+
+
+ +

{{ 'DESCRIPTION-OVERVIEW.ACTIONS.FINALIZE' | translate }}

+
+
+
+
+
+
+ +

{{ 'DESCRIPTION-OVERVIEW.ACTIONS.REVERSE' | translate }}

+
+
+ +

+ {{ 'DESCRIPTION-OVERVIEW.ACTIONS.EXPORT' | translate }}

+
+ + + + + +
+
+
+

{{ 'DESCRIPTION-OVERVIEW.DESCRIPTION-AUTHORS' | translate }}

+
+
+
+
+ +
+

{{ dmpUser.user?.name }} + + ({{ 'DESCRIPTION-OVERVIEW.YOU' | translate }}) +

+

{{ enumUtils.toDmpUserRoleString(dmpUser.role) }}

+
+
+ +
+
+
+ +
+
+
+
+
+
+
\ No newline at end of file diff --git a/dmp-frontend/src/app/ui/description/overview/dataset-overview.component.scss b/dmp-frontend/src/app/ui/description/overview/description-overview.component.scss similarity index 96% rename from dmp-frontend/src/app/ui/description/overview/dataset-overview.component.scss rename to dmp-frontend/src/app/ui/description/overview/description-overview.component.scss index 4d5c9c4c6..044796c0b 100644 --- a/dmp-frontend/src/app/ui/description/overview/dataset-overview.component.scss +++ b/dmp-frontend/src/app/ui/description/overview/description-overview.component.scss @@ -3,7 +3,7 @@ padding: 2em; } -.dataset-overview { +.description-overview { // margin-top: 5rem; } @@ -41,6 +41,8 @@ .account-icon { font-size: 2.5em; + height: auto; + width: auto; } // ********BUTTONS******** @@ -126,7 +128,7 @@ // ********TEXT******** -.dataset-logo { +.description-logo { width: 6em; height: 2.6em; background: var(--secondary-color); @@ -151,7 +153,7 @@ font-weight: 400; } -.dataset-label { +.description-label { font-weight: bold; width: auto; } @@ -173,7 +175,7 @@ margin-bottom: 0.5em; } -.dataset-label, +.description-label, .header { font-size: 1.25em; color: #212121; @@ -279,7 +281,7 @@ .mat-mini-fab-icon, .actions-btn, .status-icon, -.dataset-logo, +.description-logo, .frame-btn, .finalize-btn { display: flex; @@ -287,7 +289,7 @@ align-items: center; } -.dataset-label, +.description-label, .dmp-btn, .doi-panel, .researcher { diff --git a/dmp-frontend/src/app/ui/description/overview/description-overview.component.ts b/dmp-frontend/src/app/ui/description/overview/description-overview.component.ts new file mode 100644 index 000000000..a0de6c142 --- /dev/null +++ b/dmp-frontend/src/app/ui/description/overview/description-overview.component.ts @@ -0,0 +1,459 @@ +import { Component, OnInit } from '@angular/core'; +import { BaseComponent } from '@common/base/base.component'; +// import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item'; +import { Location } from '@angular/common'; +import { HttpClient } from '@angular/common/http'; +import { UntypedFormControl } from '@angular/forms'; +import { MatDialog } from '@angular/material/dialog'; +import { ActivatedRoute, Params, Router } from '@angular/router'; +import { DescriptionStatus } from '@app/core/common/enum/description-status'; +import { DmpAccessType } from '@app/core/common/enum/dmp-access-type'; +import { DmpStatus } from '@app/core/common/enum/dmp-status'; +import { DmpUserRole } from '@app/core/common/enum/dmp-user-role'; +import { ReferenceType } from '@app/core/common/enum/reference-type'; +import { DescriptionTemplate } from '@app/core/model/description-template/description-template'; +import { Description } from '@app/core/model/description/description'; +import { Dmp, DmpUser } from '@app/core/model/dmp/dmp'; +import { DmpReference, Reference } from '@app/core/model/reference/reference'; +import { AuthService } from '@app/core/services/auth/auth.service'; +import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; +import { DescriptionService } from '@app/core/services/description/description.service'; +import { DmpServiceNew } from '@app/core/services/dmp/dmp.service'; +import { LockService } from '@app/core/services/lock/lock.service'; +import { MatomoService } from '@app/core/services/matomo/matomo-service'; +import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; +import { ReferenceService } from '@app/core/services/reference/reference.service'; +import { UserService } from '@app/core/services/user/user.service'; +import { FileUtils } from '@app/core/services/utilities/file-utils.service'; +import { Oauth2DialogService } from '@app/ui/misc/oauth2-dialog/service/oauth2-dialog.service'; +import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; +import { Guid } from '@common/types/guid'; +import { TranslateService } from '@ngx-translate/core'; +import { filter, takeUntil } from 'rxjs/operators'; +import { nameof } from 'ts-simple-nameof'; +import { DescriptionCopyDialogComponent } from '../description-copy-dialog/description-copy-dialog.component'; +import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; + + +@Component({ + selector: 'app-description-overview', + templateUrl: './description-overview.component.html', + styleUrls: ['./description-overview.component.scss'] +}) +export class DescriptionOverviewComponent extends BaseComponent implements OnInit { + + description: Description; + researchers: DmpReference[] = []; + isNew = true; + isFinalized = false; + isPublicView = true; + hasPublishButton: boolean = true; + // breadCrumbs: Observable = observableOf(); + isUserOwner: boolean; + expand = false; + lockStatus: Boolean; + descriptionStatusEnum = DescriptionStatus; + dmpAccessTypeEnum = DmpAccessType; + referenceTypeEnum = ReferenceType; + + constructor( + private route: ActivatedRoute, + private router: Router, + private descriptionService: DescriptionService, + private translate: TranslateService, + private authentication: AuthService, + private dialog: MatDialog, + private language: TranslateService, + private uiNotificationService: UiNotificationService, + private configurationService: ConfigurationService, + private oauth2DialogService: Oauth2DialogService, + private userService: UserService, + private dmpService: DmpServiceNew, + public referenceService: ReferenceService, + private location: Location, + private lockService: LockService, + public enumUtils: EnumUtils, + private matomoService: MatomoService, + private fileUtils: FileUtils + ) { + super(); + } + + ngOnInit() { + this.matomoService.trackPageView('Description Overview'); + // Gets description data using parameter id + this.route.params + .pipe(takeUntil(this._destroyed)) + .subscribe((params: Params) => { + const itemId = params['id']; + const publicId = params['publicId']; + if (itemId != null) { + this.isNew = false; + this.isPublicView = false; + this.descriptionService.getSingle(itemId, this.lookupFields()) + .pipe(takeUntil(this._destroyed)) + .subscribe(data => { + this.description = data; + this.researchers = this.referenceService.getReferencesForTypes(this.description?.dmp?.dmpReferences, [ReferenceType.Researcher]); + // this.users = this.description.dmp.users; + this.checkLockStatus(this.description.id); + this.setIsUserOwner(); + // const breadCrumbs = []; + // breadCrumbs.push({ parentComponentName: null, label: this.language.instant('NAV-BAR.MY-DESCRIPTION-DESCRIPTIONS'), url: "/descriptions" }); + // breadCrumbs.push({ parentComponentName: 'DescriptionListingComponent', label: this.description.label, url: '/descriptions/overview/' + this.description.id }); + // this.breadCrumbs = observableOf(breadCrumbs); + }, (error: any) => { + if (error.status === 404) { + return this.onFetchingDeletedCallbackError('/descriptions/'); + } + if (error.status === 403) { + return this.onFetchingForbiddenCallbackError('/descriptions/'); + } + }); + } + else if (publicId != null) { + this.isNew = false; + this.isFinalized = true; + this.isPublicView = true; + this.descriptionService.getPublicSingle(publicId, this.lookupFields()) + .pipe(takeUntil(this._destroyed)) + .subscribe(data => { + this.description = data; + this.researchers = this.referenceService.getReferencesForTypes(this.description?.dmp?.dmpReferences, [ReferenceType.Researcher]); + // this.users = this.description.dmp.users; + // const breadCrumbs = []; + // breadCrumbs.push({ parentComponentName: null, label: this.language.instant('NAV-BAR.PUBLIC DESCRIPTIONS'), url: "/explore" }); + // breadCrumbs.push({ parentComponentName: 'DescriptionListingComponent', label: this.description.label, url: '/descriptions/publicOverview/' + this.description.id }); + // this.breadCrumbs = observableOf(breadCrumbs); + }, (error: any) => { + if (error.status === 404) { + return this.onFetchingDeletedCallbackError('/explore-descriptions'); + } + if (error.status === 403) { + return this.onFetchingForbiddenCallbackError('/explore-descriptions'); + } + }); + } + }); + } + + checkLockStatus(id: Guid) { + // TODO: add this + // this.lockService.checkLockStatus(id).pipe(takeUntil(this._destroyed)) + // .subscribe(lockStatus => { + // this.lockStatus = lockStatus + // if (lockStatus) { + // this.dialog.open(PopupNotificationDialogComponent, { + // data: { + // title: this.language.instant('DESCRIPTION-OVERVIEW.LOCKED-DIALOG.TITLE'), + // message: this.language.instant('DESCRIPTION-OVERVIEW.LOCKED-DIALOG.MESSAGE') + // }, maxWidth: '30em' + // }); + // } + // }); + } + + onFetchingDeletedCallbackError(redirectRoot: string) { + this.uiNotificationService.snackBarNotification(this.language.instant('DESCRIPTION-OVERVIEW.ERROR.DELETED-DESCRIPTION'), SnackBarNotificationLevel.Error); + this.router.navigate([redirectRoot]); + } + + onFetchingForbiddenCallbackError(redirectRoot: string) { + this.uiNotificationService.snackBarNotification(this.language.instant('DESCRIPTION-OVERVIEW.ERROR.FORBIDEN-DESCRIPTION'), SnackBarNotificationLevel.Error); + this.router.navigate([redirectRoot]); + } + + goBack(): void { + this.location.back(); + } + + reloadPage(): void { + const path = this.location.path(); + this.router.navigateByUrl('/reload', { skipLocationChange: true }).then(() => this.router.navigate([path])); + } + + setIsUserOwner() { + if (this.description) { + const principalId: Guid = this.authentication.userId(); + if (principalId) this.isUserOwner = !!this.description.dmp.dmpUsers.find(x => (x.role === DmpUserRole.Owner) && (principalId === x.id)); + } + } + + isUserAuthor(userId: Guid): boolean { + if (this.isAuthenticated()) { + const principalId: Guid = this.authentication.userId(); + return userId === principalId; + } else return false; + } + + isUserDescriptionRelated(): boolean { + const principalId: Guid = this.authentication.userId(); + return this.description.dmp.dmpUsers.some(x => (x.user.id === principalId)); + } + + + openShareDialog(rowId: any, rowName: any) { + // TODO: add dialog + // const dialogRef = this.dialog.open(DmpInvitationDialogComponent, { + // autoFocus: false, + // restoreFocus: false, + // data: { + // dmpId: rowId, + // dmpName: rowName + // } + // }); + } + + public isAuthenticated(): boolean { + return this.authentication.currentAccountIsAuthenticated(); + } + + isDraftDescription(description: Description) { + return description.status == DescriptionStatus.Draft; + } + + editClicked(description: Description) { + if (description.status === DescriptionStatus.Finalized && description.dmp.accessType === DmpAccessType.Public) { + this.router.navigate(['/descriptions/publicEdit/', description.id]); + } else { + this.router.navigate(['/descriptions/edit/', description.id]); + } + } + + deleteClicked() { + const dialogRef = this.dialog.open(ConfirmationDialogComponent, { + maxWidth: '300px', + data: { + message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'), + confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.DELETE'), + cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'), + isDeleteConfirmation: true + } + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + this.descriptionService.delete(this.description.id) + .pipe(takeUntil(this._destroyed)) + .subscribe( + complete => { + this.onDeleteCallbackSuccess(); + }, + error => this.onDeleteCallbackError(error) + ); + } + }); + } + + dmpClicked(dmp: Dmp) { + if (this.isPublicView) { + this.router.navigate(['/explore-plans/publicOverview/' + dmp.id]); + } else { + this.router.navigate(['/plans/overview/' + dmp.id]); + } + } + + private onDeleteCallbackSuccess(): void { + this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-DELETE'), SnackBarNotificationLevel.Success); + this.router.navigate(['/descriptions']); + } + + private onDeleteCallbackError(error) { + this.uiNotificationService.snackBarNotification(error.error.message ? error.error.message : this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DELETE'), SnackBarNotificationLevel.Error); + } + + private onUpdateCallbackSuccess(): void { + this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success); + this.reloadPage(); + } + + private onUpdateCallbackError(error) { + this.uiNotificationService.snackBarNotification(error.error.message ? this.tryTranslate(error.error.message) : this.language.instant('DESCRIPTION-UPLOAD.SNACK-BAR.UNSUCCESSFUL'), SnackBarNotificationLevel.Error); + } + + private tryTranslate(errorMessage: string): string { + return errorMessage.replace('Field value of', this.language.instant('Field value of')) + .replace('must be filled', this.language.instant('must be filled')); + } + + public getOrcidPath(): string { + return this.configurationService.orcidPath; + } + + isOrcid(reference: Reference) { + return reference.source === 'orcid'; + } + + getOrcidPathForResearcher(reference: string): string { + const path = this.getOrcidPath(); + return path + reference; + } + + downloadPDF(id: string) { + // TODO: add download + // this.descriptionService.downloadPDF(id) + // .pipe(takeUntil(this._destroyed)) + // .subscribe(response => { + // const blob = new Blob([response.body], { type: 'application/pdf' }); + // const filename = this.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); + + // FileSaver.saveAs(blob, filename); + // this.matomoService.trackDownload('descriptions', "pdf", id); + // }); + } + + downloadDocx(id: string) { + // TODO: add download + // this.descriptionService.downloadDocx(id) + // .pipe(takeUntil(this._destroyed)) + // .subscribe(response => { + // const blob = new Blob([response.body], { type: 'application/msword' }); + // const filename = this.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); + + // FileSaver.saveAs(blob, filename); + // this.matomoService.trackDownload('descriptions', "docx", id); + // }); + } + + downloadXml(id: string) { + // TODO: add download + // this.descriptionService.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); + // this.matomoService.trackDownload('descriptions', "xml", id); + // }); + } + + openCopyToDmpDialog() { + const formControl = new UntypedFormControl(); + const dialogRef = this.dialog.open(DescriptionCopyDialogComponent, { + width: '500px', + restoreFocus: false, + data: { + formControl: formControl, + descriptionId: this.description.id, + descriptionProfileId: this.description.descriptionTemplate.id, + descriptionProfileExist: false, + confirmButton: this.language.instant('DESCRIPTION-OVERVIEW.COPY-DIALOG.COPY'), + cancelButton: this.language.instant('DESCRIPTION-OVERVIEW.COPY-DIALOG.CANCEL') + } + }); + + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)) + .subscribe(newDmpId => { + if (newDmpId) { + this.router.navigate(['/descriptions/copy/' + this.description.id], { queryParams: { newDmpId: newDmpId } }); + // let url = this.router.createUrlTree(['/descriptions/copy/', result.descriptionId, { newDmpId: newDmpId }]) + // window.open(url.toString(), '_blank') + } + }); + } + + removeUserFromDmp(dmpUser: DmpUser) { + const dialogRef = this.dialog.open(ConfirmationDialogComponent, { + data: { + message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-USER'), + confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.REMOVE'), + cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'), + isDeleteConfirmation: false + } + }); + dialogRef.afterClosed().subscribe(result => { + if (result) { + //TODO: implement remove user from backend + // const index = this.users.findIndex(x => x.id === user.id); + // if (index > -1) { + // this.users.splice(index, 1); + // } + // this.dmpService.updateUsers(this.description.dmp.id, this.users).pipe(takeUntil(this._destroyed)) + // .subscribe( + // complete => { + // this.onUpdateCallbackSuccess(); + // }, + // error => this.onUpdateCallbackError(error) + // ); + } + }); + } + + finalize(description: Description) { + + this.dialog.open(ConfirmationDialogComponent, { + data: { + message: this.language.instant('DESCRIPTION-OVERVIEW.FINALISE-POPUP.MESSAGE'), + confirmButton: this.language.instant('DESCRIPTION-OVERVIEW.FINALISE-POPUP.CONFIRM'), + cancelButton: this.language.instant('DESCRIPTION-OVERVIEW.FINALISE-POPUP.CANCEL'), + }, + maxWidth: '30em' + }) + .afterClosed() + .pipe( + filter(x => x), + takeUntil(this._destroyed) + ) + .subscribe(_ => { + this.router.navigate(['descriptions', 'edit', description.id, 'finalize']); + }) + } + + hasReversableStatus(description: Description): boolean { + return description.dmp.status == DmpStatus.Draft && description.status == DescriptionStatus.Finalized + } + + reverse(description: Description) { + const dialogRef = this.dialog.open(ConfirmationDialogComponent, { + restoreFocus: false, + data: { + message: this.language.instant('DESCRIPTION-OVERVIEW.UNDO-FINALIZATION-DIALOG.TITLE'), + confirmButton: this.language.instant('DESCRIPTION-OVERVIEW.UNDO-FINALIZATION-DIALOG.CONFIRM'), + cancelButton: this.language.instant('DESCRIPTION-OVERVIEW.UNDO-FINALIZATION-DIALOG.CANCEL'), + isDeleteConfirmation: false + } + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + // TODO: implement endpoint to undo finalization to a Description and set it to Draft again + // this.descriptionWizardService.getSingle(description.id) + // .pipe(takeUntil(this._destroyed)) + // .subscribe(data => { + // this.description = data; + // this.description.status = DescriptionStatus.Draft; + // this.descriptionWizardService.createDescription(this.description) + // .pipe(takeUntil(this._destroyed)) + // .subscribe( + // data => this.onUpdateCallbackSuccess(), + // error => this.onUpdateCallbackError(error) + // ); + // }); + } + }); + } + + private lookupFields(): string[] { + return [ + nameof(x => x.id), + nameof(x => x.label), + nameof(x => x.status), + nameof(x => x.updatedAt), + [nameof(x => x.descriptionTemplate), nameof(x => x.id)].join('.'), + [nameof(x => x.descriptionTemplate), nameof(x => x.label)].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.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.user.name)].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)].join('.'), + [nameof(x => x.dmp), nameof(x => x.dmpReferences), nameof(x => x.reference), nameof(x => x.source)].join('.'), + [nameof(x => x.dmp), nameof(x => x.dmpReferences), nameof(x => x.reference), nameof(x => x.reference)].join('.'), + ] + } + +} diff --git a/dmp-frontend/src/app/ui/description/overview/dataset-overview.module.ts b/dmp-frontend/src/app/ui/description/overview/description-overview.module.ts similarity index 84% rename from dmp-frontend/src/app/ui/description/overview/dataset-overview.module.ts rename to dmp-frontend/src/app/ui/description/overview/description-overview.module.ts index 293bffdfb..31a9bc4d8 100644 --- a/dmp-frontend/src/app/ui/description/overview/dataset-overview.module.ts +++ b/dmp-frontend/src/app/ui/description/overview/description-overview.module.ts @@ -1,12 +1,12 @@ import { NgModule } from '@angular/core'; import { FormattingModule } from '@app/core/formatting.module'; import { AutoCompleteModule } from '@app/library/auto-complete/auto-complete.module'; -import { ConfirmationDialogModule } from '@common/modules/confirmation-dialog/confirmation-dialog.module'; import { ExportMethodDialogModule } from '@app/library/export-method-dialog/export-method-dialog.module'; import { UrlListingModule } from '@app/library/url-listing/url-listing.module'; import { CommonFormsModule } from '@common/forms/common-forms.module'; +import { ConfirmationDialogModule } from '@common/modules/confirmation-dialog/confirmation-dialog.module'; import { CommonUiModule } from '@common/ui/common-ui.module'; -import { DatasetOverviewComponent } from './dataset-overview.component'; +import { DescriptionOverviewComponent } from './description-overview.component'; @NgModule({ imports: [ @@ -19,7 +19,7 @@ import { DatasetOverviewComponent } from './dataset-overview.component'; AutoCompleteModule ], declarations: [ - DatasetOverviewComponent + DescriptionOverviewComponent ] }) -export class DatasetOverviewModule { } \ No newline at end of file +export class DescriptionOverviewModule { } \ No newline at end of file diff --git a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.ts b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.ts index 6dfef3ff8..550e9ad5d 100644 --- a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.ts +++ b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.ts @@ -35,7 +35,6 @@ import { ReferenceService } from '@app/core/services/reference/reference.service import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration'; import { CheckDeactivateBaseComponent } from '@app/library/deactivate/deactivate.component'; import { PopupNotificationDialogComponent } from '@app/library/notification/popup/popup-notification.component'; -import { GrantEditorModel } from '@app/ui/grant/editor/grant-editor.model'; import { isNullOrUndefined } from '@app/utilities/enhancers/utils'; import { FormService } from '@common/forms/form-service'; import { FormValidationErrorsDialogComponent } from '@common/forms/form-validation-errors-dialog/form-validation-errors-dialog.component'; @@ -401,8 +400,9 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im grantControl = new GrantTabModel(); grantControl.fromModel(this.formGroup.get('grant').get('existGrant').value); } else { - grantControl = new GrantEditorModel(); - grantControl.fromModel(this.formGroup.get('grant').value); + // TODO: Commented in refactor + //grantControl = new GrantEditorModel(); + //grantControl.fromModel(this.formGroup.get('grant').value); } grantControl.buildForm() diff --git a/dmp-frontend/src/app/ui/dmp/dmp.routing.ts b/dmp-frontend/src/app/ui/dmp/dmp.routing.ts index 2ea3435b6..537f6c742 100644 --- a/dmp-frontend/src/app/ui/dmp/dmp.routing.ts +++ b/dmp-frontend/src/app/ui/dmp/dmp.routing.ts @@ -24,66 +24,54 @@ const routes: Routes = [ breadcrumb: true }, }, - // Uncomment to get dmp plans for grant with grantId - { - path: 'grant/:grantId', - component: DmpListingComponent, - data: { - breadcrumb: true - }, - }, - { - path: 'edit/:id', - component: DmpEditorBlueprintComponent, - data: { - breadcrumb: true, - title: 'GENERAL.TITLES.DMP-EDIT' - }, - canDeactivate: [CanDeactivateGuard] - }, - { - path: 'publicEdit/:publicId', - component: DmpEditorComponent, - data: { - breadcrumb: true, - title: 'GENERAL.TITLES.DMP-PUBLIC-EDIT' - }, - canDeactivate: [CanDeactivateGuard] - }, - { - path: 'overview/:id', - component: DmpOverviewComponent, - data: { - breadcrumb: true, - title: 'GENERAL.TITLES.DMP-OVERVIEW' - }, - }, - { - path: 'publicOverview/:publicId', - component: DmpOverviewComponent, - data: { - breadcrumb: true, - title: 'GENERAL.TITLES.DMP-OVERVIEW' - }, - }, - // ----------- UNCOMMENT TO ADD AGAIN GRANTS -------- + // { - // path: 'new/grant/:grantId', + // path: 'edit/:id', + // component: DmpEditorBlueprintComponent, + // data: { + // breadcrumb: true, + // title: 'GENERAL.TITLES.DMP-EDIT' + // }, + // canDeactivate: [CanDeactivateGuard] + // }, + // { + // path: 'publicEdit/:publicId', // component: DmpEditorComponent, // data: { - // breadcrumbs: 'new' - // } + // breadcrumb: true, + // title: 'GENERAL.TITLES.DMP-PUBLIC-EDIT' + // }, + // canDeactivate: [CanDeactivateGuard] + // }, + // { + // path: 'overview/:id', + // component: DmpOverviewComponent, + // data: { + // breadcrumb: true, + // title: 'GENERAL.TITLES.DMP-OVERVIEW' + // }, + // }, + // { + // path: 'publicOverview/:publicId', + // component: DmpOverviewComponent, + // data: { + // breadcrumb: true, + // title: 'GENERAL.TITLES.DMP-OVERVIEW' + // }, + // }, + + + + // { + // path: 'new', + // component: DmpEditorBlueprintComponent, + // canActivate: [AuthGuard], + // data: { + // breadcrumbs: 'new', + // title: 'GENERAL.TITLES.DMP-NEW' + // }, + // canDeactivate: [CanDeactivateGuard] // }, - { - path: 'new', - component: DmpEditorBlueprintComponent, - canActivate: [AuthGuard], - data: { - breadcrumbs: 'new', - title: 'GENERAL.TITLES.DMP-NEW' - }, - canDeactivate: [CanDeactivateGuard] - }, // { // path: 'new/dataset', // component: DmpEditorComponent, @@ -102,32 +90,32 @@ const routes: Routes = [ // title: 'GENERAL.TITLES.DATASET-NEW' // } // }, - { - path: 'new_version/:id', - // component: DmpWizardComponent, - component: DmpCloneComponent, - data: { - clone: false, - breadcrumb: true, - title: 'GENERAL.TITLES.DMP-NEW-VERSION' - }, - }, - { - path: 'clone/:id', - component: DmpCloneComponent, - data: { - clone: false, - breadcrumb: true, - title: 'GENERAL.TITLES.DMP-CLONE' - }, - }, - { - path: 'invitation/:id', - component: InvitationAcceptedComponent, - data: { - breadcrumb: true - }, - } + // { + // path: 'new_version/:id', + // // component: DmpWizardComponent, + // component: DmpCloneComponent, + // data: { + // clone: false, + // breadcrumb: true, + // title: 'GENERAL.TITLES.DMP-NEW-VERSION' + // }, + // }, + // { + // path: 'clone/:id', + // component: DmpCloneComponent, + // data: { + // clone: false, + // breadcrumb: true, + // title: 'GENERAL.TITLES.DMP-CLONE' + // }, + // }, + // { + // path: 'invitation/:id', + // component: InvitationAcceptedComponent, + // data: { + // breadcrumb: true + // }, + // } ]; @NgModule({ diff --git a/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.component.ts b/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.component.ts index bde80aa87..2027b0c2c 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.component.ts +++ b/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.component.ts @@ -29,7 +29,6 @@ import { DmpFinalizeDialogComponent, DmpFinalizeDialogInput } from '@app/ui/dmp/ import { FunderFormModel } from '@app/ui/dmp/editor/grant-tab/funder-form-model'; import { GrantTabModel } from '@app/ui/dmp/editor/grant-tab/grant-tab-model'; import { ProjectFormModel } from '@app/ui/dmp/editor/grant-tab/project-form-model'; -import { GrantEditorModel } from '@app/ui/grant/editor/grant-editor.model'; // import { IBreadCrumbComponent } from '@app/ui/misc/breadcrumb/definition/IBreadCrumbComponent'; // import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item'; import { DmpBlueprint, DmpBlueprintDefinition } from '@app/core/model/dmp-blueprint/dmp-blueprint'; @@ -1071,8 +1070,9 @@ export class DmpEditorComponent extends CheckDeactivateBaseComponent implements grantControl = new GrantTabModel(); grantControl.fromModel(this.formGroup.get('grant').get('existGrant').value); } else { - grantControl = new GrantEditorModel(); - grantControl.fromModel(this.formGroup.get('grant').value); + // TODO: Commented in refactor + // grantControl = new GrantEditorModel(); + // grantControl.fromModel(this.formGroup.get('grant').value); } grantControl.buildForm() diff --git a/dmp-frontend/src/app/ui/dmp/listing/dmp-listing.component.html b/dmp-frontend/src/app/ui/dmp/listing/dmp-listing.component.html index 473852b36..71cd988bb 100644 --- a/dmp-frontend/src/app/ui/dmp/listing/dmp-listing.component.html +++ b/dmp-frontend/src/app/ui/dmp/listing/dmp-listing.component.html @@ -2,8 +2,6 @@
- -

{{'DMP-LISTING.TEXT-INFO' | translate}}

{{'DMP-LISTING.TEXT-INFO-QUESTION' | translate}} {{'DMP-LISTING.LINK-ZENODO' | translate}} {{'DMP-LISTING.GET-IDEA' | translate}}

@@ -13,7 +11,7 @@
-

{{(isPublic ? 'GENERAL.TITLES.EXPLORE-PLANS' : 'GENERAL.TITLES.PLANS') | translate}}

+

{{(isPublic ? 'GENERAL.TITLES.EXPLORE-PLANS' : 'GENERAL.TITLES.PLANS') | translate}}

-
+
{{'DMP-LISTING.SORT-BY' | translate}}: @@ -32,16 +30,10 @@ {{enumUtils.toRecentActivityOrderString(order.PUBLISHED)}} {{enumUtils.toRecentActivityOrderString(order.LABEL)}} {{enumUtils.toRecentActivityOrderString(order.STATUS)}} - -
- -
{{ 'GENERAL.ACTIONS.TAKE-A-TOUR'| translate }}
- - search @@ -50,7 +42,6 @@ {{formGroup.get('like').getError('backendError').message}} -
@@ -58,155 +49,14 @@
-
+
-
+
{{'DMP-LISTING.EMPTY-LIST' | translate}}
- - - - - - - - - diff --git a/dmp-frontend/src/app/ui/dmp/listing/dmp-listing.component.ts b/dmp-frontend/src/app/ui/dmp/listing/dmp-listing.component.ts index edc81cbec..d6e78bd01 100644 --- a/dmp-frontend/src/app/ui/dmp/listing/dmp-listing.component.ts +++ b/dmp-frontend/src/app/ui/dmp/listing/dmp-listing.component.ts @@ -1,38 +1,32 @@ import { HttpClient } from '@angular/common/http'; import { Component, OnInit, ViewChild } from '@angular/core'; -import { UntypedFormBuilder, UntypedFormControl, UntypedFormGroup } from '@angular/forms'; +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 { DataTableRequest } from '@app/core/model/data-table/data-table-request'; -import { GrantListingModel } from '@app/core/model/grant/grant-listing'; -import { DmpCriteria } from '@app/core/query/dmp/dmp-criteria'; import { AuthService } from '@app/core/services/auth/auth.service'; import { DmpService, DmpServiceNew } from '@app/core/services/dmp/dmp.service'; import { GrantService } from "@app/core/services/grant/grant.service"; import { MatomoService } from '@app/core/services/matomo/matomo-service'; -import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-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 { DmpInvitationDialogComponent } from '@app/ui/dmp/invitation/dmp-invitation-dialog.component'; -import { DmpCriteriaComponent } from '@app/ui/dmp/listing/criteria/dmp-criteria.component'; // import { IBreadCrumbComponent } from '@app/ui/misc/breadcrumb/definition/IBreadCrumbComponent'; // import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item'; -import { isNullOrUndefined } from '@app/utilities/enhancers/utils'; +import { IsActive } from '@app/core/common/enum/is-active.enum'; +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 { Observable, of as observableOf } from 'rxjs'; import { debounceTime, takeUntil } from 'rxjs/operators'; -import { DmpCriteriaDialogComponent } from './criteria/dmp-criteria-dialog.component'; -import { DmpUploadDialogue } from './upload-dialogue/dmp-upload-dialogue.component'; -import { DmpLookup } from '@app/core/query/dmp.lookup'; -import { Dmp } from '@app/core/model/dmp/dmp'; import { nameof } from 'ts-simple-nameof'; +import { Description } from '@app/core/model/description/description'; @Component({ selector: 'app-dmp-listing-component', @@ -46,23 +40,27 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr // @ViewChild(DmpCriteriaComponent, { static: true }) criteria: DmpCriteriaComponent; // breadCrumbs: Observable = observableOf([{ parentComponentName: null, label: 'DMPs', url: "/plans" }]); - itemId: string; - grantId: string; - showGrant: boolean; - titlePrefix: string; + + lookup: DmpLookup = new DmpLookup(); + groupId: string; + + + // itemId: string; + // showGrant: boolean; + // titlePrefix: string; totalCount: number; listingItems: Dmp[] = []; - allVersions: boolean = false; - groupLabel: string; + // allVersions: boolean = false; + // groupLabel: string; isPublic: boolean = false; - public isVisible = true + // public isVisible = true hasListingItems = null; - startIndex: number = 0; + // startIndex: number = 0; pageSize: number = 5; - criteria: DmpCriteria; - criteriaFormGroup: UntypedFormGroup; + // criteria: DmpCriteria; + // criteriaFormGroup: UntypedFormGroup; public formGroup = new UntypedFormBuilder().group({ like: new UntypedFormControl(), order: new UntypedFormControl() @@ -70,8 +68,8 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr scrollbar: boolean; order = RecentActivityOrder; - dmpText: string; - datasetText: string; + // dmpText: string; + // datasetText: string; constructor( private dmpService: DmpService, @@ -106,82 +104,19 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr this.route.params .pipe(takeUntil(this._destroyed)) .subscribe(async params => { - let grantLabel; - if (params['grantId']) { - this.grantId = params['grantId']; - this.showGrant = true; - this.grantService.getSingle(this.grantId) - .subscribe((grant: GrantListingModel) => { - // const grant: GrantListingModel = { - // id: this.grantId - // } - // this.breadCrumbs = Observable.of([{ parentComponentName: 'GrantEditorComponent', label: grantLabel, url: '/grants/edit/' + this.grantId }]); - grantLabel = this.route.snapshot.queryParams.grantLabel; - this.criteria = { like: null, grants: [grant], groupIds: null, allVersions: false } - // this.criteria.setCriteria({ like: null, grants: [grant], groupIds: null, allVersions: false }); + this.groupId = params['groupId']; - this.refresh(); - // this.criteria.setRefreshCallback((resetPages) => this.refresh(resetPages)); - }) + 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]; - } else if (params['groupId']) { - this.itemId = params['groupId']; - this.showGrant = true; - this.allVersions = true; - - this.language.get('NAV-BAR.MY-DMPS').pipe(takeUntil(this._destroyed)).subscribe(x => { - // this.breadCrumbs = observableOf([ - // { - // parentComponentName: null, - // label: x, - // url: '/plans' - // }] - // ); - }) - this.groupLabel = this.route.snapshot.queryParams.groupLabel; - - // this.criteria.setCriteria(this.getDefaultCriteria()); - this.criteria = this.getDefaultCriteria(); - this.criteria.groupIds ? this.criteria.groupIds.push(this.itemId) : this.criteria.groupIds = [this.itemId]; - this.refresh(); - // this.criteria.setRefreshCallback((resetPages) => this.refresh(resetPages)); - } else { - this.itemId = params['groupId']; - this.showGrant = true; - const breadCrumbs = []; - - // if (this.itemId) { - // const dmplabel = this.route.snapshot.queryParams.groupLabel; - // breadCrumbs.push({ - // parentComponentName: null, - // label: this.language.instant('NAV-BAR.DMPS'), - // url: '/plans' - // }); - // } - // else - - this.language.get('NAV-BAR.MY-DMPS').pipe(takeUntil(this._destroyed)).subscribe(x => { - // this.breadCrumbs = observableOf([ - // { - // parentComponentName: null, - // label: x, - // url: '/plans' - // }] - // ); - }) - // this.criteria.setCriteria(this.getDefaultCriteria()); - this.criteria = this.getDefaultCriteria(); - this.refresh(); - // this.criteria.setRefreshCallback((resetPages) => this.refresh(resetPages)); - } - - if (this.grantId != null) { - if (grantLabel !== undefined) { - this.titlePrefix = 'for ' + grantLabel; - } + if (this.groupId != null && Guid.isGuid(this.groupId)) { + // this.lookup.groupIds = [this.groupId]; //TODO: add filter in backend } + this.refresh(this.lookup); }); this.formGroup.get('like').valueChanges @@ -189,7 +124,7 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr .subscribe(x => this.controlModified()); this.formGroup.get('order').valueChanges .pipe(takeUntil(this._destroyed)) - .subscribe(x => this.refresh()); + .subscribe(x => this.refresh(this.lookup)); } public dashboardTour: GuidedTour = { @@ -235,336 +170,160 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr }); } - public refresh(resetPages = false) { - const fields: Array = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value]; - this.startIndex = 0; + loadMore() { + this.lookup.page = { size: this.pageSize, offset: this.lookup.page.offset + this.pageSize }; + this.refresh(this.lookup); + } - const request = new DataTableRequest(this.startIndex, this.pageSize, { fields: fields }); - this.setPublicCriteria(); - request.criteria = this.criteria; - - let lookup: DmpLookup = new DmpLookup(); + private refresh(lookup: DmpLookup) { lookup.project = { fields: [ nameof(x => x.id), nameof(x => x.label), + nameof(x => x.status), + nameof(x => x.accessType), + nameof(x => x.version), + nameof(x => x.groupId), + nameof(x => x.updatedAt), + [nameof(x => x.descriptions), nameof(x => x.id)].join('.'), + [nameof(x => x.descriptions), nameof(x => x.label)].join('.'), + // [nameof(x => x.descriptionTemplate), nameof(x => x.label)].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.accessType)].join('.'), + [nameof(x => x.dmpUsers), nameof(x => x.id)].join('.'), + [nameof(x => x.dmpUsers), nameof(x => x.user.id)].join('.'), + [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)].join('.'), + // [nameof(x => x.dmp), nameof(x => x.dmpReferences), nameof(x => x.reference), nameof(x => x.reference)].join('.'), ] }; this.dmpServiceNew.query(lookup).pipe(takeUntil(this._destroyed)) - .subscribe(result => { - if (!result) { return; } - // result.data.map(item => { - // item['datasets'].map(dmp => { - // dmp.url = 'datasets/edit/' + dmp.url; - // dmp.all = 'datasets/dmp/' + item.id; - // return dmp; - // }); - // return item; - // }); - this.listingItems = result.items; - this.hasListingItems = true; - if (!this.isPublic && this.listingItems.length === 0 && !this.hasCriteria() && !this.hasLikeCriteria()) { - this.openTour(); - } - this.totalCount = result.count; - }); - - // const fields: Array = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value]; - // this.startIndex = 0; - - // const request = new DataTableRequest(this.startIndex, this.pageSize, { fields: fields }); - // this.setPublicCriteria(); - // request.criteria = this.criteria; - - // this.dmpService - // this.dmpService.getPaged(request, "listing").pipe(takeUntil(this._destroyed)).subscribe(result => { - // if (!result) { return []; } - // result.data.map(item => { - // item['datasets'].map(dmp => { - // dmp.url = 'datasets/edit/' + dmp.url; - // dmp.all = 'datasets/dmp/' + item.id; - // return dmp; - // }); - // return item; - // }); - // this.listingItems = result.data; - // this.hasListingItems = true; - // if (!this.isPublic && this.listingItems.length === 0 && !this.hasCriteria() && !this.hasLikeCriteria()) { - // this.openTour(); - // } - // this.totalCount = result.totalCount; - // }); - } - - 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.setPublicCriteria(); - // request.criteria = this.criteria; - - // this.dmpService.getPaged(request, "listing").pipe(takeUntil(this._destroyed)).subscribe(result => { - // if (!result) { return []; } - // result.data.map(item => { - // item['datasets'].map(dmp => { - // dmp.url = 'datasets/edit/' + dmp.url; - // dmp.all = 'datasets/dmp/' + item.id; - // return dmp; - // }); - // return item; - // }); - // // this.listingItems = this.listingItems.concat(result.data); - // this.listingItems = this.mergeTwoSortedLists(this.listingItems, result.data, this.formGroup.get('order').value); - // this.hasListingItems = true; - // }); - } - - pageThisEvent(event) { - this.refresh(); - } - - hasCriteria(): boolean { - if (this.criteria.organisations && this.criteria.organisations.length > 0 || - this.criteria.grants && this.criteria.grants.length > 0 || - this.criteria.collaborators && this.criteria.collaborators.length > 0 || - this.criteria.datasetTemplates && this.criteria.datasetTemplates.length > 0 || - this.criteria.onlyPublic === true - ) { return true; } else { return false; } + .subscribe(result => { + if (!result) { return []; } + this.totalCount = result.count; + if (lookup?.page?.offset === 0) this.listingItems = []; + this.listingItems.push(...result.items); + this.hasListingItems = true; + }); } 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(); + this.lookup.like = this.formGroup.get("like").value; + this.lookup.page = { size: this.pageSize, offset: 0 }; + this.refresh(this.lookup); } - // rowClicked(dmp: Dmp) { - // this.router.navigate(['/plans/overview/' + dmp.id]); - // } - - public closeCard(): void { - this.isVisible = false; - } - - // addDataset(rowId: String) { - // this.router.navigate(['/datasets/new/' + rowId]); - // } - - showDatasets(rowId: String, rowLabel: String) { - this.router.navigate(['/datasets/dmp/' + rowId, { dmpLabel: rowLabel }]); - } - - viewVersions(rowId: String, rowLabel: String) { - this.router.navigate(['/plans/versions/' + rowId], { queryParams: { groupLabel: rowLabel } }); - } - - getDefaultCriteria(): DmpCriteria { - const defaultCriteria = new DmpCriteria(); - if (this.isPublic) { - defaultCriteria.isPublic = true; - defaultCriteria.onlyPublic = true; - } - if (this.allVersions) { - defaultCriteria.allVersions = true; - } - return defaultCriteria; - } openShareDialog(rowId: any, rowName: any) { - const dialogRef = this.dialog.open(DmpInvitationDialogComponent, { - autoFocus: false, - data: { - dmpId: rowId, - dmpName: rowName - } - }); - } - - fileSave(event) { - const dialogRef = this.dialog.open(DmpUploadDialogue, { - data: { - fileList: FileList, - success: Boolean, - dmpTitle: String - } - }); - dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { - if (result && result.success) { - this.dmpService.uploadXml(result.fileList[0], result.dmpTitle, result.dmpBlueprints) - .pipe(takeUntil(this._destroyed)) - .subscribe((complete) => this.onCallbackImportComplete(), - (error) => this.onCallbackImportFail(error.error)); - } - }); - } - - private onCallbackImportComplete() { - this.uiNotificationService.snackBarNotification(this.language.instant('DMP-UPLOAD.UPLOAD-SUCCESS'), SnackBarNotificationLevel.Success); - this.router.navigate(['/reload']).then(() => this.isPublic ? this.router.navigate(['/explore-plans']) : this.router.navigate(['/plans'])); - } - - private onCallbackImportFail(error: any) { - this.uiNotificationService.snackBarNotification(error.message, SnackBarNotificationLevel.Error); + //TODO: add this + // const dialogRef = this.dialog.open(DmpInvitationDialogComponent, { + // autoFocus: false, + // data: { + // dmpId: rowId, + // dmpName: rowName + // } + // }); } openFiltersDialog(): void { - 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" } - // } - // } - }); + //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 => { - }); + // dialogRef.afterClosed().subscribe(result => { + // }); } - updateDataFn(criteria: DmpCriteriaComponent): void { - this.criteriaFormGroup = criteria.formGroup; - this.toDmpCriteria(criteria); - this.refresh(); - } + // 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; - } + // 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; - } - } + // 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; - // } - } + // 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 } - // private mergeTwoSortedLists(arr1: Dmp[], arr2: Dmp[], order: string): Dmp[] { - // 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].modifiedTime) > new Date(arr2[index2].modifiedTime)))) { - // merged[current] = arr1[index1]; - // index1++; - // } else { - // merged[current] = arr2[index2]; - // index2++; - // } - // } else if (order === 'created') { - // if (!isArr1Depleted && (isArr2Depleted || (new Date(arr1[index1].creationTime) > new Date(arr2[index2].creationTime)))) { - // 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 === "publishedAt") { - // if (!isArr1Depleted && (isArr2Depleted || (new Date(arr1[index1].publishedAt) > new Date(arr2[index2].publishedAt)))) { - // 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' + + 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 = this.dmpText; + this.dashboardTour.steps[0].title = dmpText; } public setDashboardTourDatasetText(): void { - this.datasetText = this.language.instant('DATASET-LISTING.TEXT-INFO') + + 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 = this.datasetText; + this.dashboardTour.steps[1].title = datasetText; } public restartTour(): void { @@ -574,6 +333,6 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr } public hasLikeCriteria(): boolean { - return this.criteria.like !== undefined && this.criteria.like !== null; + return this.lookup.like !== undefined && this.lookup.like !== null; } } \ No newline at end of file diff --git a/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.html b/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.html index 6174ecdf3..9b369b991 100644 --- a/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.html +++ b/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.html @@ -7,7 +7,7 @@
{{dmp.label}}
- {{ roleDisplay(dmp.users) }} + {{ enumUtils.toDmpUserRolesString(dmpService.getCurrentUserRolesInDmp(dmp?.dmpUsers)) }} . public{{'TYPES.DMP-VISIBILITY.PUBLIC' | translate}} done{{ enumUtils.toDmpStatusString(dmp.status) }} @@ -15,14 +15,14 @@ . {{'DMP-LISTING.VERSION' | translate}} {{dmp.version}} . - + {{ 'DMP-LISTING.GRANT' | translate }}: {{referenceService.getReferencesForTypesFirstSafe(dmp?.dmpReferences, [referenceTypeEnum.Grants])?.reference?.label}}
{{'DMP-LISTING.CONTAINED-DESCRIPTIONS' | translate}}: ({{ dmp.descriptions.length }})
-
+
-
{{dataset.label}},
-
{{dataset.label}}
+
{{description.label}},
+
{{description.label}}
{{'GENERAL.ACTIONS.SHOW-MORE' | translate}} diff --git a/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.ts b/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.ts index e2befe0e1..e2a836dfe 100644 --- a/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.ts +++ b/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.ts @@ -34,6 +34,9 @@ import { GrantTabModel } from '../../editor/grant-tab/grant-tab-model'; import { ProjectFormModel } from '../../editor/grant-tab/project-form-model'; import { DmpInvitationDialogComponent } from '../../invitation/dmp-invitation-dialog.component'; import { DmpUserRole } from '@app/core/common/enum/dmp-user-role'; +import { DmpAccessType } from '@app/core/common/enum/dmp-access-type'; +import { ReferenceType } from '@app/core/common/enum/reference-type'; +import { ReferenceService } from '@app/core/services/reference/reference.service'; @Component({ selector: 'app-dmp-listing-item-component', @@ -50,9 +53,8 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit { isDraft: boolean; isFinalized: boolean; isPublished: boolean; - dmpModel: DmpEditorModel; - dmpFormGroup: UntypedFormGroup; dmpStatusEnum = DmpStatus; + referenceTypeEnum = ReferenceType; constructor( private router: Router, @@ -67,6 +69,7 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit { private location: Location, private httpClient: HttpClient, private matomoService: MatomoService, + public referenceService: ReferenceService, private fileUtils: FileUtils) { super(); } @@ -82,7 +85,7 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit { this.isDraft = false; this.isFinalized = true; this.isPublished = false; - // if (this.dmp.public == true) { this.isPublished = true } + if (this.dmp.status === DmpStatus.Finalized && this.dmp.accessType === DmpAccessType.Public) { this.isPublished = true } } } @@ -91,16 +94,17 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit { } openShareDialog(rowId: any, rowName: any) { - const dialogRef = this.dialog.open(DmpInvitationDialogComponent, { - // height: '250px', - // width: '700px', - autoFocus: false, - restoreFocus: false, - data: { - dmpId: rowId, - dmpName: rowName - } - }); + //TODO: add this. + // const dialogRef = this.dialog.open(DmpInvitationDialogComponent, { + // // height: '250px', + // // width: '700px', + // autoFocus: false, + // restoreFocus: false, + // data: { + // dmpId: rowId, + // dmpName: rowName + // } + // }); } editClicked(dmpId: String) { @@ -123,38 +127,9 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit { // } } - roleDisplay(value: any) { - const principalId: string = this.authentication.userId()?.toString(); - let role: number; - if (principalId) { - value.forEach(element => { - if (principalId === element.id) { - role = element.role; - } - }); - } - if (role === 0) { - return this.language.instant('DMP-LISTING.OWNER'); - } - else if (role === 1) { - return this.language.instant('DMP-LISTING.MEMBER'); - } - else { - return this.language.instant('DMP-LISTING.OWNER'); - } - } - isUserDMPRelated() { - const principalId: string = this.authentication.userId()?.toString(); - let isRelated: boolean = false; - if (this.dmp && principalId) { - // this.dmp.users.forEach(element => { - // if (element.id === principalId) { - // isRelated = true; - // } - // }) - } - return isRelated; + const principalId: Guid = this.authentication.userId(); + return this.dmp.dmpUsers.some(x => (x.user.id === principalId)); } cloneOrNewVersionClicked(dmp: Dmp, isNewVersion: boolean) { @@ -216,60 +191,19 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit { ); } - private checkForGrant(blueprint: DmpBlueprintDefinition) { - let hasGrant = false; - blueprint.sections.forEach(section => section.fields.forEach( - field => { - if (field.category as unknown === DmpBlueprintSectionFieldCategory.SYSTEM && field.systemFieldType === DmpBlueprintSystemFieldType.GRANT) { - hasGrant = true; - } - } - )); - if (!hasGrant) { - this.dmpFormGroup.removeControl('grant'); - } - } - - private checkForFunder(blueprint: DmpBlueprintDefinition) { - let hasFunder = false; - blueprint.sections.forEach(section => section.fields.forEach( - field => { - if (field.category as unknown === DmpBlueprintSectionFieldCategory.SYSTEM && field.systemFieldType === DmpBlueprintSystemFieldType.FUNDER) { - hasFunder = true; - } - } - )); - if (!hasFunder) { - this.dmpFormGroup.removeControl('funder'); - } - } - - private checkForProject(blueprint: DmpBlueprintDefinition) { - let hasProject = false; - blueprint.sections.forEach(section => section.fields.forEach( - field => { - if (field.category as unknown === DmpBlueprintSectionFieldCategory.SYSTEM && field.systemFieldType === DmpBlueprintSystemFieldType.PROJECT) { - hasProject = true; - } - } - )); - if (!hasProject) { - this.dmpFormGroup.removeControl('project'); - } - } - openCloneDialog(isNewVersion: boolean) { - const dialogRef = this.dialog.open(CloneDialogComponent, { - maxWidth: '700px', - maxHeight: '80vh', - data: { - formGroup: this.dmpFormGroup, - datasets: this.dmpFormGroup.get('datasets').value, - isNewVersion: isNewVersion, - confirmButton: this.language.instant('DMP-EDITOR.CLONE-DIALOG.SAVE'), - cancelButton: this.language.instant('DMP-EDITOR.CLONE-DIALOG.CANCEL'), - } - }); + // TODO: fix this + // const dialogRef = this.dialog.open(CloneDialogComponent, { + // maxWidth: '700px', + // maxHeight: '80vh', + // data: { + // formGroup: this.dmpFormGroup, + // datasets: this.dmpFormGroup.get('datasets').value, + // isNewVersion: isNewVersion, + // confirmButton: this.language.instant('DMP-EDITOR.CLONE-DIALOG.SAVE'), + // cancelButton: this.language.instant('DMP-EDITOR.CLONE-DIALOG.CANCEL'), + // } + // }); // dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { // if (result) { // if (!isNewVersion) { @@ -291,12 +225,8 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit { // }); } - // newVersion(id: String, label: String) { - // let url = this.router.createUrlTree(['/plans/new_version/', id, { dmpLabel: label }]); - // window.open(url.toString(), '_blank'); - // } - downloadXml(id: Guid) { + // TODO: Add this // this.dmpService.downloadXML(id) // .pipe(takeUntil(this._destroyed)) // .subscribe(response => { @@ -309,6 +239,7 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit { } downloadDocx(id: Guid) { + // TODO: Add this // this.dmpService.downloadDocx(id) // .pipe(takeUntil(this._destroyed)) // .subscribe(response => { @@ -321,6 +252,7 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit { } downloadPDF(id: Guid) { + // TODO: Add this // this.dmpService.downloadPDF(id) // .pipe(takeUntil(this._destroyed)) // .subscribe(response => { @@ -333,6 +265,7 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit { } downloadJson(id: Guid) { + // TODO: Add this // this.dmpService.downloadJson(id) // .pipe(takeUntil(this._destroyed)) // .subscribe(response => { @@ -345,11 +278,11 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit { // }); } - async onExportCallbackError(error: any) { - const errorJsonText = await error.error.text(); - const errorObj = JSON.parse(errorJsonText); - this.uiNotificationService.snackBarNotification(errorObj.message, SnackBarNotificationLevel.Error); - } + // async onExportCallbackError(error: any) { + // const errorJsonText = await error.error.text(); + // const errorObj = JSON.parse(errorJsonText); + // this.uiNotificationService.snackBarNotification(errorObj.message, SnackBarNotificationLevel.Error); + // } deleteClicked(id: string) { this.lockService.checkLockStatus(id).pipe(takeUntil(this._destroyed)) diff --git a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts index 730d9992b..fd76aef2b 100644 --- a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts +++ b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts @@ -377,7 +377,7 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { if (!this.isFinalized) this.router.navigate(['/plans/edit/' + dmpId], { queryParams: { tab: "datasetDescriptions" } }); else - this.router.navigate(['/explore'], { queryParams: { dmpId: dmpId } }); + this.router.navigate(['/explore-descriptions'], { queryParams: { dmpId: dmpId } }); } goToUri(uri: string) { diff --git a/dmp-frontend/src/app/ui/grant/editor/grant-editor.component.html b/dmp-frontend/src/app/ui/grant/editor/grant-editor.component.html deleted file mode 100644 index bc971b44d..000000000 --- a/dmp-frontend/src/app/ui/grant/editor/grant-editor.component.html +++ /dev/null @@ -1,112 +0,0 @@ -
-
-
- {{'GRANT-EDITOR.TITLE.NEW' | translate}} - {{formGroup?.get('label')?.value}} -
- - -
- - - - - -
- - - - -
- File is too big! -
-
-
-
-
-
- -
-
- -
-
- -
-
-
-
-
- -
- - - {{formGroup.get('label').getError('backendError').message}} - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - - - - - {{formGroup.get('abbreviation').getError('backendError').message}} - - - - - {{formGroup.get('uri').getError('backendError').message}} - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - - - - - - - {{formGroup.get('startDate').getError('backendError').message}} - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - - - - - - - {{formGroup.get('endDate').getError('backendError').message}} - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - - {{'GENERAL.VALIDATION.GRANT-START-AFTER-END' | translate}} - - - - {{formGroup.get('description').getError('backendError').message}} - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - - -
-
-
- -
-
-
- -
-
- -
-
-
-
-
-
-
-
-
-
diff --git a/dmp-frontend/src/app/ui/grant/editor/grant-editor.component.scss b/dmp-frontend/src/app/ui/grant/editor/grant-editor.component.scss deleted file mode 100644 index b5ca3188c..000000000 --- a/dmp-frontend/src/app/ui/grant/editor/grant-editor.component.scss +++ /dev/null @@ -1,20 +0,0 @@ -.grant-editor { - - .grant-editor-header-actions { - display: flex; - align-items: center; - } - - .logo-table { - table-layout: fixed; - display: inline-block; - - td { - padding: 3px; - } - } - - .hidden { - display: none; - } -} diff --git a/dmp-frontend/src/app/ui/grant/editor/grant-editor.component.ts b/dmp-frontend/src/app/ui/grant/editor/grant-editor.component.ts deleted file mode 100644 index 5cafef539..000000000 --- a/dmp-frontend/src/app/ui/grant/editor/grant-editor.component.ts +++ /dev/null @@ -1,214 +0,0 @@ - -import { Component, OnInit } from '@angular/core'; -import { FormGroup } from '@angular/forms'; -import { MatDialog } from '@angular/material/dialog'; -import { MatSnackBar } from '@angular/material/snack-bar'; -import { ActivatedRoute, Params, Router } from '@angular/router'; -import { GrantType } from '@app/core/common/enum/grant-type'; -import { GrantListingModel } from '@app/core/model/grant/grant-listing'; -import { GrantFileUploadService } from '@app/core/services/grant/grant-file-upload.service'; -import { GrantService } from '@app/core/services/grant/grant.service'; -import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; -import { GrantEditorModel } from '@app/ui/grant/editor/grant-editor.model'; -// 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 { FormService } from '@common/forms/form-service'; -import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model'; -import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; -import { TranslateService } from '@ngx-translate/core'; -import { environment } from 'environments/environment'; -import { Observable, of as observableOf } from 'rxjs'; -import { map, takeUntil } from 'rxjs/operators'; -import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; - - -@Component({ - selector: 'app-grant-editor-component', - templateUrl: 'grant-editor.component.html', - styleUrls: ['./grant-editor.component.scss'] -}) -export class GrantEditorComponent extends BaseComponent implements OnInit { //IBreadCrumbComponent - - // breadCrumbs: Observable = observableOf([]); - isNew = true; - grant: GrantEditorModel; - formGroup: FormGroup = null; - host: string; - editMode = false; - sizeError = false; - maxFileSize: number = 1048576; - constructor( - private grantService: GrantService, - private route: ActivatedRoute, - public snackBar: MatSnackBar, - public router: Router, - public language: TranslateService, - private dialog: MatDialog, - private grantFileUploadService: GrantFileUploadService, - private uiNotificationService: UiNotificationService, - private formService: FormService, - private configurationService: ConfigurationService - ) { - super(); - this.host = this.configurationService.server; - } - - ngOnInit() { - this.route.params - .pipe(takeUntil(this._destroyed)) - .subscribe((params: Params) => { - const itemId = params['id']; - - if (itemId != null) { - this.isNew = false; - this.grantService.getSingle(itemId).pipe(map(data => data as GrantListingModel)) - .pipe(takeUntil(this._destroyed)) - .subscribe(data => { - this.grant = new GrantEditorModel().fromModel(data); - this.formGroup = this.grant.buildForm(null, this.grant.type === GrantType.External || !this.editMode); - const breadCrumbs = []; - breadCrumbs.push({ - parentComponentName: null, - label: this.language.instant('NAV-BAR.GRANTS').toUpperCase(), - url: '/grants' - }); - breadCrumbs.push({ - parentComponentName: 'GrantListingComponent', - label: this.grant.label, - url: '/grants/edit/' + this.grant.id - }); - //this.breadCrumbs = observableOf(breadCrumbs); - }); - } else { - this.language.get('QUICKWIZARD.CREATE-ADD.CREATE.QUICKWIZARD_CREATE.ACTIONS.CREATE-NEW-GRANT').pipe(takeUntil(this._destroyed)).subscribe(x => { - // this.breadCrumbs = observableOf([ - // { - // parentComponentName: null, - // label: this.language.instant('NAV-BAR.GRANTS').toUpperCase(), - // url: '/grants' - // }, - // { - // parentComponentName: 'GrantListingComponent', - // label: x, - // url: '/grants/new/' - // }] - // ); - }); - - this.grant = new GrantEditorModel(); - setTimeout(() => { - this.formGroup = this.grant.buildForm(); - }); - } - }); - } - - formSubmit(): void { - this.formService.touchAllFormFields(this.formGroup); - if (!this.isFormValid()) { return; } - this.onSubmit(); - } - - public isFormValid() { - return this.formGroup.valid; - } - - onSubmit(): void { - this.grantService.createGrant(this.formGroup.value) - .pipe(takeUntil(this._destroyed)) - .subscribe( - complete => this.onCallbackSuccess(), - error => this.onCallbackError(error) - ); - } - - onCallbackSuccess(): void { - this.uiNotificationService.snackBarNotification(this.isNew ? this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-CREATION') : this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success); - this.router.navigate(['/grants']); - } - - onCallbackError(errorResponse: any) { - this.setErrorModel(errorResponse.error.payload); - this.formService.validateAllFormFields(this.formGroup); - } - - public setErrorModel(validationErrorModel: ValidationErrorModel) { - Object.keys(validationErrorModel).forEach(item => { - (this.grant.validationErrorModel)[item] = (validationErrorModel)[item]; - }); - } - - public cancel(): void { - this.router.navigate(['/grants']); - } - - public delete(): void { - const dialogRef = this.dialog.open(ConfirmationDialogComponent, { - maxWidth: '300px', - restoreFocus: false, - data: { - 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'), - isDeleteConfirmation: true - } - }); - dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { - if (result) { - this.grantService.delete(this.grant.id) - .pipe(takeUntil(this._destroyed)) - .subscribe( - complete => { this.onCallbackSuccess() }, - error => this.onCallbackError(error) - ); - } - }); - } - - public enableForm() { - if (!this.isExternalGrant()) { - this.editMode = true; - this.formGroup.enable(); - } - } - - public disableForm() { - this.editMode = false; - this.formGroup.disable(); - } - - public imgEnable(): boolean { - if (this.isNew || this.editMode) { - return true; - } - return false; - } - - public goToGrantDmps() { - this.router.navigate(['plans/grant/' + this.grant.id], { queryParams: { grantLabel: this.grant.label } }); - } - - public isExternalGrant() { - return this.grant.type === GrantType.External; - } - - public previewImage(event): void { - const fileList: FileList | File = event.target.files; - const size: number = event.target.files[0].size; // Get file size. - this.sizeError = size > this.maxFileSize; // Checks if file size is valid. - const formdata: FormData = new FormData(); - if (!this.sizeError) { - if (fileList instanceof FileList) { - for (let i = 0; i < fileList.length; i++) { - formdata.append('file', fileList[i]); - } - } else { - formdata.append('file', fileList); - } - this.grantFileUploadService.uploadFile(formdata) - .pipe(takeUntil(this._destroyed)) - .subscribe(files => this.formGroup.get('files').patchValue(files)); - } - } -} diff --git a/dmp-frontend/src/app/ui/grant/editor/grant-editor.model.ts b/dmp-frontend/src/app/ui/grant/editor/grant-editor.model.ts deleted file mode 100644 index abc99e8d9..000000000 --- a/dmp-frontend/src/app/ui/grant/editor/grant-editor.model.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; -import { BackendErrorValidator } from '@common/forms/validation/custom-validator'; -import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model'; -import { ValidationContext } from '@common/forms/validation/validation-context'; -import { GrantType } from '../../../core/common/enum/grant-type'; -import { Status } from '../../../core/common/enum/status'; -import { ContentFile, GrantListingModel } from '../../../core/model/grant/grant-listing'; - -export class GrantEditorModel { - public id: string; - public label: string; - public abbreviation: string; - public reference: string; - public type: GrantType = GrantType.Internal; - public uri: String; - public status: Status = Status.Active; - public startDate: Date; - public endDate: Date; - public description: String; - public contentUrl: string; - public files: ContentFile[]; - public validationErrorModel: ValidationErrorModel = new ValidationErrorModel(); - - fromModel(item: GrantListingModel): GrantEditorModel { - this.id = item.id; - this.label = item.label; - this.type = item.type; - this.abbreviation = item.abbreviation; - this.reference = item.reference; - this.uri = item.uri; - this.status = item.status; - this.startDate = item.startDate ? new Date(item.startDate) : null; - this.endDate = item.endDate ? new Date(item.endDate) : null; - this.description = item.description; - this.contentUrl = item.contentUrl; - this.files = item.files; - return this; - } - - buildForm(context: ValidationContext = null, disabled: boolean = false): UntypedFormGroup { - if (context == null) { context = this.createValidationContext(); } - - const formGroup = new UntypedFormBuilder().group({ - id: [{ value: this.id, disabled: disabled }, context.getValidation('id').validators], - label: [{ value: this.label, disabled: disabled }, context.getValidation('label').validators], - abbreviation: [{ value: this.abbreviation, disabled: disabled }, context.getValidation('abbreviation').validators], - uri: [{ value: this.uri, disabled: disabled }, context.getValidation('uri').validators], - status: [{ value: this.status, disabled: disabled }, context.getValidation('status').validators], - type: [{ value: this.type, disabled: disabled }, context.getValidation('type').validators], - description: [{ value: this.description, disabled: disabled }, context.getValidation('description').validators], - startDate: [{ value: this.startDate, disabled: disabled }, context.getValidation('startDate').validators], - endDate: [{ value: this.endDate, disabled: disabled }, context.getValidation('endDate').validators], - files: [{ value: this.files, disabled: disabled }, context.getValidation('files').validators] - }, { validator: startEndValidator }); - - return formGroup; - } - - createValidationContext(): ValidationContext { - const baseContext: ValidationContext = new ValidationContext(); - baseContext.validation.push({ key: 'id', validators: [] }); - baseContext.validation.push({ key: 'label', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'label')] }); - baseContext.validation.push({ key: 'abbreviation', validators: [BackendErrorValidator(this.validationErrorModel, 'abbreviation')] }); - baseContext.validation.push({ key: 'uri', validators: [BackendErrorValidator(this.validationErrorModel, 'uri')] }); - baseContext.validation.push({ key: 'type', validators: [BackendErrorValidator(this.validationErrorModel, 'type')] }); - baseContext.validation.push({ key: 'status', validators: [] }); - baseContext.validation.push({ key: 'description', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'description')] }); - baseContext.validation.push({ key: 'startDate', validators: [BackendErrorValidator(this.validationErrorModel, 'startDate')] }); - baseContext.validation.push({ key: 'endDate', validators: [BackendErrorValidator(this.validationErrorModel, 'endDate')] }); - baseContext.validation.push({ key: 'files', validators: [BackendErrorValidator(this.validationErrorModel, 'files')] }); - - return baseContext; - } -} - -export function startEndValidator(formGroup: UntypedFormGroup) { - const start = formGroup.get('startDate').value; - const end = formGroup.get('endDate').value; - if (start != null && end != null && end < start) { - return { 'startAfterEndError': {} }; - } - return null; -} diff --git a/dmp-frontend/src/app/ui/grant/grant.module.ts b/dmp-frontend/src/app/ui/grant/grant.module.ts deleted file mode 100644 index f5f78ac2f..000000000 --- a/dmp-frontend/src/app/ui/grant/grant.module.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { NgModule } from '@angular/core'; -import { ConfirmationDialogModule } from '@common/modules/confirmation-dialog/confirmation-dialog.module'; -import { UrlListingModule } from '@app/library/url-listing/url-listing.module'; -import { GrantEditorComponent } from '@app/ui/grant/editor/grant-editor.component'; -import { GrantRoutingModule } from '@app/ui/grant/grant.routing'; -import { GrantCriteriaComponent } from '@app/ui/grant/listing/criteria/grant-criteria.component'; -import { GrantListingComponent } from '@app/ui/grant/listing/grant-listing.component'; -import { GrantListingItemComponent } from '@app/ui/grant/listing/listing-item/grant-listing-item.component'; -import { CommonFormsModule } from '@common/forms/common-forms.module'; -import { CommonUiModule } from '@common/ui/common-ui.module'; - -@NgModule({ - imports: [ - CommonUiModule, - CommonFormsModule, - UrlListingModule, - ConfirmationDialogModule, - GrantRoutingModule - ], - declarations: [ - GrantListingComponent, - GrantCriteriaComponent, - GrantEditorComponent, - GrantListingItemComponent - ] -}) -export class GrantModule { } diff --git a/dmp-frontend/src/app/ui/grant/grant.routing.ts b/dmp-frontend/src/app/ui/grant/grant.routing.ts deleted file mode 100644 index 9c715987d..000000000 --- a/dmp-frontend/src/app/ui/grant/grant.routing.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { NgModule } from '@angular/core'; -import { RouterModule, Routes } from '@angular/router'; -import { GrantEditorComponent } from './editor/grant-editor.component'; -import { GrantListingComponent } from './listing/grant-listing.component'; - -// ----------- UNCOMMENT TO ADD AGAIN GRANTS -------- -const routes: Routes = [ - // { - // path: '', - // component: GrantListingComponent, - // data: { - // breadcrumb: true - // }, - // }, - // { - // path: 'edit/:id', - // component: GrantEditorComponent, - // data: { - // breadcrumb: true, - // title: 'GENERAL.TITLES.GRANT-EDIT' - // } - // }, - // { - // path: 'new', - // component: GrantEditorComponent, - // data: { - // breadcrumb: true, - // title: 'GENERAL.TITLES.GRANT-NEW' - // }, - // } -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule] -}) -export class GrantRoutingModule { } diff --git a/dmp-frontend/src/app/ui/grant/listing/criteria/grant-criteria.component.html b/dmp-frontend/src/app/ui/grant/listing/criteria/grant-criteria.component.html deleted file mode 100644 index 526b7d5d0..000000000 --- a/dmp-frontend/src/app/ui/grant/listing/criteria/grant-criteria.component.html +++ /dev/null @@ -1,38 +0,0 @@ -
-
-
{{'CRITERIA.FILTERS'| translate}}
-
- - - - search - - - - - - {{'GENERAL.VALIDATION.GRANT-START-AFTER-END' | translate}} - - - - - - - {{'GENERAL.VALIDATION.GRANT-START-AFTER-END' | translate}} - - - - - {{ 'CRITERIA.GRANTS.TYPES.NONE' | translate}} - - - {{ 'CRITERIA.GRANTS.TYPES.ON-GOING' | translate}} - - - {{ 'CRITERIA.GRANTS.TYPES.FINISHED' | translate}} - - - -
-
-
diff --git a/dmp-frontend/src/app/ui/grant/listing/criteria/grant-criteria.component.scss b/dmp-frontend/src/app/ui/grant/listing/criteria/grant-criteria.component.scss deleted file mode 100644 index 0eebb1bea..000000000 --- a/dmp-frontend/src/app/ui/grant/listing/criteria/grant-criteria.component.scss +++ /dev/null @@ -1,130 +0,0 @@ -.dmp-criteria { - mat-form-field { - padding-bottom: 5px; - width: 100%; - } - - mat-card { - padding-bottom: 0px; - } - - .hidden { - display: none; - } - - .uploadButton { - float: right; - } -} - -.search ::ng-deep.mat-form-field-infix { - margin-left: 1em; -} - -.filter-category { - background-color: #f6f6f6; - margin: 5px 0px; -} - -.category-title { - color: black; - // color: #089dbb; - margin-top: 8px; - margin-bottom: 12px; -} - -.import { - margin: 10px; - padding: 0px; -} - -.filters { - border: 1px solid #e4e4e4; - border-radius: 5px; -} - -.filters-title { - width: 90px; - // color: #089dbb; - color: var(--primary-color-2); - background-color: white; - padding: 0px 20px; - margin-top: -10px; - margin-left: 20px; - text-transform: uppercase; -} - -.style-icon { - color: #adadad; -} - -// ::ng-deep .mat-checkbox-inner-container { -// background: white; -// } - -// ::ng-deep .mat-focused .mat-form-field-label { -// color: var(--primary-color-3) !important; -// } - -// ::ng-deep.mat-form-field-underline { -// background-color: #adadad; -// } - -// ::ng-deep.mat-form-field-ripple { -// background-color: var(--primary-color-3) !important; -// } - -::ng-deep .mat-checkbox { - background-color: #f6f6f6 !important; -} - -::ng-deep .mat-checkbox .mat-checkbox-frame { - border: 1px solid #aaaaaa; -} - -::ng-deep .mat-checkbox-checked.mat-accent .mat-checkbox-background, -.mat-checkbox-indeterminate.mat-accent .mat-checkbox-background, -.mat-accent .mat-pseudo-checkbox-checked, -.mat-accent .mat-pseudo-checkbox-indeterminate, -.mat-pseudo-checkbox-checked, -.mat-pseudo-checkbox-indeterminate { - background-color: var(--primary-color-3); -} - -::ng-deep .mat-ripple-element { - background-color: #2e74b649 !important; -} - -::ng-deep .mat-radio-container { - border-radius: 1em; - background: white; -} - -::ng-deep .mat-radio-button .mat-radio-outer-circle { - border: 1px solid #aaaaaa; -} - -::ng-deep .mat-radio-button.mat-accent.mat-radio-checked .mat-radio-outer-circle { - border-color: #777777; - // border-color: var(--primary-color-3); -} - -::ng-deep .mat-radio-button.mat-accent .mat-radio-inner-circle { - color: #777777; - background-color: #777777; - // color: var(--primary-color-3); - // background-color: var(--primary-color-3); -} - -.mat-radio-button.mat-accent .mat-radio-ripple .mat-ripple-element { - background-color: #2e74b649; -} - -::ng-deep .search-form .mat-form-field-wrapper { - background-color: white !important; - padding-bottom: 0 !important; -} - -::ng-deep .mat-form-field-appearance-outline .mat-form-field-infix { - padding: 0.3rem 0rem 0.6rem 0rem !important; -} diff --git a/dmp-frontend/src/app/ui/grant/listing/criteria/grant-criteria.component.ts b/dmp-frontend/src/app/ui/grant/listing/criteria/grant-criteria.component.ts deleted file mode 100644 index ac6c14130..000000000 --- a/dmp-frontend/src/app/ui/grant/listing/criteria/grant-criteria.component.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { FormBuilder, FormControl, FormGroupDirective, NgForm } from '@angular/forms'; -import { ErrorStateMatcher } from '@angular/material/core'; -import { GrantStateType } from '@app/core/common/enum/grant-state-type'; -import { GrantCriteria } from '@app/core/query/grant/grant-criteria'; -import { BaseCriteriaComponent } from '@app/ui/misc/criteria/base-criteria.component'; -import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model'; -import { TranslateService } from '@ngx-translate/core'; - -@Component({ - selector: 'app-grant-criteria-component', - templateUrl: './grant-criteria.component.html', - styleUrls: ['./grant-criteria.component.scss'] -}) -export class GrantCriteriaComponent extends BaseCriteriaComponent implements OnInit, ErrorStateMatcher { - - public GrantStateType = GrantStateType; - public criteria: GrantCriteria = new GrantCriteria(); - - constructor( - public language: TranslateService, - public formBuilder: FormBuilder - ) { - super(new ValidationErrorModel()); - } - - ngOnInit() { - super.ngOnInit(); - if (this.criteria == null) { - this.criteria = new GrantCriteria(); - this.criteria.grantStateType = GrantStateType.OnGoing; - } - } - - setCriteria(criteria: GrantCriteria): void { - this.criteria = criteria; - } - - onCallbackError(error: any) { - this.setErrorModel(error.error); - } - - controlModified(): void { - this.clearErrorModel(); - if (this.refreshCallback != null && - (this.criteria.like == null || this.criteria.like.length === 0 || this.criteria.like.length > 2) - ) { - setTimeout(() => this.refreshCallback(true)); - } - } - - isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean { - const isSubmitted = form && form.submitted; - const isDateInvalid = this.criteria.periodStart != null && this.criteria.periodEnd != null && this.criteria.periodStart > this.criteria.periodEnd - return !!(control && isDateInvalid && (control.dirty || control.touched || isSubmitted)); - } -} diff --git a/dmp-frontend/src/app/ui/grant/listing/grant-listing.component.html b/dmp-frontend/src/app/ui/grant/listing/grant-listing.component.html deleted file mode 100644 index 5090b1016..000000000 --- a/dmp-frontend/src/app/ui/grant/listing/grant-listing.component.html +++ /dev/null @@ -1,85 +0,0 @@ -
-
-
-
-
-

{{'GRANT-LISTING.TITLE' | translate}}

- -
-
- -
-
-
-
-
- -
-
-
- -
- -
-
-
-
-
-
- diff --git a/dmp-frontend/src/app/ui/grant/listing/grant-listing.component.scss b/dmp-frontend/src/app/ui/grant/listing/grant-listing.component.scss deleted file mode 100644 index 1d4bd5726..000000000 --- a/dmp-frontend/src/app/ui/grant/listing/grant-listing.component.scss +++ /dev/null @@ -1,45 +0,0 @@ -.grant-listing { - .mat-card { - margin: 1em 0; - } - - .col-9 { - display: flex; - flex-direction: column; - } - } - -// ::ng-deep .mat-paginator { -// margin-top: auto; -// } - - ::ng-deep .mat-paginator-container { - flex-direction: row-reverse !important; - justify-content: space-between !important; - background-color: #f6f6f6; - height: 30px; - min-height: 30px !important; - } - - ::ng-deep .mat-paginator-page-size { - height: 43px; - } - - ::ng-deep .mat-icon-button { - height: 30px !important; - font-size: 12px !important; - } - - ::ng-deep .mat-paginator-range-label { - margin: 15px 32px 0 24px !important; - } - - ::ng-deep .mat-paginator-range-actions { - width: 55% !important; - min-height: 43px !important; - justify-content: space-between; - } - - ::ng-deep .mat-paginator-navigation-previous { - margin-left: auto !important; - } diff --git a/dmp-frontend/src/app/ui/grant/listing/grant-listing.component.ts b/dmp-frontend/src/app/ui/grant/listing/grant-listing.component.ts deleted file mode 100644 index d7a46710c..000000000 --- a/dmp-frontend/src/app/ui/grant/listing/grant-listing.component.ts +++ /dev/null @@ -1,85 +0,0 @@ - -import { Component, OnInit, ViewChild } from '@angular/core'; -import { MatPaginator } from '@angular/material/paginator'; -import { MatSort } from '@angular/material/sort'; -import { ActivatedRoute, Router } from '@angular/router'; -import { DataTableRequest } from '@app/core/model/data-table/data-table-request'; -import { GrantListingModel } from '@app/core/model/grant/grant-listing'; -import { GrantCriteria } from '@app/core/query/grant/grant-criteria'; -import { GrantService } from '@app/core/services/grant/grant.service'; -import { GrantCriteriaComponent } from '@app/ui/grant/listing/criteria/grant-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 { takeUntil } from 'rxjs/operators'; - -@Component({ - selector: 'app-grant-listing-component', - templateUrl: 'grant-listing.component.html', - styleUrls: ['./grant-listing.component.scss'] -}) -export class GrantListingComponent extends BaseComponent implements OnInit { //IBreadCrumbComponent - - @ViewChild(MatPaginator, { static: true }) _paginator: MatPaginator; - @ViewChild(MatSort, { static: false }) sort: MatSort; - @ViewChild(GrantCriteriaComponent, { static: true }) criteria: GrantCriteriaComponent; - - // breadCrumbs: Observable; - totalCount: number; - listingItems: GrantListingModel[] = []; - - constructor( - private grantService: GrantService, - private router: Router, - private route: ActivatedRoute, - public language: TranslateService - ) { - super(); - } - - ngOnInit() { - - 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.GRANTS').toUpperCase(), - // url: '/grants' - // }]); - - } - - 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(); - if (this.sort && 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; - this.grantService.getPaged(request, "listing").pipe(takeUntil(this._destroyed)).subscribe(result => { - if (!result) { return []; } - if (this._paginator.pageIndex === 0) { this.totalCount = result.totalCount; } - this.listingItems = result.data; - }); - } - - rowClicked(grant: GrantListingModel) { - this.router.navigate(['/grants/edit/' + grant.id]); - } - - getDefaultCriteria(): GrantCriteria { - const defaultCriteria = new GrantCriteria(); - return defaultCriteria; - } - - pageThisEvent(event) { - this.refresh(); - } -} - - diff --git a/dmp-frontend/src/app/ui/grant/listing/listing-item/grant-listing-item.component.html b/dmp-frontend/src/app/ui/grant/listing/listing-item/grant-listing-item.component.html deleted file mode 100644 index dbccdb070..000000000 --- a/dmp-frontend/src/app/ui/grant/listing/listing-item/grant-listing-item.component.html +++ /dev/null @@ -1,50 +0,0 @@ -
-
-
-
-

{{grant.abbreviation}}

-
-
-
-
- lock -

{{grant.label}}

-
-
-
-
-

{{grant.description}}

-
-
-
-
- calendar_today -

{{grant.startDate | date:'shortDate'}} - {{grant.endDate | date:'shortDate'}}

-
-
-
- -
- - - - diff --git a/dmp-frontend/src/app/ui/grant/listing/listing-item/grant-listing-item.component.scss b/dmp-frontend/src/app/ui/grant/listing/listing-item/grant-listing-item.component.scss deleted file mode 100644 index 68aa16d20..000000000 --- a/dmp-frontend/src/app/ui/grant/listing/listing-item/grant-listing-item.component.scss +++ /dev/null @@ -1,42 +0,0 @@ -.gray-container { - letter-spacing: 5px; - color: #aaaaaa; -} - -.container-header { - display: flex; - align-items: baseline; - margin-top: 0px; - text-transform: uppercase; -} - -.container-header p { - letter-spacing: 5px; - color: #aaaaaa; - margin-bottom: 0px; -} - -.about-item { - display: flex; - flex-wrap: wrap; -} - -.about-item .title { - margin: 2px 10px; -} - -.about-item p { - margin-left: auto; - margin-bottom: 0px; - padding-top: 7px; - color: #aaaaaa; -} - -.draft-icon { - color: #aaaaaa; -} - -.more-horiz { - font-size: 28px; - color: #aaaaaa; -} diff --git a/dmp-frontend/src/app/ui/grant/listing/listing-item/grant-listing-item.component.ts b/dmp-frontend/src/app/ui/grant/listing/listing-item/grant-listing-item.component.ts deleted file mode 100644 index 275013dc6..000000000 --- a/dmp-frontend/src/app/ui/grant/listing/listing-item/grant-listing-item.component.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; -import { GrantListingModel } from '../../../../core/model/grant/grant-listing'; - -@Component({ - selector: 'app-grant-listing-item-component', - templateUrl: './grant-listing-item.component.html', - styleUrls: ['./grant-listing-item.component.scss'], -}) -export class GrantListingItemComponent implements OnInit { - - @Input() grant: GrantListingModel; - @Input() showDivider: boolean = true; - @Output() onClick: EventEmitter = new EventEmitter(); - - constructor( - - ) { - } - - ngOnInit() { - } - - itemClicked() { - this.onClick.emit(this.grant); - } -} diff --git a/dmp-frontend/src/app/ui/quick-wizard/quick-wizard.module.ts b/dmp-frontend/src/app/ui/quick-wizard/quick-wizard.module.ts index eda54f35c..0811a1e48 100644 --- a/dmp-frontend/src/app/ui/quick-wizard/quick-wizard.module.ts +++ b/dmp-frontend/src/app/ui/quick-wizard/quick-wizard.module.ts @@ -26,7 +26,7 @@ import { AngularStickyThingsModule } from '@w11k/angular-sticky-things'; ConfirmationDialogModule, QuickWizardRoutingModule, DatasetDescriptionFormModule, - DmpModule, + // DmpModule, TableOfContentsModule, AngularStickyThingsModule ], diff --git a/dmp-frontend/src/app/ui/sidebar/sidebar.component.ts b/dmp-frontend/src/app/ui/sidebar/sidebar.component.ts index 802dd33a7..554cf7617 100644 --- a/dmp-frontend/src/app/ui/sidebar/sidebar.component.ts +++ b/dmp-frontend/src/app/ui/sidebar/sidebar.component.ts @@ -36,13 +36,13 @@ export const DMP_ROUTES: RouteInfo[] = [ ]; export const DATASETS_ROUTES: RouteInfo[] = [ { path: '/explore-plans', title: 'SIDE-BAR.PUBLIC-DMPS', icon: 'library_books' }, - { path: '/explore', title: 'SIDE-BAR.PUBLIC-DESC', icon: 'dns' }, + { path: '/explore-descriptions', title: 'SIDE-BAR.PUBLIC-DESC', icon: 'dns' }, // { path: '/datasetcreatewizard', title: 'SIDE-BAR.QUICK-WIZARD-DATASET', icon: "play_circle_outline" }, ]; export const PUBLIC_ROUTES: RouteInfo[] = [ { path: '/explore-plans', title: 'SIDE-BAR.PUBLIC-DMPS', icon: 'library_books' }, - { path: '/explore', title: 'SIDE-BAR.PUBLIC-DESC', icon: 'dns' } + { path: '/explore-descriptions', title: 'SIDE-BAR.PUBLIC-DESC', icon: 'dns' } ]; // export const GRANTS_ROUTES: RouteInfo[] = [ diff --git a/dmp-frontend/src/app/utilities/enhancers/utils.ts b/dmp-frontend/src/app/utilities/enhancers/utils.ts index a89763a19..fb6af1735 100644 --- a/dmp-frontend/src/app/utilities/enhancers/utils.ts +++ b/dmp-frontend/src/app/utilities/enhancers/utils.ts @@ -1,4 +1,4 @@ -import {AbstractControl, UntypedFormArray, UntypedFormControl, UntypedFormGroup} from "@angular/forms"; +import { AbstractControl, UntypedFormArray, UntypedFormControl, UntypedFormGroup } from "@angular/forms"; export function isNullOrUndefined(object: any): boolean { return object === null || object === undefined; @@ -40,7 +40,13 @@ export function cloneAbstractControl(control: T): T { throw new Error('Error: unexpected control value'); } - if (control.disabled) newControl.disable({emitEvent: false}); + if (control.disabled) newControl.disable({ emitEvent: false }); return newControl; } + +Object.defineProperty(Array.prototype, 'firstSafe', { + value() { + return this.find(e => true) // or this.find(Boolean) + } +}) \ No newline at end of file diff --git a/dmp-frontend/src/assets/i18n/en.json b/dmp-frontend/src/assets/i18n/en.json index 98651e7a0..c68ea0950 100644 --- a/dmp-frontend/src/assets/i18n/en.json +++ b/dmp-frontend/src/assets/i18n/en.json @@ -913,13 +913,41 @@ "MESSAGE": "Add dataset." } }, - "DATASET-OVERVIEW": { + "DESCRIPTION-OVERVIEW": { + "TITLE": "Description", + "PUBLIC": "Public", + "LOCKED": "Locked", + "EDITED": "Edited", + "FINALISED": "Finalized", + "PART-OF": "Part of", + "GRANT": "Grant", + "RESEARCHERS": "Researchers", + "DESCRIPTION": "Description", "DESCRIPTION-AUTHORS": "Description authors", + "YOU": "you", "ERROR": { "DELETED-DATASET": "The requested dataset is deleted", "FORBIDEN-DATASET": "You are not allowed to access this dataset" }, - "LOCKED": { + "ACTIONS": { + "BACK":"Back", + "EDIT":"Edit", + "CLONE":"Clone", + "DELETE":"Delete", + "FINALIZE":"Finalize", + "REVERSE":"Undo Finalization", + "EXPORT":"Export", + "INVITE-SHORT": "Invite" + }, + "COPY-DIALOG": { + "COPY": "Copy", + "CANCEL": "Cancel" + }, + "UNDO-FINALIZATION-DIALOG": { + "CONFIRM": "Yes", + "NEGATIVE": "No" + }, + "LOCKED-DIALOG": { "TITLE": "Dataset is locked", "MESSAGE": "Somebody else is modifying the dataset at this moment. If you would like to modify or view it, please come back later." }, @@ -929,42 +957,24 @@ "CANCEL": "Cancel" } }, - "DATASET-LISTING": { - "TITLE": "Datasets", - "DESCRIPTION": "Description", - "SELECT-DESCRIPTIONS-TO-CLONE": "Select which descriptions to include in the new DMP. Selected descriptions will be editable.", - "SELECT-DESCRIPTIONS-NONE": "Not available Descriptions for this DMP.", + "DESCRIPTION-LISTING": { + "TITLE": "My Descriptions", + "TITLE-EXPLORE": "Published Descriptions", "TEXT-INFO": "Datasets are documented following pre-defined templates which set the content of dataset descriptions. In {{ APP_NAME }}, a DMP can contain as many dataset descriptions as the datasets it documents. Browse ", "TEXT-INFO-REST": " for a look at datasets described in {{ APP_NAME }} DMPs", "LINK-PUBLIC-DATASETS": "Public Datasets", "TEXT-INFO-PAR": "New datasets can be added to existing DMPs at any time and be described with more than one template. Datasets can also be cloned and re-used in other DMPs as well as be deleted without negatively affecting the DMP as a whole.", - "COLUMNS": { - "NAME": "Name", - "REFERNCE": "Reference", - "GRANT": "Grant", - "URI": "Uri", - "STATUS": "Status", - "DESCRIPTION": "Description", - "CREATED": "Created", - "PUBLISHED": "Published", - "FINALIZED": "Finalized", - "LAST-EDITED": "Last Edited", - "ACTIONS": "Actions", - "DMP": "DMP", - "PROFILE": "Template", - "DATAREPOSITORIES": "Data Repositories", - "REGISTRIES": "Registries", - "SERVICES": "Services" - }, + "DESCRIPTION": "Description", + "GRANT":"Grant", + "LOCKED": "Dataset is Locked by another user", "ACTIONS": { - "EDIT": "Edit", - "MAKE-IT-PUBLIC": "Make it public", - "VIEW": "View", - "NEW": "New Dataset", - "CREATE-NEW": "Create new Dataset", + "ADD-DESCRIPTION": "Add Description", + "TAKE-A-TOUR": "Do you need help? Take a tour..", + "LOAD-MORE": "Load more", "EXPORT": "Export", - "INVITE-COLLABORATORS": "Invite collaborators", - "INVITE-SHORT": "Invite" + "INVITE-SHORT": "Invite", + "DELETE": "Delete", + "COPY-DESCRIPTION": "Copy Description" }, "STATES": { "EDITED": "Edited", @@ -972,19 +982,12 @@ "FINALIZED": "Finalized", "PUBLISHED": "Published" }, - "TOOLTIP": { - "DATASET-STATUS": { - "DRAFT": "Private access - Editable Dataset", - "FINALIZED": "Private access - Closed Dataset" - }, - "DMP": "DMP", - "GRANT": "Grant", - "TEMPLATES-INVOLVED": "Dataset Template", - "VERSION": "DMP Version", - "PART-OF": "Part of", - "TO-DMP": "To DMP", - "DMP-FOR": "DMP for" + "COPY-DIALOG": { + "COPY": "Copy", + "CANCEL": "Cancel" }, + "PART-OF": "Part of", + "DMP": "DMP", "EMPTY-LIST": "Nothing here yet." }, "DATASET-PUBLIC-LISTING": { @@ -1834,10 +1837,9 @@ "FINALISED": "Finalized", "CANCELED": "Canceled" }, - "DATASET-ROLE": { + "DMP-USER-ROLE": { "OWNER": "Owner", - "MEMBER": "Member", - "ANY": "Any" + "USER": "User" }, "EXTERNAL-DATASET-TYPE": { "SOURCE": "Source",