dnet-docker/dnet-app/frontends/is/src/app/wf-confs/wf-common.component.ts

213 lines
6.4 KiB
TypeScript

import { Component, Inject, OnInit, ViewChild, ElementRef, AfterViewInit } from '@angular/core';
import { FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { MatSelectChange } from '@angular/material/select';
import { SimpleResource, WfParam, WfTemplateDesc } from '../common/is.model';
import { ResMetadataDialog } from '../resources/resources.component';
import { WfConfsClient } from './wf-confs.client';
import mermaid from 'mermaid';
@Component({
selector: 'wf-template-dialog',
templateUrl: 'wf-template-dialog.html',
styleUrls: []
})
export class WfTemplateDialog implements AfterViewInit {
template: WfTemplateDesc;
@ViewChild('mermaidGraph', { static: false }) mermaidGraph!: ElementRef;
constructor(public dialogRef: MatDialogRef<WfTemplateDialog>, @Inject(MAT_DIALOG_DATA) public data: any, public client: WfConfsClient) {
this.template = data;
}
public ngAfterViewInit(): void {
const element: any = this.mermaidGraph.nativeElement;
/* flowchart TD
A[Start] --> B{Is it?}
B -- Yes --> C[OK]
C --> D[Rethink]
D --> B
B -- No ----> E[End]
*/
let code = "%%{ init: { 'theme': 'base', 'themeVariables': { 'fontSize' : '11px' } } }%%\n";
code += 'flowchart TD\n';
code += "\tstart([" + this.graphNodeText('start', undefined) + "])\n";
code += "\tclass start graphStartNode\n";
code += "\tsuccess([" + this.graphNodeText('success', undefined) + "])\n";
code += "\tclass success graphSuccessNode\n";
code += "\tfailure([" + this.graphNodeText('failure', undefined) + "])\n";
code += "\tclass failure graphFailureNode\n";
this.template.graph.forEach((node: any) => {
let from: string = node.name;
if (node.start) { code += "\tstart --> " + from + "\n"; }
code += "\t" + from;
if (node.join) {
code += '{{' + this.graphNodeText(from, node.type) + '}}';
code += "\n\tclass " + from + " graphJoinNode\n";
} else {
code += '(' + this.graphNodeText(from, node.type) + ')';
code += "\n\tclass " + from + " graphSimpleNode\n";
}
code += "\t\t" + from + " --> failure\n";
if (node.arcs.length) {
node.arcs.forEach((arc: any) => {
code += "\t\t" + from;
if (arc.condition) { code += ' -- ' + arc.condition; }
code += ' --> ' + arc.to + "\n";
});
} else {
code += "\t\t" + from + " --> success\n";
}
});
code += "classDef default font-size:9pt\n";
element.innerHTML = code;
mermaid.initialize({ theme: "base", flowchart: { titleTopMargin: 0, useMaxWidth: false, htmlLabels: false } });
mermaid.run();
}
graphNodeText(name: string, type?: string) {
let res = '"`' + name;
if (type) { res += '\n**(' + type + ')**'; }
res += '`"';
return res;
}
startRepoHiWf(wfId: string): void {
alert('TODO REPO HI');
}
showGraphModal(wfId: string): void {
alert('TODO REPO HI');
}
onNoClick(): void {
this.dialogRef.close();
}
}
@Component({
selector: 'wf-conf-dialog',
templateUrl: 'wf-conf-dialog.html',
styleUrls: []
})
export class WfConfDialog implements OnInit {
wfTemplates: SimpleResource[] = [];
wfParameters: WfParam[] = [];
editMode: boolean = true;
wfConfFormStep1 = new FormGroup({
workflows: new FormControl([], [Validators.required]),
});
wfConfFormStep2 = new FormGroup({
name: new FormControl('', [Validators.required]),
//details: Map<string, string>,
enabled: new FormControl(true, [Validators.required]),
priority: new FormControl(75, [Validators.required, Validators.min(1), Validators.max(100)]),
});
wfConfFormStep3 = new FormGroup({});
wfConfFormStep4 = new FormGroup({
schedulingEnabled: new FormControl(false, [Validators.required]),
cronExpression: new FormControl("", [Validators.required]),
cronMinInterval: new FormControl("", [Validators.required]),
});
wfConfFormFinal = new FormGroup({});
constructor(public dialogRef: MatDialogRef<ResMetadataDialog>, @Inject(MAT_DIALOG_DATA) public data: any, public client: WfConfsClient) {
if (data.id && data.workflows && data.workflows.length > 0) {
this.editMode = true;
} else {
this.editMode = false;
}
this.wfConfFormStep1.get('workflows')?.setValue(data.workflows);
this.wfConfFormStep2.get('name')?.setValue(data.name);
this.wfConfFormStep2.get('enabled')?.setValue(data.enabled);
this.wfConfFormStep2.get('priority')?.setValue(data.priority);
//details
//systemParams,
//userParams
this.wfConfFormStep4.get('schedulingEnabled')?.setValue(data.schedulingEnabled);
this.wfConfFormStep4.get('cronExpression')?.setValue(data.cronExpression);
this.wfConfFormStep4.get('cronMinInterval')?.setValue(data.cronMinInterval);
}
ngOnInit(): void {
if (this.editMode) {
this.prepareWfParameters(this.data.workflows);
} else {
this.client.loadWfTemplates((data: SimpleResource[]) => this.wfTemplates = data);
}
}
onChangeWfTemplate(e: MatSelectChange): void {
this.prepareWfParameters(e.value);
}
prepareWfParameters(wfTemplateIds: string[]): void {
this.wfConfFormStep3.controls = {};
this.wfParameters = [];
this.client.loadWfTemplatesParams(wfTemplateIds, (data: WfParam[]) => {
this.wfParameters = data;
this.wfParameters.forEach(p => {
let validations: ValidatorFn[] = [];
if (p.required) { validations.push(Validators.required); }
if (p.type == 'number') { validations.push(Validators.pattern('^[0-9]*$')); }
if (this.data.userParams[p.name]) {
this.wfConfFormStep3.addControl(p.name, new FormControl(this.data.userParams[p.name], validations));
} else if (this.data.systemParams[p.name]) {
this.wfConfFormStep3.addControl(p.name, new FormControl({ value: this.data.systemParams[p.name], disabled: true }, validations));
} else if (p.defaultValue) {
this.wfConfFormStep3.addControl(p.name, new FormControl(p.defaultValue, validations));
} else {
this.wfConfFormStep3.addControl(p.name, new FormControl('', validations));
}
})
});
}
onSubmit(): void {
const conf = Object.assign({}, this.data, this.wfConfFormStep1.value, this.wfConfFormStep2.value, this.wfConfFormStep4.value);
conf.userParams = {};
this.wfParameters.forEach(p => {
if (!this.data.systemParams[p.name]) {
conf.userParams[p.name] = this.wfConfFormStep3.get(p.name)?.value;
}
});
this.client.saveWfConfiguration(conf, (data: void) => this.dialogRef.close(data), this.wfConfFormFinal);
}
onNoClick(): void {
this.dialogRef.close();
}
}