description template upload changes, dmp description tag field type fix

This commit is contained in:
amentis 2024-04-11 17:30:55 +03:00
parent f75d9ba777
commit 15b4c7fbc6
8 changed files with 121 additions and 99 deletions

View File

@ -114,6 +114,7 @@ public class AuditableAction {
public static final EventId StorageFile_Download = new EventId(14000, "StorageFile_Download"); public static final EventId StorageFile_Download = new EventId(14000, "StorageFile_Download");
public static final EventId StorageFile_Upload = new EventId(14001, "StorageFile_Upload"); public static final EventId StorageFile_Upload = new EventId(14001, "StorageFile_Upload");
public static final EventId StorageFile_Query = new EventId(14002, "StorageFile_Query");
public static final EventId Dashboard_MyRecentActivityItems = new EventId(15000, "Dashboard_MyRecentActivityItems"); public static final EventId Dashboard_MyRecentActivityItems = new EventId(15000, "Dashboard_MyRecentActivityItems");
public static final EventId Dashboard_MyDashboardStatistics = new EventId(15001, "Dashboard_MyDashboardStatistics"); public static final EventId Dashboard_MyDashboardStatistics = new EventId(15001, "Dashboard_MyDashboardStatistics");

View File

@ -3,6 +3,7 @@ package eu.eudat.model.builder.descriptionpropertiesdefinition;
import eu.eudat.authorization.AuthorizationFlags; import eu.eudat.authorization.AuthorizationFlags;
import eu.eudat.commons.enums.FieldType; import eu.eudat.commons.enums.FieldType;
import eu.eudat.commons.types.description.FieldEntity; import eu.eudat.commons.types.description.FieldEntity;
import eu.eudat.commons.types.descriptiontemplate.fielddata.LabelAndMultiplicityDataEntity;
import eu.eudat.commons.types.descriptiontemplate.fielddata.SelectDataEntity; import eu.eudat.commons.types.descriptiontemplate.fielddata.SelectDataEntity;
import eu.eudat.convention.ConventionService; import eu.eudat.convention.ConventionService;
import eu.eudat.model.Reference; import eu.eudat.model.Reference;
@ -72,12 +73,16 @@ public class FieldBuilder extends BaseBuilder<Field, FieldEntity> {
if (fields.hasField(this.asIndexer(Field._dateValue)) && FieldType.isDateType(fieldType)) m.setDateValue(d.getDateValue()); if (fields.hasField(this.asIndexer(Field._dateValue)) && FieldType.isDateType(fieldType)) m.setDateValue(d.getDateValue());
if (fields.hasField(this.asIndexer(Field._textValue)) && FieldType.isTextType(fieldType)) m.setTextValue(d.getTextValue()); if (fields.hasField(this.asIndexer(Field._textValue)) && FieldType.isTextType(fieldType)) m.setTextValue(d.getTextValue());
if (fields.hasField(this.asIndexer(Field._textListValue)) && FieldType.isTextListType(fieldType)) { if (fields.hasField(this.asIndexer(Field._textListValue)) && FieldType.isTextListType(fieldType)) {
boolean isSelectMultiSelect = true; boolean isMultiSelect = true;
if(this.fieldEntity != null && this.fieldEntity.getData() != null && this.fieldEntity.getData().getFieldType().equals(FieldType.SELECT) && this.fieldEntity.getData() instanceof SelectDataEntity){ if(this.fieldEntity != null && this.fieldEntity.getData() != null && (this.fieldEntity.getData().getFieldType().equals(FieldType.SELECT) || this.fieldEntity.getData().getFieldType().equals(FieldType.INTERNAL_ENTRIES_DMPS) || this.fieldEntity.getData().getFieldType().equals(FieldType.INTERNAL_ENTRIES_DESCRIPTIONS))){
isSelectMultiSelect = ((SelectDataEntity) this.fieldEntity.getData()).getMultipleSelect(); if (this.fieldEntity.getData() instanceof SelectDataEntity) isMultiSelect = ((SelectDataEntity) this.fieldEntity.getData()).getMultipleSelect();
} else if (this.fieldEntity.getData() instanceof LabelAndMultiplicityDataEntity) isMultiSelect = ((LabelAndMultiplicityDataEntity) this.fieldEntity.getData()).getMultipleSelect();
if (fieldType.equals(FieldType.SELECT) && !isSelectMultiSelect && !this.conventionService.isListNullOrEmpty(d.getTextListValue())){
m.setTextValue(d.getTextListValue().stream().findFirst().orElse(null)); if (!isMultiSelect && !this.conventionService.isListNullOrEmpty(d.getTextListValue())){
m.setTextValue(d.getTextListValue().stream().findFirst().orElse(null));
}else{
m.setTextListValue(d.getTextListValue());
}
} else{ } else{
m.setTextListValue(d.getTextListValue()); m.setTextListValue(d.getTextListValue());
} }

View File

@ -516,22 +516,38 @@ public class DescriptionServiceImpl implements DescriptionService {
} }
} }
else if (FieldType.isTextListType(fieldType)) { else if (FieldType.isTextListType(fieldType)) {
if (FieldType.INTERNAL_ENTRIES_DMPS.equals(fieldType) && !this.conventionService.isListNullOrEmpty(persist.getTextListValue())){ List<UUID> ids = new ArrayList<>();
List<UUID> ids = persist.getTextListValue().stream().map(UUID::fromString).toList(); if (FieldType.INTERNAL_ENTRIES_DMPS.equals(fieldType)) {
Set<UUID> existingIds = this.queryFactory.query(DmpQuery.class).ids(ids).isActive(IsActive.Active).collectAs(new BaseFieldSet().ensure(Dmp._id)).stream().map(DmpEntity::getId).collect(Collectors.toSet()); if (!this.conventionService.isListNullOrEmpty(persist.getTextListValue())) persist.getTextListValue().stream().map(UUID::fromString).toList();
for (UUID id : ids){ else if (!this.conventionService.isNullOrEmpty(persist.getTextValue())) ids.add(UUID.fromString(persist.getTextValue()));
if (!existingIds.contains(id)) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{id, Dmp.class.getSimpleName()}, LocaleContextHolder.getLocale()));
if (ids.size() > 0){
Set<UUID> existingIds = this.queryFactory.query(DmpQuery.class).ids(ids).isActive(IsActive.Active).collectAs(new BaseFieldSet().ensure(Dmp._id)).stream().map(DmpEntity::getId).collect(Collectors.toSet());
for (UUID id : ids){
if (!existingIds.contains(id)) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{id, Dmp.class.getSimpleName()}, LocaleContextHolder.getLocale()));
}
} }
} if (FieldType.INTERNAL_ENTRIES_DESCRIPTIONS.equals(fieldType) && !this.conventionService.isListNullOrEmpty(persist.getTextListValue())){
List<UUID> ids = persist.getTextListValue().stream().map(UUID::fromString).toList(); } if (FieldType.INTERNAL_ENTRIES_DESCRIPTIONS.equals(fieldType)){
Set<UUID> existingIds = this.queryFactory.query(DescriptionQuery.class).ids(ids).isActive(IsActive.Active).collectAs(new BaseFieldSet().ensure(Description._id)).stream().map(DescriptionEntity::getId).collect(Collectors.toSet()); if ( !this.conventionService.isListNullOrEmpty(persist.getTextListValue())) ids = persist.getTextListValue().stream().map(UUID::fromString).toList();
for (UUID id : ids){ else if (!this.conventionService.isNullOrEmpty(persist.getTextValue())) ids.add(UUID.fromString(persist.getTextValue()));
if (!existingIds.contains(id)) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{id, Description.class.getSimpleName()}, LocaleContextHolder.getLocale()));
if (ids.size() > 0) {
Set<UUID> existingIds = this.queryFactory.query(DescriptionQuery.class).ids(ids).isActive(IsActive.Active).collectAs(new BaseFieldSet().ensure(Description._id)).stream().map(DescriptionEntity::getId).collect(Collectors.toSet());
for (UUID id : ids){
if (!existingIds.contains(id)) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{id, Description.class.getSimpleName()}, LocaleContextHolder.getLocale()));
}
} }
} }
if (!ids.isEmpty()){
if (ids.size() > 1) data.setTextListValue(persist.getTextListValue());
else data.setTextListValue(List.of(persist.getTextValue()));
}else{
data.setTextListValue(persist.getTextListValue());
}
if (fieldType.equals(FieldType.SELECT) && this.conventionService.isListNullOrEmpty(persist.getTextListValue()) && !this.conventionService.isNullOrEmpty(persist.getTextValue())){ if (fieldType.equals(FieldType.SELECT) && this.conventionService.isListNullOrEmpty(persist.getTextListValue()) && !this.conventionService.isNullOrEmpty(persist.getTextValue())){
data.setTextListValue(List.of(persist.getTextValue())); data.setTextListValue(List.of(persist.getTextValue()));
} else{ } else if (fieldType.equals(FieldType.SELECT) || fieldType.equals(FieldType.TAGS)){
data.setTextListValue(persist.getTextListValue()); data.setTextListValue(persist.getTextListValue());
} }
} }

