Skip to content
This repository was archived by the owner on May 14, 2025. It is now read-only.

Commit 13f72ec

Browse files
ghillertjvalkeal
authored andcommitted
gh-298 Fix Page Count incorrect on Apps tab after delete
* Provide doc comments for all methods of the `AppsComponent` * Fix Busy indicator issue + improve error handling * Rebase + code review changes
1 parent c447dca commit 13f72ec

File tree

8 files changed

+136
-50
lines changed

8 files changed

+136
-50
lines changed

ui/src/app/about/about-details.component.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ export class AboutDetailsComponent implements OnInit {
3434
data => {
3535
this.dataflowVersionInfo = data;
3636
this.toastyService.success('About details data loaded.');
37+
},
38+
error => {
39+
this.toastyService.error(error);
3740
}
3841
);
3942
}

ui/src/app/about/about.component.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ export class AboutComponent implements OnInit {
3030
data => {
3131
this.dataflowVersionInfo = data;
3232
this.toastyService.success('About data loaded.');
33+
},
34+
error => {
35+
this.toastyService.error(error);
3336
}
3437
);
3538
}

ui/src/app/apps/app-details/app-details.component.ts

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export class AppDetailsComponent implements OnInit {
2222

2323
public detailedAppRegistration: DetailedAppRegistration;
2424

25-
busy: Subscription[] = [];
25+
busy: Subscription;
2626

2727
constructor(
2828
private route: ActivatedRoute,
@@ -36,17 +36,16 @@ export class AppDetailsComponent implements OnInit {
3636
console.log(this.appsService.appRegistrations);
3737

3838
this.route.params.subscribe(params => {
39-
const appName: string = params['appName'];
40-
const appType: ApplicationType = params['appType'] as ApplicationType;
41-
42-
console.log(`Retrieving app registration details for ${appName} (${appType}).`);
43-
this.busy.push(this.appsService.getAppInfo(appType, appName).subscribe(data => {
44-
this.detailedAppRegistration = data;
45-
},
46-
error => {
47-
this.toastyService.error(error);
48-
})
49-
);
39+
const appName: string = params['appName'];
40+
const appType: ApplicationType = params['appType'] as ApplicationType;
41+
42+
console.log(`Retrieving app registration details for ${appName} (${appType}).`);
43+
this.busy = this.appsService.getAppInfo(appType, appName).subscribe(data => {
44+
this.detailedAppRegistration = data;
45+
},
46+
error => {
47+
this.toastyService.error(error);
48+
});
5049
});
5150
}
5251

ui/src/app/apps/apps-bulk-import.component.ts

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export class AppsBulkImportComponent implements OnInit, OnChanges {
1919
public model = new AppRegistrationImport(false, [], '');
2020

2121
apps: any;
22-
busy: Subscription[] = [];
22+
busy: Subscription;
2323

2424
contents: any;
2525
uriPattern = '^([a-z0-9-]+:\/\/)([\\w\\.:-]+)(\/[\\w\\.:-]+)*$';
@@ -86,19 +86,17 @@ export class AppsBulkImportComponent implements OnInit, OnChanges {
8686
console.log('Importing apps using textarea values:\n' + this.model.appsProperties + ' (force: ' + this.model.force + ')');
8787
}
8888

89-
const observable = this.appsService.bulkImportApps(this.model).subscribe(
89+
this.busy = this.appsService.bulkImportApps(this.model).subscribe(
9090
data => {
91-
console.log(data);
92-
this.toastyService.success('Apps Imported.');
93-
const reloadAppsObservable = this.appsService.getApps(true).subscribe(
94-
appRegistrations => {
95-
console.log('Back to about page ...');
96-
this.router.navigate(['apps']);
97-
}
98-
);
99-
this.busy.push(reloadAppsObservable);
100-
}
91+
console.log(data);
92+
this.toastyService.success('Apps Imported.');
93+
this.busy = this.appsService.getApps(true).subscribe(
94+
appRegistrations => {
95+
console.log('Back to about page ...');
96+
this.router.navigate(['apps']);
97+
}
98+
);
99+
}
101100
);
102-
this.busy.push(observable);
103101
}
104102
}

ui/src/app/apps/apps-register/apps-register.component.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export class AppsRegisterComponent implements OnInit, OnChanges {
2929

3030
public model = [new AppRegistration()];
3131

32-
busy: Subscription[] = [];
32+
busy: Subscription;
3333

3434
contents: any;
3535
uriPattern = '^([a-z0-9-]+:\/\/)([\\w\\.:-]+)(\/[\\w\\.:-]+)*$';
@@ -66,21 +66,20 @@ export class AppsRegisterComponent implements OnInit, OnChanges {
6666
*/
6767
register() {
6868
console.log(`Register ${this.model.length} app(s).`);
69-
this.busy.push(this.appsService.registerMultipleApps(this.model).subscribe(
69+
this.busy = this.appsService.registerMultipleApps(this.model).subscribe(
7070
data => {
7171
this.toastyService.success(`${data.length} App(s) registered.`);
72-
const reloadAppsObservable = this.appsService.getApps(true).subscribe(
72+
this.busy = this.appsService.getApps(true).subscribe(
7373
appRegistrations => {
7474
console.log('Back to apps page ...');
7575
this.router.navigate(['apps']);
7676
}
7777
);
78-
this.busy.push(reloadAppsObservable);
7978
},
8079
error => {
8180
this.toastyService.error(error);
8281
}
83-
));
82+
);
8483
}
8584

8685
/**

ui/src/app/apps/apps.component.ts

Lines changed: 80 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@ import { ToastyService } from 'ng2-toasty';
1010

1111
import { ModalDirective } from 'ngx-bootstrap/modal';
1212

13+
/**
14+
* Main entry point to the Apps Module. Provides
15+
* a paginated list of {@link AppRegistration}s and
16+
* also provides operation to unregister {@link AppRegistration}s.
17+
*
18+
* @author Gunnar Hillert
19+
*/
1320
@Component({
1421
selector: 'app-apps',
1522
templateUrl: './apps.component.html'
@@ -35,10 +42,19 @@ export class AppsComponent implements OnInit {
3542
private router: Router ) {
3643
}
3744

45+
/**
46+
* As soon as the page loads we retrieve a list
47+
* of {@link AppRegistration}s.
48+
*/
3849
ngOnInit() {
3950
this.loadAppRegistrations(false);
4051
}
4152

53+
/**
54+
* Load a paginated list of {@link AppRegistration}s.
55+
*
56+
* @param reload
57+
*/
4258
public loadAppRegistrations(reload: boolean) {
4359
this.busy = this.appsService.getApps(reload).subscribe(
4460
data => {
@@ -53,28 +69,53 @@ export class AppsComponent implements OnInit {
5369
);
5470
}
5571

72+
/**
73+
* Navigate to the page in order to register a new
74+
* {@link AppRegistration}.
75+
*/
5676
registerApps() {
5777
this.router.navigate(['apps/register-apps']);
5878
}
5979

80+
/**
81+
* Starts the unregistration process of a single {@link AppRegistration}
82+
* by opening a confirmation modal dialog.
83+
*
84+
* @param appRegistration
85+
* @param index
86+
*/
6087
unregisterSingleApp(appRegistration: AppRegistration, index: number) {
6188
console.log(`Unregister single app ${appRegistration.name} (Index: ${index})`);
6289
this.appRegistrationToUnregister = appRegistration;
6390
this.unregisterSingleAppModal.show();
6491
}
6592

93+
/**
94+
* Starts the unregistration process of multiple {@link AppRegistration}s
95+
* by opening a confirmation modal dialog.
96+
*
97+
* @param appRegistrations An array of AppRegistrations to unregister
98+
*/
6699
unregisterMultipleApps(appRegistrations: AppRegistration[]) {
67100
this.appRegistrationsToUnregister = appRegistrations.filter(item => item.isSelected);
68101
console.log(`Unregister ${this.appRegistrationsToUnregister.length} app(s).`, this.appRegistrationsToUnregister);
69102
this.unregisterMultipleAppsModal.show();
70103
}
71104

72-
105+
/**
106+
* Navigate to the page that allows for the bulk import of {@link AppRegistration}s.
107+
*/
73108
bulkImportApps() {
74109
console.log('Go to Bulk Import page ...');
75110
this.router.navigate(['apps/bulk-import-apps']);
76111
}
77112

113+
/**
114+
* Completes the unregistration step for a single {@link AppRegistration}.
115+
* Closes the open modal dialog.
116+
*
117+
* @param appRegistration The AppRegistration to unregister
118+
*/
78119
public proceedToUnregisterSingleAppRegistration(appRegistration: AppRegistration): void {
79120
console.log('Proceeding to unregister application...', appRegistration);
80121

@@ -86,31 +127,65 @@ export class AppsComponent implements OnInit {
86127

87128
if (this.appsService.appRegistrations.items.length === 0 && this.appsService.appRegistrations.pageNumber > 0) {
88129
this.appRegistrations.pageNumber = this.appRegistrations.pageNumber - 1;
89-
this.loadAppRegistrations(true);
90130
}
131+
this.busy = this.appsService.getApps(true).subscribe(
132+
appRegistrations => {}
133+
);
91134
},
92135
error => {
93136
this.toastyService.error(error);
94137
}
95138
);
96139
}
97140

141+
/**
142+
* Completes the unregistration step for multiple {@link AppRegistration}s.
143+
* Closes the open modal dialog.
144+
*
145+
* @param appRegistrations The array of AppRegistrations to unregister
146+
*/
98147
public proceedToUnregisterMultipleAppRegistrations(appRegistrations: AppRegistration[]): void {
99148
console.log(`Proceeding to unregister ${appRegistrations.length} application(s).`, appRegistrations);
100-
for (const appRegistrationToUnregister of appRegistrations) {
101-
this.proceedToUnregisterSingleAppRegistration(appRegistrationToUnregister);
102-
}
149+
const subscription = this.appsService.unregisterMultipleApps(appRegistrations).subscribe(
150+
data => {
151+
console.log(data);
152+
this.toastyService.success(`${data.length} app(s) unregistered.`);
153+
154+
if (this.appsService.appRegistrations.items.length === 0 && this.appsService.appRegistrations.pageNumber > 0) {
155+
this.appRegistrations.pageNumber = this.appRegistrations.pageNumber - 1;
156+
}
157+
this.busy = this.appsService.getApps(true).subscribe(
158+
appRegistrationsResult => {}
159+
);
160+
}
161+
);
162+
this.busy = subscription;
163+
103164
this.unregisterMultipleAppsModal.hide();
104165
}
105166

167+
/**
168+
* Close the confirmation modal dialog for
169+
* unregistering a single {@link AppRegistration}.
170+
*/
106171
public cancelUnregisterSingleApp() {
107172
this.unregisterSingleAppModal.hide();
108173
}
109174

175+
/**
176+
* Close the confirmation modal dialog for
177+
* unregistering multiple {@link AppRegistration}s.
178+
*/
110179
public cancelUnregisterMultipleApps() {
111180
this.unregisterMultipleAppsModal.hide();
112181
}
113182

183+
/**
184+
* Navigate to the page that provides a detail view for the
185+
* passed-in {@link AppRegistration}.
186+
*
187+
* @param appRegistration
188+
*/
114189
public viewDetails(appRegistration: AppRegistration) {
115190
this.router.navigate(['apps/' + appRegistration.type + '/' + appRegistration.name]);
116191
}
@@ -128,8 +203,3 @@ export class AppsComponent implements OnInit {
128203
this.loadAppRegistrations(true);
129204
}
130205
}
131-
132-
133-
134-
135-

ui/src/app/apps/apps.service.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,14 @@ export class AppsService {
102102

103103
}
104104

105+
unregisterMultipleApps(appRegs: AppRegistration[]): Observable<Response[]> {
106+
const observables: Observable<Response>[] = [];
107+
for (const appReg of appRegs) {
108+
observables.push(this.unregisterApp(appReg));
109+
}
110+
return Observable.forkJoin(observables);
111+
}
112+
105113
registerMultipleApps(appRegs: AppRegistration[]): Observable<Response[]> {
106114
const observables: Observable<Response>[] = [];
107115
for (const appReg of appRegs) {

ui/src/app/shared/model/error-handler.ts

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,25 @@ export class ErrorHandler {
99
* @returns {any} Exception to be thrown by the Observable
1010
*/
1111
public handleError(error: Response | any) {
12-
1312
let errMsg = '';
14-
1513
if (error instanceof Response) {
16-
const body = error.json() || '';
17-
let isFirst = true;
18-
for (const bodyElement of body) {
19-
if (!isFirst) {
20-
errMsg += '\n';
21-
} else {
22-
isFirst = false;
14+
let body;
15+
try {
16+
body = error.json() || '';
17+
} catch (e) {
18+
console.log('Unparsable json', error);
19+
errMsg = `${error.text()} (Status code: ${error.status})`;
20+
}
21+
if (body) {
22+
let isFirst = true;
23+
for (const bodyElement of body) {
24+
if (!isFirst) {
25+
errMsg += '\n';
26+
} else {
27+
isFirst = false;
28+
}
29+
errMsg += bodyElement.message;
2330
}
24-
errMsg += bodyElement.message;
2531
}
2632
} else {
2733
errMsg = error.message ? error.message : error.toString();

0 commit comments

Comments
 (0)