Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7670bba

Browse files
bnjjjrichardlt
authored andcommitted
feat(api,ui): add workflow template usage (#3761)
Signed-off-by: Benjamin Coenen <[email protected]>
1 parent 355d53f commit 7670bba

File tree

7 files changed

+94
-5
lines changed

7 files changed

+94
-5
lines changed

engine/api/api_routes.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,7 @@ func (api *API) InitRouter() {
447447
r.Handle("/template/{groupName}/{templateSlug}/apply", r.POST(api.applyTemplateHandler))
448448
r.Handle("/template/{groupName}/{templateSlug}/instance", r.GET(api.getTemplateInstancesHandler))
449449
r.Handle("/template/{groupName}/{templateSlug}/audit", r.GET(api.getTemplateAuditsHandler))
450+
r.Handle("/template/{groupName}/{templateSlug}/usage", r.GET(api.getTemplateUsageHandler))
450451
r.Handle("/project/{key}/workflow/{permWorkflowName}/templateInstance", r.GET(api.getTemplateInstanceHandler))
451452

452453
//Not Found handler

engine/api/templates.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,3 +583,20 @@ func (api *API) getTemplateAuditsHandler() service.Handler {
583583
return service.WriteJSON(w, as, http.StatusOK)
584584
}
585585
}
586+
587+
func (api *API) getTemplateUsageHandler() service.Handler {
588+
return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
589+
ctx, err := api.middlewareTemplate(false)(ctx, w, r)
590+
if err != nil {
591+
return err
592+
}
593+
wfTmpl := getWorkflowTemplate(ctx)
594+
595+
wfs, err := workflow.LoadByWorkflowTemplateID(ctx, api.mustDB(), wfTmpl.ID)
596+
if err != nil {
597+
return sdk.WrapError(err, "Cannot load templates")
598+
}
599+
600+
return service.WriteJSON(w, wfs, http.StatusOK)
601+
}
602+
}

engine/api/workflow/dao.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,35 @@ func LoadByEnvName(db gorp.SqlExecutor, projectKey string, envName string) ([]sd
409409
return res, nil
410410
}
411411

412+
// LoadByWorkflowTemplateID load all workflows linked to a workflow template but without loading workflow details
413+
func LoadByWorkflowTemplateID(ctx context.Context, db gorp.SqlExecutor, templateID int64) ([]sdk.Workflow, error) {
414+
var dbRes []Workflow
415+
query := `
416+
SELECT workflow.*
417+
FROM workflow
418+
JOIN workflow_template_instance ON workflow_template_instance.workflow_id = workflow.id
419+
WHERE workflow_template_instance.workflow_template_id = $1 AND workflow.to_delete = false
420+
`
421+
if _, err := db.Select(&dbRes, query, templateID); err != nil {
422+
if err == sql.ErrNoRows {
423+
return nil, nil
424+
}
425+
return nil, err
426+
}
427+
428+
workflows := make([]sdk.Workflow, len(dbRes))
429+
for i, wf := range dbRes {
430+
var err error
431+
wf.ProjectKey, err = db.SelectStr("SELECT projectkey FROM project WHERE id = $1", wf.ProjectID)
432+
if err != nil {
433+
return nil, sdk.WrapError(err, "cannot load project key for workflow %s and project_id %d", wf.Name, wf.ProjectID)
434+
}
435+
workflows[i] = sdk.Workflow(wf)
436+
}
437+
438+
return workflows, nil
439+
}
440+
412441
func load(ctx context.Context, db gorp.SqlExecutor, store cache.Store, proj *sdk.Project, opts LoadOptions, u *sdk.User, query string, args ...interface{}) (*sdk.Workflow, error) {
413442
t0 := time.Now()
414443
dbRes := Workflow{}

ui/src/app/service/workflow-template/workflow-template.service.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
WorkflowTemplateInstance,
1010
WorkflowTemplateRequest
1111
} from '../../model/workflow-template.model';
12+
import { Workflow } from '../../model/workflow.model';
1213

1314
@Injectable()
1415
export class WorkflowTemplateService {
@@ -54,4 +55,8 @@ export class WorkflowTemplateService {
5455
let url = '/template/' + groupName + '/' + templateSlug + '/audit' + (version ? '?sinceVersion=' + version : '');
5556
return this._http.get<Array<AuditWorkflowTemplate>>(url);
5657
}
58+
59+
getWorkflowTemplateUsage(groupName: string, templateSlug: string): Observable<Array<Workflow>> {
60+
return this._http.get<Array<Workflow>>('/template/' + groupName + '/' + templateSlug + '/usage');
61+
}
5762
}