View File

@ -1,23 +1,27 @@
package eu.eudat.controllers; package eu.eudat.controllers;
import eu.eudat.audit.AuditableAction; import eu.eudat.audit.AuditableAction;
import eu.eudat.authorization.AuthorizationFlags;
import eu.eudat.authorization.Permission; import eu.eudat.authorization.Permission;
import eu.eudat.commons.enums.StorageType; import eu.eudat.commons.enums.StorageType;
import eu.eudat.commons.scope.user.UserScope; import eu.eudat.commons.scope.user.UserScope;
import eu.eudat.convention.ConventionService; import eu.eudat.convention.ConventionService;
import eu.eudat.data.StorageFileEntity; import eu.eudat.data.StorageFileEntity;
import eu.eudat.model.StorageFile; import eu.eudat.model.StorageFile;
import eu.eudat.model.builder.StorageFileBuilder;
import eu.eudat.model.persist.StorageFilePersist; import eu.eudat.model.persist.StorageFilePersist;
import eu.eudat.query.StorageFileQuery; import eu.eudat.query.StorageFileQuery;
import eu.eudat.service.storage.StorageFileProperties; import eu.eudat.service.storage.StorageFileProperties;
import eu.eudat.service.storage.StorageFileService; import eu.eudat.service.storage.StorageFileService;
import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.commons.web.authz.service.AuthorizationService;
import gr.cite.tools.auditing.AuditService; import gr.cite.tools.auditing.AuditService;
import gr.cite.tools.data.builder.BuilderFactory;
import gr.cite.tools.data.query.QueryFactory; import gr.cite.tools.data.query.QueryFactory;
import gr.cite.tools.exception.MyApplicationException; import gr.cite.tools.exception.MyApplicationException;
import gr.cite.tools.exception.MyForbiddenException; import gr.cite.tools.exception.MyForbiddenException;
import gr.cite.tools.exception.MyNotFoundException; import gr.cite.tools.exception.MyNotFoundException;
import gr.cite.tools.fieldset.BaseFieldSet; import gr.cite.tools.fieldset.BaseFieldSet;
import gr.cite.tools.fieldset.FieldSet;
import gr.cite.tools.logging.LoggerService; import gr.cite.tools.logging.LoggerService;
import gr.cite.tools.logging.MapLogEntry; import gr.cite.tools.logging.MapLogEntry;
import gr.cite.tools.validation.ValidatorFactory; import gr.cite.tools.validation.ValidatorFactory;
@ -25,8 +29,8 @@ import org.apache.commons.io.FilenameUtils;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.context.MessageSource; import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -45,6 +49,7 @@ public class StorageFileController {
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(StorageFileController.class)); private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(StorageFileController.class));
private final AuditService auditService; private final AuditService auditService;
private final QueryFactory queryFactory; private final QueryFactory queryFactory;
private final BuilderFactory builderFactory;
private final MessageSource messageSource; private final MessageSource messageSource;
private final StorageFileService storageFileService; private final StorageFileService storageFileService;
private final StorageFileProperties config; private final StorageFileProperties config;
@ -55,13 +60,14 @@ public class StorageFileController {
public StorageFileController( public StorageFileController(
AuditService auditService, AuditService auditService,
QueryFactory queryFactory, QueryFactory queryFactory,
MessageSource messageSource, BuilderFactory builderFactory, MessageSource messageSource,
StorageFileService storageFileService, StorageFileService storageFileService,
StorageFileProperties config, StorageFileProperties config,
UserScope userScope, UserScope userScope,
AuthorizationService authorizationService, ConventionService conventionService, ValidatorFactory validatorFactory) { AuthorizationService authorizationService, ConventionService conventionService, ValidatorFactory validatorFactory) {
this.auditService = auditService; this.auditService = auditService;
this.queryFactory = queryFactory; this.queryFactory = queryFactory;
this.builderFactory = builderFactory;
this.messageSource = messageSource; this.messageSource = messageSource;
this.storageFileService = storageFileService; this.storageFileService = storageFileService;
this.config = config; this.config = config;
@ -71,21 +77,23 @@ public class StorageFileController {
this.validatorFactory = validatorFactory; this.validatorFactory = validatorFactory;
} }
@GetMapping("/name/{id}") @GetMapping("{id}")
public String getName(@PathVariable("id") UUID id) throws MyApplicationException, MyForbiddenException, MyNotFoundException { public StorageFile get(@PathVariable("id") UUID id, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException {
logger.debug(new MapLogEntry("get name" ).And("id", id)); logger.debug(new MapLogEntry("retrieving " + StorageFile.class.getSimpleName()).And("id", id).And("fields", fieldSet));
this.authorizationService.authorizeForce(Permission.BrowseStorageFile); this.authorizationService.authorizeForce(Permission.BrowseStorageFile);
StorageFileEntity storageFile = this.queryFactory.query(StorageFileQuery.class).ids(id).firstAs(new BaseFieldSet().ensure(StorageFile._fullName)); StorageFileQuery query = this.queryFactory.query(StorageFileQuery.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).ids(id);
if (storageFile == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{id, StorageFile.class.getSimpleName()}, LocaleContextHolder.getLocale())); StorageFile model = this.builderFactory.builder(StorageFileBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).build(fieldSet, query.firstAs(fieldSet));
if (model == null)
throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{id, StorageFile.class.getSimpleName()}, LocaleContextHolder.getLocale()));
this.auditService.track(AuditableAction.StorageFile_Download, Map.ofEntries( this.auditService.track(AuditableAction.StorageFile_Query, Map.ofEntries(
new AbstractMap.SimpleEntry<String, Object>("id", id) new AbstractMap.SimpleEntry<String, Object>("id", id),
new AbstractMap.SimpleEntry<String, Object>("fields", fieldSet)
)); ));
return model;
return storageFile.getName();
} }
@ -115,8 +123,8 @@ public class StorageFileController {
return addedFiles; return addedFiles;
} }
@GetMapping("{id}") @GetMapping("download/{id}")
public ResponseEntity<ByteArrayResource> get(@PathVariable("id") UUID id) throws MyApplicationException, MyForbiddenException, MyNotFoundException { public ResponseEntity<byte[]> get(@PathVariable("id") UUID id) throws MyApplicationException, MyForbiddenException, MyNotFoundException {
logger.debug(new MapLogEntry("download" ).And("id", id)); logger.debug(new MapLogEntry("download" ).And("id", id));
this.authorizationService.authorizeForce(Permission.BrowseStorageFile); this.authorizationService.authorizeForce(Permission.BrowseStorageFile);
@ -134,10 +142,14 @@ public class StorageFileController {
String contentType = storageFile.getMimeType(); String contentType = storageFile.getMimeType();
if (this.conventionService.isNullOrEmpty(contentType)) contentType = MediaType.APPLICATION_OCTET_STREAM_VALUE; if (this.conventionService.isNullOrEmpty(contentType)) contentType = MediaType.APPLICATION_OCTET_STREAM_VALUE;
return ResponseEntity.ok() HttpHeaders responseHeaders = new HttpHeaders();
.contentType(MediaType.valueOf(contentType)) responseHeaders.setContentLength(file.length);
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + storageFile.getName() + (storageFile.getExtension().startsWith(".") ? "" : ".") + storageFile.getExtension() + "\"") responseHeaders.setContentType(MediaType.valueOf(contentType));
.body(new ByteArrayResource(file)); responseHeaders.set("Content-Disposition", "attachment; filename=\"" + storageFile.getName() + (storageFile.getExtension().startsWith(".") ? "" : ".") + storageFile.getExtension() + "\"");
responseHeaders.set("Access-Control-Expose-Headers", "Content-Disposition");
responseHeaders.get("Access-Control-Expose-Headers").add("Content-Type");
return new ResponseEntity<>(file, responseHeaders, HttpStatus.OK);
} }
} }

