Merge branch 'dmp-refactoring' of https://code-repo.d4science.org/MaDgiK-CITE/argos into dmp-refactoring

This commit is contained in:
Sofia Papacharalampous 2024-05-29 17:14:01 +03:00
commit 6fcf4ccfe1
10 changed files with 231 additions and 4 deletions

View File

@ -166,7 +166,7 @@ export class UserService {
valueAssign: (item: DmpAssociatedUser) => item.id, valueAssign: (item: DmpAssociatedUser) => item.id,
}; };
private buildAutocompleteLookup(like?: string, excludedIds?: Guid[], ids?: Guid[]): UserLookup { public buildAutocompleteLookup(like?: string, excludedIds?: Guid[], ids?: Guid[]): UserLookup {
const lookup: UserLookup = new UserLookup(); const lookup: UserLookup = new UserLookup();
lookup.page = { size: 100, offset: 0 }; lookup.page = { size: 100, offset: 0 };
if (excludedIds && excludedIds.length > 0) { lookup.excludedIds = excludedIds; } if (excludedIds && excludedIds.length > 0) { lookup.excludedIds = excludedIds; }

View File

@ -0,0 +1,23 @@
<div class="dmp-contact-prefill-dialog">
<div class="row mt-3">
<div mat-dialog-title *ngIf="label">
<span class="mr-3 title">{{'DMP-CONTACT-PREFILL-DIALOG.TITLE' | translate}}{{label}}</span>
</div>
<div mat-dialog-title *ngIf="!label">
<span class="mr-3 title">{{'DMP-CONTACT-PREFILL-DIALOG.TITLE' | translate}}{{enumUtils.toDmpBlueprintSystemFieldTypeString(3)}}</span>
</div>
</div>
<div class="row d-flex flex-row mb-2">
<div class="col message pb-4 pl-3">{{'DMP-CONTACT-PREFILL-DIALOG.TEXT' | translate}}</div>
</div>
<div class="col-12 col-xl mt-3">
<mat-form-field class="w-100">
<mat-label>{{'DMP-CONTACT-PREFILL-DIALOG.FIELDS.USER' | translate}}</mat-label>
<app-single-auto-complete [formControl]="formGroup" [configuration]="singleAutoCompleteDmpAssociatedUserConfiguration"></app-single-auto-complete>
</mat-form-field>
</div>
<div class="row" style="justify-content: space-between;">
<div class="col-auto"><button mat-raised-button type="button" class="cancel-btn" (click)="cancel()">{{'DMP-CONTACT-PREFILL-DIALOG.ACTIONS.CANCEL' | translate}}</button></div>
<div class="col-auto"><button mat-raised-button type="button" (click)="confirm()" class="delete-btn">{{'DMP-CONTACT-PREFILL-DIALOG.ACTIONS.CONFIRM' | translate}}</button></div>
</div>
</div>

View File

@ -0,0 +1,49 @@
.dmp-contact-prefill-dialog {
padding: 24px;
overflow: hidden;
.confirmation {
padding-bottom: 20px;
}
.close-btn {
margin-left: auto;
cursor: pointer;
}
.warn-text {
// color: #f44336;
}
.cancel {
background-color: #aaaaaa;
color: #ffffff;
}
.cancel-btn {
min-width: 101px;
height: 43px;
background: #ffffff;
border: 1px solid #b5b5b5;
border-radius: 30px;
opacity: 1;
}
.delete {
background-color: #ba2c2c;
color: #ffffff;
}
.delete-btn {
min-width: 101px;
height: 43px;
background: #ffffff;
color: #ba2c2c;
border: 1px solid #ba2c2c;
border-radius: 30px;
opacity: 1;
}
}

View File

@ -0,0 +1,66 @@
import { Component, Inject } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { BaseComponent } from '@common/base/base.component';
import { UserService } from '@app/core/services/user/user.service';
import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration';
import { map } from 'rxjs';
import { DmpAssociatedUser } from '@app/core/model/user/user';
import { UntypedFormGroup } from '@angular/forms';
import { DmpContactPrefillDialogEditorModel } from './dmp-contact-prefill-dialog.editor.model';
import { FormService } from '@common/forms/form-service';
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
import { DmpBlueprintSystemFieldType } from '@app/core/common/enum/dmp-blueprint-system-field-type';
@Component({
selector: 'app-dmp-contact-prefill-dialog',
templateUrl: './dmp-contact-prefill-dialog.component.html',
styleUrls: ['./dmp-contact-prefill-dialog.component.scss']
})
export class DmpContactPrefillDialogComponent extends BaseComponent {
formGroup: UntypedFormGroup;
contactFormGroup: UntypedFormGroup;
label: string;
singleAutoCompleteDmpAssociatedUserConfiguration: SingleAutoCompleteConfiguration = {
initialItems: (data?: any) => this.userService.queryDmpAssociated(this.userService.buildAutocompleteLookup()).pipe(map(x => x.items)),
filterFn: (searchQuery: string, data?: any) => this.userService.queryDmpAssociated(this.userService.buildAutocompleteLookup(searchQuery)).pipe(map(x => x.items)),
getSelectedItem: (selectedItem: any) => this.userService.queryDmpAssociated(this.userService.buildAutocompleteLookup(null, null, [selectedItem])).pipe(map(x => x.items[0])),
displayFn: (item: DmpAssociatedUser) => item.name,
subtitleFn: (item: DmpAssociatedUser) => item.email,
titleFn: (item: DmpAssociatedUser) => item.name,
valueAssign: (item: DmpAssociatedUser) => item,
uniqueAssign: (item: DmpAssociatedUser) => item.id
}; constructor(
private userService: UserService,
private formService: FormService,
public enumUtils: EnumUtils,
public dialogRef: MatDialogRef<DmpContactPrefillDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: any
) {
super();
this.contactFormGroup = data.contactFormGroup;
this.label = data.label;
}
ngOnInit(): void {
this.formGroup = new DmpContactPrefillDialogEditorModel().buildForm();
}
cancel() {
this.dialogRef.close(false);
}
confirm() {
this.formService.touchAllFormFields(this.formGroup);
if (!this.formGroup.valid) { return; }
this.contactFormGroup.get('firstName').patchValue(this.formGroup.get('name').value);
this.contactFormGroup.get('lastName').patchValue(null);
this.contactFormGroup.get('email').patchValue(this.formGroup.get('email').value);
this.dialogRef.close(true);
}
}

View File

@ -0,0 +1,38 @@
import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms";
import { DmpAssociatedUser } from "@app/core/model/user/user";
import { BackendErrorValidator } from '@common/forms/validation/custom-validator';
import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model';
import { Validation, ValidationContext } from '@common/forms/validation/validation-context';
import { Guid } from "@common/types/guid";
export class DmpContactPrefillDialogEditorModel implements DmpAssociatedUser {
id: Guid;
name: string;
email: string;
public validationErrorModel: ValidationErrorModel = new ValidationErrorModel();
protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder();
constructor() { }
buildForm(context: ValidationContext = null, disabled: boolean = false): UntypedFormGroup {
if (context == null) { context = this.createValidationContext(); }
return this.formBuilder.group({
id: [{ value: this.id, disabled: disabled }, context.getValidation('id').validators],
name: [{ value: this.name, disabled: disabled }, context.getValidation('name').validators],
email: [{ value: this.email, disabled: disabled }, context.getValidation('email').validators],
});
}
createValidationContext(): ValidationContext {
const baseContext: ValidationContext = new ValidationContext();
const baseValidationArray: Validation[] = new Array<Validation>();
baseValidationArray.push({ key: 'id', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'id')] });
baseValidationArray.push({ key: 'name', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'name')] });
baseValidationArray.push({ key: 'email', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'email')] });
baseContext.validation = baseValidationArray;
return baseContext;
}
}