ui/src/app/shared/usage/workflows/usage.workflows.html

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@ <h3><i class="share alternate icon"></i> {{'usage_workflow_list' | translate}}</
44
<ng-template #workflowsDisplay>
55
<div class="ui stackable four column grid">
66
<div class="center aligned column" *ngFor="let workflow of workflows">
7-
<a [routerLink]="['/project', project.key, 'workflow', workflow.name]">{{workflow.name}}</a>
7+
<ng-container *ngIf="project">
8+
<a [routerLink]="['/project', project.key, 'workflow', workflow.name]">{{workflow.name}}</a>
9+
</ng-container>
10+
<ng-container *ngIf="!project">
11+
<a [routerLink]="['/project', workflow.project_key, 'workflow', workflow.name]">{{workflow.name}}</a>
12+
</ng-container>
813
</div>
914
</div>
1015
</ng-template>

ui/src/app/views/settings/workflow-template/edit/workflow-template.edit.component.ts

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ import { Component, OnInit } from '@angular/core';
22
import { ActivatedRoute, Router } from '@angular/router';
33
import { TranslateService } from '@ngx-translate/core';
44
import { finalize } from 'rxjs/internal/operators/finalize';
5+
import { first } from 'rxjs/operators';
56
import { AuditWorkflowTemplate } from '../../../../model/audit.model';
67
import { Group } from '../../../../model/group.model';
78
import { WorkflowTemplate } from '../../../../model/workflow-template.model';
9+
import { Workflow } from '../../../../model/workflow.model';
810
import { GroupService } from '../../../../service/services.module';
911
import { WorkflowTemplateService } from '../../../../service/workflow-template/workflow-template.service';
1012
import { PathItem } from '../../../../shared/breadcrumb/breadcrumb.component';
@@ -24,13 +26,17 @@ export class WorkflowTemplateEditComponent implements OnInit {
2426
workflowTemplate: WorkflowTemplate;
2527
groups: Array<Group>;
2628
audits: Array<AuditWorkflowTemplate>;
29+
workflowsLinked: Array<Workflow>;
2730
loading: boolean;
2831
loadingAudits: boolean;
32+
loadingUsage: boolean;
2933
path: Array<PathItem>;
3034
tabs: Array<Tab>;
3135
selectedTab: Tab;
3236
columns: Array<Column>;
3337
diffItems: Array<Item>;
38+
groupName: string;
39+
templateSlug: string;
3440

3541
constructor(
3642
private _workflowTemplateService: WorkflowTemplateService,
@@ -51,6 +57,10 @@ export class WorkflowTemplateEditComponent implements OnInit {
5157
translate: 'common_audit',
5258
icon: 'history',
5359
key: 'audits'
60+
}, <Tab>{
61+
translate: 'common_usage',
62+
icon: 'map signs',
63+
key: 'usage'
5464
}];
5565

5666
this.columns = [
@@ -79,10 +89,10 @@ export class WorkflowTemplateEditComponent implements OnInit {
7989
];
8090

8191
this._route.params.subscribe(params => {
82-
const groupName = params['groupName'];
83-
const templateSlug = params['templateSlug'];
84-
this.getTemplate(groupName, templateSlug);
85-
this.getAudits(groupName, templateSlug);
92+
this.groupName = params['groupName'];
93+
this.templateSlug = params['templateSlug'];
94+
this.getTemplate(this.groupName, this.templateSlug);
95+
this.getAudits(this.groupName, this.templateSlug);
8696
});
8797

8898
this.getGroups();
@@ -160,6 +170,9 @@ export class WorkflowTemplateEditComponent implements OnInit {
160170
}
161171

162172
selectTab(tab: Tab): void {
173+
if (tab.key === 'usage') {
174+
this.getUsage();
175+
}
163176
this.selectedTab = tab;
164177
}
165178

@@ -192,4 +205,15 @@ export class WorkflowTemplateEditComponent implements OnInit {
192205
}
193206
this.saveWorkflowTemplate();
194207
}
208+
209+
getUsage() {
210+
if (this.workflowsLinked) {
211+
return;
212+
}
213+
this.loadingUsage = true;
214+
this._workflowTemplateService.getWorkflowTemplateUsage(this.groupName, this.templateSlug)
215+
.pipe(first())
216+
.pipe(finalize(() => this.loadingUsage = false))
217+
.subscribe((workflows) => this.workflowsLinked = workflows);
218+
}
195219
}

ui/src/app/views/settings/workflow-template/edit/workflow-template.edit.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,13 @@ <h3>{{ "common_last_modified" | translate }}</h3>
3232
<app-diff-list *ngIf="diffItems" [items]="diffItems"></app-diff-list>
3333
</div>
3434
</div>
35+
<div *ngSwitchCase="'usage'" class="ui grid">
36+
<div class="sixteen wide column">
37+
<div class="ui active centered inline loader" *ngIf="loadingUsage"></div>
38+
<ng-container *ngIf="!loadingUsage">
39+
<app-usage [workflows]="workflowsLinked"></app-usage>
40+
</ng-container>
41+
</div>
42+
</div>
3543
</app-scrollview>
3644
</div>

0 commit comments

Comments
 (0)