View File

@ -21,20 +21,25 @@ export class StorageFileService {
private get apiBase(): string { return `${this.configurationService.server}storage-file`; } private get apiBase(): string { return `${this.configurationService.server}storage-file`; }
getName(id: Guid ): Observable<string> { getSingle(id: Guid, reqFields: string[] = []): Observable<StorageFile> {
const url = `${this.apiBase}/name/${id}`; const url = `${this.apiBase}/${id}`;
const options = { params: { f: reqFields } };
return this.http return this.http
.get<string>(url).pipe( .get<StorageFile>(url, options).pipe(
catchError((error: any) => throwError(error))); catchError((error: any) => throwError(error)));
} }
download(id: Guid ): Observable<HttpResponse<Blob>> { download(id: Guid ): Observable<HttpResponse<Blob>> {
const url = `${this.apiBase}/${id}`; const url = `${this.apiBase}/download/${id}`;
const params = new BaseHttpParams();
params.interceptorContext = {
excludedInterceptors: [InterceptorType.JSONContentType, InterceptorType.ResponsePayload]
};
return this.http return this.http
.get<HttpResponse<Blob>>(url).pipe( .get(url, {params: params, responeType: 'blob', observe: 'response'});
catchError((error: any) => throwError(error)));
} }
uploadTempFiles(item: File): Observable<StorageFile[]> { uploadTempFiles(item: File): Observable<StorageFile[]> {

View File

@ -177,8 +177,8 @@
<app-description-template-editor-external-datasets-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.EXTERNAL_DATASETS" class="col-12" [form]="form"></app-description-template-editor-external-datasets-field-component> <app-description-template-editor-external-datasets-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.EXTERNAL_DATASETS" class="col-12" [form]="form"></app-description-template-editor-external-datasets-field-component>
<app-description-template-editor-multiplicity-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.INTERNAL_ENTRIES_DMPS" class="col-12" [form]="form"></app-description-template-editor-multiplicity-field-component> <app-description-template-editor-label-and-multiplicity-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.INTERNAL_ENTRIES_DMPS" class="col-12" [form]="form"></app-description-template-editor-label-and-multiplicity-field-component>
<app-description-template-editor-multiplicity-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.INTERNAL_ENTRIES_DESCRIPTIONS" class="col-12" [form]="form"></app-description-template-editor-multiplicity-field-component> <app-description-template-editor-label-and-multiplicity-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.INTERNAL_ENTRIES_DESCRIPTIONS" class="col-12" [form]="form"></app-description-template-editor-label-and-multiplicity-field-component>
</div> </div>
</ng-container> </ng-container>

View File

@ -47,13 +47,13 @@
<div class="row"> <div class="row">
<mat-form-field class="col-md-12"> <mat-form-field class="col-md-12">
<ng-container *ngIf="field.data.multipleSelect"> <ng-container *ngIf="field.data.multipleSelect">
<app-multiple-auto-complete placeholder="{{ (field.data.label | translate) + (isRequired? ' *': '') }}" [formControl]="propertiesFormGroup?.get(field.id).get('textListValue')" [configuration]="multipleAutoCompleteConfiguration"> <app-multiple-auto-complete placeholder="{{ (field.data.label | translate) + (isRequired? ' *': '') }}" [formControl]="propertiesFormGroup?.get(field.id).get('textListValue')" [configuration]="descriptionService.multipleAutocompleteConfiguration">
</app-multiple-auto-complete> </app-multiple-auto-complete>
<mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textListValue').hasError('backendError')">{{propertiesFormGroup?.get(field.id).get('textListValue').getError('backendError').message}}</mat-error> <mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textListValue').hasError('backendError')">{{propertiesFormGroup?.get(field.id).get('textListValue').getError('backendError').message}}</mat-error>
<mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textListValue').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error> <mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textListValue').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</ng-container> </ng-container>
<ng-container *ngIf="!(field.data.multipleSelect)"> <ng-container *ngIf="!(field.data.multipleSelect)">
<app-single-auto-complete placeholder="{{ (field.data.label | translate) + (isRequired? ' *': '') }}" [formControl]="propertiesFormGroup?.get(field.id).get('textValue')" [configuration]="singleAutoCompleteConfiguration" [required]="isRequired"> <app-single-auto-complete placeholder="{{ (field.data.label | translate) + (isRequired? ' *': '') }}" [formControl]="propertiesFormGroup?.get(field.id).get('textValue')" [configuration]="descriptionService.singleAutocompleteConfiguration" [required]="isRequired">
</app-single-auto-complete> </app-single-auto-complete>
<mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textValue').hasError('backendError')">{{propertiesFormGroup?.get(field.id).get('textValue').getError('backendError').message}}</mat-error> <mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textValue').hasError('backendError')">{{propertiesFormGroup?.get(field.id).get('textValue').getError('backendError').message}}</mat-error>
<mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textValue').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error> <mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textValue').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
@ -62,17 +62,17 @@
</mat-form-field> </mat-form-field>
</div> </div>
</div> </div>
<div *ngSwitchCase="descriptionTemplateFieldTypeEnum.INTERNAL_DMP_ENTRIES_DMPS" class="col-12"> <div *ngSwitchCase="descriptionTemplateFieldTypeEnum.INTERNAL_ENTRIES_DMPS" class="col-12">
<div class="row"> <div class="row">
<mat-form-field class="col-md-12"> <mat-form-field class="col-md-12">
<ng-container *ngIf="field.data.multipleSelect"> <ng-container *ngIf="field.data.multipleSelect">
<app-multiple-auto-complete placeholder="{{ (field.data.label | translate) + (isRequired? ' *': '') }}" [formControl]="propertiesFormGroup?.get(field.id).get('textListValue')" [configuration]="multipleAutoCompleteConfiguration"> <app-multiple-auto-complete placeholder="{{ (field.data.label | translate) + (isRequired? ' *': '') }}" [formControl]="propertiesFormGroup?.get(field.id).get('textListValue')" [configuration]="dmpService.multipleAutocompleteConfiguration">
</app-multiple-auto-complete> </app-multiple-auto-complete>
<mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textListValue').hasError('backendError')">{{propertiesFormGroup?.get(field.id).get('textListValue').getError('backendError').message}}</mat-error> <mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textListValue').hasError('backendError')">{{propertiesFormGroup?.get(field.id).get('textListValue').getError('backendError').message}}</mat-error>
<mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textListValue').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error> <mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textListValue').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</ng-container> </ng-container>
<ng-container *ngIf="!(field.data.multipleSelect)"> <ng-container *ngIf="!(field.data.multipleSelect)">
<app-single-auto-complete placeholder="{{ (field.data.label | translate) + (isRequired? ' *': '') }}" [formControl]="propertiesFormGroup?.get(field.id).get('textValue')" [configuration]="singleAutoCompleteConfiguration" [required]="isRequired"> <app-single-auto-complete placeholder="{{ (field.data.label | translate) + (isRequired? ' *': '') }}" [formControl]="propertiesFormGroup?.get(field.id).get('textValue')" [configuration]="dmpService.singleAutocompleteConfiguration" [required]="isRequired">
</app-single-auto-complete> </app-single-auto-complete>
<mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textValue').hasError('backendError')">{{propertiesFormGroup?.get(field.id).get('textValue').getError('backendError').message}}</mat-error> <mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textValue').hasError('backendError')">{{propertiesFormGroup?.get(field.id).get('textValue').getError('backendError').message}}</mat-error>
<mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textValue').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error> <mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textValue').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
@ -107,9 +107,9 @@
</ng-container> </ng-container>
<ng-container *ngSwitchCase="descriptionTemplateFieldTypeEnum.UPLOAD"> <ng-container *ngSwitchCase="descriptionTemplateFieldTypeEnum.UPLOAD">
<div class="col-12 d-flex justify-content-center"> <div class="col-12 d-flex justify-content-center">
<ngx-dropzone #drop class="drop-file col-12" (change)="fileChangeEvent($event, true)" [multiple]="false" [accept]="typesToString()" [disabled]="propertiesFormGroup?.get(field.id).get('textValue').disabled"> <ngx-dropzone class="drop-file col-12" (change)="fileChangeEvent($event, true)" [multiple]="false" [accept]="typesToString()" [disabled]="propertiesFormGroup?.get(field.id).get('textValue').disabled">
<ngx-dropzone-preview *ngIf="propertiesFormGroup?.get(field.id).get('textValue').value && fileNameDisplay" class="file-preview" [removable]="true" (removed)="onRemove()"> <ngx-dropzone-preview *ngIf="propertiesFormGroup?.get(field.id).get('textValue').value" class="file-preview" [removable]="true" (removed)="onRemove()">
<ngx-dropzone-label class="file-label">{{ fileNameDisplay}}</ngx-dropzone-label> <ngx-dropzone-label class="file-label">{{ fileNameDisplay }}</ngx-dropzone-label>
</ngx-dropzone-preview> </ngx-dropzone-preview>
</ngx-dropzone> </ngx-dropzone>
</div> </div>
@ -157,7 +157,7 @@
<div *ngSwitchCase="descriptionTemplateFieldTypeEnum.TAGS" class="col-12"> <div *ngSwitchCase="descriptionTemplateFieldTypeEnum.TAGS" class="col-12">
<div class="row"> <div class="row">
<mat-form-field class="col-md-12"> <mat-form-field class="col-md-12">
<app-multiple-auto-complete [configuration]="tagsAutoCompleteConfiguration" [formControl]="propertiesFormGroup?.get(field.id).get('textListValue')" placeholder="{{('DATASET-EDITOR.FIELDS.TAGS' | translate) + (isRequired? ' *': '')}}"></app-multiple-auto-complete> <app-multiple-auto-complete [configuration]="tagService.multipleAutocompleteConfiguration" [formControl]="propertiesFormGroup?.get(field.id).get('textListValue')" placeholder="{{ (field.data.label | translate) + (isRequired? ' *': '') }}"></app-multiple-auto-complete>
<mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textListValue').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error> <mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textListValue').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field> </mat-form-field>
</div> </div>

