refactor: use reactive breakpoints with observables and constants in ResizeService
This commit is contained in:
parent
ab6c4ce2b9
commit
815b8ef605
7 changed files with 76 additions and 22 deletions
|
|
@ -12,7 +12,7 @@ import { ApiService } from '../../services/api.service';
|
||||||
import { Task } from '../../interfaces/task.interface';
|
import { Task } from '../../interfaces/task.interface';
|
||||||
import { TaskService } from '../../services/task.service';
|
import { TaskService } from '../../services/task.service';
|
||||||
import { LoadingSpinnerComponent } from '../../shared/components/loading-spinner/loading-spinner.component';
|
import { LoadingSpinnerComponent } from '../../shared/components/loading-spinner/loading-spinner.component';
|
||||||
import { debounceTime, finalize, Subject, takeUntil } from 'rxjs';
|
import { debounceTime, finalize, Subject, take, takeUntil } from 'rxjs';
|
||||||
import { UpdateNotifierService } from '../../services/update-notifier.service';
|
import { UpdateNotifierService } from '../../services/update-notifier.service';
|
||||||
import { ToastNotificationService } from '../../services/toast-notification.service';
|
import { ToastNotificationService } from '../../services/toast-notification.service';
|
||||||
import { ResizeService } from '../../services/resize.service';
|
import { ResizeService } from '../../services/resize.service';
|
||||||
|
|
@ -48,6 +48,7 @@ export class BoardComponent implements OnInit, OnDestroy {
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
|
|
||||||
private destroy$ = new Subject<void>();
|
private destroy$ = new Subject<void>();
|
||||||
|
private pageViewMedia$ = this.resizeService.pageViewMedia$;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public dragDropService: DragDropService,
|
public dragDropService: DragDropService,
|
||||||
|
|
@ -143,9 +144,11 @@ export class BoardComponent implements OnInit, OnDestroy {
|
||||||
* @param status The status to be used for the new task.
|
* @param status The status to be used for the new task.
|
||||||
*/
|
*/
|
||||||
addNewTaskOverlay(status: string) {
|
addNewTaskOverlay(status: string) {
|
||||||
this.resizeService.isPageViewMedia
|
this.pageViewMedia$.pipe(take(1)).subscribe((isPageViewMedia) => {
|
||||||
|
isPageViewMedia
|
||||||
? this.router.navigate(['/add-task', status])
|
? this.router.navigate(['/add-task', status])
|
||||||
: this.overlayService.setOverlayData('newTaskOverlay', status);
|
: this.overlayService.setOverlayData('newTaskOverlay', status);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
>
|
>
|
||||||
{{ task.category }}
|
{{ task.category }}
|
||||||
</div>
|
</div>
|
||||||
@if (resizeService.isPageViewMedia) {
|
@if (pageViewMedia$ | async) {
|
||||||
<div class="menu-btn" (click)="handleMenuButtonClick($event, task.id)">
|
<div class="menu-btn" (click)="handleMenuButtonClick($event, task.id)">
|
||||||
<img
|
<img
|
||||||
class="menu-img"
|
class="menu-img"
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import { OverlayService } from '../../../services/overlay.service';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { TaskMenuComponent } from './task-menu/task-menu.component';
|
import { TaskMenuComponent } from './task-menu/task-menu.component';
|
||||||
import { ResizeService } from '../../../services/resize.service';
|
import { ResizeService } from '../../../services/resize.service';
|
||||||
|
import { take } from 'rxjs';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-task',
|
selector: 'app-task',
|
||||||
|
|
@ -16,6 +17,7 @@ import { ResizeService } from '../../../services/resize.service';
|
||||||
})
|
})
|
||||||
export class TaskComponent {
|
export class TaskComponent {
|
||||||
@Input() task: Task = {} as Task;
|
@Input() task: Task = {} as Task;
|
||||||
|
|
||||||
isMenuOpen: boolean = false;
|
isMenuOpen: boolean = false;
|
||||||
AssignedDialogId: string = '';
|
AssignedDialogId: string = '';
|
||||||
dialogX: number = 0;
|
dialogX: number = 0;
|
||||||
|
|
@ -23,12 +25,13 @@ export class TaskComponent {
|
||||||
|
|
||||||
creator: any = '';
|
creator: any = '';
|
||||||
assignees: any[] = [];
|
assignees: any[] = [];
|
||||||
|
|
||||||
categoryColors = new Map<string, string>([
|
categoryColors = new Map<string, string>([
|
||||||
['User Story', '#0038ff'],
|
['User Story', '#0038ff'],
|
||||||
['Technical Task', '#20d7c2'],
|
['Technical Task', '#20d7c2'],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
pageViewMedia$ = this.resizeService.pageViewMedia$;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public dragDropService: DragDropService,
|
public dragDropService: DragDropService,
|
||||||
public overlayService: OverlayService,
|
public overlayService: OverlayService,
|
||||||
|
|
@ -72,9 +75,11 @@ export class TaskComponent {
|
||||||
if (this.isMenuOpen) {
|
if (this.isMenuOpen) {
|
||||||
this.toggleTaskMenu();
|
this.toggleTaskMenu();
|
||||||
}
|
}
|
||||||
this.resizeService.isPageViewMedia
|
this.pageViewMedia$.pipe(take(1)).subscribe((isPageViewMedia) => {
|
||||||
|
isPageViewMedia
|
||||||
? this.router.navigate(['/task', taskId])
|
? this.router.navigate(['/task', taskId])
|
||||||
: this.overlayService.setOverlayData('taskOverlay', taskId);
|
: this.overlayService.setOverlayData('taskOverlay', taskId);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@HostListener('document:click', ['$event'])
|
@HostListener('document:click', ['$event'])
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,7 @@ export class ContactsComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
@HostListener('window:resize', ['$event'])
|
@HostListener('window:resize', ['$event'])
|
||||||
onResize() {
|
onResize() {
|
||||||
if (window.innerWidth <= 1150 && this.selectedUserId != undefined) {
|
if (window.innerWidth <= 1000 && this.selectedUserId != undefined) {
|
||||||
this.showAllUsers = false;
|
this.showAllUsers = false;
|
||||||
} else {
|
} else {
|
||||||
this.showAllUsers = true;
|
this.showAllUsers = true;
|
||||||
|
|
|
||||||
|
|
@ -1,29 +1,73 @@
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable, OnDestroy } from '@angular/core';
|
||||||
|
import { BehaviorSubject } from 'rxjs';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
})
|
})
|
||||||
export class ResizeService {
|
export class ResizeService implements OnDestroy {
|
||||||
isPageViewMedia: boolean = window.innerWidth <= 650;
|
private readonly PAGE_VIEW_BREAKPOINT = 650;
|
||||||
isContactViewMedia: boolean = window.innerWidth <= 800;
|
private readonly CONTACT_VIEW_BREAKPOINT = 800;
|
||||||
|
|
||||||
|
private pageViewMediaSubject = new BehaviorSubject<boolean>(
|
||||||
|
window.innerWidth <= this.PAGE_VIEW_BREAKPOINT
|
||||||
|
);
|
||||||
|
private contactViewMediaSubject = new BehaviorSubject<boolean>(
|
||||||
|
window.innerWidth <= this.CONTACT_VIEW_BREAKPOINT
|
||||||
|
);
|
||||||
|
|
||||||
|
pageViewMedia$ = this.pageViewMediaSubject.asObservable();
|
||||||
|
contactViewMedia$ = this.contactViewMediaSubject.asObservable();
|
||||||
|
|
||||||
private resizeListener!: () => void;
|
private resizeListener!: () => void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the resize event listener, which updates the media query subjects
|
||||||
|
* based on the current window width whenever the window is resized.
|
||||||
|
*/
|
||||||
constructor() {
|
constructor() {
|
||||||
this.initResizeListener();
|
this.initResizeListener();
|
||||||
}
|
}
|
||||||
|
|
||||||
private initResizeListener() {
|
/**
|
||||||
|
* Cleans up resources by removing the resize event listener,
|
||||||
|
* ensuring that no memory leaks occur when the service is no longer in use.
|
||||||
|
*/
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this.cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the resize event listener.
|
||||||
|
*
|
||||||
|
* This method binds the onResize method to the resizeListener and adds it as an event listener
|
||||||
|
* for the window's resize event. This allows the service to respond to changes in window size
|
||||||
|
* by updating the relevant media query subjects.
|
||||||
|
*/
|
||||||
|
private initResizeListener(): void {
|
||||||
this.resizeListener = this.onResize.bind(this);
|
this.resizeListener = this.onResize.bind(this);
|
||||||
window.addEventListener('resize', this.resizeListener);
|
window.addEventListener('resize', this.resizeListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
private onResize() {
|
/**
|
||||||
this.isPageViewMedia = window.innerWidth <= 650;
|
* Updates the media query subjects based on the current window width.
|
||||||
this.isContactViewMedia = window.innerWidth <= 800;
|
*
|
||||||
|
* This method checks the window's inner width against predefined breakpoints
|
||||||
|
* and updates the pageViewMediaSubject and contactViewMediaSubject accordingly.
|
||||||
|
* It is triggered whenever a window resize event occurs.
|
||||||
|
*/
|
||||||
|
private onResize(): void {
|
||||||
|
this.pageViewMediaSubject.next(
|
||||||
|
window.innerWidth <= this.PAGE_VIEW_BREAKPOINT
|
||||||
|
);
|
||||||
|
this.contactViewMediaSubject.next(
|
||||||
|
window.innerWidth <= this.CONTACT_VIEW_BREAKPOINT
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup() {
|
/**
|
||||||
|
* Remove the event listener for window resizing.
|
||||||
|
*/
|
||||||
|
cleanup(): void {
|
||||||
window.removeEventListener('resize', this.resizeListener);
|
window.removeEventListener('resize', this.resizeListener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
@if (resizeService.isContactViewMedia) {
|
@if (contactViewMedia$ | async) {
|
||||||
<div class="error-msg">
|
<div class="error-msg">
|
||||||
@if (firstName.hasError('pattern') && firstName.touched) {
|
@if (firstName.hasError('pattern') && firstName.touched) {
|
||||||
<p>{{ "contactDialogForm.invalidPattern" | translate }}</p>
|
<p>{{ "contactDialogForm.invalidPattern" | translate }}</p>
|
||||||
|
|
@ -48,7 +48,7 @@
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@if (resizeService.isContactViewMedia) {
|
@if (contactViewMedia$ | async) {
|
||||||
<div class="error-msg">
|
<div class="error-msg">
|
||||||
@if (lastName.hasError('pattern') && lastName.touched) {
|
@if (lastName.hasError('pattern') && lastName.touched) {
|
||||||
<p>{{ "contactDialogForm.invalidPattern" | translate }}</p>
|
<p>{{ "contactDialogForm.invalidPattern" | translate }}</p>
|
||||||
|
|
@ -56,7 +56,7 @@
|
||||||
<p>{{ "contactDialogForm.invalidLastName" | translate }}</p>
|
<p>{{ "contactDialogForm.invalidLastName" | translate }}</p>
|
||||||
}}
|
}}
|
||||||
</div>
|
</div>
|
||||||
} @if (!resizeService.isContactViewMedia) {
|
} @else {
|
||||||
<div class="error-msg">
|
<div class="error-msg">
|
||||||
@if (firstName.hasError('pattern') || lastName.hasError('pattern') &&
|
@if (firstName.hasError('pattern') || lastName.hasError('pattern') &&
|
||||||
firstName.touched) {
|
firstName.touched) {
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,8 @@ export class ContactFormComponent implements OnInit, OnChanges {
|
||||||
lastLogin: 0,
|
lastLogin: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
contactViewMedia$ = this.resizeService.contactViewMedia$;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OnInit lifecycle hook.
|
* OnInit lifecycle hook.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue