1
0
Files
yel-dspace-angular/src/app/process-page/form/process-form.component.ts

213 lines
6.3 KiB
TypeScript

import {
NgFor,
NgIf,
} from '@angular/common';
import {
Component,
Input,
OnInit,
} from '@angular/core';
import {
FormsModule,
NgForm,
} from '@angular/forms';
import {
NavigationExtras,
Router,
RouterLink,
} from '@angular/router';
import {
TranslateModule,
TranslateService,
} from '@ngx-translate/core';
import { ScriptDataService } from '../../core/data/processes/script-data.service';
import { RemoteData } from '../../core/data/remote-data';
import { getFirstCompletedRemoteData } from '../../core/shared/operators';
import { isEmpty } from '../../shared/empty.util';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { getProcessListRoute } from '../process-page-routing.paths';
import { Process } from '../processes/process.model';
import { ProcessParameter } from '../processes/process-parameter.model';
import { Script } from '../scripts/script.model';
import { ScriptParameter } from '../scripts/script-parameter.model';
import { ProcessParametersComponent } from './process-parameters/process-parameters.component';
import { ScriptHelpComponent } from './script-help/script-help.component';
import { ScriptsSelectComponent } from './scripts-select/scripts-select.component';
/**
* Component to create a new script
*/
@Component({
selector: 'ds-process-form',
templateUrl: './process-form.component.html',
styleUrls: ['./process-form.component.scss'],
standalone: true,
imports: [FormsModule, ScriptsSelectComponent, ProcessParametersComponent, RouterLink, ScriptHelpComponent, NgIf, NgFor, TranslateModule],
})
export class ProcessFormComponent implements OnInit {
/**
* The currently selected script
*/
@Input() public selectedScript: Script = undefined;
/**
* The process to create
*/
@Input() public process: Process = undefined;
/**
* The parameter values to use to start the process
*/
@Input() public parameters: ProcessParameter[] = [];
/**
* Optional files that are used as parameter values
*/
public files: File[] = [];
/**
* Message key for the header of the form
*/
@Input() public headerKey: string;
/**
* Contains the missing parameters on submission
*/
public missingParameters = [];
constructor(
private scriptService: ScriptDataService,
private notificationsService: NotificationsService,
private translationService: TranslateService,
private router: Router) {
}
ngOnInit(): void {
this.process = new Process();
}
/**
* Validates the form, sets the parameters to correct values and invokes the script with the correct parameters
* @param form
*/
submitForm(form: NgForm) {
if (isEmpty(this.parameters)) {
this.parameters = [];
}
if (!this.validateForm(form) || this.isRequiredMissing()) {
return;
}
const stringParameters: ProcessParameter[] = this.parameters.map((parameter: ProcessParameter) => {
return {
name: parameter.name,
value: this.checkValue(parameter),
};
},
);
this.scriptService.invoke(this.selectedScript.id, stringParameters, this.files)
.pipe(getFirstCompletedRemoteData())
.subscribe((rd: RemoteData<Process>) => {
if (rd.hasSucceeded) {
const title = this.translationService.get('process.new.notification.success.title');
const content = this.translationService.get('process.new.notification.success.content');
this.notificationsService.success(title, content);
this.sendBack(rd.payload);
} else {
const title = this.translationService.get('process.new.notification.error.title');
const content = this.translationService.get('process.new.notification.error.content');
this.notificationsService.error(title, content);
}
});
}
/**
* Checks whether the parameter values are files
* Replaces file parameters by strings and stores the files in a separate list
* @param processParameter The parameter value to check
*/
private checkValue(processParameter: ProcessParameter): string {
if (typeof processParameter.value === 'object') {
this.files = [...this.files, processParameter.value];
return processParameter.value.name;
}
return processParameter.value;
}
/**
* Validates the form
* Returns false if the form is invalid
* Returns true if the form is valid
* @param form The NgForm object to validate
*/
private validateForm(form: NgForm) {
let valid = true;
Object.keys(form.controls).forEach((key) => {
if (form.controls[key].invalid) {
form.controls[key].markAsDirty();
valid = false;
}
});
return valid;
}
private isRequiredMissing() {
this.missingParameters = [];
const setParams: string[] = this.parameters
.map((param) => param.name);
const requiredParams: ScriptParameter[] = this.selectedScript.parameters.filter((param) => param.mandatory);
for (const rp of requiredParams) {
if (!setParams.includes(rp.name)) {
this.missingParameters.push(rp.name);
}
}
return this.missingParameters.length > 0;
}
/**
* Redirect the user to the processes overview page with the new process' ID,
* so it can be highlighted in the overview table.
* @param newProcess The newly created process
* @private
*/
private sendBack(newProcess: Process) {
const extras: NavigationExtras = {
queryParams: { new_process_id: newProcess.processId },
};
void this.router.navigate([getProcessListRoute()], extras);
}
updateScript($event: Script) {
this.selectedScript = $event;
this.parameters = undefined;
this.updateName();
}
updateName(): void {
if (isEmpty(this.customName)) {
this.processName = this.generatedProcessName;
} else {
this.processName = this.customName;
}
}
get generatedProcessName() {
const paramsString = this.parameters?.map((p: ProcessParameter) => {
const value = this.parseValue(p.value);
return isEmpty(value) ? p.name : `${p.name} ${value}`;
}).join(' ') || '';
return isEmpty(paramsString) ? this.selectedScript.name : `${this.selectedScript.name} ${paramsString}`;
}
private parseValue(value: any) {
if (typeof value === 'boolean') {
return undefined;
}
if (value instanceof File) {
return value.name;
}
return value?.toString();
}
}