Skip to content

Commit 7c898db

Browse files
committed
feat: ui: add template expression widget
Signed-off-by: Thomas Bétrancourt <[email protected]>
1 parent 31a60a1 commit 7c898db

File tree

7 files changed

+139
-1
lines changed

7 files changed

+139
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import { ChangeDetectionStrategy, Component, Input } from "@angular/core";
2+
import { FormBuilder, FormGroup, Validators } from "@angular/forms";
3+
import { BehaviorSubject } from "rxjs";
4+
import Resolution from "../../@models/resolution.model";
5+
import { ApiService } from "../../@services/api.service";
6+
7+
@Component({
8+
selector: "lib-utask-resoution-expression",
9+
templateUrl: "./resolution-expression.html",
10+
styleUrls: ["./resolution-expression.sass"],
11+
changeDetection: ChangeDetectionStrategy.OnPush,
12+
})
13+
export class ResolutionExpressionComponent {
14+
private _resolution: Resolution;
15+
private _steps$ = new BehaviorSubject<String[]>([]);
16+
private _result$ = new BehaviorSubject<String | null>(null);
17+
private _error$ = new BehaviorSubject<String | null>(null);
18+
19+
readonly formGroup: FormGroup;
20+
21+
readonly steps$ = this._steps$.asObservable();
22+
readonly result$ = this._result$.asObservable();
23+
readonly error$ = this._error$.asObservable();
24+
25+
@Input("resolution") set resolution(r: Resolution) {
26+
if ((this._resolution = r)) {
27+
this._steps$.next(Object.keys(r.steps));
28+
} else {
29+
this._steps$.next([]);
30+
}
31+
}
32+
33+
get resolution(): Resolution {
34+
return this._resolution;
35+
}
36+
37+
constructor(private _api: ApiService, _builder: FormBuilder) {
38+
this.formGroup = _builder.group({
39+
step: ["", [Validators.required]],
40+
expression: ["", [Validators.required]],
41+
});
42+
}
43+
44+
reset(): void {
45+
this.formGroup.reset();
46+
this._result$.next(null);
47+
this._error$.next(null);
48+
}
49+
50+
submit(): void {
51+
const { step, expression } = this.formGroup.value;
52+
53+
this._api.resolution
54+
.templating(this._resolution, step, expression)
55+
.subscribe(
56+
(result) => {
57+
if (result.error) {
58+
this._result$.next(null);
59+
this._error$.next(result.error);
60+
} else {
61+
this._result$.next(result.result);
62+
this._error$.next(null);
63+
}
64+
},
65+
(e) => {
66+
this._result$.next(null);
67+
this._error$.next(e.error.error);
68+
}
69+
);
70+
}
71+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<form *ngIf="formGroup" nz-form [formGroup]="formGroup" [nzLayout]="'vertical'" (ngSubmit)="submit()">
2+
<nz-form-item>
3+
<nz-form-label nzFor="step" [nzRequired]="true">Step</nz-form-label>
4+
<nz-form-control nzErrorTip="Please select step!">
5+
<nz-select formControlName="step" nzPlaceHolder="Please select">
6+
<nz-option *ngFor="let step of steps$ | async" [nzLabel]="step" [nzValue]="step"></nz-option>
7+
</nz-select>
8+
</nz-form-control>
9+
</nz-form-item>
10+
<nz-form-item>
11+
<nz-form-label nzFor="expression" [nzRequired]="true">Template expression</nz-form-label>
12+
<nz-form-control nzErrorTip="Please set a valid value for expression!">
13+
<input type="string" formControlName="expression" nz-input [placeholder]="'{{.input}}'"/>
14+
</nz-form-control>
15+
</nz-form-item>
16+
</form>
17+
<lib-utask-error-message *ngIf="error$ | async as error" [data]="error">
18+
</lib-utask-error-message>
19+
<div class="buttons">
20+
<button nz-button nzType="secondary" type="button" (click)="reset()">Reset</button>
21+
<button nz-button nzType="primary" [disabled]="!formGroup.valid" type="button" (click)="submit()">Submit</button>
22+
</div>
23+
<div *ngIf="result$ | async as result" class="result">
24+
<pre>{{ result }}</pre>
25+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
.buttons
2+
margin-top: 1em
3+
4+
button
5+
margin-right: 0.5em
6+
7+
.result
8+
margin-top: 1em
9+
border: 1px solid #d9d9d9
10+
padding: 1em
11+
12+
pre
13+
margin: 0

ui/dashboard/projects/utask-lib/src/lib/@models/resolution.model.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,9 @@ export default class Resolution {
1414
task_id: string;
1515
task_title: string;
1616
steps: { [key: string]: Step };
17-
}
17+
}
18+
19+
export class TemplateExpression {
20+
result: string;
21+
error?: string;
22+
}

ui/dashboard/projects/utask-lib/src/lib/@routes/task/task.html

+11
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,17 @@
272272
</div>
273273
</lib-utask-box>
274274

275+
<!-- Templating expression box -->
276+
<lib-utask-box [header]="{openable: true, init: false, class: 'primary'}"
277+
*ngIf="meta.user_is_admin && resolution && resolution.steps">
278+
<div app-box-header>
279+
Template expression
280+
<span *ngIf="loaders.execution || loaders.refreshTask">&nbsp;<i nz-icon nzType="loading"></i></span>
281+
</div>
282+
<div app-box-content>
283+
<lib-utask-resoution-expression [resolution]="resolution"></lib-utask-resoution-expression>
284+
</div>
285+
</lib-utask-box>
275286
</ng-container>
276287

277288

ui/dashboard/projects/utask-lib/src/lib/@services/api.service.ts

+11
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { Observable } from 'rxjs';
55
import { HttpClient, HttpResponse } from '@angular/common/http';
66
import Meta from '../@models/meta.model';
77
import Template from '../@models/template.model';
8+
import Resolution, { TemplateExpression } from '../@models/resolution.model';
89

910
export class ParamsListTasks {
1011
page_size?: number;
@@ -314,6 +315,16 @@ export class ApiServiceResolution {
314315
resolution
315316
);
316317
}
318+
319+
templating(resolution: Resolution, step: string, expression: string) {
320+
return this.http.post<TemplateExpression>(
321+
`${this.base}resolution/${resolution.id}/templating`,
322+
{
323+
step_name: step,
324+
templating_expression: expression,
325+
}
326+
);
327+
}
317328
}
318329

319330
@Injectable({

ui/dashboard/projects/utask-lib/src/lib/utask-lib.module.ts

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { InputsFormComponent } from './@components/inputs-form/inputs-form.compo
1515
import { InputTagsComponent } from './@components/input-tags/input-tags.component';
1616
import { InputEditorComponent } from './@components/input-editor/input-editor.component';
1717
import { LoaderComponent } from './@components/loader/loader.component';
18+
import { ResolutionExpressionComponent } from './@components/resolution-expression/resolution-expression.component';
1819
import { MetaResolve } from './@resolves/meta.resolve';
1920
import { ModalApiYamlComponent } from './@modals/modal-api-yaml/modal-api-yaml.component';
2021
import { ModalEditResolutionStepStateComponent } from './@modals/modal-edit-resolution-step-state/modal-edit-resolution-step-state.component';
@@ -77,6 +78,7 @@ const components: any[] = [
7778
ModalEditResolutionStepStateComponent,
7879
ModalApiYamlEditComponent,
7980
NzModalContentWithErrorComponent,
81+
ResolutionExpressionComponent,
8082
StepNodeComponent,
8183
StepsListComponent,
8284
StepsViewerComponent,

0 commit comments

Comments
 (0)