argos/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.componen...

661 lines
25 KiB
TypeScript

import { AfterViewInit, Component, ViewChild } from '@angular/core';
import { FormArray, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
import { ActivatedRoute, Params, Router } from '@angular/router';
import { DmpProfileFieldDataType } from '@app/core/common/enum/dmp-profile-field-type';
import { DmpProfileStatus } from '@app/core/common/enum/dmp-profile-status';
import { DmpProfileType } from '@app/core/common/enum/dmp-profile-type';
import { DmpProfile } from '@app/core/model/dmp-profile/dmp-profile';
import { DmpProfileService } from '@app/core/services/dmp/dmp-profile.service';
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
import { DmpProfileEditorModel, DmpProfileFieldEditorModel } from '@app/ui/admin/dmp-profile/editor/dmp-profile-editor.model';
import { DmpProfileExternalAutoCompleteFieldDataEditorModel } from '@app/ui/admin/dmp-profile/editor/external-autocomplete/dmp-profile-external-autocomplete-field-editor.model';
import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item';
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 { TranslateService } from '@ngx-translate/core';
import { environment } from 'environments/environment';
import * as FileSaver from 'file-saver';
import { Observable, of as observableOf } from 'rxjs';
import { map, takeUntil } from 'rxjs/operators';
import { ConfigurationService } from '@app/core/services/configuration/configuration.service';
import { HttpClient } from '@angular/common/http';
import { MatomoService } from '@app/core/services/matomo/matomo-service';
import { MatDialog } from '@angular/material/dialog';
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration';
import { DatasetProfileModel } from '@app/core/model/dataset/dataset-profile';
import { DataTableRequest } from '@app/core/model/data-table/data-table-request';
import { DatasetProfileCriteria } from '@app/core/query/dataset-profile/dataset-profile-criteria';
import { DmpService } from '@app/core/services/dmp/dmp.service';
import { AvailableProfilesComponent } from '@app/ui/dmp/editor/available-profiles/available-profiles.component';
import { DatasetPreviewDialogComponent } from '@app/ui/dmp/dataset-preview/dataset-preview-dialog.component';
import { CdkDragDrop, CdkDropList, CdkDrag, moveItemInArray } from '@angular/cdk/drag-drop';
import { DmpBlueprint, DmpBlueprintDefinition, ExtraFieldType, FieldCategory, SystemFieldType } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint';
import { DescriptionTemplatesInSectionEditor, DmpBlueprintEditor, FieldInSectionEditor, SectionDmpBlueprintEditor } from './dmp-blueprint-editor.model';
import { Guid } from '@common/types/guid';
import { isNullOrUndefined } from '@app/utilities/enhancers/utils';
import { DmpBlueprintListing } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint-listing';
import { FormValidationErrorsDialogComponent } from '@common/forms/form-validation-errors-dialog/form-validation-errors-dialog.component';
@Component({
selector: 'app-dmp-profile-editor-component',
templateUrl: 'dmp-profile-editor.component.html',
styleUrls: ['./dmp-profile-editor.component.scss']
})
export class DmpProfileEditorComponent extends BaseComponent implements AfterViewInit {
isNew = true;
isClone = false;
viewOnly = false;
dmpProfileModel: DmpProfileEditorModel;
dmpBlueprintModel: DmpBlueprintEditor;
formGroup: FormGroup = null;
host: string;
dmpProfileId: string;
breadCrumbs: Observable<BreadcrumbItem[]>;
dmpBlueprintsFormGroup: FormGroup = null;
profilesAutoCompleteConfiguration: MultipleAutoCompleteConfiguration;
fieldList = [
{label: 'Title', type: SystemFieldType.TEXT},
{label: 'Description', type: SystemFieldType.HTML_TEXT},
{label: 'Researchers', type: SystemFieldType.RESEARCHERS},
{label: 'Organizations', type: SystemFieldType.ORGANIZATIONS},
{label: 'Language', type: SystemFieldType.LANGUAGE},
{label: 'Contact', type: SystemFieldType.CONTACT},
{label: 'Funder', type: SystemFieldType.FUNDER},
{label: 'Grant', type: SystemFieldType.GRANT},
{label: 'Project', type: SystemFieldType.PROJECT},
{label: 'License', type: SystemFieldType.LICENSE},
{label: 'Access Rights', type: SystemFieldType.ACCESS_RIGHTS}
];
systemFieldListPerSection: Array<Array<any>> = new Array();
descriptionTemplatesPerSection: Array<Array<DatasetProfileModel>> = new Array<Array<DatasetProfileModel>>();
constructor(
private dmpProfileService: DmpProfileService,
private _service: DmpService,
private route: ActivatedRoute,
private router: Router,
private language: TranslateService,
private enumUtils: EnumUtils,
private uiNotificationService: UiNotificationService,
private formService: FormService,
private fb: FormBuilder,
private configurationService: ConfigurationService,
private httpClient: HttpClient,
private matomoService: MatomoService,
private dialog: MatDialog
) {
super();
this.host = configurationService.server;
}
ngAfterViewInit() {
this.matomoService.trackPageView('Admin: DMP Profile Edit');
this.profilesAutoCompleteConfiguration = {
filterFn: this.filterProfiles.bind(this),
initialItems: (excludedItems: any[]) => this.filterProfiles('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))),
displayFn: (item) => item['label'],
titleFn: (item) => item['label'],
subtitleFn: (item) => item['description'],
popupItemActionIcon: 'visibility'
};
this.route.params
.pipe(takeUntil(this._destroyed))
.subscribe((params: Params) => {
this.dmpProfileId = params['id'];
const cloneId = params['cloneid'];
if (this.dmpProfileId != null) {
this.isNew = false;
this.dmpProfileService.getSingleBlueprint(this.dmpProfileId).pipe(map(data => data as DmpBlueprint))
.pipe(takeUntil(this._destroyed))
.subscribe(data => {
this.dmpBlueprintModel = new DmpBlueprintEditor().fromModel(data);
this.formGroup = this.dmpBlueprintModel.buildForm();
this.buildSystemFields();
this.fillDescriptionTemplatesInMultAutocomplete();
if (this.dmpBlueprintModel.status == DmpProfileStatus.Finalized) {
this.formGroup.disable();
this.viewOnly = true
}
this.breadCrumbs = observableOf([{
parentComponentName: 'DmpProfileListingComponent',
label: this.language.instant('NAV-BAR.TEMPLATE'),
url: '/dmp-profiles/' + this.dmpProfileId
}]);
});
} else if (cloneId != null) {
this.isClone = true;
this.dmpProfileService.clone(cloneId).pipe(map(data => data as DmpBlueprint), takeUntil(this._destroyed))
.subscribe(
data => {
this.dmpBlueprintModel = new DmpBlueprintEditor().fromModel(data);
this.dmpBlueprintModel.id = null;
this.dmpBlueprintModel.created = null;
this.dmpBlueprintModel.status = DmpProfileStatus.Draft;
this.formGroup = this.dmpBlueprintModel.buildForm();
this.buildSystemFields();
this.fillDescriptionTemplatesInMultAutocomplete();
},
error => this.onCallbackError(error)
);
} else {
this.dmpProfileModel = new DmpProfileEditorModel();
this.dmpBlueprintModel = new DmpBlueprintEditor();
setTimeout(() => {
// this.formGroup = this.dmpProfileModel.buildForm();
// this.addField();
this.dmpBlueprintModel.status = DmpProfileStatus.Draft;
this.formGroup = this.dmpBlueprintModel.buildForm();
});
this.breadCrumbs = observableOf([{
parentComponentName: 'DmpProfileListingComponent',
label: this.language.instant('NAV-BAR.TEMPLATE'),
url: '/dmp-profiles/' + this.dmpProfileId
}]);
}
});
}
buildSystemFields(){
const sections = this.sectionsArray().controls.length;
for(let i = 0; i < sections; i++){
let systemFieldsInSection = new Array();
this.fieldsArray(i).controls.forEach((field) => {
if((field.get('category').value == FieldCategory.SYSTEM || field.get('category').value == 'SYSTEM')){
systemFieldsInSection.push(this.fieldList.find(f => f.type == field.get('type').value).type);
}
})
this.systemFieldListPerSection.push(systemFieldsInSection);
}
}
fillDescriptionTemplatesInMultAutocomplete(){
const sections = this.sectionsArray().controls.length;
for(let i = 0; i < sections; i++){
let descriptionTemplatesInSection = new Array<DatasetProfileModel>();
this.descriptionTemplatesArray(i).controls.forEach((template) => {
descriptionTemplatesInSection.push({id: template.value.descriptionTemplateId, label: template.value.label, description: ""});
})
this.descriptionTemplatesPerSection.push(descriptionTemplatesInSection);
}
}
checkForProfiles(event, sectionIndex: number) {
if (event.checked === false) {
this.descriptionTemplatesPerSection[sectionIndex] = new Array<DatasetProfileModel>();
this.descriptionTemplatesArray(sectionIndex).clear();
}
}
filterProfiles(value: string): Observable<DatasetProfileModel[]> {
const request = new DataTableRequest<DatasetProfileCriteria>(null, null, { fields: ['+label'] });
const criteria = new DatasetProfileCriteria();
criteria.like = value;
request.criteria = criteria;
return this._service.searchDMPProfiles(request);
}
sectionsArray(): FormArray {
//return this.dmpBlueprintsFormGroup.get('sections') as FormArray;
return this.formGroup.get('definition').get('sections') as FormArray;
}
addSection(): void {
const section: SectionDmpBlueprintEditor = new SectionDmpBlueprintEditor();
section.id = Guid.create().toString();
section.ordinal = this.sectionsArray().length + 1;
section.hasTemplates = false;
this.sectionsArray().push(section.buildForm());
this.systemFieldListPerSection.push(new Array());
this.descriptionTemplatesPerSection.push(new Array());
}
removeSection(sectionIndex: number): void {
this.systemFieldListPerSection.splice(sectionIndex, 1);
this.descriptionTemplatesPerSection.splice(sectionIndex, 1);
this.sectionsArray().removeAt(sectionIndex);
this.sectionsArray().controls.forEach((section, index) => {
section.get('ordinal').setValue(index + 1);
});
}
fieldsArray(sectionIndex: number): FormArray {
return this.sectionsArray().at(sectionIndex).get('fields') as FormArray;
}
addField(sectionIndex: number, fieldCategory: FieldCategory, fieldType?: number): void {
const field: FieldInSectionEditor = new FieldInSectionEditor();
field.id = Guid.create().toString();
field.ordinal = this.fieldsArray(sectionIndex).length + 1;
field.category = fieldCategory;
if(!isNullOrUndefined(fieldType)){
field.type = fieldType
}
field.required = (!isNullOrUndefined(fieldType) && (fieldType == 0 || fieldType == 1)) ? true : false;
this.fieldsArray(sectionIndex).push(field.buildForm());
}
removeField(sectionIndex: number, fieldIndex: number): void {
this.fieldsArray(sectionIndex).removeAt(fieldIndex);
}
systemFieldsArray(sectionIndex: number): FormArray {
return this.sectionsArray().at(sectionIndex).get('systemFields') as FormArray;
}
initSystemField(systemField?: SystemFieldType): FormGroup {
return this.fb.group({
id: this.fb.control(Guid.create().toString()),
type: this.fb.control(systemField),
label: this.fb.control(''),
placeholder: this.fb.control(''),
description: this.fb.control(''),
required: this.fb.control(true),
ordinal: this.fb.control('')
});
}
addSystemField(sectionIndex: number, systemField?: SystemFieldType): void {
this.addField(sectionIndex, FieldCategory.SYSTEM, systemField);
}
transfromEnumToString(type: SystemFieldType): string{
return this.fieldList.find(f => f.type == type).label;
}
selectedFieldType(type: SystemFieldType, sectionIndex: number): void {
if (this.systemFieldDisabled(type, sectionIndex)) return;
let index = this.systemFieldListPerSection[sectionIndex].indexOf(type);
if (index == -1) {
this.systemFieldListPerSection[sectionIndex].push(type);
this.addSystemField(sectionIndex, type);
}
else {
this.systemFieldListPerSection[sectionIndex].splice(index, 1);
this.removeSystemField(sectionIndex, type);
}
}
systemFieldDisabled(systemField: SystemFieldType, sectionIndex: number) {
let i = 0;
for (let s in this.sectionsArray().controls) {
if (i != sectionIndex) {
for (let f of this.fieldsArray(i).controls) {
if ((f.get('category').value == FieldCategory.SYSTEM || f.get('category').value == 'SYSTEM') && f.get('type').value == systemField) {
return true;
}
}
}
i++;
}
return false;
}
removeSystemFieldWithIndex(sectionIndex: number, fieldIndex: number): void {
let type: SystemFieldType = this.fieldsArray(sectionIndex).at(fieldIndex).get('type').value;
let index = this.systemFieldListPerSection[sectionIndex].indexOf(type);
this.systemFieldListPerSection[sectionIndex] = this.systemFieldListPerSection[sectionIndex].filter(types => types != type);
this.fieldsArray(sectionIndex).removeAt(fieldIndex);
}
removeSystemField(sectionIndex: number, systemField: SystemFieldType): void {
let i = 0;
for(let f of this.fieldsArray(sectionIndex).controls){
if((f.get('category').value == FieldCategory.SYSTEM || f.get('category').value == 'SYSTEM') && f.get('type').value == systemField){
this.fieldsArray(sectionIndex).removeAt(i);
return;
}
i++;
}
}
descriptionTemplatesArray(sectionIndex: number): FormArray {
return this.sectionsArray().at(sectionIndex).get('descriptionTemplates') as FormArray;
}
addDescriptionTemplate(descriptionTemplate, sectionIndex: number): void {
this.descriptionTemplatesArray(sectionIndex).push(this.fb.group({
label: this.fb.control(descriptionTemplate.value)
}));
}
removeDescriptionTemplate(sectionIndex: number, templateIndex: number): void {
this.descriptionTemplatesArray(sectionIndex).removeAt(templateIndex);
}
extraFieldsArray(sectionIndex: number): FormArray {
return this.sectionsArray().at(sectionIndex).get('extraFields') as FormArray;
}
addExtraField(sectionIndex: number): void {
this.addField(sectionIndex, FieldCategory.EXTRA);
}
removeExtraField(sectionIndex: number, fieldIndex: number): void {
this.fieldsArray(sectionIndex).removeAt(fieldIndex);
}
getExtraFieldTypes(): Number[] {
let keys: string[] = Object.keys(ExtraFieldType);
keys = keys.slice(0, keys.length / 2);
const values: Number[] = keys.map(Number);
return values;
}
getExtraFieldTypeValue(extraFieldType: ExtraFieldType): string {
switch (extraFieldType) {
case ExtraFieldType.TEXT: return 'Text';
case ExtraFieldType.RICH_TEXT: return 'Rich Text';
case ExtraFieldType.DATE: return 'Date';
case ExtraFieldType.NUMBER: return 'Number';
}
}
drop(event: CdkDragDrop<string[]>, sectionIndex: number) {
moveItemInArray(this.fieldsArray(sectionIndex).controls, event.previousIndex, event.currentIndex);
moveItemInArray(this.fieldsArray(sectionIndex).value, event.previousIndex, event.currentIndex);
}
dropSections(event: CdkDragDrop<string[]>) {
moveItemInArray(this.sectionsArray().controls, event.previousIndex, event.currentIndex);
moveItemInArray(this.sectionsArray().value, event.previousIndex, event.currentIndex);
this.sectionsArray().controls.forEach((section, index) => {
section.get('ordinal').setValue(index + 1);
});
moveItemInArray(this.systemFieldListPerSection, event.previousIndex, event.currentIndex);
moveItemInArray(this.descriptionTemplatesPerSection, event.previousIndex, event.currentIndex);
}
moveItemInFormArray(formArray: FormArray, fromIndex: number, toIndex: number): void {
const dir = toIndex > fromIndex ? 1 : -1;
const item = formArray.at(fromIndex);
for (let i = fromIndex; i * dir < toIndex * dir; i = i + dir) {
const current = formArray.at(i + dir);
formArray.setControl(i, current);
}
formArray.setControl(toIndex, item);
}
// clearForm(): void{
// this.dmpBlueprintsFormGroup.reset();
// }
onRemoveTemplate(event, sectionIndex: number) {
const profiles = this.descriptionTemplatesArray(sectionIndex).controls;
const foundIndex = profiles.findIndex(profile => profile.get('descriptionTemplateId').value === event.id);
foundIndex !== -1 && this.descriptionTemplatesArray(sectionIndex).removeAt(foundIndex);
}
onPreviewTemplate(event, sectionIndex: number) {
const dialogRef = this.dialog.open(DatasetPreviewDialogComponent, {
width: '590px',
minHeight: '200px',
restoreFocus: false,
data: {
template: event
},
panelClass: 'custom-modalbox'
});
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
if (result) {
const profile: DescriptionTemplatesInSectionEditor = new DescriptionTemplatesInSectionEditor();
profile.id = Guid.create().toString();
profile.descriptionTemplateId = event.id;
profile.label = event.label;
this.descriptionTemplatesArray(sectionIndex).push(profile.buildForm());
const items = this.descriptionTemplatesPerSection[sectionIndex];
items.push({id: event.id, label: event.label, description: ""});
this.descriptionTemplatesPerSection[sectionIndex] = [...items];
}
});
}
onOptionSelected(item, sectionIndex){
const profile: DescriptionTemplatesInSectionEditor = new DescriptionTemplatesInSectionEditor();
profile.id = Guid.create().toString();
profile.descriptionTemplateId = item.id;
profile.label = item.label;
this.descriptionTemplatesArray(sectionIndex).push(profile.buildForm());
}
checkValidity() {
this.formService.touchAllFormFields(this.formGroup);
if (!this.isFormValid()) { return false; }
let errorMessages = [];
if(!this.hasTitle()) {
errorMessages.push("Title should be set.");
}
if(!this.hasDescription()) {
errorMessages.push("Description should be set.");
}
if(!this.hasDescriptionTemplates()) {
errorMessages.push("At least one section should have description templates.");
}
if(errorMessages.length > 0) {
this.showValidationErrorsDialog(undefined, errorMessages);
return false;
}
return true;
}
formSubmit(): void {
if (this.checkValidity())
this.onSubmit();
}
public isFormValid() {
return this.formGroup.valid;
}
hasTitle(): boolean {
const dmpBlueprint: DmpBlueprint = this.formGroup.value;
return dmpBlueprint.definition.sections.some(section => section.fields.some(field => (field.category === FieldCategory.SYSTEM || field.category as unknown === 'SYSTEM') && field.type === SystemFieldType.TEXT));
}
hasDescription(): boolean {
const dmpBlueprint: DmpBlueprint = this.formGroup.value;
return dmpBlueprint.definition.sections.some(section => section.fields.some(field => (field.category === FieldCategory.SYSTEM || field.category as unknown === 'SYSTEM') && field.type === SystemFieldType.HTML_TEXT));
}
hasDescriptionTemplates(): boolean {
const dmpBlueprint: DmpBlueprint = this.formGroup.value;
return dmpBlueprint.definition.sections.some(section => section.hasTemplates == true);
}
private showValidationErrorsDialog(projectOnly?: boolean, errmess?: string[]) {
const dialogRef = this.dialog.open(FormValidationErrorsDialogComponent, {
disableClose: true,
autoFocus: false,
restoreFocus: false,
data: {
errorMessages:errmess,
projectOnly: projectOnly
},
});
}
onSubmit(): void {
this.dmpProfileService.createBlueprint(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(['/dmp-profiles']);
}
onCallbackError(errorResponse: any) {
this.setErrorModel(errorResponse.error);
this.formService.validateAllFormFields(this.formGroup);
}
public setErrorModel(validationErrorModel: ValidationErrorModel) {
Object.keys(validationErrorModel).forEach(item => {
(<any>this.dmpProfileModel.validationErrorModel)[item] = (<any>validationErrorModel)[item];
});
}
public cancel(): void {
this.router.navigate(['/dmp-profiles']);
}
// addField() {
// (<FormArray>this.formGroup.get('definition').get('fields')).push(new DmpProfileFieldEditorModel().buildForm());
// }
// removeField(index: number) {
// (<FormArray>this.formGroup.get('definition').get('fields')).controls.splice(index, 1);
// }
getDMPProfileFieldDataTypeValues(): Number[] {
let keys: string[] = Object.keys(DmpProfileFieldDataType);
keys = keys.slice(0, keys.length / 2);
const values: Number[] = keys.map(Number);
return values;
}
getDMPProfileFieldDataTypeWithLanguage(fieldType: DmpProfileFieldDataType): string {
let result = '';
this.language.get(this.enumUtils.toDmpProfileFieldDataTypeString(fieldType))
.pipe(takeUntil(this._destroyed))
.subscribe((value: string) => {
result = value;
});
return result;
}
getDMPProfileFieldTypeValues(): Number[] {
let keys: string[] = Object.keys(DmpProfileType);
keys = keys.slice(0, keys.length / 2);
const values: Number[] = keys.map(Number);
return values;
}
getDMPProfileFieldTypeWithLanguage(profileType: DmpProfileType): string {
let result = '';
this.language.get(this.enumUtils.toDmpProfileTypeString(profileType))
.pipe(takeUntil(this._destroyed))
.subscribe((value: string) => {
result = value;
});
return result;
}
delete() {
this.dialog.open(ConfirmationDialogComponent,{data:{
isDeleteConfirmation: true,
confirmButton: this.language.instant('DMP-PROFILE-EDITOR.CONFIRM-DELETE-DIALOG.CONFIRM-BUTTON'),
cancelButton: this.language.instant("DMP-PROFILE-EDITOR.CONFIRM-DELETE-DIALOG.CANCEL-BUTTON"),
message: this.language.instant("DMP-PROFILE-EDITOR.CONFIRM-DELETE-DIALOG.MESSAGE")
}})
.afterClosed()
.subscribe(
confirmed =>{
if(confirmed){
if(this.formGroup.get('status').value == DmpProfileStatus.Draft) {
this.formGroup.get('status').setValue(DmpProfileStatus.Deleted);
this.dmpProfileService.createBlueprint(this.formGroup.value)
.pipe(takeUntil(this._destroyed))
.subscribe(
complete => this.onCallbackSuccess(),
error => this.onCallbackError(error)
);
}
else {
this.dmpProfileService.delete(this.dmpProfileId)
.pipe(takeUntil(this._destroyed))
.subscribe(
complete => this.onCallbackSuccess(),
error => {
if (error.error.statusCode == 674) {
this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DMP-BLUEPRINT-DELETE'), SnackBarNotificationLevel.Error);
} else {
this.uiNotificationService.snackBarNotification(this.language.instant(error.message), SnackBarNotificationLevel.Error);
}
}
);
}
}
}
)
}
finalize() {
if (this.checkValidity()) {
this.formGroup.get('status').setValue(DmpProfileStatus.Finalized);
this.onSubmit();
}
}
downloadXML(): void {
this.dmpProfileService.downloadXML(this.dmpProfileId)
.pipe(takeUntil(this._destroyed))
.subscribe(response => {
const blob = new Blob([response.body], { type: 'application/xml' });
const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
FileSaver.saveAs(blob, filename);
});
}
getFilenameFromContentDispositionHeader(header: string): string {
const regex: RegExp = new RegExp(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/g);
const matches = header.match(regex);
let filename: string;
for (let i = 0; i < matches.length; i++) {
const match = matches[i];
if (match.includes('filename="')) {
filename = match.substring(10, match.length - 1);
break;
} else if (match.includes('filename=')) {
filename = match.substring(9);
break;
}
}
return filename;
}
isExternalAutocomplete(formGroup: FormGroup) {
if (formGroup.get('dataType').value == DmpProfileFieldDataType.ExternalAutocomplete) {
this.addControl(formGroup);
return true;
} else {
this.removeControl(formGroup);
return false;
}
}
addControl(formGroup: FormGroup) {
if (formGroup.get('dataType').value == 3)
formGroup.addControl('externalAutocomplete', new DmpProfileExternalAutoCompleteFieldDataEditorModel().buildForm());
}
removeControl(formGroup: FormGroup) {
if (formGroup.get('dataType').value != 3)
formGroup.removeControl('externalAutocomplete');
}
}