@koalarx/ui 21.2.1 → 21.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,11 +4,11 @@ import { randomString } from '@koalarx/utils/KlString';
4
4
 
5
5
  class SideWindowContent {
6
6
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: SideWindowContent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: SideWindowContent, isStandalone: true, selector: "kl-side-window-content", ngImport: i0, template: "<div class=\"fixed flex z-10000 bg-base-100/20 h-screen w-screen justify-end p-2\">\n <div class=\"side-window-content w-auto h-full bg-base-200 rounded-xl shadow-2xl border-4 border-neutral-200 dark:border-neutral-900 animate-slide-in-left\">\n <ng-content />\n </div>\n</div>\n", changeDetection: i0.ChangeDetectionStrategy.OnPush });
7
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: SideWindowContent, isStandalone: true, selector: "kl-side-window-content", ngImport: i0, template: "<div class=\"backdrop fixed flex z-10000 bg-base-100/20 h-screen w-screen justify-end p-2\">\n <div class=\"side-window-content w-auto h-full bg-base-200 rounded-xl shadow-2xl border-4 border-neutral-200 dark:border-neutral-900 animate-slide-in-left\">\n <ng-content />\n </div>\n</div>\n", changeDetection: i0.ChangeDetectionStrategy.OnPush });
8
8
  }
9
9
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: SideWindowContent, decorators: [{
10
10
  type: Component,
11
- args: [{ selector: 'kl-side-window-content', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"fixed flex z-10000 bg-base-100/20 h-screen w-screen justify-end p-2\">\n <div class=\"side-window-content w-auto h-full bg-base-200 rounded-xl shadow-2xl border-4 border-neutral-200 dark:border-neutral-900 animate-slide-in-left\">\n <ng-content />\n </div>\n</div>\n" }]
11
+ args: [{ selector: 'kl-side-window-content', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"backdrop fixed flex z-10000 bg-base-100/20 h-screen w-screen justify-end p-2\">\n <div class=\"side-window-content w-auto h-full bg-base-200 rounded-xl shadow-2xl border-4 border-neutral-200 dark:border-neutral-900 animate-slide-in-left\">\n <ng-content />\n </div>\n</div>\n" }]
12
12
  }] });
13
13
 
14
14
  const SIDE_WINDOW_CONFIG = new InjectionToken('SideWindowConfig');
@@ -95,8 +95,8 @@ class SideWindowRef {
95
95
  }
96
96
  };
97
97
  onClick = (event) => {
98
- const contentElement = this.componentRef().location.nativeElement.querySelector('.side-window-content');
99
- if (contentElement && !contentElement.contains(event.target)) {
98
+ if (event.target instanceof HTMLElement &&
99
+ event.target.classList.contains('backdrop')) {
100
100
  this.dismiss();
101
101
  }
102
102
  };
@@ -1 +1 @@
1
- {"version":3,"file":"koalarx-ui-shared-components-side-window.mjs","sources":["../../projects/koala-ui/shared/components/side-window/side-window-content.ts","../../projects/koala-ui/shared/components/side-window/side-window-content.html","../../projects/koala-ui/shared/components/side-window/side-window.ts","../../projects/koala-ui/shared/components/side-window/side-window-ref.ts","../../projects/koala-ui/shared/components/side-window/koalarx-ui-shared-components-side-window.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component } from '@angular/core';\n\n@Component({\n selector: 'kl-side-window-content',\n templateUrl: './side-window-content.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class SideWindowContent {}\n","<div class=\"fixed flex z-10000 bg-base-100/20 h-screen w-screen justify-end p-2\">\n <div class=\"side-window-content w-auto h-full bg-base-200 rounded-xl shadow-2xl border-4 border-neutral-200 dark:border-neutral-900 animate-slide-in-left\">\n <ng-content />\n </div>\n</div>\n","import {\n ApplicationRef,\n createComponent,\n EnvironmentInjector,\n inject,\n Injectable,\n InjectionToken,\n Injector,\n Type,\n} from '@angular/core';\nimport { randomString } from '@koalarx/utils/KlString';\nimport { SIDE_WINDOW_REF_TOKEN, SideWindowRef } from './side-window-ref';\n\nexport type SideWindowAfterCloseTrigger = string | Record<string, any>;\nexport type SideWindowAfterCloseTriggerFn = (\n trigger: SideWindowAfterCloseTrigger\n) => void;\nexport const SIDE_WINDOW_CONFIG = new InjectionToken('SideWindowConfig');\nexport const SIDE_WINDOW_DATA = new InjectionToken('SideWindowData');\nexport const SIDE_WINDOW_APP_REF = new InjectionToken('SideWindowAppRef');\nexport const SIDE_WINDOW_AFTER_CLOSE_TRIGGER =\n new InjectionToken<SideWindowAfterCloseTriggerFn>(\n 'SideWindowAfterCloseTrigger'\n );\n\nexport interface SideWindowConfig {\n data?: any;\n afterClosed?: {\n trigger: SideWindowAfterCloseTrigger;\n callback: (trigger: any) => void;\n };\n}\n\n@Injectable({ providedIn: 'root' })\nexport class SideWindow {\n private readonly appRef = inject(ApplicationRef);\n private readonly injector = inject(EnvironmentInjector);\n\n private generateElementId() {\n let elementId: string;\n\n do {\n elementId = randomString(50, {\n numbers: false,\n lowercase: true,\n uppercase: true,\n specialCharacters: false,\n });\n } while (document.getElementById(elementId));\n\n return elementId;\n }\n\n open(component: Type<any>, config?: SideWindowConfig) {\n const main = document.querySelector<HTMLElement>(\n 'kl-side-window-container .side-window-container'\n );\n\n if (main) {\n const elementId = this.generateElementId();\n const container = main.appendChild(document.createElement('div'));\n\n container.id = elementId;\n\n const componentRef = createComponent(component, {\n environmentInjector: this.injector,\n hostElement: container,\n elementInjector: Injector.create({\n providers: [\n { provide: SIDE_WINDOW_CONFIG, useValue: config },\n { provide: SIDE_WINDOW_APP_REF, useValue: this.appRef },\n {\n provide: SIDE_WINDOW_REF_TOKEN,\n useValue: () => componentRef,\n },\n { provide: SIDE_WINDOW_DATA, useValue: config?.data },\n {\n provide: SIDE_WINDOW_AFTER_CLOSE_TRIGGER,\n useValue: (trigger: SideWindowAfterCloseTrigger) => {\n if (\n config?.afterClosed &&\n (config.afterClosed.trigger === trigger ||\n typeof trigger === 'object')\n ) {\n config.afterClosed.callback(trigger);\n }\n },\n },\n {\n provide: SideWindowRef,\n deps: [\n SIDE_WINDOW_CONFIG,\n SIDE_WINDOW_APP_REF,\n SIDE_WINDOW_REF_TOKEN,\n SIDE_WINDOW_AFTER_CLOSE_TRIGGER,\n SIDE_WINDOW_DATA,\n ],\n },\n ],\n }),\n });\n\n this.appRef.attachView(componentRef.hostView);\n\n componentRef.changeDetectorRef.detectChanges();\n\n document.body.style.overflowY = 'hidden';\n }\n }\n}\n","import {\n ApplicationRef,\n ComponentRef,\n inject,\n Injectable,\n InjectionToken,\n OnDestroy,\n Type,\n} from '@angular/core';\nimport {\n SIDE_WINDOW_AFTER_CLOSE_TRIGGER,\n SIDE_WINDOW_APP_REF,\n SideWindowAfterCloseTrigger,\n SideWindowAfterCloseTriggerFn,\n} from './side-window';\n\nexport const SIDE_WINDOW_REF_TOKEN = new InjectionToken('SideWindowRefToken');\n\n@Injectable()\nexport class SideWindowRef implements OnDestroy {\n private readonly appRef = inject<ApplicationRef>(SIDE_WINDOW_APP_REF);\n private readonly componentRef = inject<() => ComponentRef<Type<any>>>(\n SIDE_WINDOW_REF_TOKEN,\n );\n private readonly afterCloseTrigger = inject<SideWindowAfterCloseTriggerFn>(\n SIDE_WINDOW_AFTER_CLOSE_TRIGGER,\n );\n private readonly onKeyUp = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n this.dismiss();\n }\n };\n private readonly onClick = (event: MouseEvent) => {\n const contentElement =\n this.componentRef().location.nativeElement.querySelector(\n '.side-window-content',\n );\n if (contentElement && !contentElement.contains(event.target as Node)) {\n this.dismiss();\n }\n };\n\n constructor() {\n setTimeout(() => {\n document.addEventListener('keyup', this.onKeyUp);\n document.addEventListener('click', this.onClick);\n }, 150);\n }\n\n ngOnDestroy() {\n document.removeEventListener('keyup', this.onKeyUp);\n document.removeEventListener('click', this.onClick);\n }\n\n dismiss(afterCloseTrigger?: SideWindowAfterCloseTrigger) {\n const componentRef = this.componentRef();\n componentRef.location.nativeElement\n .querySelector('div div')\n .classList.add('animate-slide-out-right');\n\n document.body.style.overflowY = 'auto';\n\n setTimeout(() => {\n componentRef.destroy();\n this.appRef.detachView(componentRef.hostView);\n\n if (afterCloseTrigger) {\n this.afterCloseTrigger(afterCloseTrigger);\n }\n }, 50);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"koalarx-ui-shared-components-side-window.mjs","sources":["../../projects/koala-ui/shared/components/side-window/side-window-content.ts","../../projects/koala-ui/shared/components/side-window/side-window-content.html","../../projects/koala-ui/shared/components/side-window/side-window.ts","../../projects/koala-ui/shared/components/side-window/side-window-ref.ts","../../projects/koala-ui/shared/components/side-window/koalarx-ui-shared-components-side-window.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component } from '@angular/core';\n\n@Component({\n selector: 'kl-side-window-content',\n templateUrl: './side-window-content.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class SideWindowContent {}\n","<div class=\"backdrop fixed flex z-10000 bg-base-100/20 h-screen w-screen justify-end p-2\">\n <div class=\"side-window-content w-auto h-full bg-base-200 rounded-xl shadow-2xl border-4 border-neutral-200 dark:border-neutral-900 animate-slide-in-left\">\n <ng-content />\n </div>\n</div>\n","import {\n ApplicationRef,\n createComponent,\n EnvironmentInjector,\n inject,\n Injectable,\n InjectionToken,\n Injector,\n Type,\n} from '@angular/core';\nimport { randomString } from '@koalarx/utils/KlString';\nimport { SIDE_WINDOW_REF_TOKEN, SideWindowRef } from './side-window-ref';\n\nexport type SideWindowAfterCloseTrigger = string | Record<string, any>;\nexport type SideWindowAfterCloseTriggerFn = (\n trigger: SideWindowAfterCloseTrigger\n) => void;\nexport const SIDE_WINDOW_CONFIG = new InjectionToken('SideWindowConfig');\nexport const SIDE_WINDOW_DATA = new InjectionToken('SideWindowData');\nexport const SIDE_WINDOW_APP_REF = new InjectionToken('SideWindowAppRef');\nexport const SIDE_WINDOW_AFTER_CLOSE_TRIGGER =\n new InjectionToken<SideWindowAfterCloseTriggerFn>(\n 'SideWindowAfterCloseTrigger'\n );\n\nexport interface SideWindowConfig {\n data?: any;\n afterClosed?: {\n trigger: SideWindowAfterCloseTrigger;\n callback: (trigger: any) => void;\n };\n}\n\n@Injectable({ providedIn: 'root' })\nexport class SideWindow {\n private readonly appRef = inject(ApplicationRef);\n private readonly injector = inject(EnvironmentInjector);\n\n private generateElementId() {\n let elementId: string;\n\n do {\n elementId = randomString(50, {\n numbers: false,\n lowercase: true,\n uppercase: true,\n specialCharacters: false,\n });\n } while (document.getElementById(elementId));\n\n return elementId;\n }\n\n open(component: Type<any>, config?: SideWindowConfig) {\n const main = document.querySelector<HTMLElement>(\n 'kl-side-window-container .side-window-container'\n );\n\n if (main) {\n const elementId = this.generateElementId();\n const container = main.appendChild(document.createElement('div'));\n\n container.id = elementId;\n\n const componentRef = createComponent(component, {\n environmentInjector: this.injector,\n hostElement: container,\n elementInjector: Injector.create({\n providers: [\n { provide: SIDE_WINDOW_CONFIG, useValue: config },\n { provide: SIDE_WINDOW_APP_REF, useValue: this.appRef },\n {\n provide: SIDE_WINDOW_REF_TOKEN,\n useValue: () => componentRef,\n },\n { provide: SIDE_WINDOW_DATA, useValue: config?.data },\n {\n provide: SIDE_WINDOW_AFTER_CLOSE_TRIGGER,\n useValue: (trigger: SideWindowAfterCloseTrigger) => {\n if (\n config?.afterClosed &&\n (config.afterClosed.trigger === trigger ||\n typeof trigger === 'object')\n ) {\n config.afterClosed.callback(trigger);\n }\n },\n },\n {\n provide: SideWindowRef,\n deps: [\n SIDE_WINDOW_CONFIG,\n SIDE_WINDOW_APP_REF,\n SIDE_WINDOW_REF_TOKEN,\n SIDE_WINDOW_AFTER_CLOSE_TRIGGER,\n SIDE_WINDOW_DATA,\n ],\n },\n ],\n }),\n });\n\n this.appRef.attachView(componentRef.hostView);\n\n componentRef.changeDetectorRef.detectChanges();\n\n document.body.style.overflowY = 'hidden';\n }\n }\n}\n","import {\n ApplicationRef,\n ComponentRef,\n inject,\n Injectable,\n InjectionToken,\n OnDestroy,\n Type,\n} from '@angular/core';\nimport {\n SIDE_WINDOW_AFTER_CLOSE_TRIGGER,\n SIDE_WINDOW_APP_REF,\n SideWindowAfterCloseTrigger,\n SideWindowAfterCloseTriggerFn,\n} from './side-window';\n\nexport const SIDE_WINDOW_REF_TOKEN = new InjectionToken('SideWindowRefToken');\n\n@Injectable()\nexport class SideWindowRef implements OnDestroy {\n private readonly appRef = inject<ApplicationRef>(SIDE_WINDOW_APP_REF);\n private readonly componentRef = inject<() => ComponentRef<Type<any>>>(\n SIDE_WINDOW_REF_TOKEN,\n );\n private readonly afterCloseTrigger = inject<SideWindowAfterCloseTriggerFn>(\n SIDE_WINDOW_AFTER_CLOSE_TRIGGER,\n );\n private readonly onKeyUp = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n this.dismiss();\n }\n };\n private readonly onClick = (event: MouseEvent) => {\n if (\n event.target instanceof HTMLElement &&\n event.target.classList.contains('backdrop')\n ) {\n this.dismiss();\n }\n };\n\n constructor() {\n setTimeout(() => {\n document.addEventListener('keyup', this.onKeyUp);\n document.addEventListener('click', this.onClick);\n }, 150);\n }\n\n ngOnDestroy() {\n document.removeEventListener('keyup', this.onKeyUp);\n document.removeEventListener('click', this.onClick);\n }\n\n dismiss(afterCloseTrigger?: SideWindowAfterCloseTrigger) {\n const componentRef = this.componentRef();\n componentRef.location.nativeElement\n .querySelector('div div')\n .classList.add('animate-slide-out-right');\n\n document.body.style.overflowY = 'auto';\n\n setTimeout(() => {\n componentRef.destroy();\n this.appRef.detachView(componentRef.hostView);\n\n if (afterCloseTrigger) {\n this.afterCloseTrigger(afterCloseTrigger);\n }\n }, 50);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -94,11 +94,15 @@ class Authorization {
94
94
  });
95
95
  effect(() => {
96
96
  const hasToken = this.hasToken();
97
+ const publicRoutes = this.authConfig.publicRoutes ?? [];
98
+ if (this.authConfig.loginRoute) {
99
+ publicRoutes.push(this.authConfig.loginRoute);
100
+ }
97
101
  if (hasToken) {
98
102
  this.loadUserInfo();
99
103
  }
100
104
  else if (this.authConfig.loginRoute &&
101
- !location.hash.includes(this.authConfig.loginRoute)) {
105
+ !publicRoutes.some((route) => location.hash.includes(route))) {
102
106
  this.router.navigate([this.authConfig.loginRoute]);
103
107
  }
104
108
  });
@@ -1 +1 @@
1
- {"version":3,"file":"koalarx-ui-shared-services.mjs","sources":["../../projects/koala-ui/shared/services/authorization.ts","../../projects/koala-ui/shared/services/koalarx-ui-shared-services.ts"],"sourcesContent":["import { HttpClient } from '@angular/common/http';\nimport { computed, effect, inject, Injectable, signal } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { AppConfig } from '@koalarx/ui/core/config';\nimport { AuthConfig } from '@koalarx/ui/core/models';\nimport { Confirm } from '@koalarx/ui/shared/components/confirm';\nimport { jwtDecode } from 'jwt-decode';\nimport { first } from 'rxjs/internal/operators/first';\nimport { tap } from 'rxjs/internal/operators/tap';\n\n@Injectable({ providedIn: 'root' })\nexport class Authorization<TUser = any> {\n private readonly appConfig = inject(AppConfig);\n private readonly translation =\n this.appConfig.translation.jwtAuthorizationService;\n private readonly authConfig = this.appConfig.authConfig as AuthConfig;\n private _accessToken = signal<string | null>(null);\n private _refreshToken = signal<string | null>(null);\n private _isAuthenticated = signal<boolean>(false);\n private _userinfo = signal<TUser | null>(null);\n private readonly router = inject(Router);\n private readonly http = inject(HttpClient);\n private readonly confirm = inject(Confirm);\n\n get accessToken() {\n const accessToken = this._accessToken();\n return accessToken;\n }\n\n set accessToken(accessToken: string | null) {\n if (accessToken) {\n localStorage.setItem(this.authConfig.storageTokenKey, accessToken);\n } else {\n localStorage.removeItem(this.authConfig.storageTokenKey);\n }\n\n this._accessToken.set(accessToken);\n }\n\n get refreshToken() {\n const refreshToken = this._refreshToken();\n return refreshToken;\n }\n\n set refreshToken(refreshToken: string | null) {\n if (refreshToken) {\n localStorage.setItem(\n this.authConfig.storageRefreshTokenKey,\n refreshToken\n );\n } else {\n localStorage.removeItem(this.authConfig.storageRefreshTokenKey);\n }\n\n this._refreshToken.set(refreshToken);\n }\n\n get isAuthenticated() {\n return this._isAuthenticated.asReadonly();\n }\n\n get userinfo() {\n return this._userinfo.asReadonly();\n }\n\n get isExpired() {\n return computed(() => {\n const accessToken = this._accessToken();\n\n if (accessToken) {\n const decodedToken = jwtDecode(accessToken);\n\n if (decodedToken) {\n const exp = new Date((decodedToken.exp ?? 0) * 1000);\n const now = new Date();\n\n return exp < now;\n }\n }\n\n return true;\n });\n }\n\n get hasToken() {\n return computed(() => !!this._accessToken());\n }\n\n constructor() {\n if (this.appConfig.authConfig) {\n this.init();\n }\n }\n\n private init() {\n this._accessToken.set(\n localStorage.getItem(this.authConfig.storageTokenKey)\n );\n this._refreshToken.set(\n localStorage.getItem(this.authConfig?.storageRefreshTokenKey)\n );\n\n effect(() => {\n const userInfo = this._userinfo();\n\n if (userInfo) {\n this.updateAuthState();\n }\n });\n\n effect(() => {\n const isAuthenticated = this.isAuthenticated();\n\n if (\n isAuthenticated &&\n (!this.authConfig.loginRoute ||\n (this.authConfig.loginRoute &&\n location.hash.includes(this.authConfig.loginRoute))) &&\n this.authConfig.homeRoute\n ) {\n this.router.navigate([this.authConfig.homeRoute]);\n }\n });\n\n effect(() => {\n const hasToken = this.hasToken();\n\n if (hasToken) {\n this.loadUserInfo();\n } else if (\n this.authConfig.loginRoute &&\n !location.hash.includes(this.authConfig.loginRoute)\n ) {\n this.router.navigate([this.authConfig.loginRoute]);\n }\n });\n }\n\n private updateAuthState() {\n this._isAuthenticated.set(\n this.hasToken() && !this.isExpired() && !!this._userinfo()\n );\n }\n\n private logoutUser() {\n localStorage.removeItem(this.authConfig.storageTokenKey);\n localStorage.removeItem(this.authConfig.storageRefreshTokenKey);\n this._userinfo.set(null);\n this._refreshToken.set(null);\n this._accessToken.set(null);\n this.updateAuthState();\n }\n\n private loadUserInfo() {\n this.http.get<TUser>(this.authConfig.userInfo.url).subscribe({\n next: (userInfo) => this._userinfo.set(userInfo),\n error: () => this.logoutUser(),\n });\n }\n\n logout(force = false) {\n if (force) {\n this.logoutUser();\n return;\n }\n\n this.confirm.open({\n message: this.translation.questionLogoutMessage,\n yesCallback: () => this.logoutUser(),\n });\n }\n\n updateToken() {\n return this.http.post<any>(this.authConfig.refreshToken.url, {}).pipe(\n tap({\n next: (response) => {\n this.accessToken =\n response[this.authConfig.refreshToken.response.accessTokenKeyName];\n this.refreshToken =\n response[this.authConfig.refreshToken.response.refreshTokenKeyName];\n this.updateAuthState();\n },\n error: () => {\n this.logout(true);\n this.router.navigate([this.authConfig.loginRoute]);\n },\n }),\n first()\n );\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"koalarx-ui-shared-services.mjs","sources":["../../projects/koala-ui/shared/services/authorization.ts","../../projects/koala-ui/shared/services/koalarx-ui-shared-services.ts"],"sourcesContent":["import { HttpClient } from '@angular/common/http';\nimport { computed, effect, inject, Injectable, signal } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { AppConfig } from '@koalarx/ui/core/config';\nimport { AuthConfig } from '@koalarx/ui/core/models';\nimport { Confirm } from '@koalarx/ui/shared/components/confirm';\nimport { jwtDecode } from 'jwt-decode';\nimport { first } from 'rxjs/internal/operators/first';\nimport { tap } from 'rxjs/internal/operators/tap';\n\n@Injectable({ providedIn: 'root' })\nexport class Authorization<TUser = any> {\n private readonly appConfig = inject(AppConfig);\n private readonly translation =\n this.appConfig.translation.jwtAuthorizationService;\n private readonly authConfig = this.appConfig.authConfig as AuthConfig;\n private _accessToken = signal<string | null>(null);\n private _refreshToken = signal<string | null>(null);\n private _isAuthenticated = signal<boolean>(false);\n private _userinfo = signal<TUser | null>(null);\n private readonly router = inject(Router);\n private readonly http = inject(HttpClient);\n private readonly confirm = inject(Confirm);\n\n get accessToken() {\n const accessToken = this._accessToken();\n return accessToken;\n }\n\n set accessToken(accessToken: string | null) {\n if (accessToken) {\n localStorage.setItem(this.authConfig.storageTokenKey, accessToken);\n } else {\n localStorage.removeItem(this.authConfig.storageTokenKey);\n }\n\n this._accessToken.set(accessToken);\n }\n\n get refreshToken() {\n const refreshToken = this._refreshToken();\n return refreshToken;\n }\n\n set refreshToken(refreshToken: string | null) {\n if (refreshToken) {\n localStorage.setItem(\n this.authConfig.storageRefreshTokenKey,\n refreshToken,\n );\n } else {\n localStorage.removeItem(this.authConfig.storageRefreshTokenKey);\n }\n\n this._refreshToken.set(refreshToken);\n }\n\n get isAuthenticated() {\n return this._isAuthenticated.asReadonly();\n }\n\n get userinfo() {\n return this._userinfo.asReadonly();\n }\n\n get isExpired() {\n return computed(() => {\n const accessToken = this._accessToken();\n\n if (accessToken) {\n const decodedToken = jwtDecode(accessToken);\n\n if (decodedToken) {\n const exp = new Date((decodedToken.exp ?? 0) * 1000);\n const now = new Date();\n\n return exp < now;\n }\n }\n\n return true;\n });\n }\n\n get hasToken() {\n return computed(() => !!this._accessToken());\n }\n\n constructor() {\n if (this.appConfig.authConfig) {\n this.init();\n }\n }\n\n private init() {\n this._accessToken.set(\n localStorage.getItem(this.authConfig.storageTokenKey),\n );\n this._refreshToken.set(\n localStorage.getItem(this.authConfig?.storageRefreshTokenKey),\n );\n\n effect(() => {\n const userInfo = this._userinfo();\n\n if (userInfo) {\n this.updateAuthState();\n }\n });\n\n effect(() => {\n const isAuthenticated = this.isAuthenticated();\n\n if (\n isAuthenticated &&\n (!this.authConfig.loginRoute ||\n (this.authConfig.loginRoute &&\n location.hash.includes(this.authConfig.loginRoute))) &&\n this.authConfig.homeRoute\n ) {\n this.router.navigate([this.authConfig.homeRoute]);\n }\n });\n\n effect(() => {\n const hasToken = this.hasToken();\n const publicRoutes = this.authConfig.publicRoutes ?? [];\n\n if (this.authConfig.loginRoute) {\n publicRoutes.push(this.authConfig.loginRoute);\n }\n\n if (hasToken) {\n this.loadUserInfo();\n } else if (\n this.authConfig.loginRoute &&\n !publicRoutes.some((route) => location.hash.includes(route))\n ) {\n this.router.navigate([this.authConfig.loginRoute]);\n }\n });\n }\n\n private updateAuthState() {\n this._isAuthenticated.set(\n this.hasToken() && !this.isExpired() && !!this._userinfo(),\n );\n }\n\n private logoutUser() {\n localStorage.removeItem(this.authConfig.storageTokenKey);\n localStorage.removeItem(this.authConfig.storageRefreshTokenKey);\n this._userinfo.set(null);\n this._refreshToken.set(null);\n this._accessToken.set(null);\n this.updateAuthState();\n }\n\n private loadUserInfo() {\n this.http.get<TUser>(this.authConfig.userInfo.url).subscribe({\n next: (userInfo) => this._userinfo.set(userInfo),\n error: () => this.logoutUser(),\n });\n }\n\n logout(force = false) {\n if (force) {\n this.logoutUser();\n return;\n }\n\n this.confirm.open({\n message: this.translation.questionLogoutMessage,\n yesCallback: () => this.logoutUser(),\n });\n }\n\n updateToken() {\n return this.http.post<any>(this.authConfig.refreshToken.url, {}).pipe(\n tap({\n next: (response) => {\n this.accessToken =\n response[this.authConfig.refreshToken.response.accessTokenKeyName];\n this.refreshToken =\n response[this.authConfig.refreshToken.response.refreshTokenKeyName];\n this.updateAuthState();\n },\n error: () => {\n this.logout(true);\n this.router.navigate([this.authConfig.loginRoute]);\n },\n }),\n first(),\n );\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@koalarx/ui",
3
- "version": "21.2.1",
3
+ "version": "21.2.3",
4
4
  "peerDependencies": {
5
5
  "@angular/common": ">=21.0.0",
6
6
  "@angular/core": ">=21.0.0"
@@ -18,6 +18,7 @@ interface AuthConfig {
18
18
  storageRefreshTokenKey: string;
19
19
  homeRoute?: string;
20
20
  loginRoute?: string;
21
+ publicRoutes?: string[];
21
22
  userInfo: {
22
23
  url: string;
23
24
  };