Skip to content

Commit

Permalink
feat(ui): display run result in artifacts list (#5815)
Browse files Browse the repository at this point in the history
  • Loading branch information
sguiheux authored May 21, 2021
1 parent 43cffbd commit 762f22c
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 52 deletions.
1 change: 1 addition & 0 deletions cli/cdsctl/workflow_run_result.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ func toCLIRunResult(results []sdk.WorkflowRunResult) ([]RunResultCli, error) {
return nil, err
}
name = artiResult.Name
artiType = artiResult.RepoType
}

cliresults = append(cliresults, RunResultCli{
Expand Down
17 changes: 17 additions & 0 deletions ui/src/app/model/workflow.run.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,14 @@ export class WorkflowRunResult {
data: any;
}

export class UIArtifact {
name: string;
md5: string;
size: number;
link: string;
type: string;
}


export class WorkflowRunResultArtifact {
name: string
Expand All @@ -154,6 +162,15 @@ export class WorkflowRunResultArtifact {
cdn_hash: string;
}

export class WorkflowRunResultArtifactManager {
name: string;
size: number;
md5: string;
path: string;
repository_name: string;
repository_type: string;
}

export class WorkflowNodeOutgoingHookRunCallback {
workflow_node_outgoing_hook_id: number;
start: Date;
Expand Down
12 changes: 7 additions & 5 deletions ui/src/app/shared/table/data-table.html
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,13 @@
{{' '}}<span *ngFor="let l of c.selector.labels" class="ui label {{l.color}}">{{l.title | translate}}</span>
</ng-container>
<div *ngSwitchCase="'text-copy'" class="ui fluid action input">
<input type="text" value="{{c.selector}}">
<button class="ui icon button copyButton" [title]="'common_copy_clipboard' | translate"
ngxClipboard [cbContent]="c.selector">
<i class="copy icon"></i>
</button>
<ng-container *ngIf="c.selector">
<input type="text" value="{{c.selector}}">
<button class="ui icon button copyButton" [title]="'common_copy_clipboard' | translate"
ngxClipboard [cbContent]="c.selector">
<i class="copy icon"></i>
</button>
</ng-container>
</div>
<span *ngSwitchCase="'text-labels'" class="text-labels">
{{c.selector.value |
Expand Down
127 changes: 90 additions & 37 deletions ui/src/app/views/workflow/run/node/artifact/artifact.list.component.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
import { Select, Store } from '@ngxs/store';
import {
UIArtifact,
WorkflowNodeRun,
WorkflowNodeRunArtifact,
WorkflowNodeRunStaticFiles,
WorkflowRunResultArtifact
WorkflowNodeRunStaticFiles, WorkflowRunResult,
WorkflowRunResultArtifact, WorkflowRunResultArtifactManager
} from 'app/model/workflow.run.model';

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

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

runResult: Array<WorkflowRunResult>
artifacts: Array<WorkflowNodeRunArtifact>;

uiArtifacts: Array<UIArtifact>;
staticFiles: Array<WorkflowNodeRunStaticFiles>;

filter: Filter<WorkflowNodeRunArtifact>;
columns: Array<Column<WorkflowNodeRunArtifact>>;
filter: Filter<UIArtifact>;
columns: Array<Column<UIArtifact>>;

constructor(private _cd: ChangeDetectorRef, private _store: Store) {
this.filter = f => {
const lowerFilter = f.toLowerCase();
return d => d.name.toLowerCase().indexOf(lowerFilter) !== -1 ||
d.sha512sum.toLowerCase().indexOf(lowerFilter) !== -1
d.md5.toLowerCase().indexOf(lowerFilter) !== -1
};
this.columns = [
<Column<WorkflowNodeRunArtifact>>{
<Column<UIArtifact>>{
type: ColumnType.LINK,
name: 'artifact_name',
selector: (a: WorkflowNodeRunArtifact) => {
selector: (a: UIArtifact) => {
let size = this.getHumainFileSize(a.size);
let link = `./cdsapi/workflow/artifact/${a.download_hash}`
if (!a.id) {
link = `./cdscdn/item/run-result/${a.download_hash}/download`
let link = a.link;
let value = a.name;
if (size) {
value += ` (${size})`;
}
return {
link,
value: `${a.name} (${size})`
value
};
}
},
<Column<WorkflowNodeRunArtifact>>{
name: 'artifact_tag',
selector: (a: WorkflowNodeRunArtifact) => a.tag
<Column<UIArtifact>>{
name: 'Type of artifact',
selector: (a: UIArtifact) => a.type
},
<Column<WorkflowNodeRunArtifact>>{
<Column<UIArtifact>>{
type: ColumnType.TEXT_COPY,
name: 'MD5 Sum',
selector: (a: WorkflowNodeRunArtifact) => a.md5sum
selector: (a: UIArtifact) => a.md5
}
];
}
Expand All @@ -70,16 +76,36 @@ export class WorkflowRunArtifactListComponent implements OnInit, OnDestroy {
if (!nr) {
return;
}
let resultArtifacts = nr?.results.filter(r => r.type === 'artifact').map(r => <WorkflowRunResultArtifact>r.data);
if (!resultArtifacts) {
resultArtifacts = new Array<WorkflowRunResultArtifact>();

let computeArtifact = false;
if (nr.results && (!this.runResult || nr.results.length !== this.runResult.length)) {
computeArtifact = true
}
if (nr.artifacts && (!this.artifacts || nr.artifacts.length !== this.artifacts.length)) {
computeArtifact = true
}
if ( (!this.artifacts && (nr.artifacts || resultArtifacts.length > 0)) || (this.artifacts && nr.artifacts && this.artifacts.length !== (nr.artifacts.length + resultArtifacts.length))) {
this.artifacts = new Array<WorkflowNodeRunArtifact>();
if (computeArtifact) {
let uiArtifacts: Array<UIArtifact>;
let uiRunResults: Array<UIArtifact>;
this.uiArtifacts = new Array<UIArtifact>();
if (nr.results) {
let w = this._store.selectSnapshot(WorkflowState.workflowRunSnapshot).workflow
uiRunResults = this.toUIArtifact(w, nr.results);
this.uiArtifacts.push(...uiRunResults);
}

if (nr.artifacts) {
this.artifacts.push(...nr.artifacts);
uiArtifacts = nr.artifacts.map(a => {
let uiArt = new UIArtifact();
uiArt.name = a.name;
uiArt.size = a.size;
uiArt.md5 = a.md5sum;
uiArt.type = 'file';
uiArt.link = `./cdscdn/item/artifact/${a.download_hash}/download`;
return uiArt;
});
this.uiArtifacts.push(...uiArtifacts)
}
this.artifacts.push(...this.toWorkflowNodeRunArtifacts(resultArtifacts));
this._cd.markForCheck();
}
if ((!this.staticFiles && nr.static_files) ||
Expand All @@ -90,25 +116,52 @@ export class WorkflowRunArtifactListComponent implements OnInit, OnDestroy {
});
}

toWorkflowNodeRunArtifacts(results: Array<WorkflowRunResultArtifact>): Array<WorkflowNodeRunArtifact> {
let arts = new Array<WorkflowNodeRunArtifact>();
results.forEach(r => {
let a = new WorkflowNodeRunArtifact();
a.download_hash = r.cdn_hash;
a.md5sum = r.md5;
a.size = r.size;
a.name = r.name;
arts.push(a);
})
return arts;
}

getHumainFileSize(size: number): string {
if (size === 0) {
return '0B';
return '';
}
let i = Math.floor(Math.log(size) / Math.log(1024));
let hSize = (size / Math.pow(1024, i)).toFixed(2);
return hSize + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][i];
}

private toUIArtifact(w: Workflow, results: Array<WorkflowRunResult>): Array<UIArtifact> {
if (!results) {
return [];
}
let integrationArtifactManagerURL = '';
if (w?.integrations) {
for (let i = 0; i < w.integrations.length; i++) {
let integ = w.integrations[i];
if (!integ.project_integration.model.artifact_manager) {
continue
}
integrationArtifactManagerURL = integ?.project_integration?.config['url']?.value;
}
}

return results.map(r => {
switch (r.type) {
case 'artifact':
case 'coverage':
let data = <WorkflowRunResultArtifact>r.data;
let uiArtifact = new UIArtifact();
uiArtifact.link = `./cdscdn/item/run-result/${data.cdn_hash}/download`;
uiArtifact.md5 = data.md5;
uiArtifact.name = data.name;
uiArtifact.size = data.size;
uiArtifact.type = 'file';
return uiArtifact;
case 'artifact-manager':
let dataAM = <WorkflowRunResultArtifactManager>r.data;
let uiArtifactAM = new UIArtifact();
uiArtifactAM.link = `${integrationArtifactManagerURL}${dataAM.repository_name}/${dataAM.path}`;
uiArtifactAM.md5 = dataAM.md5;
uiArtifactAM.name = dataAM.name;
uiArtifactAM.size = dataAM.size;
uiArtifactAM.type = dataAM.repository_type;
return uiArtifactAM;
}
})
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div class="artifact" *ngIf="artifacts || staticFiles">
<div class="artifact" *ngIf="uiArtifacts || staticFiles">
<table class="ui fixed celled table" *ngIf="staticFiles && staticFiles.length > 0">
<thead>
<tr>
Expand All @@ -21,5 +21,5 @@
</tr>
</tbody>
</table>
<app-data-table [withFilter]="filter" [withPagination]="10" [columns]="columns" [data]="artifacts"></app-data-table>
</div>
<app-data-table [withFilter]="filter" [withPagination]="10" [columns]="columns" [data]="uiArtifacts"></app-data-table>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -124,16 +124,13 @@ export class WorkflowNodeRunComponent implements OnInit, OnDestroy {
refresh = true;
}

let artiResults = nr?.results?.filter(r => r.type === 'artifact');
let artiResultsLength = 0;
if (artiResults) {
artiResultsLength = artiResults.length
}

let artiResultsLength = nr?.results?.length ?? 0
let oldArtiLength = 0;
if (nr.artifacts) {
oldArtiLength = nr.artifacts.length;
}
if ((nr.artifacts || artiResults) && (oldArtiLength + artiResultsLength) !== this.artifactLength) {
if ((nr.artifacts || artiResultsLength > 0) && (oldArtiLength + artiResultsLength) !== this.artifactLength) {
this.artifactLength = oldArtiLength + artiResultsLength;
refresh = true;
}
Expand Down
1 change: 0 additions & 1 deletion ui/src/assets/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@
"application_variable_list_title": "List of application variables: ",
"application_variable_form_title": "Add a new variable: ",
"artifact_name": "Artifact name",
"artifact_tag": "Tag",
"ascode_error_unknown_type": "Cannot determine the resource to update",
"ascode_modal_title": "Save as code",
"ascode_modal_label_branch": "Select or create a branch",
Expand Down

0 comments on commit 762f22c

Please sign in to comment.