Skip to content

Commit 73209c2

Browse files
committed
feat(portal): add dockerfile optimization panel to artifact view
Signed-off-by: Hanna Czifrus <czifrus.hanna@gmail.com>
1 parent 4b8d30c commit 73209c2

8 files changed

Lines changed: 1000 additions & 0 deletions

File tree

src/portal/src/app/base/project/repository/artifact/artifact-additions/artifact-additions.component.html

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,26 @@ <h4 class="margin-bottom-025">{{ 'ARTIFACT.ADDITIONS' | translate }}</h4>
154154
</clr-tab-content>
155155
</ng-template>
156156
</clr-tab>
157+
} @if (isImageArtifact()) {
158+
<clr-tab>
159+
<button
160+
clrTabLink
161+
id="dockerfile-link"
162+
(click)="actionTab('dockerfile-link')">
163+
{{ 'REPOSITORY.DOCKERFILE' | translate }}
164+
</button>
165+
<ng-template
166+
[clrIfActive]="currentTabLinkId === 'dockerfile-link'">
167+
<clr-tab-content id="dockerfile-content">
168+
@if (currentTabLinkId === 'dockerfile-link') {
169+
<hbr-dockerfile-optimization
170+
[projectName]="projectName"
171+
[repoName]="repoName"
172+
[digest]="digest"></hbr-dockerfile-optimization>
173+
}
174+
</clr-tab-content>
175+
</ng-template>
176+
</clr-tab>
157177
}
158178
</clr-tabs>
159179
</div>

src/portal/src/app/base/project/repository/artifact/artifact-additions/artifact-additions.component.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import { AdditionLink } from '../../../../../../../ng-swagger-gen/models/additio
2525
import { Artifact } from '../../../../../../../ng-swagger-gen/models/artifact';
2626
import { ClrLoadingState, ClrTabs } from '@clr/angular';
2727
import { ArtifactListPageService } from '../artifact-list-page/artifact-list-page.service';
28+
import { ArtifactType } from '../artifact';
2829