View File

@ -6,10 +6,13 @@ import { MatDialog } from "@angular/material/dialog";
import { DescriptionTemplateFieldType } from '@app/core/common/enum/description-template-field-type'; import { DescriptionTemplateFieldType } from '@app/core/common/enum/description-template-field-type';
import { DescriptionTemplateFieldValidationType } from '@app/core/common/enum/description-template-field-validation-type'; import { DescriptionTemplateFieldValidationType } from '@app/core/common/enum/description-template-field-validation-type';
import { DescriptionTemplateField, DescriptionTemplateFieldSet, DescriptionTemplateLabelAndMultiplicityData, DescriptionTemplateUploadData } from '@app/core/model/description-template/description-template'; import { DescriptionTemplateField, DescriptionTemplateFieldSet, DescriptionTemplateLabelAndMultiplicityData, DescriptionTemplateUploadData } from '@app/core/model/description-template/description-template';
import { StorageFile } from '@app/core/model/storage-file/storage-file';
import { DescriptionService } from '@app/core/services/description/description.service';
import { DmpService } from '@app/core/services/dmp/dmp.service'; import { DmpService } from '@app/core/services/dmp/dmp.service';
import { SnackBarNotificationLevel, UiNotificationService } from "@app/core/services/notification/ui-notification-service"; import { SnackBarNotificationLevel, UiNotificationService } from "@app/core/services/notification/ui-notification-service";
import { ReferenceService } from '@app/core/services/reference/reference.service'; import { ReferenceService } from '@app/core/services/reference/reference.service';
import { StorageFileService } from '@app/core/services/storage-file/storage-file.service'; import { StorageFileService } from '@app/core/services/storage-file/storage-file.service';
import { TagService } from '@app/core/services/tag/tag.service';
import { FileUtils } from '@app/core/services/utilities/file-utils.service'; import { FileUtils } from '@app/core/services/utilities/file-utils.service';
import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration'; import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration';
import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration'; import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration';
@ -21,6 +24,7 @@ import { TranslateService } from '@ngx-translate/core';
import * as FileSaver from 'file-saver'; import * as FileSaver from 'file-saver';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { distinctUntilChanged, map, takeUntil } from 'rxjs/operators'; import { distinctUntilChanged, map, takeUntil } from 'rxjs/operators';
import { nameof } from 'ts-simple-nameof';
@Component({ @Component({
selector: 'app-description-form-field', selector: 'app-description-form-field',
@ -70,11 +74,13 @@ export class DescriptionFormFieldComponent extends BaseComponent implements OnIn
]; ];
filesToUpload: FileList; filesToUpload: FileList;
fileNameDisplay: string; fileNameDisplay: string = null;
constructor( constructor(
private language: TranslateService, private language: TranslateService,
private dmpService: DmpService, public dmpService: DmpService,
public descriptionService: DescriptionService,
public tagService: TagService,
private cdr: ChangeDetectorRef, private cdr: ChangeDetectorRef,
private uiNotificationService: UiNotificationService, private uiNotificationService: UiNotificationService,
public dialog: MatDialog, public dialog: MatDialog,
@ -92,8 +98,24 @@ export class DescriptionFormFieldComponent extends BaseComponent implements OnIn
ngOnInit() { ngOnInit() {
if(this.field?.data?.fieldType == DescriptionTemplateFieldType.UPLOAD && this.field && this.field.id && (this.propertiesFormGroup?.get(this.field.id).get('textValue').value != undefined)) this.getUploadFileName(); if(this.field?.data?.fieldType == DescriptionTemplateFieldType.UPLOAD && this.field && this.field.id && (this.propertiesFormGroup?.get(this.field.id).get('textValue').value != undefined) && !this.fileNameDisplay) {
const id = Guid.parse((this.propertiesFormGroup?.get(this.field.id).get('textValue').value as string));
const fields = [
nameof<StorageFile>(x => x.id),
nameof<StorageFile>(x => x.name),
]
this.storageFileService.getSingle(id, fields).pipe(takeUntil(this._destroyed)).subscribe(storageFile => {
this.fileNameDisplay = storageFile.name;
this.applyFieldType();
});
} else {
this.applyFieldType();
}
}
private applyFieldType(){
this.isRequired = this.field.validations?.includes(DescriptionTemplateFieldValidationType.Required); this.isRequired = this.field.validations?.includes(DescriptionTemplateFieldValidationType.Required);
switch (this.field?.data?.fieldType) { switch (this.field?.data?.fieldType) {
@ -140,12 +162,6 @@ export class DescriptionFormFieldComponent extends BaseComponent implements OnIn
// this.form.disable(); // this.form.disable();
// } // }
break; break;
case DescriptionTemplateFieldType.INTERNAL_ENTRIES_DESCRIPTIONS:
this.makeAutocompleteConfiguration(this.searchDatasets.bind(this), "label");
break;
case DescriptionTemplateFieldType.INTERNAL_ENTRIES_DMPS:
this.makeAutocompleteConfiguration(this.searchDmps.bind(this), "label");
break;
} }
// this.form = this.visibilityRulesService.getFormGroup(this.field.id); // this.form = this.visibilityRulesService.getFormGroup(this.field.id);
@ -161,28 +177,6 @@ export class DescriptionFormFieldComponent extends BaseComponent implements OnIn
}); });
} }
searchDatasets(query: string) {
//TODO refactor
return null;
// let fields: Array<string> = new Array();
// const datasetsAutocompleteRequestItem: DataTableRequest<DatasetCriteria> = new DataTableRequest(0, 25, { fields: fields });
// datasetsAutocompleteRequestItem.criteria = new DatasetCriteria();
// datasetsAutocompleteRequestItem.criteria.like = query;
// //TODO: refactor this
// // return this.datasetService.getPaged(datasetsAutocompleteRequestItem).pipe(map(item => item.data));
// return null;
}
searchDmps(query: string) {
//TODO refactor
return null;
// let fields: Array<string> = new Array();
// const dmpsAutocompleteRequestItem: DataTableRequest<DmpCriteria> = new DataTableRequest(0, 25, { fields: fields });
// dmpsAutocompleteRequestItem.criteria = new DmpCriteria();
// dmpsAutocompleteRequestItem.criteria.like = query;
// return this.dmpService.getPaged(dmpsAutocompleteRequestItem).pipe(map(item => item.data));
}
makeAutocompleteConfiguration(myfunc: Function, title: string, subtitle?: string): void { makeAutocompleteConfiguration(myfunc: Function, title: string, subtitle?: string): void {
if (!((this.field.data as DescriptionTemplateLabelAndMultiplicityData).multipleSelect)) { if (!((this.field.data as DescriptionTemplateLabelAndMultiplicityData).multipleSelect)) {
this.singleAutoCompleteConfiguration = { this.singleAutoCompleteConfiguration = {
@ -275,16 +269,6 @@ export class DescriptionFormFieldComponent extends BaseComponent implements OnIn
} }
private getUploadFileName(){
const id = Guid.parse((this.propertiesFormGroup?.get(this.field.id).get('textValue').value as string));
this.storageFileService.getName(id)
.pipe(takeUntil(this._destroyed)).subscribe((name) => {
this.fileNameDisplay = name;
}, error => {
this.fileNameDisplay = null;
})
}
public upload() { public upload() {
this.storageFileService.uploadTempFiles(this.filesToUpload[0]) this.storageFileService.uploadTempFiles(this.filesToUpload[0])
@ -364,13 +348,12 @@ export class DescriptionFormFieldComponent extends BaseComponent implements OnIn
if (this.propertiesFormGroup?.get(this.field.id).get('textValue').value) { if (this.propertiesFormGroup?.get(this.field.id).get('textValue').value) {
const id = Guid.parse((this.propertiesFormGroup?.get(this.field.id).get('textValue').value as string)); const id = Guid.parse((this.propertiesFormGroup?.get(this.field.id).get('textValue').value as string));
this.storageFileService.download(id).subscribe((response) => { this.storageFileService.download(id).pipe(takeUntil(this._destroyed))
const blob = new Blob([response.body]); .subscribe(response => {
const filename = this.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); const blob = new Blob([response.body]);
FileSaver.saveAs(blob, filename); const filename = this.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
}, error => { FileSaver.saveAs(blob, filename);
this.onCallbackUploadFail(error.error); });
})
} }
} }