View File

@ -0,0 +1,14 @@
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { CommonUiModule } from '@common/ui/common-ui.module';
import { AutoCompleteModule } from '@app/library/auto-complete/auto-complete.module';
import { DmpContactPrefillDialogComponent } from './dmp-contact-prefill-dialog.component';
@NgModule({
imports: [CommonUiModule, FormsModule, ReactiveFormsModule, AutoCompleteModule],
declarations: [DmpContactPrefillDialogComponent],
exports: [DmpContactPrefillDialogComponent]
})
export class DmpContactPrefillDialogModule {
constructor() { }
}

View File

@ -222,6 +222,11 @@
</div> </div>
</div> </div>
</div> </div>
<div *ngIf="canSave || isNew" class="col-12 col-xl-auto">
<button [disabled]="!this.canSave" mat-icon-button class="action-list-icon" matTooltip="{{'DMP-EDITOR.ACTIONS.SEARCH-CONTACT' | translate}}" (click)="searchContact(contactIndex, field)" [disabled]="formGroup.disabled">
<mat-icon>search</mat-icon>
</button>
</div>
<div *ngIf="canSave || isNew" class="col-12 col-xl-auto"> <div *ngIf="canSave || isNew" class="col-12 col-xl-auto">
<button [disabled]="!this.canSave" mat-icon-button class="action-list-icon" matTooltip="{{'DMP-EDITOR.ACTIONS.REMOVE-CONTACT' | translate}}" (click)="removeContact(contactIndex)" [disabled]="formGroup.disabled"> <button [disabled]="!this.canSave" mat-icon-button class="action-list-icon" matTooltip="{{'DMP-EDITOR.ACTIONS.REMOVE-CONTACT' | translate}}" (click)="removeContact(contactIndex)" [disabled]="formGroup.disabled">
<mat-icon>delete</mat-icon> <mat-icon>delete</mat-icon>

