refactor: simplify the delete client dialog
Simplified the dialog by:
moving the logic into the client service
removing the EventEmitter
pass data via injection
MODIFY
src/app/components/dialogs/unregister-client/unregister-client.component.html
src/app/components/dialogs/unregister-client/unregister-client.component.html
<mat-dialog-content>
<span
[innerHTML]="
- 'DIALOGS.DELETE_CLIENT.DELETE_SURE' | translate: clientNameVersion
+ 'DIALOGS.DELETE_CLIENT.DELETE_SURE' | translate: translations
"></span>
</mat-dialog-content>

MODIFY
src/app/components/dialogs/unregister-client/unregister-client.component.ts
src/app/components/dialogs/unregister-client/unregister-client.component.ts
* imitations under the License.
*/
-import { Component, EventEmitter } from '@angular/core';
-import { IAction } from '../../../interfaces/ICommunication';
-import { BackendService } from '../../../services/backend/backend.service';
-import { catchError, switchMap } from 'rxjs/operators';
-import { EMPTY, iif, of } from 'rxjs';
-import { SnackbarService } from '../../../services/snackbar/snackbar.service';
-import { TranslateService } from '@ngx-translate/core';
+import { Component, Inject } from '@angular/core';
import { IClientVersionExt } from '../../../interfaces/IClientVersionSummaryExt';
+import { ClientService } from '../../../services/client/client.service';
+import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
@Component({
selector: 'app-unregister-client',
@@ -29,50 +25,22 @@ import { IClientVersionExt } from '../../../interfaces/IClientVersionSummaryExt'
styleUrls: ['./unregister-client.component.scss']
})
export class UnregisterClientComponent {
- extendedClientVersion!: IClientVersionExt;
- clientNameVersion = { value: '' };
-
- unregisterEmitter = new EventEmitter();
+ clientVersion: IClientVersionExt;
+ translations = { client: '' };
constructor(
- private backend: BackendService,
- private snackbarService: SnackbarService,
- private translator: TranslateService
- ) {}
+ private clientService: ClientService,
+ public dialogRef: MatDialogRef<UnregisterClientComponent>,
+ @Inject(MAT_DIALOG_DATA)
+ public data: { clientVersion: IClientVersionExt; clientName: string }
+ ) {
+ this.clientVersion = data.clientVersion;
+ this.translations.client = data.clientName;
+ }
- /**
- * This method deletes and optionally unregisters a client.
- * If the client is in the "Registered" or in the "AwaitingApproval" state, we unregister the client before deletion.
- */
onUnregister(): void {
- const action: IAction = {
- type: 'unregisterClient',
- organizationId: this.extendedClientVersion.client.organization.id,
- entityId: this.extendedClientVersion.client.id,
- entityVersion: this.extendedClientVersion.version
- };
-
- iif(
- () =>
- this.extendedClientVersion.status === 'Registered' ||
- this.extendedClientVersion.status === 'AwaitingApproval',
- this.backend.sendAction(action),
- of(void 0)
- )
- .pipe(
- switchMap(() =>
- this.backend.deleteClient(action.organizationId, action.entityId)
- ),
- catchError((err) => {
- console.error('Deleting client failed: ', err);
- this.snackbarService.showErrorSnackBar(
- this.translator.instant('CLIENTS.DELETE_CLIENT_FAILED') as string
- );
- return EMPTY;
- })
- )
- .subscribe(() => {
- this.unregisterEmitter.emit();
- });
+ this.clientService
+ .deleteClient(this.clientVersion)
+ .subscribe(() => this.dialogRef.close(true));
}
}

MODIFY
src/app/components/my-apps/my-apps.component.html
src/app/components/my-apps/my-apps.component.html
</div>
</div>
<ng-container
- *ngIf="clientHasContracts(client.id); else noContracts">
+ *ngIf="contractCount(client.id) > 0; else noContracts">
<ng-container *ngFor="let contract of contracts$ | async">
<div
*ngIf="contract.client.id === client.id"
<div class="app-api-header-labels">
<button
id="api-delete-btn"
- *ngIf="client.deletable"
+ *ngIf="
+ client.deletable && contractCount(client.id) > 1
+ "
(click)="breakContract(contract)"
mat-icon-button
color="primary"

