From 890d69af021d45c956b1f4c20a1a216ded01c036 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20=C3=87etin?= <92744169+mehmetcetin01140@users.noreply.github.com> Date: Fri, 22 Dec 2023 10:16:50 +0300 Subject: [PATCH] Refactor appConfig component, update layoutService and implement Angular signals --- package.json | 2 +- .../auth/login/login.component.html | 2 +- .../dashboard/dashboard.component.ts | 6 +- .../documentation.component.html | 5 +- .../components/landing/landing.component.html | 4 +- .../uikit/charts/chartsdemo.component.ts | 13 ++-- src/app/layout/app.footer.component.html | 2 +- src/app/layout/app.layout.component.ts | 14 ++--- src/app/layout/app.menu.component.html | 2 +- src/app/layout/app.topbar.component.html | 2 +- src/app/layout/config/app.config.component.ts | 55 +++++++---------- src/app/layout/service/app.layout.service.ts | 61 +++++++++++++++++-- 12 files changed, 107 insertions(+), 61 deletions(-) diff --git a/package.json b/package.json index 1371935..8479670 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sakai-ng", - "version": "17.0.0", + "version": "17.2.0", "license": "PrimeNG Commercial", "scripts": { "ng": "ng", diff --git a/src/app/demo/components/auth/login/login.component.html b/src/app/demo/components/auth/login/login.component.html index e147466..7fb5edb 100644 --- a/src/app/demo/components/auth/login/login.component.html +++ b/src/app/demo/components/auth/login/login.component.html @@ -1,6 +1,6 @@
- Sakai logo + Sakai logo
diff --git a/src/app/demo/components/dashboard/dashboard.component.ts b/src/app/demo/components/dashboard/dashboard.component.ts index 804d9f9..6e9fe23 100644 --- a/src/app/demo/components/dashboard/dashboard.component.ts +++ b/src/app/demo/components/dashboard/dashboard.component.ts @@ -2,7 +2,7 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; import { MenuItem } from 'primeng/api'; import { Product } from '../../api/product'; import { ProductService } from '../../service/product.service'; -import { Subscription } from 'rxjs'; +import { Subscription, debounceTime } from 'rxjs'; import { LayoutService } from 'src/app/layout/service/app.layout.service'; @Component({ @@ -21,7 +21,9 @@ export class DashboardComponent implements OnInit, OnDestroy { subscription!: Subscription; constructor(private productService: ProductService, public layoutService: LayoutService) { - this.subscription = this.layoutService.configUpdate$.subscribe(() => { + this.subscription = this.layoutService.configUpdate$ + .pipe(debounceTime(25)) + .subscribe((config) => { this.initChart(); }); } diff --git a/src/app/demo/components/documentation/documentation.component.html b/src/app/demo/components/documentation/documentation.component.html index 350c49d..41b6f52 100644 --- a/src/app/demo/components/documentation/documentation.component.html +++ b/src/app/demo/components/documentation/documentation.component.html @@ -43,7 +43,7 @@ Run 'ng help' for more options.
import { Component, OnInit } from '@angular/core';
 import { PrimeNGConfig } from 'primeng/api';
-import { LayoutService } from './layout/service/app.layout.service';
+import { LayoutService, AppConfig } from './layout/service/app.layout.service';
 
 @Component({
     selector: 'app-root',
@@ -57,7 +57,7 @@ export class AppComponent implements OnInit {
         this.primengConfig.ripple = true;       //enables core ripple functionality
 
         //optional configuration with the default configuration
-        this.layoutService.config = {
+        const config: AppConfig = {
             ripple: false,                      //toggles ripple on and off
             inputStyle: 'outlined',             //default style for input elements
             menuMode: 'static',                 //layout mode of the menu, valid values are "static" and "overlay"
@@ -65,6 +65,7 @@ export class AppComponent implements OnInit {
             theme: 'lara-light-indigo',         //default component theme for PrimeNG
             scale: 14                           //size of the body font size to scale the whole application
         };
+        this.layoutService.config.set(config);
     }
 
 }
diff --git a/src/app/demo/components/landing/landing.component.html b/src/app/demo/components/landing/landing.component.html index a274f50..80e9642 100644 --- a/src/app/demo/components/landing/landing.component.html +++ b/src/app/demo/components/landing/landing.component.html @@ -2,7 +2,7 @@
- Sakai LogoSAKAI + Sakai LogoSAKAI @@ -317,7 +317,7 @@
diff --git a/src/app/demo/components/uikit/charts/chartsdemo.component.ts b/src/app/demo/components/uikit/charts/chartsdemo.component.ts index 2871b66..7f48bb3 100755 --- a/src/app/demo/components/uikit/charts/chartsdemo.component.ts +++ b/src/app/demo/components/uikit/charts/chartsdemo.component.ts @@ -1,5 +1,5 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; -import { Subscription } from 'rxjs'; +import { Subscription, debounceTime } from 'rxjs'; import { LayoutService } from 'src/app/layout/service/app.layout.service'; @Component({ @@ -28,11 +28,12 @@ export class ChartsDemoComponent implements OnInit, OnDestroy { radarOptions: any; subscription: Subscription; - - constructor(public layoutService: LayoutService) { - this.subscription = this.layoutService.configUpdate$.subscribe(config => { - this.initCharts(); - }); + constructor(private layoutService: LayoutService) { + this.subscription = this.layoutService.configUpdate$ + .pipe(debounceTime(25)) + .subscribe((config) => { + this.initCharts(); + }); } ngOnInit() { diff --git a/src/app/layout/app.footer.component.html b/src/app/layout/app.footer.component.html index da4a248..255f480 100644 --- a/src/app/layout/app.footer.component.html +++ b/src/app/layout/app.footer.component.html @@ -1,5 +1,5 @@ diff --git a/src/app/layout/app.layout.component.ts b/src/app/layout/app.layout.component.ts index 802b5a9..43aea03 100644 --- a/src/app/layout/app.layout.component.ts +++ b/src/app/layout/app.layout.component.ts @@ -97,15 +97,15 @@ export class AppLayoutComponent implements OnDestroy { get containerClass() { return { - 'layout-theme-light': this.layoutService.config.colorScheme === 'light', - 'layout-theme-dark': this.layoutService.config.colorScheme === 'dark', - 'layout-overlay': this.layoutService.config.menuMode === 'overlay', - 'layout-static': this.layoutService.config.menuMode === 'static', - 'layout-static-inactive': this.layoutService.state.staticMenuDesktopInactive && this.layoutService.config.menuMode === 'static', + 'layout-theme-light': this.layoutService.config().colorScheme === 'light', + 'layout-theme-dark': this.layoutService.config().colorScheme === 'dark', + 'layout-overlay': this.layoutService.config().menuMode === 'overlay', + 'layout-static': this.layoutService.config().menuMode === 'static', + 'layout-static-inactive': this.layoutService.state.staticMenuDesktopInactive && this.layoutService.config().menuMode === 'static', 'layout-overlay-active': this.layoutService.state.overlayMenuActive, 'layout-mobile-active': this.layoutService.state.staticMenuMobileActive, - 'p-input-filled': this.layoutService.config.inputStyle === 'filled', - 'p-ripple-disabled': !this.layoutService.config.ripple + 'p-input-filled': this.layoutService.config().inputStyle === 'filled', + 'p-ripple-disabled': !this.layoutService.config().ripple } } diff --git a/src/app/layout/app.menu.component.html b/src/app/layout/app.menu.component.html index c9b3bf6..128ed4e 100644 --- a/src/app/layout/app.menu.component.html +++ b/src/app/layout/app.menu.component.html @@ -5,7 +5,7 @@
  • - Prime Blocks + Prime Blocks
  • diff --git a/src/app/layout/app.topbar.component.html b/src/app/layout/app.topbar.component.html index c748da9..8475660 100644 --- a/src/app/layout/app.topbar.component.html +++ b/src/app/layout/app.topbar.component.html @@ -1,6 +1,6 @@
    diff --git a/src/app/layout/config/app.config.component.ts b/src/app/layout/config/app.config.component.ts index fb3bb7b..d2290e9 100644 --- a/src/app/layout/config/app.config.component.ts +++ b/src/app/layout/config/app.config.component.ts @@ -23,35 +23,44 @@ export class AppConfigComponent { } get scale(): number { - return this.layoutService.config.scale; + return this.layoutService.config().scale; } set scale(_val: number) { - this.layoutService.config.scale = _val; + this.layoutService.config.update((config) => ({ + ...config, + scale: _val, + })); } get menuMode(): string { - return this.layoutService.config.menuMode; + return this.layoutService.config().menuMode; } set menuMode(_val: string) { - this.layoutService.config.menuMode = _val; + this.layoutService.config.update((config) => ({ + ...config, + menuMode: _val, + })); } get inputStyle(): string { - return this.layoutService.config.inputStyle; + return this.layoutService.config().inputStyle; } set inputStyle(_val: string) { - this.layoutService.config.inputStyle = _val; + this.layoutService.config().inputStyle = _val; } get ripple(): boolean { - return this.layoutService.config.ripple; + return this.layoutService.config().ripple; } set ripple(_val: boolean) { - this.layoutService.config.ripple = _val; + this.layoutService.config.update((config) => ({ + ...config, + ripple: _val, + })); } onConfigButtonClick() { @@ -59,32 +68,9 @@ export class AppConfigComponent { } changeTheme(theme: string, colorScheme: string) { - const themeLink = document.getElementById('theme-css'); - const newHref = themeLink.getAttribute('href')!.replace(this.layoutService.config.theme, theme); - this.layoutService.config.colorScheme - this.replaceThemeLink(newHref, () => { - this.layoutService.config.theme = theme; - this.layoutService.config.colorScheme = colorScheme; - this.layoutService.onConfigUpdate(); - }); + this.layoutService.config.update((config) => ({ ...config, theme:theme,colorScheme:colorScheme })); } - replaceThemeLink(href: string, onComplete: Function) { - const id = 'theme-css'; - const themeLink = document.getElementById('theme-css'); - const cloneLinkElement = themeLink.cloneNode(true); - - cloneLinkElement.setAttribute('href', href); - cloneLinkElement.setAttribute('id', id + '-clone'); - - themeLink.parentNode!.insertBefore(cloneLinkElement, themeLink.nextSibling); - - cloneLinkElement.addEventListener('load', () => { - themeLink.remove(); - cloneLinkElement.setAttribute('id', id); - onComplete(); - }); - } decrementScale() { this.scale--; @@ -97,6 +83,9 @@ export class AppConfigComponent { } applyScale() { - document.documentElement.style.fontSize = this.scale + 'px'; + this.layoutService.config.update((config) => ({ + ...config, + scale: this.scale, + })); } } diff --git a/src/app/layout/service/app.layout.service.ts b/src/app/layout/service/app.layout.service.ts index 11c82d8..e9ef2d4 100644 --- a/src/app/layout/service/app.layout.service.ts +++ b/src/app/layout/service/app.layout.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@angular/core'; +import { Injectable, effect, signal } from '@angular/core'; import { Subject } from 'rxjs'; export interface AppConfig { @@ -24,7 +24,7 @@ interface LayoutState { }) export class LayoutService { - config: AppConfig = { + _config: AppConfig = { ripple: false, inputStyle: 'outlined', menuMode: 'static', @@ -33,6 +33,8 @@ export class LayoutService { scale: 14, }; + config = signal(this._config); + state: LayoutState = { staticMenuDesktopInactive: false, overlayMenuActive: false, @@ -82,7 +84,7 @@ export class LayoutService { } isOverlay() { - return this.config.menuMode === 'overlay'; + return this.config().menuMode === 'overlay'; } isDesktop() { @@ -94,7 +96,58 @@ export class LayoutService { } onConfigUpdate() { - this.configUpdate.next(this.config); + this._config = { ...this.config() }; + this.configUpdate.next(this.config()); + } + + constructor() { + effect(() => { + const config = this.config(); + this.changeTheme(); + this.changeScale(config.scale); + this.onConfigUpdate(); + }); + } + + changeTheme() { + const config = this.config(); + const themeLink = ( + document.getElementById('theme-css') + ); + const themeLinkHref = themeLink.getAttribute('href')!; + const newHref = themeLinkHref + .split('/') + .map((el) => + el == this._config.theme + ? (el = config.theme) + : el == `theme-${this._config.colorScheme}` + ? (el = `theme-${config.colorScheme}`) + : el + ) + .join('/'); + + this.replaceThemeLink(newHref); + } + replaceThemeLink(href: string) { + const id = 'theme-css'; + let themeLink = document.getElementById(id); + const cloneLinkElement = themeLink.cloneNode(true); + + cloneLinkElement.setAttribute('href', href); + cloneLinkElement.setAttribute('id', id + '-clone'); + + themeLink.parentNode!.insertBefore( + cloneLinkElement, + themeLink.nextSibling + ); + cloneLinkElement.addEventListener('load', () => { + themeLink.remove(); + cloneLinkElement.setAttribute('id', id); + }); + } + + changeScale(value: number) { + document.documentElement.style.fontSize = `${value}px`; } }