diff --git a/packages/desktop-ui-lib/src/lib/directives/debounce-click.directive.ts b/packages/desktop-ui-lib/src/lib/directives/debounce-click.directive.ts index 9caaab9c568..08b1c28a426 100644 --- a/packages/desktop-ui-lib/src/lib/directives/debounce-click.directive.ts +++ b/packages/desktop-ui-lib/src/lib/directives/debounce-click.directive.ts @@ -6,11 +6,11 @@ import { debounceTime } from 'rxjs/operators'; selector: '[debounceClick]' }) export class DebounceClickDirective implements OnInit, OnDestroy { - private clicks = new Subject(); + private clicks: Subject = new Subject(); private subscription: Subscription; @Input() debounceTime = 300; - @Output() throttledClick = new EventEmitter(); + @Output() throttledClick: EventEmitter = new EventEmitter(); /** * Handles the click event and emits it after a debounce time. @@ -20,8 +20,6 @@ export class DebounceClickDirective implements OnInit, OnDestroy { */ @HostListener('click', ['$event']) clickEvent(event: Event): void { - event.preventDefault(); - event.stopPropagation(); this.clicks.next(event); } diff --git a/packages/desktop-ui-lib/src/lib/login/features/login-magic/login-magic.component.html b/packages/desktop-ui-lib/src/lib/login/features/login-magic/login-magic.component.html index a7b1501ac08..8af5440baa2 100644 --- a/packages/desktop-ui-lib/src/lib/login/features/login-magic/login-magic.component.html +++ b/packages/desktop-ui-lib/src/lib/login/features/login-magic/login-magic.component.html @@ -43,7 +43,7 @@

{{ 'LOGIN_PAGE.TITLE' | translate }}

[status]="email.dirty ? (email.invalid ? 'danger' : 'success') : 'basic'" [attr.aria-invalid]="email.invalid && email.touched ? true : null" autofocus - autocomplete-off + autocomplete="off" [ngClass]="isCodeSent ? 'not-allowed' : ''" /> {{ 'LOGIN_PAGE.TITLE' | translate }}
-
- diff --git a/packages/desktop-ui-lib/src/lib/login/features/login-workspace/login-workspace.component.ts b/packages/desktop-ui-lib/src/lib/login/features/login-workspace/login-workspace.component.ts index 23d0767c005..804a6773c3b 100644 --- a/packages/desktop-ui-lib/src/lib/login/features/login-workspace/login-workspace.component.ts +++ b/packages/desktop-ui-lib/src/lib/login/features/login-workspace/login-workspace.component.ts @@ -1,5 +1,5 @@ import { Component } from '@angular/core'; -import { FormControl, UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; +import { FormBuilder, FormControl, FormGroup, UntypedFormBuilder, Validators } from '@angular/forms'; import { HttpStatus, IAuthResponse, IUser, IUserSigninWorkspaceResponse, IWorkspaceResponse } from '@gauzy/contracts'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { asyncScheduler, catchError, EMPTY, filter, tap } from 'rxjs'; @@ -21,7 +21,7 @@ export class NgxLoginWorkspaceComponent { public showPassword = false; /** The FormGroup for the sign-in form */ - public form: UntypedFormGroup = NgxLoginWorkspaceComponent.buildForm(this._fb); + public form: FormGroup = NgxLoginWorkspaceComponent.buildForm(this._fb); /** * Static method to build a FormGroup for the sign-in form. @@ -29,7 +29,7 @@ export class NgxLoginWorkspaceComponent { * @param fb - The FormBuilder service for creating form controls. * @returns A FormGroup for the sign-in form. */ - static buildForm(fb: UntypedFormBuilder): UntypedFormGroup { + static buildForm(fb: FormBuilder): FormGroup { return fb.group({ email: new FormControl(null, [Validators.required, Validators.email]), // Email input with email validation password: new FormControl(null, [Validators.required]) // Password input with required validation @@ -51,57 +51,46 @@ export class NgxLoginWorkspaceComponent { return; // Exit if the form is invalid } - try { - // - this.loading = true; + // + this.loading = true; - // Get the values of email and password from the form - const email = this.form.get('email').value; - const password = this.password.value; + // Get the values of email and password from the form + const email = this.form.get('email').value; + const password = this.password.value; - // Send a request to sign in to workspaces using the authentication service - this._authService - .findWorkspaces({ email, password }) - .pipe( - tap((response: any) => { - if (response['status'] === HttpStatus.UNAUTHORIZED) { - throw new Error(`${response['message']}`); - } - }), - // Update component state with the fetched workspaces - tap( - ({ - workspaces, - show_popup, - total_workspaces, - confirmed_email - }: IUserSigninWorkspaceResponse) => { - this.workspaces = workspaces; - this.showPopup = show_popup; - this.confirmedEmail = confirmed_email; - this.totalWorkspaces = total_workspaces; - /** */ - if (total_workspaces == 1) { - const [workspace] = this.workspaces; - this.signInWorkspace(workspace); - } else { - this.loading = false; - } - } - ), - catchError((error) => { - // Handle and log errors using the error handling service + // Send a request to sign in to workspaces using the authentication service + this._authService + .findWorkspaces({ email, password }) + .pipe( + tap((response) => { + if (response['status'] === HttpStatus.UNAUTHORIZED) { + throw new Error(`${response['message']}`); + } + }), + // Update component state with the fetched workspaces + tap(({ workspaces, show_popup, total_workspaces, confirmed_email }: IUserSigninWorkspaceResponse) => { + this.workspaces = workspaces; + this.showPopup = show_popup; + this.confirmedEmail = confirmed_email; + this.totalWorkspaces = total_workspaces; + /** */ + if (total_workspaces == 1) { + const [workspace] = this.workspaces; + this.signInWorkspace(workspace); + } else { this.loading = false; - this._errorHandlingService.handleError(error); - return EMPTY; - }), - // Handle component lifecycle to avoid memory leaks - untilDestroyed(this) - ) - .subscribe(); - } catch (error) { - console.log(error); - } + } + }), + catchError((error) => { + // Handle and log errors using the error handling service + this.loading = false; + this._errorHandlingService.handleError(error); + return EMPTY; + }), + // Handle component lifecycle to avoid memory leaks + untilDestroyed(this) + ) + .subscribe(); } /** diff --git a/packages/desktop-ui-lib/src/lib/login/features/magic-login-workspace/magic-login-workspace.component.scss b/packages/desktop-ui-lib/src/lib/login/features/magic-login-workspace/magic-login-workspace.component.scss index d185cfe1b67..39c77fe88de 100644 --- a/packages/desktop-ui-lib/src/lib/login/features/magic-login-workspace/magic-login-workspace.component.scss +++ b/packages/desktop-ui-lib/src/lib/login/features/magic-login-workspace/magic-login-workspace.component.scss @@ -37,5 +37,5 @@ margin-right: 15px; } h3 { - margin-bottom: 10px; + margin-bottom: 0.625rem; } diff --git a/packages/desktop-ui-lib/src/lib/login/features/magic-login-workspace/magic-login-workspace.component.ts b/packages/desktop-ui-lib/src/lib/login/features/magic-login-workspace/magic-login-workspace.component.ts index 2bbe51b03b2..5876d751722 100644 --- a/packages/desktop-ui-lib/src/lib/login/features/magic-login-workspace/magic-login-workspace.component.ts +++ b/packages/desktop-ui-lib/src/lib/login/features/magic-login-workspace/magic-login-workspace.component.ts @@ -39,7 +39,7 @@ export class NgxMagicSignInWorkspaceComponent implements OnInit { // Tap into the observable to update the 'form.email' property with the 'email' query parameter. tap(({ email, code }: Params) => { if (email && code) { - this.confirmSingInCode(); + this.confirmSignInCode(); } }), // Use 'untilDestroyed' to handle component lifecycle and avoid memory leaks. @@ -51,7 +51,7 @@ export class NgxMagicSignInWorkspaceComponent implements OnInit { /** * Confirm the sign in code */ - async confirmSingInCode() { + async confirmSignInCode() { // Get the email & code value from the query params const { email, code } = this._activatedRoute.snapshot.queryParams; if (!email || !code) { @@ -109,41 +109,39 @@ export class NgxMagicSignInWorkspaceComponent implements OnInit { // Extract workspace, email, and token from the parameter and component state const email = this.confirmedEmail; const token = workspace.token; + // Send a request to sign in to the workspace using the authentication service + this._authService + .signinWorkspaceByToken({ email, token }) + .pipe( + filter(({ user, token }: IAuthResponse) => !!user && !!token), + tap((response: IAuthResponse) => { + const user: IUser = response.user; + const token: string = response.token; - try { - // Send a request to sign in to the workspace using the authentication service - this._authService - .signinWorkspaceByToken({ email, token }) - .pipe( - filter(({ user, token }: IAuthResponse) => !!user && !!token), - tap((response: IAuthResponse) => { - const user: IUser = response.user; - const token: string = response.token; + const { id, employee, tenantId } = user; - const { id, employee, tenantId } = user; + if (employee) { TimeTrackerDateManager.organization = employee.organization; this._store.organizationId = employee.organizationId; - this._store.tenantId = tenantId; - this._store.userId = id; - this._store.token = token; - this._store.user = user; + } - asyncScheduler.schedule(() => { - this._authService.electronAuthentication({ token, user }); - }, 3000); - }), - catchError((error) => { - // Handle and log errors using the error handling service - this._errorHandlingService.handleError(error); - return EMPTY; - }), - // Handle component lifecycle to avoid memory leaks - untilDestroyed(this) - ) - .subscribe(); - } catch (error) { - console.log('Error while signing in workspace', error); - this._errorHandlingService.handleError(error); - } + this._store.tenantId = tenantId; + this._store.userId = id; + this._store.token = token; + this._store.user = user; + + asyncScheduler.schedule(() => { + this._authService.electronAuthentication({ token, user }); + }, 3000); + }), + catchError((error) => { + // Handle and log errors using the error handling service + this._errorHandlingService.handleError(error); + return EMPTY; + }), + // Handle component lifecycle to avoid memory leaks + untilDestroyed(this) + ) + .subscribe(); } } diff --git a/packages/desktop-ui-lib/src/lib/login/login.module.ts b/packages/desktop-ui-lib/src/lib/login/login.module.ts index 5f64a804f9b..25234036b3c 100644 --- a/packages/desktop-ui-lib/src/lib/login/login.module.ts +++ b/packages/desktop-ui-lib/src/lib/login/login.module.ts @@ -47,7 +47,6 @@ const shared = [ NbFormFieldModule, DesktopDirectiveModule, LanguageModule.forChild(), - FormsModule, ReactiveFormsModule, SwitchThemeModule, NbListModule, diff --git a/packages/desktop-ui-lib/src/lib/login/shared/ui/workspace-selection/workspace-selection.component.scss b/packages/desktop-ui-lib/src/lib/login/shared/ui/workspace-selection/workspace-selection.component.scss index 9b46ac28778..21beaa92efa 100644 --- a/packages/desktop-ui-lib/src/lib/login/shared/ui/workspace-selection/workspace-selection.component.scss +++ b/packages/desktop-ui-lib/src/lib/login/shared/ui/workspace-selection/workspace-selection.component.scss @@ -113,13 +113,3 @@ } } } - -::ng-deep { - ngx-gauzy-logo { - object { - max-width: unset !important; - max-height: unset !important; - height: 36px; - } - } -} diff --git a/packages/desktop-ui-lib/src/lib/shared/components/ui/avatar/avatar.component.scss b/packages/desktop-ui-lib/src/lib/shared/components/ui/avatar/avatar.component.scss index 7dfbb13eab4..a4454176125 100644 --- a/packages/desktop-ui-lib/src/lib/shared/components/ui/avatar/avatar.component.scss +++ b/packages/desktop-ui-lib/src/lib/shared/components/ui/avatar/avatar.component.scss @@ -1,17 +1,16 @@ @import 'themes'; -@mixin common { +@mixin avatarMixin($radius: var(--border-radius), $imageSize: 48px) { .inner-wrapper { - border-radius: var(--button-rectangle-border-radius); + display: flex; align-items: center; overflow: hidden; - display: flex; - gap: 8px; + border-radius: $radius; } .avatar-wrapper { width: 100%; - border-radius: var(--border-radius); + border-radius: $radius; } .names-wrapper { @@ -36,23 +35,23 @@ } .image-container { - width: 20px; + width: $imageSize; cursor: pointer; - border-radius: var(--border-radius); + border-radius: $radius; display: flex; position: relative; img { - width: 20px; - height: 20px; + width: $imageSize; + height: $imageSize; object-fit: cover; - border-radius: var(--border-radius) !important; + border-radius: $radius !important; } .status-indicator { position: absolute; - width: 10px; - height: 10px; - border-radius: 8px; + width: calc($imageSize / 2); + height: calc($imageSize / 2); + border-radius: calc($radius / 2); border: 2px solid #ebebeb; right: 0; top: 0; @@ -94,12 +93,10 @@ .image-container { width: 48px; - cursor: pointer; img { width: 48px; height: 48px; - object-fit: cover; } &.lg { @@ -139,7 +136,7 @@ color: var(--text-primary-color) !important; } - @include common; + @include avatarMixin(); } :host-context(.avatar-dashboard) { @@ -172,26 +169,25 @@ } } - @include common; + @include avatarMixin(); } :host-context(.workspace) { - $radius: var(--border-radius); width: 100%; .inner-wrapper { width: fit-content; - padding: calc($radius / 4); + padding: calc(var(--border-radius) / 4); background-color: var(--color-primary-transparent-100); - border-radius: calc($radius / 2) !important; + border-radius: calc(var(--border-radius) / 2) !important; } - @include common; + @include avatarMixin($radius: calc(var(--border-radius) / 2), $imageSize: 48px); .image-container { &, img { - border-radius: calc($radius / 4) !important; + border-radius: calc(var(--border-radius) / 4) !important; } } diff --git a/packages/desktop-ui-lib/src/lib/shared/components/ui/avatar/avatar.component.ts b/packages/desktop-ui-lib/src/lib/shared/components/ui/avatar/avatar.component.ts index 484ba6bd6dd..dccbba43948 100644 --- a/packages/desktop-ui-lib/src/lib/shared/components/ui/avatar/avatar.component.ts +++ b/packages/desktop-ui-lib/src/lib/shared/components/ui/avatar/avatar.component.ts @@ -21,7 +21,7 @@ export class AvatarComponent implements OnInit { /** * A class member and getter/setter for managing an employee object. */ - private _employee = new BehaviorSubject(null); + private _employee = new BehaviorSubject(null); @Input() set employee(value: IEmployee) { this._employee.next(value); } @@ -50,10 +50,6 @@ export class AvatarComponent implements OnInit { } ngOnInit() { - if (this._employee) { - this.online$ = this._employee - .asObservable() - .pipe(map((employee) => employee?.isOnline && !employee?.isAway)); - } + this.online$ = this._employee.asObservable().pipe(map((employee) => employee?.isOnline && !employee?.isAway)); } }