MODIFY
src/app/components/my-apps/my-apps.component.ts
src/app/components/my-apps/my-apps.component.ts
@@ -345,19 +345,18 @@ export class MyAppsComponent implements OnInit {
.subscribe();
}
- clientHasContracts(clientVersionId: number): boolean {
- let hasContracts = false;
+ contractCount(clientVersionId: number): number {
+ let count = 0;
this.contracts$
.pipe(
tap((contracts: IContractExt[]) => {
- hasContracts =
- contracts.filter((contract) => {
+ count = contracts.filter((contract) => {
return contract.client.id === clientVersionId;
- }).length > 0;
+ }).length;
})
)
.subscribe();
- return hasContracts;
+ return count;
}
formatApiVersionPlanTitle(contract: IContractExt): string {
@@ -381,20 +380,20 @@ export class MyAppsComponent implements OnInit {
unregister(extendedClientVersion: IClientVersionExt): void {
const dialogRef = this.dialog.open(UnregisterClientComponent, {
+ data: {
+ clientVersion: extendedClientVersion,
+ clientName: this.formatClientContractTitle(extendedClientVersion)
+ },
autoFocus: false
});
- dialogRef.componentInstance.extendedClientVersion = extendedClientVersion;
- dialogRef.componentInstance.clientNameVersion = {
- value: this.formatClientContractTitle(extendedClientVersion)
- };
- dialogRef.componentInstance.unregisterEmitter.subscribe(() => {
+ dialogRef.afterClosed().subscribe((clientDeleted) => {
+ if (clientDeleted) {
this.snackbarService.showPrimarySnackBar(
this.translator.instant('CLIENTS.CLIENT_DELETED') as string
);
this.fetchData();
-
- dialogRef.close();
+ }
});
}

MODIFY
src/app/services/client/client.service.ts
src/app/services/client/client.service.ts
import { Injectable } from '@angular/core';
import { catchError, map, switchMap } from 'rxjs/operators';
import { HttpErrorResponse } from '@angular/common/http';
-import { EMPTY, forkJoin, Observable, throwError } from 'rxjs';
+import { EMPTY, forkJoin, iif, Observable, of, throwError } from 'rxjs';
import { BackendService } from '../backend/backend.service';
import {
IAction,
@@ -28,6 +28,8 @@ import {
} from '../../interfaces/ICommunication';
import { PermissionsService } from '../permissions/permissions.service';
import { IClientVersionExt } from '../../interfaces/IClientVersionSummaryExt';
+import { SnackbarService } from '../snackbar/snackbar.service';
+import { TranslateService } from '@ngx-translate/core';
@Injectable({
providedIn: 'root'
@@ -35,7 +37,9 @@ import { IClientVersionExt } from '../../interfaces/IClientVersionSummaryExt';
export class ClientService {
constructor(
private backend: BackendService,
- private permissionsService: PermissionsService
+ private permissionsService: PermissionsService,
+ private snackbarService: SnackbarService,
+ private translator: TranslateService
) {}
/**
@@ -78,9 +82,8 @@ export class ClientService {
this.permissionsService.getAllowedOrganizations({
name: 'clientAdmin'
} as IPermission);
- return (
- clientVersion.status !== 'Retired' &&
- clientAdminOrganizations.includes(clientVersion.client.organization.id)
+ return clientAdminOrganizations.includes(
+ clientVersion.client.organization.id
);
}
@@ -170,4 +173,38 @@ export class ClientService {
} as IClientVersionExt;
});
}
+
+ /**
+ * This method deletes and optionally unregisters a client.
+ * If the client is in the "Registered" or in the "AwaitingApproval" state, we unregister the client before deletion.
+ */
+ public deleteClient(
+ extendedClientVersion: IClientVersionExt | IClientVersion
+ ): Observable<void> {
+ const action: IAction = {
+ type: 'unregisterClient',
+ organizationId: extendedClientVersion.client.organization.id,
+ entityId: extendedClientVersion.client.id,
+ entityVersion: extendedClientVersion.version
+ };
+
+ return iif(
+ () =>
+ extendedClientVersion.status === 'Registered' ||
+ extendedClientVersion.status === 'AwaitingApproval',
+ this.backend.sendAction(action),
+ of(void 0)
+ ).pipe(
+ switchMap(() =>
+ this.backend.deleteClient(action.organizationId, action.entityId)
+ ),
+ catchError((err) => {
+ console.error('Deleting client failed: ', err);
+ this.snackbarService.showErrorSnackBar(
+ this.translator.instant('CLIENTS.DELETE_CLIENT_FAILED') as string
+ );
+ return EMPTY;
+ })
+ );
+ }
}

MODIFY
src/assets/i18n/en.json
src/assets/i18n/en.json
"DIALOGS": {
"DELETE_CLIENT": {
"TITLE":"Delete Client",
- "DELETE_SURE": "Are you sure you want to <span class='warn'>delete</span> the client <b>{{value}}</b> and all of its contracts?",
+ "DELETE_SURE": "Are you sure you want to <span class='warn'>delete</span> the client <b>{{client}}</b> and all of its contracts?",
"DELETE_BTN": "Delete Client"
},
"DELETE_CONTRACT": {

refactor: simplify the delete client dialog

Simplified the dialog by:
- moving the logic into the client service
- removing the EventEmitter
- pass data via injection