import {of as observableOf, Observable } from 'rxjs'; import { Component, OnInit, ViewChild } from '@angular/core'; import { AbstractControl, FormArray, FormControl, FormGroup } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; import { MatSnackBar } from '@angular/material/snack-bar'; import { MatStepper } from '@angular/material/stepper'; import { ActivatedRoute, Router } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; import { takeUntil } from 'rxjs/operators'; import { ValidationErrorModel } from '../../../common/forms/validation/error-model/validation-error-model'; import { BaseComponent } from "../../../core/common/base/base.component"; import { DatasetStatus } from '../../../core/common/enum/dataset-status'; import { DmpStatus } from '../../../core/common/enum/dmp-status'; import { DatasetService } from '../../../core/services/dataset/dataset.service'; import { SnackBarNotificationLevel, UiNotificationService } from '../../../core/services/notification/ui-notification-service'; import { QuickWizardService } from '../../../core/services/quick-wizard/quick-wizard.service'; import { ConfirmationDialogComponent } from '../../../library/confirmation-dialog/confirmation-dialog.component'; import { DmpFinalizeDialogComponent, DmpFinalizeDialogDataset, DmpFinalizeDialogInput } from '../../dmp/editor/dmp-finalize-dialog/dmp-finalize-dialog.component'; import { BreadcrumbItem } from '../../misc/breadcrumb/definition/breadcrumb-item'; import { IBreadCrumbComponent } from '../../misc/breadcrumb/definition/IBreadCrumbComponent'; import { DatasetEditorWizardComponent } from '../dataset-editor/dataset-editor-wizard.component'; import { GrantEditorWizardModel } from '../grant-editor/grant-editor-wizard-model'; import { QuickWizardEditorWizardModel } from './quick-wizard-editor.model'; import { FunderFormModel } from '../../dmp/editor/grant-tab/funder-form-model'; import { ProjectFormModel } from '../../dmp/editor/grant-tab/project-form-model'; @Component({ selector: 'app-quick-wizard-editor-component', templateUrl: 'quick-wizard-editor.component.html', styleUrls: ['./quick-wizard-editor.component.scss'] }) export class QuickWizardEditorComponent extends BaseComponent implements OnInit, IBreadCrumbComponent { breadCrumbs: Observable = observableOf([]); @ViewChild('stepper', { static: true }) stepper: MatStepper; @ViewChild(DatasetEditorWizardComponent, { static: false }) datasetEditorWizardComponent: DatasetEditorWizardComponent; isNew = true; quickWizard: QuickWizardEditorWizardModel; allDatasets: DmpFinalizeDialogDataset[] = []; formGroup: FormGroup = null; constructor( public snackBar: MatSnackBar, private route: ActivatedRoute, public router: Router, public language: TranslateService, public datasetService: DatasetService, public quickWizardService: QuickWizardService, private uiNotificationService: UiNotificationService, private dialog: MatDialog ) { super(); } ngOnInit(): void { this.quickWizard = new QuickWizardEditorWizardModel(); this.quickWizard.grant = new GrantEditorWizardModel(); this.quickWizard.funder = new FunderFormModel(); this.quickWizard.project = new ProjectFormModel(); this.formGroup = this.quickWizard.buildForm(); this.language.get('NAV-BAR.DMP-WIZARD').pipe(takeUntil(this._destroyed)).subscribe(x => { this.breadCrumbs = observableOf([ { parentComponentName: 'Dashboard', label: x, url: '/quick-wizard' }] ); }) } isActive(step: string): boolean { switch (step) { case 'step1': return this.stepper.selectedIndex == 0; case 'step2': return this.stepper.selectedIndex == 1; case 'step3': return this.stepper.selectedIndex == 2; } } formSubmit(): void { this.touchAllFormFields(this.formGroup); if (this.formGroup.get('datasets') && this.formGroup.get('datasets').get('datasetsList') && (this.formGroup.get('datasets').get('datasetsList') as FormArray).length > 0) { for (let control of (this.formGroup.get('datasets').get('datasetsList') as FormArray).controls) { control.get('status').setValue(DatasetStatus.Draft); } this.onSubmitSave(); } else { return; } } saveFinalize() { if (!this.isFormValid()) { return; } const dialogInputModel: DmpFinalizeDialogInput = { dmpLabel: this.formGroup.get('dmp').get('label').value, dmpDescription: this.formGroup.get('dmp').get('description').value, datasets: (this.formGroup.get('datasets').get('datasetsList') as FormArray).controls.map(x => { return { label: x.get('datasetLabel').value, status: DatasetStatus.Finalized }; }) } const dialogRef = this.dialog.open(DmpFinalizeDialogComponent, { maxWidth: '500px', data: { dialogInputModel: dialogInputModel, confirmButton: this.language.instant('DMP-FINALISE-DIALOG.SUBMIT'), cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'), } }); dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { if (result && !result.cancelled) { if (this.formGroup.get('datasets') && this.formGroup.get('datasets').get('datasetsList') && (this.formGroup.get('datasets').get('datasetsList') as FormArray).length > 0) { for (let control of (this.formGroup.get('datasets').get('datasetsList') as FormArray).controls) { control.get('status').setValue(DatasetStatus.Finalized); } this.formGroup.get('dmp').get('status').setValue(DmpStatus.Finalized); this.onSubmitSaveAndFinalize(); } } }); } hasDatasets() { return (this.formGroup.get('datasets').get('datasetsList') as FormArray).length > 0; } public isFormValid() { return this.formGroup.get('grant').valid; } public touchAllFormFields(formControl: AbstractControl) { if (formControl instanceof FormControl) { formControl.markAsTouched(); } else if (formControl instanceof FormGroup) { Object.keys(formControl.controls).forEach(item => { const control = formControl.get(item); this.touchAllFormFields(control); }); } else if (formControl instanceof FormArray) { formControl.controls.forEach(item => { this.touchAllFormFields(item); }); } } onSubmitSaveAndFinalize() { this.quickWizardService.createQuickWizard(this.formGroup.getRawValue()) .pipe(takeUntil(this._destroyed)) .subscribe( complete => this.onCallbackSuccess(), error => this.onCallbackError(error) ); } onSubmitSave(): void { const dialogRef = this.dialog.open(ConfirmationDialogComponent, { data: { message: this.language.instant('QUICKWIZARD.SAVE-DIALOG.TITLE'), 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.datasetEditorWizardComponent.addDataset(false); } else if (result === false) { this.quickWizardService.createQuickWizard(this.formGroup.value) .pipe(takeUntil(this._destroyed)) .subscribe( complete => this.onCallbackSuccess() ) } }); } 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(['/home']); } onCallbackError(errorResponse: any) { this.setErrorModel(errorResponse.error.payload); this.validateAllFormFields(this.formGroup); } public setErrorModel(validationErrorModel: ValidationErrorModel) { Object.keys(validationErrorModel).forEach(item => { (this.quickWizard.validationErrorModel)[item] = (validationErrorModel)[item]; }); } public validateAllFormFields(formControl: AbstractControl) { if (formControl instanceof FormControl) { formControl.updateValueAndValidity({ emitEvent: false }); } else if (formControl instanceof FormGroup) { Object.keys(formControl.controls).forEach(item => { const control = formControl.get(item); this.validateAllFormFields(control); }); } else if (formControl instanceof FormArray) { formControl.controls.forEach(item => { this.validateAllFormFields(item); }); } } getGrantLabel(): string { if (this.formGroup.get('grant').get('existGrant').value) { return this.formGroup.get('grant').get('existGrant').value['label']; } else { return this.formGroup.get('grant').get('label').value; } } }