Skip to content

Commit 60518a5

Browse files
authored
Merge pull request #36 from OpenTOSCA/feature/enrichment-ui
Feature/enrichment ui
2 parents 6f2ebb9 + e839302 commit 60518a5

File tree

8 files changed

+124
-36
lines changed

8 files changed

+124
-36
lines changed

src/app/application-management/application-management.module.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,25 @@ import { ApplicationDetailResolverService } from './application-detail/applicati
2525
import { ApplicationOverviewComponent } from './application-overview/application-overview.component';
2626
import { RouterModule } from '@angular/router';
2727
import {
28-
AccordionModule, ButtonModule, CardModule, ConfirmationService, ConfirmDialogModule, DataTableModule, DialogModule,
29-
DropdownModule, FieldsetModule, FileUploadModule, InputTextareaModule, PanelModule, ProgressBarModule,
30-
ProgressSpinnerModule, ScrollPanelModule, SharedModule, TabViewModule, ToolbarModule, TooltipModule
28+
AccordionModule,
29+
ButtonModule,
30+
CardModule,
31+
CheckboxModule,
32+
ConfirmationService,
33+
ConfirmDialogModule,
34+
DataTableModule,
35+
DialogModule,
36+
FieldsetModule,
37+
FileUploadModule,
38+
ProgressBarModule,
39+
SharedModule,
40+
TabViewModule,
41+
ScrollPanelModule,
42+
ToolbarModule,
43+
TooltipModule,
44+
ProgressSpinnerModule,
45+
InputTextareaModule,
46+
PanelModule, DropdownModule,
3147
} from 'primeng/primeng';
3248
import { FormsModule } from '@angular/forms';
3349
import { NgSpinKitModule } from 'ng-spin-kit';
@@ -51,6 +67,7 @@ import { ApplicationInstanceBoundaryDefinitionInterfacesListComponent } from './
5167
SharedModule,
5268
TooltipModule,
5369
CardModule,
70+
CheckboxModule,
5471
ButtonModule,
5572
PanelModule,
5673
ScrollPanelModule,

src/app/application-management/application-upload/application-upload.component.html

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,23 @@
1818
</p-header>
1919
<p-tabView>
2020
<p-tabPanel header="Upload local File">
21-
<p-fileUpload name="file" [url]="postURL" chooseLabel="Select File"
21+
<p-fileUpload #form name="file" [url]="postURL" customUpload="true" chooseLabel="Select File"
22+
(uploadHandler)="handleUpload($event, form)"
2223
(onSelect)="onSelect()"
23-
(onProgress)="onUploadProgress($event.originalEvent)"
2424
(onUpload)="onUploadFinished($event)"
25-
(onError)="onUploadError($event)"
2625
(onClear)="onClear()">
2726
<ng-template let-file pTemplate="file">
2827
<div>
2928
<p>Name: {{ file.name }}</p>
3029
<p>Size: {{file.size | humanizeBytes}}</p>
3130
<p>Last Modified: {{file.lastModifiedDate}}</p>
31+
<p-checkbox [(ngModel)]="applyEnrichment" label="Apply Management Feature Enrichment"
32+
binary="true">
33+
</p-checkbox>
3234
</div>
3335
</ng-template>
3436
<ng-template pTemplate="content">
3537
<div *ngIf="!fileSelected">Please select a file</div>
36-
<p *ngIf="showUploadProgressLabel">Uploaded {{bytesUploaded | humanizeBytes}} of {{bytesTotal |
37-
humanizeBytes}}</p>
3838
<div *ngIf="deploymentInProgress">
3939
<div class="p-grid">
4040
<div class="p-col-1">
@@ -77,6 +77,13 @@
7777
(validityChange)='nameValidityChange($event)'>
7878
</opentosca-debounced-validated-input>
7979
</div>
80+
<div class="p-col-9">
81+
<p-checkbox *ngIf="(this.tempData.validURL && this.tempData.validName)"
82+
(onChange)="applyEnrichmentChange()"
83+
[(ngModel)]="applyEnrichment" label="Apply Management Feature Enrichment"
84+
binary="true">
85+
</p-checkbox>
86+
</div>
8087
</div>
8188
<button type="button"
8289
pButton

