Skip to content
This repository was archived by the owner on Mar 18, 2023. It is now read-only.

Commit 300edcd

Browse files
committed
feat: add register button to my clients page
Closes: #129
1 parent 633623d commit 300edcd

File tree

9 files changed

+155
-27
lines changed

9 files changed

+155
-27
lines changed

src/app/components/marketplace-signup-stepper/marketplace-signup-stepper.component.ts

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { Router } from '@angular/router';
1919
import { HeroService } from '../../services/hero/hero.service';
2020
import { TranslateService } from '@ngx-translate/core';
2121
import {
22+
IAction,
2223
IClientSummary,
2324
IContract,
2425
IContractSummary,
@@ -32,10 +33,11 @@ import { ISignUpInfo } from '../../interfaces/ISignUpInfo';
3233
import { BackendService } from '../../services/backend/backend.service';
3334
import { MatStepper } from '@angular/material/stepper';
3435
import { IContractExt } from '../../interfaces/IContractExt';
35-
import { catchError, map, switchMap } from 'rxjs/operators';
36+
import { map, switchMap } from 'rxjs/operators';
3637
import { TocService } from '../../services/toc/toc.service';
3738
import { HttpErrorResponse } from '@angular/common/http';
38-
import { EMPTY, throwError } from 'rxjs';
39+
import { Observable } from 'rxjs';
40+
import { ClientService } from '../../services/client/client.service';
3941

4042
@Component({
4143
selector: 'app-marketplace-signup-stepper',
@@ -60,7 +62,8 @@ export class MarketplaceSignupStepperComponent implements OnInit {
6062
private signUpService: SignUpService,
6163
private router: Router,
6264
private backend: BackendService,
63-
private tocService: TocService
65+
private tocService: TocService,
66+
private clientService: ClientService
6467
) {
6568
this.termsEnabled = this.configService.getTerms().enabled;
6669
this.newContractDetails = this.signUpService.getSignUpInfo();
@@ -204,25 +207,14 @@ export class MarketplaceSignupStepperComponent implements OnInit {
204207
);
205208
}
206209

207-
private registerClient() {
208-
return this.backend
209-
.sendAction({
210-
type: 'registerClient',
211-
entityVersion: '1.0',
212-
organizationId: this.contract.client.client.organization.id,
213-
entityId: this.contract.client.client.id
214-
})
215-
.pipe(
216-
catchError((err: HttpErrorResponse) => {
217-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
218-
if (err.error.type === 'InvalidContractStatusException') {
219-
// Ignore this error because this is still valid
220-
return EMPTY;
221-
} else {
222-
return throwError(() => err);
223-
}
224-
})
225-
);
210+
private registerClient(): Observable<void> {
211+
const action: IAction = {
212+
type: 'registerClient',
213+
entityVersion: '1.0',
214+
organizationId: this.contract.client.client.organization.id,
215+
entityId: this.contract.client.client.id
216+
};
217+
return this.clientService.registerClient(action);
226218
}
227219

228220
finish(): void {

src/app/components/my-apps/my-apps.component.html

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,15 @@
7171
matTooltip="{{ 'CLIENTS.REMOVE_CLIENT_TOOLTIP' | translate }}">
7272
<mat-icon>delete</mat-icon>
7373
</button>
74+
<button
75+
id="client-register-btn"
76+
*ngIf="cliCon.value[0].registerable"
77+
(click)="register(cliCon.value[0])"
78+
mat-icon-button
79+
color="primary"
80+
matTooltip="{{ 'CLIENTS.REGISTER' | translate }}">
81+
<mat-icon>app_registration</mat-icon>
82+
</button>
7483
<span
7584
id="client-status-label"
7685
matTooltip="Client Status"

src/app/components/my-apps/my-apps.component.scss

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@
4747
.app-client-header-label {
4848
white-space: nowrap;
4949
text-align: right;
50+
display: grid;
51+
grid-auto-flow: column;
52+
align-items: center;
5053

5154
span {
5255
margin-left: 8px;
@@ -57,6 +60,12 @@
5760
span:last-child {
5861
margin-right: 0;
5962
}
63+
64+
mat-icon {
65+
font-size: 28px;
66+
height: 28px;
67+
width: 28px;
68+
}
6069
}
6170

6271
/* stylelint-disable no-descending-specificity */

src/app/components/my-apps/my-apps.component.ts

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import {
2626
statusColorMap
2727
} from '../../interfaces/IStatus';
2828
import {
29+
IAction,
2930
IClientSummary,
3031
IClientVersionSummary,
3132
IContract,
@@ -54,6 +55,7 @@ import { SnackbarService } from '../../services/snackbar/snackbar.service';
5455
import { ConfigService } from '../../services/config/config.service';
5556
import { IPolicyExt, IPolicyProbe } from '../../interfaces/IPolicy';
5657
import { PermissionsService } from '../../services/permissions/permissions.service';
58+
import { ClientService } from '../../services/client/client.service';
5759

5860
@Component({
5961
selector: 'app-my-apps',
@@ -90,7 +92,8 @@ export class MyAppsComponent implements OnInit {
9092
private snackbarService: SnackbarService,
9193
public configService: ConfigService,
9294
private cdr: ChangeDetectorRef,
93-
private permissionsService: PermissionsService
95+
private permissionsService: PermissionsService,
96+
private clientService: ClientService
9497
) {}
9598

9699
ngOnInit(): void {
@@ -194,7 +197,8 @@ export class MyAppsComponent implements OnInit {
194197
docsAvailable: this.apiService.isApiDocAvailable(
195198
contract.api
196199
),
197-
deletable: this.isDeleteAllowed(contract)
200+
deletable: this.isDeleteAllowed(contract),
201+
registerable: this.isRegisterable(contract)
198202
} as IContractExt;
199203
})
200204
);
@@ -413,6 +417,21 @@ export class MyAppsComponent implements OnInit {
413417
return `${contract.api.api.name} ${contract.api.version} - ${contract.plan.plan.name}`;
414418
}
415419

420+
register(contract: IContractExt) {
421+
const action: IAction = {
422+
type: 'registerClient',
423+
organizationId: contract.client.client.organization.id,
424+
entityId: contract.client.client.id,
425+
entityVersion: contract.client.version
426+
};
427+
this.clientService.registerClient(action).subscribe(() => {
428+
console.info(
429+
`Client ${action.organizationId}/${action.entityId}/${action.entityVersion} successfully registered`
430+
);
431+
contract.client.status = 'Registered';
432+
});
433+
}
434+
416435
unregister(contract: IContractExt, clientNameVersion: string): void {
417436
const dialogRef = this.dialog.open(UnregisterClientComponent, {
418437
autoFocus: false
@@ -432,6 +451,12 @@ export class MyAppsComponent implements OnInit {
432451
});
433452
}
434453

454+
private getClientAdminOrgs() {
455+
return this.permissionsService.getAllowedOrganizations({
456+
name: 'clientAdmin'
457+
} as IPermission);
458+
}
459+
435460
private isDeleteAllowed(contract: IContract): boolean {
436461
const clientAdminOrganizations =
437462
this.permissionsService.getAllowedOrganizations({
@@ -443,6 +468,16 @@ export class MyAppsComponent implements OnInit {
443468
);
444469
}
445470

471+
private isRegisterable(contract: IContract): boolean {
472+
const clientAdminOrganizations = this.getClientAdminOrgs();
473+
return (
474+
(contract.client.status === 'Ready' ||
475+
contract.client.status === 'Unregistered' ||
476+
contract.client.status === 'Retired') &&
477+
clientAdminOrganizations.includes(contract.client.client.organization.id)
478+
);
479+
}
480+
446481
onSetSection($event: { contract: IContractExt; section: ISection }): void {
447482
this.setSection($event.contract, $event.section);
448483
this.cdr.detectChanges();

src/app/interfaces/IContractExt.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2021 Scheer PAS Schweiz AG
2+
* Copyright 2022 Scheer PAS Schweiz AG
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -28,4 +28,5 @@ export interface IContractExt extends IContract {
2828
policies: IPolicyExt[];
2929
docsAvailable: boolean;
3030
deletable: boolean;
31+
registerable: boolean;
3132
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright 2022 Scheer PAS Schweiz AG
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* imitations under the License.
15+
*/
16+
17+
import { TestBed } from '@angular/core/testing';
18+
19+
import { ClientService } from './client.service';
20+
21+
describe('ClientService', () => {
22+
let service: ClientService;
23+
24+
beforeEach(() => {
25+
TestBed.configureTestingModule({});
26+
service = TestBed.inject(ClientService);
27+
});
28+
29+
it('should be created', () => {
30+
expect(service).toBeTruthy();
31+
});
32+
});
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright 2022 Scheer PAS Schweiz AG
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* imitations under the License.
15+
*/
16+
17+
import { Injectable } from '@angular/core';
18+
import { catchError } from 'rxjs/operators';
19+
import { HttpErrorResponse } from '@angular/common/http';
20+
import { EMPTY, Observable, throwError } from 'rxjs';
21+
import { BackendService } from '../backend/backend.service';
22+
import { IAction } from '../../interfaces/ICommunication';
23+
24+
@Injectable({
25+
providedIn: 'root'
26+
})
27+
export class ClientService {
28+
constructor(private backend: BackendService) {}
29+
30+
/**
31+
* This method registers a client, if we got an InvalidContractStatusException which can happen
32+
* if one API needs approval we will do nothing as this is okay
33+
* @param action - the action with the client to register
34+
*/
35+
public registerClient(action: IAction): Observable<void> {
36+
return this.backend.sendAction(action).pipe(
37+
catchError((err: HttpErrorResponse) => {
38+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
39+
if (err.error.type === 'InvalidContractStatusException') {
40+
// Ignore this error because this is still valid
41+
return EMPTY;
42+
} else {
43+
return throwError(() => err);
44+
}
45+
})
46+
);
47+
}
48+
}

src/assets/i18n/de.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@
7575
"RETIRED_API": "Diese API kann nicht mehr verwendet werden.",
7676
"SELECT": "Aus vorhandenen Anwendungen auswählen",
7777
"CLIENT_TOOLTIP": "Client Organization: {{ client.client.organization.name }}\nClient Name (Version): {{ client.client.name }} ({{ client.version }})",
78-
"API_TOOLTIP": "API Organization: {{ api.api.organization.name }}\nAPI Name (Version): {{ api.api.name }} ({{ api.version }})\nPlan Name (Version): {{ plan.plan.name }} ({{ plan.version }})"
78+
"API_TOOLTIP": "API Organization: {{ api.api.organization.name }}\nAPI Name (Version): {{ api.api.name }} ({{ api.version }})\nPlan Name (Version): {{ plan.plan.name }} ({{ plan.version }})",
79+
"REGISTER": "Client registrieren"
7980
},
8081
"WIZARD": {
8182
"FIRST_STEP_LABEL": "Client auswählen/erstellen",

src/assets/i18n/en.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@
7575
"RETIRED_API": "This API is retired and can no longer be used.",
7676
"SELECT": "Select from available Clients",
7777
"CLIENT_TOOLTIP": "Client Organization: {{ client.client.organization.name }}\nClient Name (Version): {{ client.client.name }} ({{ client.version }})",
78-
"API_TOOLTIP": "API Organization: {{ api.api.organization.name }}\nAPI Name (Version): {{ api.api.name }} ({{ api.version }})\nPlan Name (Version): {{ plan.plan.name }} ({{ plan.version }})"
78+
"API_TOOLTIP": "API Organization: {{ api.api.organization.name }}\nAPI Name (Version): {{ api.api.name }} ({{ api.version }})\nPlan Name (Version): {{ plan.plan.name }} ({{ plan.version }})",
79+
"REGISTER": "Register client"
7980
},
8081
"WIZARD": {
8182
"FIRST_STEP_LABEL": "Select/create Client",

0 commit comments

Comments
 (0)