View File

@ -18,7 +18,7 @@ import { LockTargetType } from '@app/core/common/enum/lock-target-type';
import { AppPermission } from '@app/core/common/enum/permission.enum'; import { AppPermission } from '@app/core/common/enum/permission.enum';
import { DescriptionTemplate } from '@app/core/model/description-template/description-template'; import { DescriptionTemplate } from '@app/core/model/description-template/description-template';
import { DescriptionSectionPermissionResolver } from '@app/core/model/description/description'; import { DescriptionSectionPermissionResolver } from '@app/core/model/description/description';
import { DmpBlueprint, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint'; import { DmpBlueprint, DmpBlueprintDefinitionSection, FieldInSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
import { Dmp, DmpPersist } from '@app/core/model/dmp/dmp'; import { Dmp, DmpPersist } from '@app/core/model/dmp/dmp';
import { LanguageInfo } from '@app/core/model/language-info'; import { LanguageInfo } from '@app/core/model/language-info';
import { AuthService } from '@app/core/services/auth/auth.service'; import { AuthService } from '@app/core/services/auth/auth.service';
@ -51,6 +51,7 @@ import { DmpEditorResolver } from './dmp-editor.resolver';
import { DmpEditorService } from './dmp-editor.service'; import { DmpEditorService } from './dmp-editor.service';
import { Title } from '@angular/platform-browser'; import { Title } from '@angular/platform-browser';
import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; import { AnalyticsService } from '@app/core/services/matomo/analytics-service';
import { DmpContactPrefillDialogComponent } from '../dmp-contact-prefill-dialog/dmp-contact-prefill-dialog.component';
@Component({ @Component({
selector: 'app-dmp-editor', selector: 'app-dmp-editor',
@ -527,6 +528,22 @@ export class DmpEditorComponent extends BaseEditor<DmpEditorModel, Dmp> implemen
this.formGroup.get('properties').get('contacts').markAsDirty(); this.formGroup.get('properties').get('contacts').markAsDirty();
} }
searchContact(contactIndex: number, field: FieldInSection): void{
const dialogRef = this.dialog.open(DmpContactPrefillDialogComponent, {
maxWidth: '700px',
maxHeight: '80vh',
data: {
contactFormGroup: (this.formGroup.get('properties').get('contacts') as FormArray).at(contactIndex),
label: field.label
}
});
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe((result: Dmp) => {
if (result) {
this.uiNotificationService.snackBarNotification(this.language.instant('DMP-EDITOR.SNACK-BAR.SUCCESSFUL-DMP-CONTACT'), SnackBarNotificationLevel.Success);
}
});
}
// //
// //

View File

@ -12,6 +12,7 @@ import { DmpEditorComponent } from './dmp-editor.component';
import { DmpEditorRoutingModule } from './dmp-editor.routing'; import { DmpEditorRoutingModule } from './dmp-editor.routing';
import { DmpFormProgressIndicationModule } from './form-progress-indication/dmp-form-progress-indication.module'; import { DmpFormProgressIndicationModule } from './form-progress-indication/dmp-form-progress-indication.module';
import { DmpDeleteDialogModule } from '../dmp-delete-dialog/dmp-delete-dialog.module'; import { DmpDeleteDialogModule } from '../dmp-delete-dialog/dmp-delete-dialog.module';
import { DmpContactPrefillDialogModule } from '../dmp-contact-prefill-dialog/dmp-contact-prefill-dialog.module';
@NgModule({ @NgModule({
imports: [ imports: [
@ -26,7 +27,8 @@ import { DmpDeleteDialogModule } from '../dmp-delete-dialog/dmp-delete-dialog.mo
ReferenceFieldModule, ReferenceFieldModule,
DragDropModule, DragDropModule,
DmpUserFieldModule, DmpUserFieldModule,
DmpFormProgressIndicationModule DmpFormProgressIndicationModule,
DmpContactPrefillDialogModule
], ],
declarations: [ declarations: [
DmpEditorComponent, DmpEditorComponent,

View File

@ -1568,6 +1568,7 @@
"DEFAULT-BLUEPRINT": "Default Blueprint", "DEFAULT-BLUEPRINT": "Default Blueprint",
"OR-CONTINUE-WITH": "or continue with", "OR-CONTINUE-WITH": "or continue with",
"REMOVE-CONTACT": "Remove Contact", "REMOVE-CONTACT": "Remove Contact",
"SEARCH-CONTACT": "Search Contact",
"REMOVE-USER": "Remove User" "REMOVE-USER": "Remove User"
}, },
"PLACEHOLDER": { "PLACEHOLDER": {
@ -1577,7 +1578,8 @@
}, },
"SNACK-BAR": { "SNACK-BAR": {
"UNSUCCESSFUL-DOI": "Unsuccessful DOI creation", "UNSUCCESSFUL-DOI": "Unsuccessful DOI creation",
"SUCCESSFUL-DOI": "Successful DOI creation" "SUCCESSFUL-DOI": "Successful DOI creation",
"SUCCESSFUL-DMP-CONTACT": "User added"
}, },
"DESCRIPTION-TEMPLATE-LIST": { "DESCRIPTION-TEMPLATE-LIST": {
"TITLE": "Available Description Templates", "TITLE": "Available Description Templates",
@ -1652,6 +1654,17 @@
"TOGGLE-DESCRIPTIONS": "Check/Uncheck" "TOGGLE-DESCRIPTIONS": "Check/Uncheck"
} }
}, },
"DMP-CONTACT-PREFILL-DIALOG": {
"TITLE": "Add ",
"TEXT": "Search an existing user where associated with your plans",
"FIELDS": {
"USER": "User"
},
"ACTIONS": {
"CANCEL": "Cancel",
"CONFIRM": "Confirm"
}
},
"DMP-USER-INVITATION-DIALOG": { "DMP-USER-INVITATION-DIALOG": {
"TITLE": "Invite authors", "TITLE": "Invite authors",
"ACTIONS": { "ACTIONS": {