src/app/application-management/application-upload/application-upload.component.ts

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,16 @@ import { ConfigurationService } from '../../configuration/configuration.service'
1717
import { ApplicationManagementService } from '../../core/service/application-management.service';
1818
import { NgRedux } from '@angular-redux/store';
1919
import { Router } from '@angular/router';
20-
import { LoggerService } from '../../core/service/logger.service';
2120
import { AppState } from '../../store/app-state.model';
2221
import { DeploymentCompletionService } from '../../core/service/deployment-completion.service';
2322
import { RepositoryService } from '../../core/service/repository.service';
2423
import { Path } from '../../core/path';
2524
import { GrowlActions } from '../../core/growl/growl-actions';
2625
import { CsarUploadReference } from '../../core/model/csar-upload-request.model';
27-
import { HttpClient, HttpResponse } from '@angular/common/http';
26+
import { HttpClient, HttpHeaders, HttpResponse } from '@angular/common/http';
2827
import { Observable, of } from 'rxjs';
2928
import {MarketplaceApplication} from '../../core/model/marketplace-application.model';
29+
import { LoggerService } from '../../core/service/logger.service';
3030

3131
@Component({
3232
selector: 'opentosca-application-upload',
@@ -41,20 +41,20 @@ export class ApplicationUploadComponent implements OnInit {
4141
@Output() completionRequest = new EventEmitter();
4242
public deploymentInProgress = false;
4343
public fileSelected = false;
44-
public showUploadProgressLabel = false;
4544
public postURL = new Path(this.adminService.getContainerUrl())
4645
.append('csars')
4746
.toString();
48-
public bytesUploaded = 0;
49-
public bytesTotal = 0;
47+
48+
public applyEnrichment = false;
49+
5050
public linkToWineryResourceForCompletion: string;
5151
public appToComplete: MarketplaceApplication;
5252
public showCompletionDialog = false;
5353
public initializeCompletionComponent = false;
5454

5555
// temporary data derived from the user input for the url upload
5656
public tempData = {
57-
cur: new CsarUploadReference(null, null),
57+
cur: new CsarUploadReference(null, null, null),
5858
validURL: false,
5959
validName: false
6060
};
@@ -97,22 +97,36 @@ export class ApplicationUploadComponent implements OnInit {
9797
onClear(): void {
9898
this.fileSelected = false;
9999
this.deploymentInProgress = false;
100+
this.applyEnrichment = false;
100101
}
101102

102103
/**
103-
* Handler for upload progress of file upload component.
104+
* Handler for file upload.
105+
* @param event: upload event triggered when upload button is clicked
104106
*/
105-
onUploadProgress(event: ProgressEvent): void {
106-
this.bytesUploaded = event.loaded;
107-
this.bytesTotal = event.total;
108-
this.deploymentInProgress = this.bytesUploaded === this.bytesTotal;
107+
handleUpload(event: any, form: any): void {
108+
this.deploymentInProgress = true;
109+
const fileToUpload = event.files[0];
110+
const formData: FormData = new FormData();
111+
formData.append('enrichment', JSON.stringify(this.applyEnrichment));
112+
formData.append('file', fileToUpload, fileToUpload.name);
113+
const headers = new HttpHeaders();
114+
this.handleCSARUpload(formData, headers).subscribe(
115+
data => this.onUploadFinished(data),
116+
error => this.onUploadError(event, error, form)
117+
);
118+
}
119+
120+
handleCSARUpload(formData, headers): Observable<Object> {
121+
return this.http.post(this.postURL, formData, {headers: headers});
109122
}
110123

111124
/**
112125
* Handler for upload finished event of file upload component.
113126
* This handler is called when the XHR request returns, i.e., when deployment in container is done.
114127
*/
115128
onUploadFinished(event): void {
129+
this.deploymentInProgress = false;
116130
// This is called when XHR request returns
117131
this.ngRedux.dispatch(GrowlActions.addGrowl(
118132
{
@@ -129,14 +143,16 @@ export class ApplicationUploadComponent implements OnInit {
129143
* Handler for emitted errors of file upload component.
130144
* If topology completion is required this is caught within this handler.
131145
*/
132-
onUploadError(event): void {
133-
switch (event.error.status) {
146+
onUploadError(event, error, form): void {
147+
form.clear();
148+
this.resetUploadStats();
149+
const fileExtension = '.csar';
150+
switch (error.status) {
134151
case 406:
135-
const response = event.error.error;
136-
this.linkToWineryResourceForCompletion = response['Location'];
152+
this.linkToWineryResourceForCompletion = error.error.Location;
137153
const fileName = event.files[0].name;
138-
const csarName = fileName.substr(0, fileName.length - 5);
139-
const csarID = fileName.lastIndexOf('.csar');
154+
const csarName = fileName.substr(0, fileName.length - fileExtension.length);
155+
const csarID = fileName.lastIndexOf(fileExtension);
140156
this.deploymentService.getAppFromCompletionHandlerWinery(this.linkToWineryResourceForCompletion, csarID,
141157
csarName).then(app => {
142158
this.appToComplete = app;
@@ -175,6 +191,7 @@ export class ApplicationUploadComponent implements OnInit {
175191
const postURL = new Path(this.adminService.getContainerUrl())
176192
.append('csars')
177193
.toString();
194+
178195
this.repositoryManagementService.installApplication(this.tempData.cur, postURL)
179196
.toPromise()
180197
.then(() => {
@@ -212,6 +229,7 @@ export class ApplicationUploadComponent implements OnInit {
212229
*/
213230
resetUploadStats(): void {
214231
this.deploymentInProgress = false;
232+
this.applyEnrichment = false;
215233
this.tempData.cur.url = null;
216234
this.tempData.cur.name = null;
217235
this.tempData.validURL = false;
@@ -226,6 +244,10 @@ export class ApplicationUploadComponent implements OnInit {
226244
this.tempData.cur.name = name;
227245
}
228246

247+
applyEnrichmentChange(): void {
248+
this.tempData.cur.enrich = JSON.stringify(this.applyEnrichment);
249+
}
250+
229251
urlValidityChange(validity: boolean): void {
230252
this.tempData.validURL = validity;
231253
}
@@ -275,11 +297,10 @@ export class ApplicationUploadComponent implements OnInit {
275297
detail: `The completion process was successful, app "${app.displayName}" is now getting installed in container.`
276298
}
277299
));
278-
// Todo: Container should check itself if the app already exists and respond appropriately
279300
const postURL = new Path(this.adminService.getContainerUrl())
280301
.append('csars')
281302
.toString();
282-
const completedApp = new CsarUploadReference(app.csarURL, app.csarName);
303+
const completedApp = new CsarUploadReference(app.csarURL, app.csarName, JSON.stringify(this.applyEnrichment));
283304
this.repoService.installApplication(completedApp, postURL)
284305
.subscribe(() => {
285306
this.ngRedux.dispatch(GrowlActions.addGrowl(

src/app/core/model/csar-upload-request.model.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@
1313
*/
1414

1515
export class CsarUploadReference {
16-
constructor(public url: string, public name: string) {
16+
constructor(public url: string, public name: string, public enrich: string) {
1717
}
1818
}

src/app/core/service/repository.service.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ export class RepositoryService {
7070
}
7171

7272
installApplication(app: CsarUploadReference, containerUrl: string): Observable<any> {
73-
console.log(app);
7473
const httpOptions = {
7574
headers: new HttpHeaders({
7675
'Content-Type': 'application/json'

src/app/repository/repository.component.html

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
class="ui-button-info" icon="fas fa-download"
5757
pTooltip="Download as CSAR..." showDelay="500" tooltipPosition="top"></button>
5858
&nbsp;
59-
<button pButton type="button" (click)="install(app)"
59+
<button pButton type="button" (click)="openEnrichmentDialog(app)"
6060
class="ui-button-info" icon="fas fa-plus-circle"
6161
pTooltip="Install in OpenTOSCA Container" showDelay="500" tooltipPosition="top"
6262
*ngIf="!app.inContainer && !app.isInstalling"></button>
@@ -73,6 +73,30 @@
7373
</p-card>
7474
</div>
7575
</div>
76+
77+
<div>
78+
<p-dialog styleClass="modal-scrollable" [modal]="true" [draggable]="false" [resizable]="false" [width]="450"
79+
[(visible)]="showEnrichmentDialog">
80+
<p-header>
81+
Management Feature Enrichment Dialog
82+
</p-header>
83+
<p style="height: 75px">
84+
Do you want to enrich the CSAR with additional management features?
85+
</p>
86+
<p-checkbox [(ngModel)]="applyEnrichment" label="Apply Management Feature Enrichment"
87+
binary="true">
88+
</p-checkbox>
89+
<p-footer>
90+
<button type="button"
91+
pButton
92+
(click)="install(this.currentlySelectedApp)"
93+
label="Install"
94+
icon="fa fa-upload">
95+
</button>
96+
</p-footer>
97+
</p-dialog>
98+
</div>
99+
76100
<opentosca-deployment-completion *ngIf="initializeCompletionComponent"
77101
[(visible)]="showCompletionDialog"
78102
[appToComplete]="appToComplete"

src/app/repository/repository.component.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,20 @@ export class RepositoryComponent implements OnInit {
4141
selectedRepository: Item;
4242

4343
apps: Array<MarketplaceApplication> = [];
44+
currentlySelectedApp: MarketplaceApplication;
4445

4546
searchTerm: string;
4647

47-
public linkToWineryResourceForCompletion: string;
48-
public appToComplete: MarketplaceApplication;
48+
49+
public applyEnrichment = false;
50+
public showEnrichmentDialog = false;
51+
4952
public showCompletionDialog = false;
5053
public initializeCompletionComponent = false;
5154

55+
public linkToWineryResourceForCompletion: string;
56+
public appToComplete: MarketplaceApplication;
57+
5258
constructor(private ngRedux: NgRedux<AppState>, private repositoryService: RepositoryService,
5359
private configurationService: ConfigurationService, private applicationService: ApplicationManagementService,
5460
private logger: LoggerService, private adminService: ConfigurationService, private repoService: RepositoryService ) {
@@ -113,10 +119,16 @@ export class RepositoryComponent implements OnInit {
113119
this.searchTerm = searchTerm;
114120
}
115121

122+
openEnrichmentDialog(app): void {
123+
this.showEnrichmentDialog = true;
124+
this.currentlySelectedApp = app;
125+
}
126+
116127
install(app: MarketplaceApplication): void {
128+
this.showEnrichmentDialog = false;
117129
app.isInstalling = true;
118130
const url = new Path(this.configurationService.getContainerUrl()).append('csars').toString();
119-
const app$ = new CsarUploadReference(app.csarURL, app.id);
131+
const app$ = new CsarUploadReference(app.csarURL, app.id, JSON.stringify(this.applyEnrichment));
120132
this.repositoryService.installApplication(app$, url)
121133
.subscribe(() => {
122134
app.isInstalling = false;
@@ -160,7 +172,7 @@ export class RepositoryComponent implements OnInit {
160172
const postURL = new Path(this.adminService.getContainerUrl())
161173
.append('csars')
162174
.toString();
163-
const completedApp = new CsarUploadReference(app.csarURL, app.csarName);
175+
const completedApp = new CsarUploadReference(app.csarURL, app.csarName, JSON.stringify(this.applyEnrichment));
164176
this.repoService.installApplication(completedApp, postURL)
165177
.subscribe(() => {
166178
this.ngRedux.dispatch(GrowlActions.addGrowl(

src/app/repository/repository.module.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,17 @@ import { RepositoryComponent } from './repository.component';
1919
import { RouterModule } from '@angular/router';
2020
import { CoreModule } from '../core/core.module';
2121
import { NgSpinKitModule } from 'ng-spin-kit';
22-
import { ButtonModule, CardModule, DropdownModule, ScrollPanelModule, ToolbarModule, TooltipModule } from 'primeng/primeng';
22+
import {
23+
ButtonModule, CardModule, CheckboxModule, ConfirmDialogModule, DialogModule,
24+
DropdownModule, ScrollPanelModule, ToolbarModule,
25+
TooltipModule
26+
} from 'primeng/primeng';
2327
import { FormsModule } from '@angular/forms';
2428

2529
@NgModule({
2630
imports: [
2731
CommonModule,
32+
CheckboxModule,
2833
FormsModule,
2934
RouterModule,
3035
TooltipModule,
@@ -33,9 +38,12 @@ import { FormsModule } from '@angular/forms';
3338
ScrollPanelModule,
3439
ToolbarModule,
3540
DropdownModule,
41+
DialogModule,
3642
NgSpinKitModule,
3743
CoreModule,
38-
RepositoryRoutingModule
44+
RepositoryRoutingModule,
45+
CheckboxModule,
46+
ConfirmDialogModule
3947
],
4048
declarations: [RepositoryComponent],
4149
providers: [ConfigurationService]

0 commit comments

Comments
 (0)