Skip to content

Commit 762f22c

Browse files
authored
feat(ui): display run result in artifacts list (#5815)
1 parent 43cffbd commit 762f22c

File tree

7 files changed

+121
-52
lines changed

7 files changed

+121
-52
lines changed

cli/cdsctl/workflow_run_result.go

+1
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ func toCLIRunResult(results []sdk.WorkflowRunResult) ([]RunResultCli, error) {
244244
return nil, err
245245
}
246246
name = artiResult.Name
247+
artiType = artiResult.RepoType
247248
}
248249

249250
cliresults = append(cliresults, RunResultCli{

ui/src/app/model/workflow.run.model.ts

+17
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,14 @@ export class WorkflowRunResult {
146146
data: any;
147147
}
148148

149+
export class UIArtifact {
150+
name: string;
151+
md5: string;
152+
size: number;
153+
link: string;
154+
type: string;
155+
}
156+
149157

150158
export class WorkflowRunResultArtifact {
151159
name: string
@@ -154,6 +162,15 @@ export class WorkflowRunResultArtifact {
154162
cdn_hash: string;
155163
}
156164

165+
export class WorkflowRunResultArtifactManager {
166+
name: string;
167+
size: number;
168+
md5: string;
169+
path: string;
170+
repository_name: string;
171+
repository_type: string;
172+
}
173+
157174
export class WorkflowNodeOutgoingHookRunCallback {
158175
workflow_node_outgoing_hook_id: number;
159176
start: Date;

ui/src/app/shared/table/data-table.html

+7-5
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,13 @@
9999
{{' '}}<span *ngFor="let l of c.selector.labels" class="ui label {{l.color}}">{{l.title | translate}}</span>
100100
</ng-container>
101101
<div *ngSwitchCase="'text-copy'" class="ui fluid action input">
102-
<input type="text" value="{{c.selector}}">
103-
<button class="ui icon button copyButton" [title]="'common_copy_clipboard' | translate"
104-
ngxClipboard [cbContent]="c.selector">
105-
<i class="copy icon"></i>
106-
</button>
102+
<ng-container *ngIf="c.selector">
103+
<input type="text" value="{{c.selector}}">
104+
<button class="ui icon button copyButton" [title]="'common_copy_clipboard' | translate"
105+
ngxClipboard [cbContent]="c.selector">
106+
<i class="copy icon"></i>
107+
</button>
108+
</ng-container>
107109
</div>
108110
<span *ngSwitchCase="'text-labels'" class="text-labels">
109111
{{c.selector.value |
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
22
import { Select, Store } from '@ngxs/store';
33
import {
4+
UIArtifact,
45
WorkflowNodeRun,
56
WorkflowNodeRunArtifact,
6-
WorkflowNodeRunStaticFiles,
7-
WorkflowRunResultArtifact
7+
WorkflowNodeRunStaticFiles, WorkflowRunResult,
8+
WorkflowRunResultArtifact, WorkflowRunResultArtifactManager
89
} from 'app/model/workflow.run.model';
910

1011
import { AutoUnsubscribe } from 'app/shared/decorator/autoUnsubscribe';
1112
import { Column, ColumnType, Filter } from 'app/shared/table/data-table.component';
1213
import { WorkflowState } from 'app/store/workflow.state';
1314
import { Observable, Subscription } from 'rxjs';
15+
import { Workflow } from 'app/model/workflow.model';
1416

1517
@Component({
1618
selector: 'app-workflow-artifact-list',
@@ -23,42 +25,46 @@ export class WorkflowRunArtifactListComponent implements OnInit, OnDestroy {
2325
@Select(WorkflowState.getSelectedNodeRun()) nodeRun$: Observable<WorkflowNodeRun>;
2426
nodeRunSubs: Subscription;
2527

28+
runResult: Array<WorkflowRunResult>
2629
artifacts: Array<WorkflowNodeRunArtifact>;
30+
31+
uiArtifacts: Array<UIArtifact>;
2732
staticFiles: Array<WorkflowNodeRunStaticFiles>;
2833

29-
filter: Filter<WorkflowNodeRunArtifact>;
30-
columns: Array<Column<WorkflowNodeRunArtifact>>;
34+
filter: Filter<UIArtifact>;
35+
columns: Array<Column<UIArtifact>>;
3136

3237
constructor(private _cd: ChangeDetectorRef, private _store: Store) {
3338
this.filter = f => {
3439
const lowerFilter = f.toLowerCase();
3540
return d => d.name.toLowerCase().indexOf(lowerFilter) !== -1 ||
36-
d.sha512sum.toLowerCase().indexOf(lowerFilter) !== -1
41+
d.md5.toLowerCase().indexOf(lowerFilter) !== -1
3742
};
3843
this.columns = [
39-
<Column<WorkflowNodeRunArtifact>>{
44+
<Column<UIArtifact>>{
4045
type: ColumnType.LINK,
4146
name: 'artifact_name',
42-
selector: (a: WorkflowNodeRunArtifact) => {
47+
selector: (a: UIArtifact) => {
4348
let size = this.getHumainFileSize(a.size);
44-
let link = `./cdsapi/workflow/artifact/${a.download_hash}`
45-
if (!a.id) {
46-
link = `./cdscdn/item/run-result/${a.download_hash}/download`
49+
let link = a.link;
50+
let value = a.name;
51+
if (size) {
52+
value += ` (${size})`;
4753
}
4854
return {
4955
link,
50-
value: `${a.name} (${size})`
56+
value
5157
};
5258
}
5359
},
54-
<Column<WorkflowNodeRunArtifact>>{
55-
name: 'artifact_tag',
56-
selector: (a: WorkflowNodeRunArtifact) => a.tag
60+
<Column<UIArtifact>>{
61+
name: 'Type of artifact',
62+
selector: (a: UIArtifact) => a.type
5763
},
58-
<Column<WorkflowNodeRunArtifact>>{
64+
<Column<UIArtifact>>{
5965
type: ColumnType.TEXT_COPY,
6066
name: 'MD5 Sum',
61-
selector: (a: WorkflowNodeRunArtifact) => a.md5sum
67+
selector: (a: UIArtifact) => a.md5
6268
}
6369
];
6470
}
@@ -70,16 +76,36 @@ export class WorkflowRunArtifactListComponent implements OnInit, OnDestroy {
7076
if (!nr) {
7177
return;
7278
}
73-
let resultArtifacts = nr?.results.filter(r => r.type === 'artifact').map(r => <WorkflowRunResultArtifact>r.data);
74-
if (!resultArtifacts) {
75-
resultArtifacts = new Array<WorkflowRunResultArtifact>();
79+
80+
let computeArtifact = false;
81+
if (nr.results && (!this.runResult || nr.results.length !== this.runResult.length)) {
82+
computeArtifact = true
83+
}
84+
if (nr.artifacts && (!this.artifacts || nr.artifacts.length !== this.artifacts.length)) {
85+
computeArtifact = true
7686
}
77-
if ( (!this.artifacts && (nr.artifacts || resultArtifacts.length > 0)) || (this.artifacts && nr.artifacts && this.artifacts.length !== (nr.artifacts.length + resultArtifacts.length))) {
78-
this.artifacts = new Array<WorkflowNodeRunArtifact>();
87+
if (computeArtifact) {
88+
let uiArtifacts: Array<UIArtifact>;
89+
let uiRunResults: Array<UIArtifact>;
90+
this.uiArtifacts = new Array<UIArtifact>();
91+
if (nr.results) {
92+
let w = this._store.selectSnapshot(WorkflowState.workflowRunSnapshot).workflow
93+
uiRunResults = this.toUIArtifact(w, nr.results);
94+
this.uiArtifacts.push(...uiRunResults);
95+
}
96+
7997
if (nr.artifacts) {
80-
this.artifacts.push(...nr.artifacts);
98+
uiArtifacts = nr.artifacts.map(a => {
99+
let uiArt = new UIArtifact();
100+
uiArt.name = a.name;
101+
uiArt.size = a.size;
102+
uiArt.md5 = a.md5sum;
103+
uiArt.type = 'file';
104+
uiArt.link = `./cdscdn/item/artifact/${a.download_hash}/download`;
105+
return uiArt;
106+
});
107+
this.uiArtifacts.push(...uiArtifacts)
81108
}
82-
this.artifacts.push(...this.toWorkflowNodeRunArtifacts(resultArtifacts));
83109
this._cd.markForCheck();
84110
}
85111
if ((!this.staticFiles && nr.static_files) ||
@@ -90,25 +116,52 @@ export class WorkflowRunArtifactListComponent implements OnInit, OnDestroy {
90116
});
91117
}
92118

93-
toWorkflowNodeRunArtifacts(results: Array<WorkflowRunResultArtifact>): Array<WorkflowNodeRunArtifact> {
94-
let arts = new Array<WorkflowNodeRunArtifact>();
95-
results.forEach(r => {
96-
let a = new WorkflowNodeRunArtifact();
97-
a.download_hash = r.cdn_hash;
98-
a.md5sum = r.md5;
99-
a.size = r.size;
100-
a.name = r.name;
101-
arts.push(a);
102-
})
103-
return arts;
104-
}
105-
106119
getHumainFileSize(size: number): string {
107120
if (size === 0) {
108-
return '0B';
121+
return '';
109122
}
110123
let i = Math.floor(Math.log(size) / Math.log(1024));
111124
let hSize = (size / Math.pow(1024, i)).toFixed(2);
112125
return hSize + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][i];
113126
}
127+
128+
private toUIArtifact(w: Workflow, results: Array<WorkflowRunResult>): Array<UIArtifact> {
129+
if (!results) {
130+
return [];
131+
}
132+
let integrationArtifactManagerURL = '';
133+
if (w?.integrations) {
134+
for (let i = 0; i < w.integrations.length; i++) {
135+
let integ = w.integrations[i];
136+
if (!integ.project_integration.model.artifact_manager) {
137+
continue
138+
}
139+
integrationArtifactManagerURL = integ?.project_integration?.config['url']?.value;
140+
}
141+
}
142+
143+
return results.map(r => {
144+
switch (r.type) {
145+
case 'artifact':
146+
case 'coverage':
147+
let data = <WorkflowRunResultArtifact>r.data;
148+
let uiArtifact = new UIArtifact();
149+
uiArtifact.link = `./cdscdn/item/run-result/${data.cdn_hash}/download`;
150+
uiArtifact.md5 = data.md5;
151+
uiArtifact.name = data.name;
152+
uiArtifact.size = data.size;
153+
uiArtifact.type = 'file';
154+
return uiArtifact;
155+
case 'artifact-manager':
156+
let dataAM = <WorkflowRunResultArtifactManager>r.data;
157+
let uiArtifactAM = new UIArtifact();
158+
uiArtifactAM.link = `${integrationArtifactManagerURL}${dataAM.repository_name}/${dataAM.path}`;
159+
uiArtifactAM.md5 = dataAM.md5;
160+
uiArtifactAM.name = dataAM.name;
161+
uiArtifactAM.size = dataAM.size;
162+
uiArtifactAM.type = dataAM.repository_type;
163+
return uiArtifactAM;
164+
}
165+
})
166+
}
114167
}

ui/src/app/views/workflow/run/node/artifact/artifact.list.html

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<div class="artifact" *ngIf="artifacts || staticFiles">
1+
<div class="artifact" *ngIf="uiArtifacts || staticFiles">
22
<table class="ui fixed celled table" *ngIf="staticFiles && staticFiles.length > 0">
33
<thead>
44
<tr>
@@ -21,5 +21,5 @@
2121
</tr>
2222
</tbody>
2323
</table>
24-
<app-data-table [withFilter]="filter" [withPagination]="10" [columns]="columns" [data]="artifacts"></app-data-table>
25-
</div>
24+
<app-data-table [withFilter]="filter" [withPagination]="10" [columns]="columns" [data]="uiArtifacts"></app-data-table>
25+
</div>

ui/src/app/views/workflow/run/node/workflow.run.node.component.ts

+3-6
Original file line numberDiff line numberDiff line change
@@ -124,16 +124,13 @@ export class WorkflowNodeRunComponent implements OnInit, OnDestroy {
124124
refresh = true;
125125
}
126126

127-
let artiResults = nr?.results?.filter(r => r.type === 'artifact');
128-
let artiResultsLength = 0;
129-
if (artiResults) {
130-
artiResultsLength = artiResults.length
131-
}
127+
128+
let artiResultsLength = nr?.results?.length ?? 0
132129
let oldArtiLength = 0;
133130
if (nr.artifacts) {
134131
oldArtiLength = nr.artifacts.length;
135132
}
136-
if ((nr.artifacts || artiResults) && (oldArtiLength + artiResultsLength) !== this.artifactLength) {
133+
if ((nr.artifacts || artiResultsLength > 0) && (oldArtiLength + artiResultsLength) !== this.artifactLength) {
137134
this.artifactLength = oldArtiLength + artiResultsLength;
138135
refresh = true;
139136
}

ui/src/assets/i18n/en.json

-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@
9898
"application_variable_list_title": "List of application variables: ",
9999
"application_variable_form_title": "Add a new variable: ",
100100
"artifact_name": "Artifact name",
101-
"artifact_tag": "Tag",
102101
"ascode_error_unknown_type": "Cannot determine the resource to update",
103102
"ascode_modal_title": "Save as code",
104103
"ascode_modal_label_branch": "Select or create a branch",

0 commit comments

Comments
 (0)