@sd-angular/core 19.0.9 → 19.0.10
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.
- package/README.md +1 -1
- package/assets/scss/core/utilities/_grid.scss +149 -143
- package/components/form-generic/src/components/form-builder/components/attribute-table/attribute-table.component.d.ts +2 -4
- package/components/form-generic/src/components/form-builder/components/attribute-template/attribute-template.component.d.ts +2 -4
- package/components/form-generic/src/components/form-builder/components/configure-validation/configure-validation.component.d.ts +5 -6
- package/components/form-generic/src/components/form-render/form-render.component.d.ts +4 -6
- package/components/form-generic/src/services/form-generic.service.d.ts +1 -3
- package/components/modal/src/modal.component.d.ts +1 -1
- package/components/tab-router/src/models/tab-router.model.d.ts +2 -1
- package/components/tab-router/src/services/tab-router.service.d.ts +0 -1
- package/components/table/src/components/command/desktop-command.component.d.ts +7 -7
- package/components/table/src/components/command/pipes/command.pipe.d.ts +1 -12
- package/components/table/src/components/command/pipes/filter.pipe.d.ts +1 -8
- package/components/table/src/components/filter/column-filter/column-filter.component.d.ts +1 -0
- package/components/table/src/models/table-column.model.d.ts +3 -2
- package/components/table/src/pipes/selection-disabled.pipe.d.ts +1 -1
- package/components/table/src/services/config.service.d.ts +4 -5
- package/fesm2022/sd-angular-core-components-anchor.mjs +14 -14
- package/fesm2022/sd-angular-core-components-anchor.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-autoid-inspector.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-avatar.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-badge.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-button.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-ckeditor-styles.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-code-editor.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-document-builder.mjs +0 -1
- package/fesm2022/sd-angular-core-components-document-builder.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-form-generic.mjs +37 -66
- package/fesm2022/sd-angular-core-components-form-generic.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-import-excel.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-inform.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-mini-editor.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-modal-resizable.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-modal.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-operator.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-org-chart.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-query-builder.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-quick-action.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-section.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-side-drawer.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-splitter.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-stepper.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-tab-router.mjs +31 -26
- package/fesm2022/sd-angular-core-components-tab-router.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-tab.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-table.mjs +47 -58
- package/fesm2022/sd-angular-core-components-table.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-tree.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-upload-file.mjs.map +1 -1
- package/fesm2022/sd-angular-core-directives.mjs +0 -1
- package/fesm2022/sd-angular-core-directives.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-autocomplete.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-chip-calendar.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-chip.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-date-range.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-date.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-datetime.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-input-color.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-input-number.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-input.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-radio.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-select.mjs +45 -12
- package/fesm2022/sd-angular-core-forms-select.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-textarea.mjs.map +1 -1
- package/fesm2022/sd-angular-core-interceptors.mjs +0 -2
- package/fesm2022/sd-angular-core-interceptors.mjs.map +1 -1
- package/fesm2022/sd-angular-core-modules-auth.mjs +14 -38
- package/fesm2022/sd-angular-core-modules-auth.mjs.map +1 -1
- package/fesm2022/sd-angular-core-modules-layout.mjs +5 -12
- package/fesm2022/sd-angular-core-modules-layout.mjs.map +1 -1
- package/fesm2022/sd-angular-core-modules-permission.mjs +5 -12
- package/fesm2022/sd-angular-core-modules-permission.mjs.map +1 -1
- package/fesm2022/sd-angular-core-pipes.mjs +4 -12
- package/fesm2022/sd-angular-core-pipes.mjs.map +1 -1
- package/fesm2022/sd-angular-core-services-confirm.mjs +16 -21
- package/fesm2022/sd-angular-core-services-confirm.mjs.map +1 -1
- package/fesm2022/sd-angular-core-services-docx.mjs +1 -8
- package/fesm2022/sd-angular-core-services-docx.mjs.map +1 -1
- package/fesm2022/sd-angular-core-services-license.mjs +5 -12
- package/fesm2022/sd-angular-core-services-license.mjs.map +1 -1
- package/fesm2022/sd-angular-core-services-notify.mjs +70 -87
- package/fesm2022/sd-angular-core-services-notify.mjs.map +1 -1
- package/fesm2022/sd-angular-core-services-storage.mjs +4 -12
- package/fesm2022/sd-angular-core-services-storage.mjs.map +1 -1
- package/fesm2022/sd-angular-core-utilities-extensions.mjs +43 -1
- package/fesm2022/sd-angular-core-utilities-extensions.mjs.map +1 -1
- package/forms/select/src/select-footer-action.directive.d.ts +5 -1
- package/forms/select/src/select.component.d.ts +4 -0
- package/modules/auth/guards/auth.guard.d.ts +2 -4
- package/modules/auth/guards/portal.guard.d.ts +2 -4
- package/modules/auth/services/auth.service.d.ts +3 -4
- package/modules/layout/modules/home/guards/home-redirect.guard.d.ts +3 -5
- package/modules/permission/src/guards/permission.guard.d.ts +2 -5
- package/package.json +66 -66
- package/pipes/src/format-number.pipe.d.ts +1 -3
- package/sd-angular-core-19.0.10.tgz +0 -0
- package/services/confirm/src/lib/components/dialog-confirm/dialog-confirm.component.d.ts +3 -3
- package/services/license/src/license.service.d.ts +2 -3
- package/services/notify/src/components/toast/toast.component.d.ts +9 -13
- package/services/notify/src/notify.service.d.ts +4 -5
- package/services/storage/src/storage.service.d.ts +3 -4
- package/utilities/extensions/index.d.ts +1 -0
- package/utilities/extensions/src/object.extension.d.ts +8 -0
- package/sd-angular-core-19.0.9.tgz +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sd-angular-core-interceptors.mjs","sources":["../../../projects/sd-angular/interceptors/no-internet/no-internet.interceptor.ts","../../../projects/sd-angular/interceptors/unauthorized/unauthorized.interceptor.ts","../../../projects/sd-angular/interceptors/sd-angular-core-interceptors.ts"],"sourcesContent":["import { HttpClient, HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';\r\nimport { inject, Injectable, Injector } from '@angular/core';\r\nimport { MatSnackBar, MatSnackBarRef } from '@angular/material/snack-bar';\r\nimport { I18nService } from '@sd-angular/core/i18n';\r\nimport { Observable, throwError } from 'rxjs';\r\nimport { catchError, switchMap } from 'rxjs/operators';\r\n\r\n@Injectable()\r\nexport class SdNoInternetInterceptor implements HttpInterceptor {\r\n readonly #i18n = inject(I18nService);\r\n\r\n // Trạng thái offline để tránh spam request check hoặc hiển thị nhiều snackbar\r\n #isOffline = false;\r\n\r\n // Giữ tham chiếu để có thể đóng/thao tác snackbar\r\n #snackBarRef: MatSnackBarRef<any> | null = null;\r\n\r\n // Giữ tham chiếu interval để clear khi có mạng lại\r\n #pollInterval: ReturnType<typeof setInterval> | null = null;\r\n\r\n // Lazy load HttpClient\r\n #http: HttpClient | null = null;\r\n\r\n // Endpoint kiểm tra mạng (Nên dùng 1 file tĩnh nhẹ hoặc API ping public uy tín)\r\n readonly #healthCheckUrl = 'https://jsonplaceholder.typicode.com/todos/1';\r\n\r\n // Thời gian lặp lại việc kiểm tra mạng (ms)\r\n readonly #checkIntervalDuration = 3000;\r\n\r\n constructor(\r\n private snackBar: MatSnackBar,\r\n private injector: Injector\r\n ) {}\r\n\r\n intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {\r\n return next.handle(request).pipe(\r\n catchError((error: HttpErrorResponse) => {\r\n // --- TRƯỜNG HỢP 1: Lỗi mất kết nối (Status 0) ---\r\n if (error.status === 0 && !this.#isOffline) {\r\n this.#isOffline = true;\r\n\r\n // Lazy load HttpClient để tránh lỗi Circular Dependency\r\n if (!this.#http) {\r\n this.#http = this.injector.get(HttpClient);\r\n }\r\n\r\n // Gọi thử một API public để xác minh xem là Mất mạng thật hay do CORS/Server chặn\r\n return this.#http.get(this.#healthCheckUrl).pipe(\r\n // 1. Ưu tiên bắt lỗi kết nối trước (Đây là logic MẤT MẠNG THẬT)\r\n catchError(_checkError => {\r\n // Hiển thị thông báo và bắt đầu polling chờ mạng\r\n this.#showReloadSnackbar(this.#i18n.t('core.interceptor.no-internet.offline'), { isSticky: true });\r\n this.#startPolling();\r\n\r\n // Ném lại lỗi gốc để Component biết request thất bại\r\n return throwError(() => error);\r\n }),\r\n\r\n // 2. Nếu không vào catchError ở trên -> Check thành công -> CÓ MẠNG\r\n // Lỗi status 0 ban đầu là do CORS, SSL, hoặc Server chặn connection\r\n switchMap(() => {\r\n this.#isOffline = false; // Reset cờ\r\n\r\n this.snackBar.open(this.#i18n.t('core.interceptor.no-internet.cors-error'), this.#i18n.t('core.common.close'), {\r\n duration: 5000,\r\n horizontalPosition: 'center',\r\n verticalPosition: 'top',\r\n });\r\n\r\n // Ném lại lỗi gốc\r\n return throwError(() => error);\r\n })\r\n );\r\n }\r\n\r\n // --- TRƯỜNG HỢP 2: Server bảo trì (503) ---\r\n else if (error.status === 503) {\r\n this.snackBar.open(this.#i18n.t('core.interceptor.no-internet.maintenance'), this.#i18n.t('core.common.close'), {\r\n horizontalPosition: 'center',\r\n verticalPosition: 'top',\r\n duration: 5000,\r\n });\r\n }\r\n\r\n // --- TRƯỜNG HỢP KHÁC: 401, 404, 500... ---\r\n // Ném lỗi ra để component xử lý bình thường\r\n return throwError(() => error);\r\n })\r\n );\r\n }\r\n\r\n /**\r\n * Hiển thị Snackbar thông báo trạng thái mạng\r\n */\r\n #showReloadSnackbar = (message: string, options?: { duration?: number; isSticky?: boolean }): void => {\r\n // Đóng snackbar cũ nếu đang hiện\r\n if (this.#snackBarRef) {\r\n this.#snackBarRef.dismiss();\r\n }\r\n\r\n this.#snackBarRef = this.snackBar.open(message, this.#i18n.t('core.common.reload'), {\r\n horizontalPosition: 'center',\r\n verticalPosition: 'top',\r\n // Nếu isSticky = true (mất mạng) -> Không tự tắt. Nếu có duration -> tự tắt.\r\n duration: options?.duration,\r\n panelClass: options?.isSticky ? ['offline-snackbar'] : undefined, // Class CSS tùy chọn\r\n });\r\n\r\n // Xử lý sự kiện bấm nút \"Tải lại trang\"\r\n this.#snackBarRef.onAction().subscribe(() => {\r\n window.location.reload();\r\n });\r\n };\r\n\r\n /**\r\n * Bắt đầu vòng lặp kiểm tra kết nối mạng\r\n */\r\n #startPolling = (): void => {\r\n this.#stopPolling(); // Clear cũ nếu có\r\n\r\n // @i18n-ignore — dev console log\r\n console.log('--- Bắt đầu chế độ theo dõi mạng ---');\r\n\r\n this.#pollInterval = setInterval(() => {\r\n if (!this.#http) {\r\n this.#http = this.injector.get(HttpClient);\r\n }\r\n\r\n // Check nhẹ\r\n this.#http.get(this.#healthCheckUrl).subscribe({\r\n next: () => {\r\n // --> ĐÃ CÓ MẠNG LẠI\r\n // @i18n-ignore — dev console log\r\n console.log('--> Kết nối đã được khôi phục!');\r\n\r\n this.#stopPolling();\r\n this.#isOffline = false;\r\n\r\n // Thông báo thành công (tự tắt sau 5s)\r\n this.#showReloadSnackbar(this.#i18n.t('core.interceptor.no-internet.restored'), { duration: 5000, isSticky: false });\r\n },\r\n error: () => {\r\n // --> VẪN MẤT MẠNG: Không làm gì cả, chờ lần check tiếp theo\r\n },\r\n });\r\n }, this.#checkIntervalDuration);\r\n };\r\n\r\n /**\r\n * Dừng vòng lặp kiểm tra\r\n */\r\n #stopPolling = (): void => {\r\n if (this.#pollInterval) {\r\n clearInterval(this.#pollInterval);\r\n this.#pollInterval = null;\r\n }\r\n };\r\n}\r\n","import { HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';\r\nimport { Injectable } from '@angular/core';\r\nimport { SdAuthService } from '@sd-angular/core/modules';\r\nimport { Observable, throwError } from 'rxjs';\r\nimport { catchError } from 'rxjs/operators';\r\n\r\n@Injectable()\r\nexport class SdUnauthorizedInterceptor implements HttpInterceptor {\r\n #unauthorizedHandled = false;\r\n\r\n constructor(private authService: SdAuthService) {}\r\n\r\n intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {\r\n return next.handle(request).pipe(\r\n catchError((error: HttpErrorResponse) => {\r\n if (error.status === 401 && !this.#unauthorizedHandled) {\r\n this.#unauthorizedHandled = true;\r\n this.authService.signout();\r\n }\r\n\r\n return throwError(() => error);\r\n })\r\n );\r\n }\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sd-angular-core-interceptors.mjs","sources":["../../../projects/sd-angular/interceptors/no-internet/no-internet.interceptor.ts","../../../projects/sd-angular/interceptors/unauthorized/unauthorized.interceptor.ts","../../../projects/sd-angular/interceptors/sd-angular-core-interceptors.ts"],"sourcesContent":["import { HttpClient, HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';\r\nimport { inject, Injectable, Injector } from '@angular/core';\r\nimport { MatSnackBar, MatSnackBarRef } from '@angular/material/snack-bar';\r\nimport { I18nService } from '@sd-angular/core/i18n';\r\nimport { Observable, throwError } from 'rxjs';\r\nimport { catchError, switchMap } from 'rxjs/operators';\r\n\r\n@Injectable()\r\nexport class SdNoInternetInterceptor implements HttpInterceptor {\r\n readonly #i18n = inject(I18nService);\r\n\r\n // Trạng thái offline để tránh spam request check hoặc hiển thị nhiều snackbar\r\n #isOffline = false;\r\n\r\n // Giữ tham chiếu để có thể đóng/thao tác snackbar\r\n #snackBarRef: MatSnackBarRef<any> | null = null;\r\n\r\n // Giữ tham chiếu interval để clear khi có mạng lại\r\n #pollInterval: ReturnType<typeof setInterval> | null = null;\r\n\r\n // Lazy load HttpClient\r\n #http: HttpClient | null = null;\r\n\r\n // Endpoint kiểm tra mạng (Nên dùng 1 file tĩnh nhẹ hoặc API ping public uy tín)\r\n readonly #healthCheckUrl = 'https://jsonplaceholder.typicode.com/todos/1';\r\n\r\n // Thời gian lặp lại việc kiểm tra mạng (ms)\r\n readonly #checkIntervalDuration = 3000;\r\n\r\n constructor(\r\n private snackBar: MatSnackBar,\r\n private injector: Injector\r\n ) {}\r\n\r\n intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {\r\n return next.handle(request).pipe(\r\n catchError((error: HttpErrorResponse) => {\r\n // --- TRƯỜNG HỢP 1: Lỗi mất kết nối (Status 0) ---\r\n if (error.status === 0 && !this.#isOffline) {\r\n this.#isOffline = true;\r\n\r\n // Lazy load HttpClient để tránh lỗi Circular Dependency\r\n if (!this.#http) {\r\n this.#http = this.injector.get(HttpClient);\r\n }\r\n\r\n // Gọi thử một API public để xác minh xem là Mất mạng thật hay do CORS/Server chặn\r\n return this.#http.get(this.#healthCheckUrl).pipe(\r\n // 1. Ưu tiên bắt lỗi kết nối trước (Đây là logic MẤT MẠNG THẬT)\r\n catchError(_checkError => {\r\n // Hiển thị thông báo và bắt đầu polling chờ mạng\r\n this.#showReloadSnackbar(this.#i18n.t('core.interceptor.no-internet.offline'), { isSticky: true });\r\n this.#startPolling();\r\n\r\n // Ném lại lỗi gốc để Component biết request thất bại\r\n return throwError(() => error);\r\n }),\r\n\r\n // 2. Nếu không vào catchError ở trên -> Check thành công -> CÓ MẠNG\r\n // Lỗi status 0 ban đầu là do CORS, SSL, hoặc Server chặn connection\r\n switchMap(() => {\r\n this.#isOffline = false; // Reset cờ\r\n\r\n this.snackBar.open(this.#i18n.t('core.interceptor.no-internet.cors-error'), this.#i18n.t('core.common.close'), {\r\n duration: 5000,\r\n horizontalPosition: 'center',\r\n verticalPosition: 'top',\r\n });\r\n\r\n // Ném lại lỗi gốc\r\n return throwError(() => error);\r\n })\r\n );\r\n }\r\n\r\n // --- TRƯỜNG HỢP 2: Server bảo trì (503) ---\r\n else if (error.status === 503) {\r\n this.snackBar.open(this.#i18n.t('core.interceptor.no-internet.maintenance'), this.#i18n.t('core.common.close'), {\r\n horizontalPosition: 'center',\r\n verticalPosition: 'top',\r\n duration: 5000,\r\n });\r\n }\r\n\r\n // --- TRƯỜNG HỢP KHÁC: 401, 404, 500... ---\r\n // Ném lỗi ra để component xử lý bình thường\r\n return throwError(() => error);\r\n })\r\n );\r\n }\r\n\r\n /**\r\n * Hiển thị Snackbar thông báo trạng thái mạng\r\n */\r\n #showReloadSnackbar = (message: string, options?: { duration?: number; isSticky?: boolean }): void => {\r\n // Đóng snackbar cũ nếu đang hiện\r\n if (this.#snackBarRef) {\r\n this.#snackBarRef.dismiss();\r\n }\r\n\r\n this.#snackBarRef = this.snackBar.open(message, this.#i18n.t('core.common.reload'), {\r\n horizontalPosition: 'center',\r\n verticalPosition: 'top',\r\n // Nếu isSticky = true (mất mạng) -> Không tự tắt. Nếu có duration -> tự tắt.\r\n duration: options?.duration,\r\n panelClass: options?.isSticky ? ['offline-snackbar'] : undefined, // Class CSS tùy chọn\r\n });\r\n\r\n // Xử lý sự kiện bấm nút \"Tải lại trang\"\r\n this.#snackBarRef.onAction().subscribe(() => {\r\n window.location.reload();\r\n });\r\n };\r\n\r\n /**\r\n * Bắt đầu vòng lặp kiểm tra kết nối mạng\r\n */\r\n #startPolling = (): void => {\r\n this.#stopPolling(); // Clear cũ nếu có\r\n\r\n // @i18n-ignore — dev console log\r\n\r\n this.#pollInterval = setInterval(() => {\r\n if (!this.#http) {\r\n this.#http = this.injector.get(HttpClient);\r\n }\r\n\r\n // Check nhẹ\r\n this.#http.get(this.#healthCheckUrl).subscribe({\r\n next: () => {\r\n // --> ĐÃ CÓ MẠNG LẠI\r\n // @i18n-ignore — dev console log\r\n\r\n this.#stopPolling();\r\n this.#isOffline = false;\r\n\r\n // Thông báo thành công (tự tắt sau 5s)\r\n this.#showReloadSnackbar(this.#i18n.t('core.interceptor.no-internet.restored'), { duration: 5000, isSticky: false });\r\n },\r\n error: () => {\r\n // --> VẪN MẤT MẠNG: Không làm gì cả, chờ lần check tiếp theo\r\n },\r\n });\r\n }, this.#checkIntervalDuration);\r\n };\r\n\r\n /**\r\n * Dừng vòng lặp kiểm tra\r\n */\r\n #stopPolling = (): void => {\r\n if (this.#pollInterval) {\r\n clearInterval(this.#pollInterval);\r\n this.#pollInterval = null;\r\n }\r\n };\r\n}\r\n","import { HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';\r\nimport { Injectable } from '@angular/core';\r\nimport { SdAuthService } from '@sd-angular/core/modules';\r\nimport { Observable, throwError } from 'rxjs';\r\nimport { catchError } from 'rxjs/operators';\r\n\r\n@Injectable()\r\nexport class SdUnauthorizedInterceptor implements HttpInterceptor {\r\n #unauthorizedHandled = false;\r\n\r\n constructor(private authService: SdAuthService) {}\r\n\r\n intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {\r\n return next.handle(request).pipe(\r\n catchError((error: HttpErrorResponse) => {\r\n if (error.status === 401 && !this.#unauthorizedHandled) {\r\n this.#unauthorizedHandled = true;\r\n this.authService.signout();\r\n }\r\n\r\n return throwError(() => error);\r\n })\r\n );\r\n }\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1"],"mappings":"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"}
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken,
|
|
2
|
+
import { InjectionToken, inject, signal, Injectable } from '@angular/core';
|
|
3
3
|
import { Subject } from 'rxjs';
|
|
4
4
|
import { normalizeAsync, resolveMaybeAsync } from '@sdcorejs/utils/models';
|
|
5
5
|
import { toSignal } from '@angular/core/rxjs-interop';
|
|
6
|
-
import
|
|
6
|
+
import { Router } from '@angular/router';
|
|
7
7
|
|
|
8
8
|
const SD_AUTH_CONFIGURATION = new InjectionToken('sd.auth.configuration');
|
|
9
9
|
|
|
10
10
|
class SdAuthService {
|
|
11
|
-
authConfiguration;
|
|
12
11
|
// Đăng nhập
|
|
13
12
|
// #signin = new Subject<void>();
|
|
14
13
|
// signin$?: Observable<void>;
|
|
@@ -19,8 +18,8 @@ class SdAuthService {
|
|
|
19
18
|
// Thay đổi mật khẩu
|
|
20
19
|
#changePassword = new Subject();
|
|
21
20
|
changePassword$;
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
authConfiguration = inject(SD_AUTH_CONFIGURATION, { optional: true });
|
|
22
|
+
constructor() {
|
|
24
23
|
// this.#handleSignin();
|
|
25
24
|
this.#handleSignout();
|
|
26
25
|
this.#handleChangePassword();
|
|
@@ -62,26 +61,17 @@ class SdAuthService {
|
|
|
62
61
|
});
|
|
63
62
|
}
|
|
64
63
|
};
|
|
65
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdAuthService, deps: [
|
|
64
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdAuthService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
66
65
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdAuthService, providedIn: 'root' });
|
|
67
66
|
}
|
|
68
67
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdAuthService, decorators: [{
|
|
69
68
|
type: Injectable,
|
|
70
69
|
args: [{ providedIn: 'root' }]
|
|
71
|
-
}], ctorParameters: () => [
|
|
72
|
-
type: Optional
|
|
73
|
-
}, {
|
|
74
|
-
type: Inject,
|
|
75
|
-
args: [SD_AUTH_CONFIGURATION]
|
|
76
|
-
}] }] });
|
|
70
|
+
}], ctorParameters: () => [] });
|
|
77
71
|
|
|
78
72
|
class SdAuthGuard {
|
|
79
|
-
authConfiguration;
|
|
80
|
-
router;
|
|
81
|
-
constructor(authConfiguration, router) {
|
|
82
|
-
this.authConfiguration = authConfiguration;
|
|
83
|
-
this.router = router;
|
|
84
|
-
}
|
|
73
|
+
authConfiguration = inject(SD_AUTH_CONFIGURATION, { optional: true });
|
|
74
|
+
router = inject(Router);
|
|
85
75
|
canActivate = (route, state) => {
|
|
86
76
|
if (this.authConfiguration?.guard?.auth) {
|
|
87
77
|
return this.authConfiguration.guard.auth(route, state);
|
|
@@ -89,26 +79,17 @@ class SdAuthGuard {
|
|
|
89
79
|
// Nếu chưa tích hợp Auth Guard thì pass canActive
|
|
90
80
|
return true;
|
|
91
81
|
};
|
|
92
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdAuthGuard, deps: [
|
|
82
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdAuthGuard, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
93
83
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdAuthGuard, providedIn: 'root' });
|
|
94
84
|
}
|
|
95
85
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdAuthGuard, decorators: [{
|
|
96
86
|
type: Injectable,
|
|
97
87
|
args: [{ providedIn: 'root' }]
|
|
98
|
-
}]
|
|
99
|
-
type: Optional
|
|
100
|
-
}, {
|
|
101
|
-
type: Inject,
|
|
102
|
-
args: [SD_AUTH_CONFIGURATION]
|
|
103
|
-
}] }, { type: i1.Router }] });
|
|
88
|
+
}] });
|
|
104
89
|
|
|
105
90
|
class SdPortalGuard {
|
|
106
|
-
authConfiguration;
|
|
107
|
-
router;
|
|
108
|
-
constructor(authConfiguration, router) {
|
|
109
|
-
this.authConfiguration = authConfiguration;
|
|
110
|
-
this.router = router;
|
|
111
|
-
}
|
|
91
|
+
authConfiguration = inject(SD_AUTH_CONFIGURATION, { optional: true });
|
|
92
|
+
router = inject(Router);
|
|
112
93
|
canActivate = (route, state) => {
|
|
113
94
|
if (this.authConfiguration?.guard?.portal) {
|
|
114
95
|
return this.authConfiguration.guard.portal(route, state);
|
|
@@ -116,18 +97,13 @@ class SdPortalGuard {
|
|
|
116
97
|
// Nếu chưa tích hợp Portal Guard thì pass canActive
|
|
117
98
|
return true;
|
|
118
99
|
};
|
|
119
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdPortalGuard, deps: [
|
|
100
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdPortalGuard, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
120
101
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdPortalGuard, providedIn: 'root' });
|
|
121
102
|
}
|
|
122
103
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdPortalGuard, decorators: [{
|
|
123
104
|
type: Injectable,
|
|
124
105
|
args: [{ providedIn: 'root' }]
|
|
125
|
-
}]
|
|
126
|
-
type: Optional
|
|
127
|
-
}, {
|
|
128
|
-
type: Inject,
|
|
129
|
-
args: [SD_AUTH_CONFIGURATION]
|
|
130
|
-
}] }, { type: i1.Router }] });
|
|
106
|
+
}] });
|
|
131
107
|
|
|
132
108
|
/**
|
|
133
109
|
* Generated bundle index. Do not edit.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sd-angular-core-modules-auth.mjs","sources":["../../../projects/sd-angular/modules/auth/configurations/auth.configuration.ts","../../../projects/sd-angular/modules/auth/services/auth.service.ts","../../../projects/sd-angular/modules/auth/guards/auth.guard.ts","../../../projects/sd-angular/modules/auth/guards/portal.guard.ts","../../../projects/sd-angular/modules/auth/sd-angular-core-modules-auth.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\r\nimport { CanActivate } from '@angular/router';\r\nimport { MaybeAsync } from '@sdcorejs/utils/models';\r\nimport { SdAuthInfo } from '../services';\r\n\r\nexport interface ISdAuthConfiguration {\r\n action?: IAuthConfigurationAction;\r\n guard?: IAuthConfigurationGuard;\r\n}\r\n\r\nexport const SD_AUTH_CONFIGURATION = new InjectionToken<ISdAuthConfiguration>('sd.auth.configuration');\r\n\r\ninterface IAuthConfigurationAction {\r\n signout: () => MaybeAsync<void>;\r\n changePassword?: () => MaybeAsync<void>;\r\n}\r\n\r\ninterface IAuthConfigurationGuard {\r\n auth?: CanActivate['canActivate'];\r\n portal?: CanActivate['canActivate'];\r\n authInfo: () => MaybeAsync<SdAuthInfo>;\r\n}\r\n","import {
|
|
1
|
+
{"version":3,"file":"sd-angular-core-modules-auth.mjs","sources":["../../../projects/sd-angular/modules/auth/configurations/auth.configuration.ts","../../../projects/sd-angular/modules/auth/services/auth.service.ts","../../../projects/sd-angular/modules/auth/guards/auth.guard.ts","../../../projects/sd-angular/modules/auth/guards/portal.guard.ts","../../../projects/sd-angular/modules/auth/sd-angular-core-modules-auth.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\r\nimport { CanActivate } from '@angular/router';\r\nimport { MaybeAsync } from '@sdcorejs/utils/models';\r\nimport { SdAuthInfo } from '../services';\r\n\r\nexport interface ISdAuthConfiguration {\r\n action?: IAuthConfigurationAction;\r\n guard?: IAuthConfigurationGuard;\r\n}\r\n\r\nexport const SD_AUTH_CONFIGURATION = new InjectionToken<ISdAuthConfiguration>('sd.auth.configuration');\r\n\r\ninterface IAuthConfigurationAction {\r\n signout: () => MaybeAsync<void>;\r\n changePassword?: () => MaybeAsync<void>;\r\n}\r\n\r\ninterface IAuthConfigurationGuard {\r\n auth?: CanActivate['canActivate'];\r\n portal?: CanActivate['canActivate'];\r\n authInfo: () => MaybeAsync<SdAuthInfo>;\r\n}\r\n","import { inject, Injectable, signal, Signal } from '@angular/core';\r\nimport { from, Observable, Subject } from 'rxjs';\r\nimport { ISdAuthConfiguration, SD_AUTH_CONFIGURATION } from '../configurations';\r\nimport { normalizeAsync, resolveMaybeAsync } from '@sdcorejs/utils/models';\r\nimport { SdAuthInfo } from './auth.model';\r\nimport { toSignal } from '@angular/core/rxjs-interop';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class SdAuthService {\r\n // Đăng nhập\r\n // #signin = new Subject<void>();\r\n // signin$?: Observable<void>;\r\n getAuthInfo?: Signal<SdAuthInfo | undefined>;\r\n\r\n // Đăng xuất\r\n #signout = new Subject<void>();\r\n signout$?: Observable<void>;\r\n\r\n // Thay đổi mật khẩu\r\n #changePassword = new Subject<void>();\r\n changePassword$?: Observable<void>;\r\n private readonly authConfiguration: ISdAuthConfiguration | null = inject(SD_AUTH_CONFIGURATION, { optional: true });\r\n\r\n constructor() {\r\n // this.#handleSignin();\r\n this.#handleSignout();\r\n this.#handleChangePassword();\r\n const defaultUser = {\r\n id: 'guest-id',\r\n username: 'guest',\r\n firstName: 'Guest',\r\n email: 'guest@gmail.com',\r\n };\r\n if (this.authConfiguration?.guard?.authInfo) {\r\n this.getAuthInfo = toSignal(normalizeAsync(this.authConfiguration.guard?.authInfo()), {\r\n initialValue: defaultUser,\r\n });\r\n } else {\r\n this.getAuthInfo = signal(defaultUser);\r\n }\r\n }\r\n\r\n // #handleSignin = () => {\r\n // this.signin$ = this.#signin.asObservable();\r\n // };\r\n\r\n #handleSignout = () => {\r\n this.signout$ = this.#signout.asObservable();\r\n };\r\n\r\n #handleChangePassword = () => {\r\n this.changePassword$ = this.#changePassword.asObservable();\r\n };\r\n signout = () => {\r\n if (this.authConfiguration?.action?.signout) {\r\n resolveMaybeAsync(this.authConfiguration.action.signout()).then(() => {\r\n this.#signout.next();\r\n });\r\n }\r\n };\r\n\r\n changePassword = () => {\r\n if (this.authConfiguration?.action?.changePassword) {\r\n resolveMaybeAsync(this.authConfiguration.action.changePassword()).then(() => {\r\n this.#changePassword.next();\r\n });\r\n }\r\n };\r\n}\r\n","import { inject, Injectable } from '@angular/core';\r\nimport { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router';\r\nimport { ISdAuthConfiguration, SD_AUTH_CONFIGURATION } from '../configurations';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class SdAuthGuard implements CanActivate {\r\n private readonly authConfiguration: ISdAuthConfiguration | null = inject(SD_AUTH_CONFIGURATION, { optional: true });\r\n protected readonly router = inject(Router);\r\n\r\n canActivate = (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => {\r\n if (this.authConfiguration?.guard?.auth) {\r\n return this.authConfiguration.guard.auth(route, state);\r\n }\r\n // Nếu chưa tích hợp Auth Guard thì pass canActive\r\n return true;\r\n };\r\n}\r\n","import { inject, Injectable } from '@angular/core';\r\nimport { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router';\r\nimport { ISdAuthConfiguration, SD_AUTH_CONFIGURATION } from '../configurations';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class SdPortalGuard implements CanActivate {\r\n private readonly authConfiguration: ISdAuthConfiguration | null = inject(SD_AUTH_CONFIGURATION, { optional: true });\r\n protected readonly router = inject(Router);\r\n\r\n canActivate = (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => {\r\n if (this.authConfiguration?.guard?.portal) {\r\n return this.authConfiguration.guard.portal(route, state);\r\n }\r\n // Nếu chưa tích hợp Portal Guard thì pass canActive\r\n return true;\r\n };\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, ElementRef, input, booleanAttribute, effect, Component, Injectable, InjectionToken, signal, Pipe, output, DestroyRef, computed, untracked, viewChild,
|
|
2
|
+
import { inject, ElementRef, input, booleanAttribute, effect, Component, Injectable, InjectionToken, signal, Pipe, output, DestroyRef, computed, untracked, viewChild, NgModule } from '@angular/core';
|
|
3
3
|
import * as i1$4 from '@angular/common';
|
|
4
4
|
import { CommonModule, NgTemplateOutlet } from '@angular/common';
|
|
5
5
|
import * as i1$6 from '@angular/router';
|
|
@@ -1399,12 +1399,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
|
|
|
1399
1399
|
}] });
|
|
1400
1400
|
|
|
1401
1401
|
class HomeRedirectGuard {
|
|
1402
|
-
router;
|
|
1403
|
-
layoutConfiguration;
|
|
1404
|
-
constructor(router, layoutConfiguration) {
|
|
1405
|
-
this.router = router;
|
|
1406
|
-
this.layoutConfiguration = layoutConfiguration;
|
|
1407
|
-
}
|
|
1402
|
+
router = inject(Router);
|
|
1403
|
+
layoutConfiguration = inject(SD_LAYOUT_CONFIGURATION);
|
|
1408
1404
|
async canActivate() {
|
|
1409
1405
|
const homeUrl = this.layoutConfiguration?.homeUrl;
|
|
1410
1406
|
if (homeUrl) {
|
|
@@ -1415,7 +1411,7 @@ class HomeRedirectGuard {
|
|
|
1415
1411
|
// Nếu không có homeUrl, cho phép kích hoạt route
|
|
1416
1412
|
return true;
|
|
1417
1413
|
}
|
|
1418
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: HomeRedirectGuard, deps: [
|
|
1414
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: HomeRedirectGuard, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1419
1415
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: HomeRedirectGuard, providedIn: 'root' });
|
|
1420
1416
|
}
|
|
1421
1417
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: HomeRedirectGuard, decorators: [{
|
|
@@ -1423,10 +1419,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
|
|
|
1423
1419
|
args: [{
|
|
1424
1420
|
providedIn: 'root',
|
|
1425
1421
|
}]
|
|
1426
|
-
}]
|
|
1427
|
-
type: Inject,
|
|
1428
|
-
args: [SD_LAYOUT_CONFIGURATION]
|
|
1429
|
-
}] }] });
|
|
1422
|
+
}] });
|
|
1430
1423
|
|
|
1431
1424
|
const routes = [
|
|
1432
1425
|
{
|