Merge remote-tracking branch 'origin/dmp-refactoring' into dmp-refactoring
This commit is contained in:
commit
805702459f
|
@ -0,0 +1,72 @@
|
|||
package eu.eudat.model.persist;
|
||||
|
||||
import eu.eudat.commons.validation.BaseValidator;
|
||||
import eu.eudat.convention.ConventionService;
|
||||
import eu.eudat.errorcode.ErrorThesaurusProperties;
|
||||
import gr.cite.tools.validation.specification.Specification;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class UpdateDescriptionTemplatePersist {
|
||||
|
||||
private UUID id;
|
||||
|
||||
public static final String _id = "id";
|
||||
|
||||
public UUID getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(UUID id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
private UUID descriptionTemplateGroupId;
|
||||
|
||||
public static final String _descriptionTemplateGroupId = "descriptionTemplateGroupId";
|
||||
|
||||
public UUID getDescriptionTemplateGroupId() {
|
||||
return descriptionTemplateGroupId;
|
||||
}
|
||||
|
||||
public void setDescriptionTemplateGroupId(UUID descriptionTemplateGroupId) {
|
||||
this.descriptionTemplateGroupId = descriptionTemplateGroupId;
|
||||
}
|
||||
|
||||
@Component(UpdateDescriptionTemplatePersistValidator.ValidatorName)
|
||||
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
public static class UpdateDescriptionTemplatePersistValidator extends BaseValidator<UpdateDescriptionTemplatePersist> {
|
||||
|
||||
public static final String ValidatorName = "UpdateDescriptionTemplatePersistValidator";
|
||||
|
||||
private final MessageSource messageSource;
|
||||
|
||||
protected UpdateDescriptionTemplatePersistValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource) {
|
||||
super(conventionService, errors);
|
||||
this.messageSource = messageSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<UpdateDescriptionTemplatePersist> modelClass() {
|
||||
return UpdateDescriptionTemplatePersist.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<Specification> specifications(UpdateDescriptionTemplatePersist item) {
|
||||
return Arrays.asList(
|
||||
this.spec()
|
||||
.must(() -> this.isValidGuid(item.getId()))
|
||||
.failOn(UpdateDescriptionTemplatePersist._id)
|
||||
.failWith(messageSource.getMessage("Validation_Required", new Object[]{UpdateDescriptionTemplatePersist._id}, LocaleContextHolder.getLocale()))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -18,6 +18,7 @@ import eu.eudat.model.censorship.DescriptionCensor;
|
|||
import eu.eudat.model.censorship.PublicDescriptionCensor;
|
||||
import eu.eudat.model.persist.DescriptionPersist;
|
||||
import eu.eudat.model.persist.DescriptionStatusPersist;
|
||||
import eu.eudat.model.persist.UpdateDescriptionTemplatePersist;
|
||||
import eu.eudat.model.result.QueryResult;
|
||||
import eu.eudat.query.DescriptionQuery;
|
||||
import eu.eudat.query.DmpQuery;
|
||||
|
@ -267,4 +268,15 @@ public class DescriptionController {
|
|||
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + storageFile.getName() + (storageFile.getExtension().startsWith(".") ? "" : ".") + storageFile.getExtension() + "\"")
|
||||
.body(new ByteArrayResource(file));
|
||||
}
|
||||
|
||||
@PostMapping("update-description-template")
|
||||
// @Transactional
|
||||
@ValidationFilterAnnotation(validator = UpdateDescriptionTemplatePersist.UpdateDescriptionTemplatePersistValidator.ValidatorName, argumentName = "model")
|
||||
public Boolean updateDescriptionTemplate(@RequestBody UpdateDescriptionTemplatePersist model) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException, IOException {
|
||||
logger.debug(new MapLogEntry("persisting" + Description.class.getSimpleName()).And("model", model));
|
||||
|
||||
// TODO
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -149,3 +149,8 @@ export interface DescriptionSectionPermissionResolver {
|
|||
sectionIds: Guid[];
|
||||
permissions: string[];
|
||||
}
|
||||
|
||||
export interface UpdateDescriptionTemplatePersist {
|
||||
id: Guid;
|
||||
descriptionTemplateGroupId: Guid;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { HttpClient, HttpHeaders, HttpParamsOptions, HttpResponse } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { IsActive } from '@app/core/common/enum/is-active.enum';
|
||||
import { Description, DescriptionPersist, DescriptionSectionPermissionResolver, DescriptionStatusPersist, PublicDescription } from '@app/core/model/description/description';
|
||||
import { Description, DescriptionPersist, DescriptionSectionPermissionResolver, DescriptionStatusPersist, PublicDescription, UpdateDescriptionTemplatePersist } from '@app/core/model/description/description';
|
||||
import { DescriptionLookup } from '@app/core/query/description.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';
|
||||
|
@ -114,6 +114,13 @@ export class DescriptionService {
|
|||
return this.httpClient.get(`${this.apiBase}/${id}/export/${format}`, { responseType: 'blob', observe: 'response', headers: this.headers });
|
||||
}
|
||||
|
||||
public updateDescriptionTemplate(item: UpdateDescriptionTemplatePersist): Observable<boolean> {
|
||||
const url = `${this.apiBase}/update-description-template`;
|
||||
|
||||
return this.http.post<boolean>(url, item).pipe(
|
||||
catchError((error: any) => throwError(error)));
|
||||
}
|
||||
|
||||
//
|
||||
// Autocomplete Commons
|
||||
//
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<div class="confirmation-dialog">
|
||||
<div class="row d-flex">
|
||||
<div class="container-fluid">
|
||||
<div class="row d-flex mt-2">
|
||||
<div class="confirmation-message col-auto align-self-center">
|
||||
<h4>{{ data.message }}</h4>
|
||||
</div>
|
||||
|
@ -7,35 +7,38 @@
|
|||
<mat-icon class="close-btn" (click)="cancel()">close</mat-icon>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<ngx-dropzone class="drop-file" (change)="selectXML($event)" [accept]="'text/xml'" [multiple]="false">
|
||||
<ngx-dropzone-preview class="file-preview" [removable]="true" *ngIf="hasBlueprint()" (removed)="onRemove()">
|
||||
<ngx-dropzone-label class="file-label">{{ selectedFileName }}</ngx-dropzone-label>
|
||||
</ngx-dropzone-preview>
|
||||
</ngx-dropzone>
|
||||
<mat-dialog-content>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<ngx-dropzone class="drop-file" (change)="selectXML($event)" [accept]="'text/xml'" [multiple]="false">
|
||||
<ngx-dropzone-preview class="file-preview" [removable]="true" *ngIf="hasBlueprint()" (removed)="onRemove()">
|
||||
<ngx-dropzone-label class="file-label">{{ selectedFileName }}</ngx-dropzone-label>
|
||||
</ngx-dropzone-preview>
|
||||
</ngx-dropzone>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12 d-flex justify-content-center attach-btn">
|
||||
<button mat-button type="button" class="col-auto attach-file" (click)="imgFileInput.click()">
|
||||
<mat-icon class="mr-2">input</mat-icon>
|
||||
<span *ngIf="!hasBlueprint()">{{'GENERAL.START-NEW-DMP-DIALOG.UPLOAD-FILE' | translate}}</span>
|
||||
<span *ngIf="hasBlueprint()">{{'GENERAL.START-NEW-DMP-DIALOG.REPLACE-FILE' | translate}}</span>
|
||||
</button>
|
||||
<input class="hidden" type="file" #imgFileInput (change)="selectXML($event)" accept="text/xml" />
|
||||
<div class="row">
|
||||
<div class="col-12 d-flex justify-content-center attach-btn">
|
||||
<button mat-button type="button" class="col-auto attach-file" (click)="imgFileInput.click()">
|
||||
<mat-icon class="mr-2">input</mat-icon>
|
||||
<span *ngIf="!hasBlueprint()">{{'GENERAL.START-NEW-DMP-DIALOG.UPLOAD-FILE' | translate}}</span>
|
||||
<span *ngIf="hasBlueprint()">{{'GENERAL.START-NEW-DMP-DIALOG.REPLACE-FILE' | translate}}</span>
|
||||
</button>
|
||||
<input class="hidden" type="file" #imgFileInput (change)="selectXML($event)" accept="text/xml" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<mat-form-field class="col-12">
|
||||
<input matInput placeholder="{{'DMP-BLUEPRINT-LISTING.IMPORT.UPLOAD-XML-NAME'| translate}}" name="datasetBlueprintName" [(ngModel)]="data.name">
|
||||
</mat-form-field>
|
||||
<div class="col-auto">
|
||||
<button mat-button type="button" class="cancel-btn" (click)="cancel()">{{ data.cancelButton }}</button>
|
||||
<div class="row">
|
||||
<mat-form-field class="col-12">
|
||||
<input matInput placeholder="{{'DMP-BLUEPRINT-LISTING.IMPORT.UPLOAD-XML-NAME'| translate}}" name="datasetBlueprintName" [(ngModel)]="data.name">
|
||||
</mat-form-field>
|
||||
<div class="col-auto">
|
||||
<button mat-button type="button" class="cancel-btn" (click)="cancel()">{{ data.cancelButton }}</button>
|
||||
</div>
|
||||
<div class="col"></div>
|
||||
<div class="col-auto">
|
||||
<button mat-button color="primary" class="next-btn" type="button" (click)="confirm()" [disabled]="!hasBlueprint()">{{ data.confirmButton }}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col"></div>
|
||||
<div class="col-auto">
|
||||
<button mat-button color="primary" class="next-btn" type="button" (click)="confirm()" [disabled]="!hasBlueprint()">{{ data.confirmButton }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</mat-dialog-content>
|
||||
|
||||
</div>
|
||||
|
|
|
@ -50,8 +50,10 @@
|
|||
<mat-form-field class="w-100">
|
||||
<mat-select placeholder="{{'DESCRIPTION-EDITOR.BASE-INFO.FIELDS.DESCRIPTION-TEMPLATE-PLACEHOLDER'| translate}}" [required]="true" [compareWith]="compareWith" [formControl]="formGroup.get('descriptionTemplateId')">
|
||||
<mat-option *ngFor="let descriptionTemplate of availableDescriptionTemplates" [value]="descriptionTemplate.id" class="multiline-mat-option">
|
||||
<div>{{descriptionTemplate.label}}</div>
|
||||
<div>{{'DESCRIPTION-EDITOR.BASE-INFO.FIELDS.DESCRIPTION-TEMPLATE-VERSION'| translate}} {{descriptionTemplate.version}}</div>
|
||||
<div>
|
||||
<span>{{descriptionTemplate.label}}, </span>
|
||||
<span>{{'DESCRIPTION-EDITOR.BASE-INFO.FIELDS.DESCRIPTION-TEMPLATE-VERSION'| translate}} {{descriptionTemplate.version}}</span>
|
||||
</div>
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-error *ngIf="formGroup.get('descriptionTemplateId').hasError('backendError')">{{formGroup.get('descriptionTemplateId').getError('backendError').message}}</mat-error>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { Component, Input } from '@angular/core';
|
||||
import { UntypedFormGroup } from '@angular/forms';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { IsActive } from '@app/core/common/enum/is-active.enum';
|
||||
import { DescriptionTemplate } from '@app/core/model/description-template/description-template';
|
||||
import { Description } from '@app/core/model/description/description';
|
||||
|
@ -10,6 +11,7 @@ import { DescriptionService } from '@app/core/services/description/description.s
|
|||
import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service';
|
||||
import { BaseComponent } from '@common/base/base.component';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { DeprecatedDescriptionTemplateDialog } from './dialog-description-template/deprecated-description-template-dialog.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-description-base-fields-editor-component',
|
||||
|
@ -23,20 +25,55 @@ export class DescriptionBaseFieldsEditorComponent extends BaseComponent {
|
|||
availableDescriptionTemplates: DescriptionTemplate[] = [];
|
||||
viewOnly = false; //TODO: not used.
|
||||
|
||||
constructor(
|
||||
) { super(); }
|
||||
constructor(private dialog: MatDialog,
|
||||
private descriptionService: DescriptionService) {
|
||||
super();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
const dmpDescriptionTemplates: DmpDescriptionTemplate[] = this.description.dmp.dmpDescriptionTemplates.filter(x => x.sectionId == this.description.dmpDescriptionTemplate.sectionId && x.isActive == IsActive.Active);
|
||||
const currentVersionsOfDescriptionTemplates = dmpDescriptionTemplates.map(x => x.currentDescriptionTemplate);
|
||||
//Check if the used tempalte in included in the current list. If not add it.
|
||||
if (this.description.descriptionTemplate && currentVersionsOfDescriptionTemplates.find(x => x.id == this.description?.descriptionTemplate?.id) == null) {
|
||||
this.availableDescriptionTemplates.push(this.description.descriptionTemplate)
|
||||
}
|
||||
this.availableDescriptionTemplates.push(...currentVersionsOfDescriptionTemplates);
|
||||
this.loadDescriptionTemplates();
|
||||
}
|
||||
|
||||
public compareWith(object1: any, object2: any) {
|
||||
return object1 && object2 && object1.id === object2.id;
|
||||
}
|
||||
|
||||
private loadDescriptionTemplates(): void {
|
||||
const dmpDescriptionTemplates: DmpDescriptionTemplate[] = this.description.dmp.dmpDescriptionTemplates.filter(x => x.sectionId == this.description.dmpDescriptionTemplate.sectionId && x.isActive == IsActive.Active);
|
||||
const currentVersionsOfDescriptionTemplates = dmpDescriptionTemplates.map(x => x.currentDescriptionTemplate);
|
||||
if (this.description.descriptionTemplate && currentVersionsOfDescriptionTemplates.find(x => x.id == this.description?.descriptionTemplate?.id) == null) {
|
||||
if (this.description.status === 0) {
|
||||
this.openDeprecatedDescriptionTemplateDialog();
|
||||
} else {
|
||||
this.availableDescriptionTemplates.push(this.description.descriptionTemplate);
|
||||
}
|
||||
}
|
||||
this.availableDescriptionTemplates.push(...currentVersionsOfDescriptionTemplates);
|
||||
}
|
||||
|
||||
private openDeprecatedDescriptionTemplateDialog(): void {
|
||||
const dialogRef = this.dialog.open(DeprecatedDescriptionTemplateDialog, {
|
||||
data: {
|
||||
label: this.description.descriptionTemplate.label
|
||||
}
|
||||
});
|
||||
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(
|
||||
result => {
|
||||
if(result) {
|
||||
this.descriptionService.updateDescriptionTemplate({
|
||||
id: this.description.id,
|
||||
descriptionTemplateGroupId: this.description.descriptionTemplate.groupId
|
||||
})
|
||||
.subscribe(
|
||||
result => {
|
||||
if (result) {
|
||||
this.loadDescriptionTemplates();
|
||||
}
|
||||
},
|
||||
error => console.error(error));
|
||||
} else {
|
||||
this.availableDescriptionTemplates.push(this.description.descriptionTemplate);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
<div class="container-fluid">
|
||||
<div class="row d-flex mt-2">
|
||||
<div class="col-auto align-self-center">
|
||||
<h4> {{ 'DESCRIPTION-EDITOR.DEPRECATED-DESCRIPTION-TEMPLATE.TITLE' | translate}} {{ data.label }}</h4>
|
||||
</div>
|
||||
<div class="col-auto ml-auto">
|
||||
<mat-icon class="close-btn" (click)="cancel()">close</mat-icon>
|
||||
</div>
|
||||
</div>
|
||||
<mat-dialog-content>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<span>{{ 'DESCRIPTION-EDITOR.DEPRECATED-DESCRIPTION-TEMPLATE.MESSAGE' | translate}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-2">
|
||||
<div class="col-auto">
|
||||
<button type="button" class="default-btn" (click)="cancel()"><span>{{ 'DESCRIPTION-EDITOR.DEPRECATED-DESCRIPTION-TEMPLATE.ACTIONS.CANCEL' | translate}}</span></button>
|
||||
</div>
|
||||
<div class="col"></div>
|
||||
<div class="col-auto">
|
||||
<button type="button" class="normal-btn" (click)="update()"><span>{{ 'DESCRIPTION-EDITOR.DEPRECATED-DESCRIPTION-TEMPLATE.ACTIONS.UPDATE' | translate}}</span></button>
|
||||
</div>
|
||||
</div>
|
||||
</mat-dialog-content>
|
||||
</div>
|
|
@ -0,0 +1,4 @@
|
|||
|
||||
.close-btn:hover{
|
||||
cursor: pointer;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
import { Component, Inject, OnInit } from "@angular/core";
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from "@angular/material/dialog";
|
||||
|
||||
@Component({
|
||||
selector: 'app-deprecated-description-template-dialog',
|
||||
templateUrl: 'deprecated-description-template-dialog.component.html',
|
||||
styleUrls: ['deprecated-description-template-dialog.component.scss']
|
||||
})
|
||||
export class DeprecatedDescriptionTemplateDialog implements OnInit {
|
||||
constructor(
|
||||
public dialogRef: MatDialogRef<DeprecatedDescriptionTemplateDialog>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: any
|
||||
) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
cancel(): void {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
|
||||
update(): void {
|
||||
this.dialogRef.close(true);
|
||||
}
|
||||
}
|
|
@ -14,6 +14,7 @@ import { RichTextEditorModule } from '@app/library/rich-text-editor/rich-text-ed
|
|||
import { TagsFieldModule } from '@app/ui/tag/tags-field/tags-field.module';
|
||||
import { PrefillDescriptionDialogComponent } from './prefill-description/prefill-description.component';
|
||||
import { AutoCompleteModule } from '@app/library/auto-complete/auto-complete.module';
|
||||
import { DeprecatedDescriptionTemplateDialog } from './description-base-fields-editor/dialog-description-template/deprecated-description-template-dialog.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
|
@ -32,7 +33,8 @@ import { AutoCompleteModule } from '@app/library/auto-complete/auto-complete.mod
|
|||
declarations: [
|
||||
DescriptionEditorComponent,
|
||||
DescriptionBaseFieldsEditorComponent,
|
||||
PrefillDescriptionDialogComponent
|
||||
PrefillDescriptionDialogComponent,
|
||||
DeprecatedDescriptionTemplateDialog
|
||||
],
|
||||
exports: [
|
||||
],
|
||||
|
|
|
@ -746,6 +746,14 @@
|
|||
"LOCKED-DIALOG": {
|
||||
"TITLE": "Description is locked",
|
||||
"MESSAGE": "Somebody else is modifying the description at this moment. You may view the description but you cannot make any changes. If you would like to modify it please come back later."
|
||||
},
|
||||
"DEPRECATED-DESCRIPTION-TEMPLATE": {
|
||||
"TITLE": "Found a newer version of ",
|
||||
"MESSAGE": "The selected description template has become obsolete. Would you like to update it?",
|
||||
"ACTIONS": {
|
||||
"CANCEL": "Cancel",
|
||||
"UPDATE": "Update"
|
||||
}
|
||||
}
|
||||
},
|
||||
"DESCRIPTION-COPY-DIALOG": {
|
||||
|
|
Loading…
Reference in New Issue