Skip to content

Commit

Permalink
refactor: migrate constructor-based injection to inject function
Browse files Browse the repository at this point in the history
  • Loading branch information
k-genov committed Feb 3, 2025
1 parent b80e196 commit 930bab7
Show file tree
Hide file tree
Showing 12 changed files with 162 additions and 182 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Directive, ElementRef} from '@angular/core';
import {Directive, ElementRef, inject} from '@angular/core';
import {asyncScheduler} from 'rxjs';

/**
Expand All @@ -7,7 +7,8 @@ import {asyncScheduler} from 'rxjs';
@Directive({selector: '[appAutoFocus]'})
export class AutofocusDirective {

constructor(private _host: ElementRef<HTMLElement>) {
asyncScheduler.schedule(() => this._host.nativeElement.focus());
constructor() {
const host = inject(ElementRef).nativeElement as HTMLElement;
asyncScheduler.schedule(() => host.focus());
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Component} from '@angular/core';
import {Component, inject} from '@angular/core';
import {MatDialogActions, MatDialogContent, MatDialogRef, MatDialogTitle} from '@angular/material/dialog';
import {FormControl, ReactiveFormsModule, Validators} from '@angular/forms';
import {PromptAccessTokenProvider} from '../prompt-access-token.provider';
Expand All @@ -22,17 +22,16 @@ import {MatButtonModule} from '@angular/material/button';
})
export class EnterAccessTokenComponent {

public accessTokenFormControl = new FormControl('', {validators: Validators.required, nonNullable: true});
private readonly _dialogRef = inject(MatDialogRef);
private readonly _accessTokenProvider = inject(PromptAccessTokenProvider);

constructor(private _dialogRef: MatDialogRef<void>,
private _accessTokenProvider: PromptAccessTokenProvider) {
}
protected readonly accessTokenFormControl = new FormControl('', {validators: Validators.required, nonNullable: true});

public onCancel(): void {
protected onCancel(): void {
this._dialogRef.close();
}

public onOk(): void {
protected onOk(): void {
this._accessTokenProvider.updateAccessToken(this.accessTokenFormControl.value);
this._dialogRef.close();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import {Injectable} from '@angular/core';
import {inject, Injectable} from '@angular/core';
import {Router} from '@angular/router';
import {SessionConfigStore} from './session-config-store';

@Injectable({providedIn: 'root'})
export class LocationService {

constructor(private _router: Router) {
}
private readonly _router = inject(Router);

public navigateToAppRoot(options: {clearConnectProperties: boolean}): void {
if (options.clearConnectProperties) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import {Component, OnDestroy} from '@angular/core';
import {Component, inject} from '@angular/core';
import {FormBuilder, FormGroup, ReactiveFormsModule, Validators} from '@angular/forms';
import {LocationService} from '../location.service';
import {SolaceMessageClientConfig} from '@solace-community/angular-solace-message-client';
import {SessionConfigStore} from '../session-config-store';
import {AuthenticationScheme} from 'solclientjs';
import {promptForAccessToken} from '../prompt-access-token.provider';
import {startWith, Subject} from 'rxjs';
import {takeUntil} from 'rxjs/operators';
import {startWith} from 'rxjs';
import {MatCardModule} from '@angular/material/card';
import {MatFormFieldModule} from '@angular/material/form-field';
import {MatInputModule} from '@angular/material/input';
import {MatSelectModule} from '@angular/material/select';
import {MatCheckboxModule} from '@angular/material/checkbox';
import {MatButtonModule} from '@angular/material/button';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';

export const URL = 'url';
export const VPN_NAME = 'vpnName';
Expand All @@ -36,62 +36,61 @@ export const RECONNECT_RETRIES = 'reconnectRetries';
MatButtonModule,
],
})
export class LoginComponent implements OnDestroy {
export class LoginComponent {

public readonly URL = URL;
public readonly VPN_NAME = VPN_NAME;
public readonly AUTHENTICATION_SCHEME = AUTHENTICATION_SCHEME;
public readonly USER_NAME = USER_NAME;
public readonly PASSWORD = PASSWORD;
public readonly REAPPLY_SUBSCRIPTIONS = REAPPLY_SUBSCRIPTIONS;
public readonly RECONNECT_RETRIES = RECONNECT_RETRIES;
private readonly _locationService = inject(LocationService);
private readonly _formBuilder = inject(FormBuilder);

public form: FormGroup;
public AuthenticationScheme = AuthenticationScheme;
protected readonly URL = URL;
protected readonly VPN_NAME = VPN_NAME;
protected readonly AUTHENTICATION_SCHEME = AUTHENTICATION_SCHEME;
protected readonly USER_NAME = USER_NAME;
protected readonly PASSWORD = PASSWORD;
protected readonly REAPPLY_SUBSCRIPTIONS = REAPPLY_SUBSCRIPTIONS;
protected readonly RECONNECT_RETRIES = RECONNECT_RETRIES;
protected readonly AuthenticationScheme = AuthenticationScheme;

private _destroy$ = new Subject<void>();
protected readonly form = new FormGroup({
[URL]: this._formBuilder.control('wss://public.messaging.solace.cloud:443', {validators: Validators.required, nonNullable: true}),
[VPN_NAME]: this._formBuilder.control('public', {validators: Validators.required, nonNullable: true}),
[AUTHENTICATION_SCHEME]: this._formBuilder.control(AuthenticationScheme.BASIC),
[USER_NAME]: this._formBuilder.control('angular'),
[PASSWORD]: this._formBuilder.control('public'),
[REAPPLY_SUBSCRIPTIONS]: this._formBuilder.control(true),
[RECONNECT_RETRIES]: this._formBuilder.control(-1),
});

constructor(formBuilder: FormBuilder,
private _locationService: LocationService) {
this.form = new FormGroup({
[URL]: formBuilder.control('wss://public.messaging.solace.cloud:443', {validators: Validators.required, nonNullable: true}),
[VPN_NAME]: formBuilder.control('public', {validators: Validators.required, nonNullable: true}),
[AUTHENTICATION_SCHEME]: formBuilder.control(AuthenticationScheme.BASIC),
[USER_NAME]: formBuilder.control('angular'),
[PASSWORD]: formBuilder.control('public'),
[REAPPLY_SUBSCRIPTIONS]: formBuilder.control(true),
[RECONNECT_RETRIES]: formBuilder.control(-1),
});
constructor() {
this.installAuthenticationSchemeChangeListener();
}

public onLogin(): void {
protected onLogin(): void {
const oAuthEnabled = this.form.get(AUTHENTICATION_SCHEME)!.value === AuthenticationScheme.OAUTH2;
const sessionConfig: SolaceMessageClientConfig = {
url: this.form.get(URL)!.value as string | string[],
vpnName: this.form.get(VPN_NAME)!.value as string,
userName: this.form.get(USER_NAME)!.value as string,
password: this.form.get(PASSWORD)!.value as string,
reapplySubscriptions: this.form.get(REAPPLY_SUBSCRIPTIONS)!.value as boolean,
reconnectRetries: this.form.get(RECONNECT_RETRIES)!.value as number,
connectRetries: this.form.get(RECONNECT_RETRIES)!.value as number,
authenticationScheme: this.form.get(AUTHENTICATION_SCHEME)!.value as AuthenticationScheme,
url: this.form.get(URL)!.value,
vpnName: this.form.get(VPN_NAME)!.value as string | undefined,
userName: this.form.get(USER_NAME)!.value as string | undefined,
password: this.form.get(PASSWORD)!.value as string | undefined,
reapplySubscriptions: this.form.get(REAPPLY_SUBSCRIPTIONS)!.value as boolean | undefined,
reconnectRetries: this.form.get(RECONNECT_RETRIES)!.value as number | undefined,
connectRetries: this.form.get(RECONNECT_RETRIES)!.value as number | undefined,
authenticationScheme: this.form.get(AUTHENTICATION_SCHEME)!.value as AuthenticationScheme | undefined,
accessToken: oAuthEnabled ? promptForAccessToken : undefined,
};

SessionConfigStore.store(sessionConfig);
this._locationService.navigateToAppRoot({clearConnectProperties: false});
}

public onReset(): void {
protected onReset(): void {
this.form.reset();
}

private installAuthenticationSchemeChangeListener(): void {
this.form.get(AUTHENTICATION_SCHEME)!.valueChanges
.pipe(
startWith(undefined),
takeUntil(this._destroy$),
takeUntilDestroyed(),
)
.subscribe(() => {
const basicAuthFormControls = [this.form.get(USER_NAME)!, this.form.get(PASSWORD)!];
Expand All @@ -103,8 +102,4 @@ export class LoginComponent implements OnDestroy {
});
});
}

public ngOnDestroy(): void {
this._destroy$.next();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,10 @@ import {EnterAccessTokenComponent} from './enter-access-token/enter-access-token
@Injectable({providedIn: 'root'})
export class PromptAccessTokenProvider {

private _empty = true;
private _accessToken$ = new ReplaySubject<string>(1);
private readonly _matDialog = inject(MatDialog);
private readonly _accessToken$ = new ReplaySubject<string>(1);

constructor(private _matDialog: MatDialog) {
}
private _empty = true;

public provide$(): Observable<string> {
// If not provided an access token yet, prompt for input.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy} from '@angular/core';
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, DestroyRef, inject} from '@angular/core';
import {FormBuilder, FormGroup, ReactiveFormsModule, Validators} from '@angular/forms';
import {DestinationType, MessageDeliveryModeType, MessageType, SDTField, SDTFieldType, SolclientFactory} from 'solclientjs';
import {Data, MessageEnvelope, PublishOptions, SolaceMessageClient} from '@solace-community/angular-solace-message-client';
import {defer, Observable, Subject, Subscription, tap, throwError} from 'rxjs';
import {finalize, takeUntil} from 'rxjs/operators';
import {defer, Observable, Subscription, tap, throwError} from 'rxjs';
import {finalize} from 'rxjs/operators';
import {Arrays} from '@scion/toolkit/util';
import {MatCardModule} from '@angular/material/card';
import {SciViewportComponent} from '@scion/components/viewport';
Expand All @@ -13,6 +13,7 @@ import {MatCheckboxModule} from '@angular/material/checkbox';
import {MessageListItemComponent} from '../message-list-item/message-list-item.component';
import {MatInputModule} from '@angular/material/input';
import {MatButtonModule} from '@angular/material/button';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';

export const DESTINATION = 'destination';
export const DESTINATION_TYPE = 'destinationType';
Expand All @@ -39,42 +40,41 @@ export const REQUEST_REPLY = 'request/reply';
MessageListItemComponent,
],
})
export class PublisherComponent implements OnDestroy {
export class PublisherComponent {

private readonly _solaceMessageClient = inject(SolaceMessageClient);
private readonly _cd = inject(ChangeDetectorRef);
private readonly _formBuilder = inject(FormBuilder);
private readonly _destroyRef = inject(DestroyRef);

protected readonly DESTINATION = DESTINATION;
protected readonly DESTINATION_TYPE = DESTINATION_TYPE;
protected readonly DELIVERY_MODE = DELIVERY_MODE;
protected readonly MESSAGE = MESSAGE;
protected readonly MESSAGE_TYPE = MESSAGE_TYPE;
protected readonly HEADERS = HEADERS;
protected readonly REQUEST_REPLY = REQUEST_REPLY;

protected readonly MessageType = MessageType;
protected readonly DestinationType = DestinationType;
protected readonly MessageDeliveryModeType = MessageDeliveryModeType;

protected readonly form = new FormGroup({
[DESTINATION]: this._formBuilder.control('', Validators.required),
[DESTINATION_TYPE]: this._formBuilder.control(DestinationType.TOPIC, Validators.required),
[DELIVERY_MODE]: this._formBuilder.control(undefined),
[MESSAGE]: this._formBuilder.control(''),
[MESSAGE_TYPE]: this._formBuilder.control(MessageType.BINARY, Validators.required),
[HEADERS]: this._formBuilder.control(''),
[REQUEST_REPLY]: this._formBuilder.control(false),
});

private _destroy$ = new Subject<void>();
private _publishSubscription: Subscription | null = null;

public readonly DESTINATION = DESTINATION;
public readonly DESTINATION_TYPE = DESTINATION_TYPE;
public readonly DELIVERY_MODE = DELIVERY_MODE;
public readonly MESSAGE = MESSAGE;
public readonly MESSAGE_TYPE = MESSAGE_TYPE;
public readonly HEADERS = HEADERS;
public readonly REQUEST_REPLY = REQUEST_REPLY;

public form: FormGroup;
public publishError: string | null = null;
public MessageType = MessageType;
public DestinationType = DestinationType;
public MessageDeliveryModeType = MessageDeliveryModeType;

public replies: MessageEnvelope[] = [];

constructor(formBuilder: FormBuilder,
private _solaceMessageClient: SolaceMessageClient,
private _cd: ChangeDetectorRef) {
this.form = new FormGroup({
[DESTINATION]: formBuilder.control('', Validators.required),
[DESTINATION_TYPE]: formBuilder.control(DestinationType.TOPIC, Validators.required),
[DELIVERY_MODE]: formBuilder.control(undefined),
[MESSAGE]: formBuilder.control(''),
[MESSAGE_TYPE]: formBuilder.control(MessageType.BINARY, Validators.required),
[HEADERS]: formBuilder.control(''),
[REQUEST_REPLY]: formBuilder.control(false),
});
}
protected publishError: string | null = null;
protected replies: MessageEnvelope[] = [];

public async onPublish(): Promise<void> {
protected async onPublish(): Promise<void> {
this.form.disable();
this.publishError = null;
this._publishSubscription = this.publish$()
Expand All @@ -88,27 +88,27 @@ export class PublisherComponent implements OnDestroy {
this.form.enable();
this._publishSubscription = null;
}),
takeUntil(this._destroy$),
takeUntilDestroyed(this._destroyRef),
)
.subscribe({
error: (error: unknown) => this.publishError = `${error}`, // eslint-disable-line @typescript-eslint/restrict-template-expressions
});
}

public onCancelPublish(): void {
protected onCancelPublish(): void {
this._publishSubscription?.unsubscribe();
this._publishSubscription = null;
this.replies.length = 0;
}

public onClearReplies(): void {
protected onClearReplies(): void {
this.replies.length = 0;
}

private publish$(): Observable<any> {
try {
const destination = this.form.get(DESTINATION)!.value as string;
const destinationType = this.form.get(DESTINATION_TYPE)!.value as DestinationType;
const destination = this.form.get(DESTINATION)!.value!;
const destinationType = this.form.get(DESTINATION_TYPE)!.value;
const message: Data | undefined = this.readMessageFromUI();
const publishOptions: PublishOptions = this.readPublishOptionsFromUI();

Expand Down Expand Up @@ -143,22 +143,22 @@ export class PublisherComponent implements OnDestroy {
}
}

public onDeleteReply(reply: MessageEnvelope): void {
protected onDeleteReply(reply: MessageEnvelope): void {
Arrays.remove(this.replies, reply);
}

public get requestReply(): boolean {
return this.form.get(REQUEST_REPLY)!.value as boolean;
protected get requestReply(): boolean {
return this.form.get(REQUEST_REPLY)!.value!;
}

public get publishing(): boolean {
protected get publishing(): boolean {
return this._publishSubscription !== null;
}

private readPublishOptionsFromUI(): PublishOptions {
return {
headers: this.readHeadersFromUI(),
deliveryMode: this.form.get(DELIVERY_MODE)!.value as MessageDeliveryModeType,
deliveryMode: this.form.get(DELIVERY_MODE)!.value! as MessageDeliveryModeType,
};
}

Expand All @@ -177,7 +177,7 @@ export class PublisherComponent implements OnDestroy {
}

private readHeadersFromUI(): Map<string, string | boolean | number> | undefined {
const headers = this.form.get(HEADERS)!.value as string;
const headers = this.form.get(HEADERS)!.value!;
if (!headers.length) {
return undefined;
}
Expand All @@ -197,8 +197,4 @@ export class PublisherComponent implements OnDestroy {
});
return headerMap;
}

public ngOnDestroy(): void {
this._destroy$.next();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,16 @@ import {MatButtonModule} from '@angular/material/button';
})
export class SessionPropertiesComponent {

public sessionProperties = obfuscateSecrets(inject<SessionProperties>(MAT_SNACK_BAR_DATA));
private readonly _snackbar = inject(MatSnackBar);
private readonly _clipboard = inject(Clipboard);

constructor(private _snackbar: MatSnackBar,
private _clipboard: Clipboard) {
}
protected readonly sessionProperties = obfuscateSecrets(inject<SessionProperties>(MAT_SNACK_BAR_DATA));

public onClose(): void {
protected onClose(): void {
this._snackbar.dismiss();
}

public onCopyToClipboard(): void {
protected onCopyToClipboard(): void {
this._clipboard.copy(JSON.stringify(this.sessionProperties));
}
}
Expand Down
Loading

0 comments on commit 930bab7

Please sign in to comment.