2930
@Component({
3031
selector: 'artifact-additions',
@@ -132,6 +133,10 @@ export class ArtifactAdditionsComponent implements AfterViewChecked, OnInit {
132133
return null;
133134
}
134135

136+
isImageArtifact(): boolean {
137+
return this.artifact?.type === ArtifactType.IMAGE;
138+
}
139+
135140
actionTab(tab: string): void {
136141
this.currentTabLinkId = tab;
137142
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
<div class="dockerfile-optimization-container">
2+
<div *ngIf="loadingCached || loadingAvailability" class="spinner-container">
3+
<clr-spinner></clr-spinner>
4+
</div>
5+
6+
<ng-container *ngIf="!loadingCached && !loadingAvailability && result">
7+
<div *ngIf="result.generated" class="alert alert-warning" role="alert">
8+
<div class="alert-items">
9+
<div class="alert-item static">
10+
<div class="alert-icon-wrapper">
11+
<cds-icon
12+
class="alert-icon"
13+
shape="exclamation-triangle"></cds-icon>
14+
</div>
15+
<span class="alert-text">{{
16+
'REPOSITORY.DOCKERFILE_GENERATED_HINT' | translate
17+
}}</span>
18+
</div>
19+
</div>
20+
</div>
21+
<div class="clr-row comparison-panels">
22+
<div class="clr-col-6">
23+
<h5>
24+
{{
25+
(result.generated
26+
? 'REPOSITORY.DOCKERFILE_ORIGINAL_GENERATED'
27+
: 'REPOSITORY.DOCKERFILE_ORIGINAL'
28+
) | translate
29+
}}
30+
</h5>
31+
<pre class="dockerfile-pre">{{ result.dockerfile }}</pre>
32+
</div>
33+
<div class="clr-col-6">
34+
<h5>{{ 'REPOSITORY.DOCKERFILE_OPTIMIZED' | translate }}</h5>
35+
<textarea
36+
class="dockerfile-pre dockerfile-textarea"
37+
[(ngModel)]="editedDockerfile"></textarea>
38+
</div>
39+
</div>
40+
41+
<div class="action-row build-row" *ngIf="hasSourceTag">
42+
<button class="btn btn-outline" (click)="downloadDockerfile()">
43+
<clr-icon shape="download" size="16"></clr-icon>
44+
<span>{{ 'REPOSITORY.DOWNLOAD_DOCKERFILE' | translate }}</span>
45+
</button>
46+
<p class="hint-text">
47+
{{ 'REPOSITORY.BUILD_COMMAND_HINT' | translate }}
48+
</p>
49+
<hbr-copy-input
50+
inputSize="65"
51+
headerTitle="{{ 'REPOSITORY.BUILD_COMMAND' | translate }}"
52+
defaultValue="{{ buildCommand }}"
53+
(onCopySuccess)="onCpSuccess()"
54+
(onCopyError)="onCpError()"></hbr-copy-input>
55+
</div>
56+
</ng-container>
57+
58+
<ng-container *ngIf="!loadingCached && !loadingAvailability && inProgress">
59+
<div class="action-row">
60+
<clr-spinner [clrSmall]="true"></clr-spinner>
61+
<span class="hint-text">{{
62+
'REPOSITORY.DOCKERFILE_IN_PROGRESS' | translate
63+
}}</span>
64+
</div>
65+
</ng-container>
66+
67+
<ng-container
68+
*ngIf="
69+
!loadingCached &&
70+
!loadingAvailability &&
71+
!inProgress &&
72+
showButton &&
73+
!result
74+
">
75+
<div class="action-row">
76+
<button
77+
class="btn btn-primary"
78+
[disabled]="loading"
79+
(click)="optimize()">
80+
<clr-spinner *ngIf="loading" [clrSmall]="true"></clr-spinner>
81+
<span>{{ 'REPOSITORY.OPTIMIZE_DOCKERFILE' | translate }}</span>
82+
</button>
83+
</div>
84+
<p *ngIf="!loading" class="hint-text">
85+
{{ 'REPOSITORY.DOCKERFILE_HINT' | translate }}
86+
</p>
87+
</ng-container>
88+
89+
<div
90+
*ngIf="
91+
!loadingCached &&
92+
!loadingAvailability &&
93+
!inProgress &&
94+
!result &&
95+
unavailableReason
96+
"
97+
class="alert alert-warning"
98+
role="alert">
99+
<div class="alert-items">
100+
<div class="alert-item static">
101+
<div class="alert-icon-wrapper">
102+
<cds-icon
103+
class="alert-icon"
104+
shape="exclamation-triangle"></cds-icon>
105+
</div>
106+
<span class="alert-text">{{ unavailableReason }}</span>
107+
</div>
108+
</div>
109+
</div>
110+
111+
<div *ngIf="errorMessage" class="alert alert-danger" role="alert">
112+
<div class="alert-items">
113+
<div class="alert-item static">
114+
<div class="alert-icon-wrapper">
115+
<cds-icon
116+
class="alert-icon"
117+
shape="exclamation-circle"></cds-icon>
118+
</div>
119+
<span class="alert-text">{{ errorMessage }}</span>
120+
</div>
121+
</div>
122+
</div>
123+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
.dockerfile-optimization-container {
2+
padding: 1rem 0;
3+
}
4+
5+
.action-row {
6+
margin-bottom: 1rem;
7+
8+
button {
9+
display: inline-flex;
10+
align-items: center;
11+
gap: 0.4rem;
12+
}
13+
}
14+
15+
.comparison-panels {
16+
margin-top: 1rem;
17+
18+
h5 {
19+
margin-bottom: 0.5rem;
20+
}
21+
}
22+
23+
.dockerfile-pre {
24+
background: var(--clr-vertical-nav-bg-color);
25+
color: var(--cds-alias-typography-color-500);
26+
border: 1px solid var(--clr-color-neutral-400, #ccc);
27+
border-radius: 3px;
28+
padding: 0.75rem;
29+
overflow-x: auto;
30+
white-space: pre;
31+
font-size: 0.75rem;
32+
max-height: 480px;
33+
}
34+
35+
.dockerfile-textarea {
36+
width: 100%;
37+
min-height: 480px;
38+
resize: vertical;
39+
font-family: monospace;
40+
white-space: pre;
41+
appearance: none;
42+
-webkit-appearance: none;
43+
color-scheme: normal;
44+
background-color: var(--clr-vertical-nav-bg-color);
45+
color: var(--cds-alias-typography-color-500);
46+
}
47+
48+
.build-row {
49+
display: flex;
50+
flex-direction: column;
51+
align-items: flex-start;
52+
gap: 0.4rem;
53+
}
54+
55+
.hint-text {
56+
color: var(--clr-color-neutral-600, #666);
57+
font-style: italic;
58+
}

0 commit comments

Comments
 (0)