@sd-angular/core 19.0.11 → 19.0.12

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.
Files changed (87) hide show
  1. package/README.md +20 -20
  2. package/assets/STYLE-GUIDE.md +19 -19
  3. package/assets/fonts/fonts.scss +115 -115
  4. package/assets/scss/core/scrollbar.scss +30 -30
  5. package/assets/scss/core/utilities/_grid.scss +149 -149
  6. package/components/form-generic/src/components/form-builder/components/expression-builder/expression-builder.component.d.ts +1 -1
  7. package/components/form-generic/src/components/form-builder/components/table/control/table-control.component.d.ts +1 -1
  8. package/components/form-generic/src/components/sd-feel-expression/sd-feel-expression.component.d.ts +1 -1
  9. package/components/table/src/components/filter/column-filter/column-filter.component.d.ts +1 -1
  10. package/fesm2022/sd-angular-core-components-anchor.mjs.map +1 -1
  11. package/fesm2022/sd-angular-core-components-autoid-inspector.mjs.map +1 -1
  12. package/fesm2022/sd-angular-core-components-avatar.mjs +2 -2
  13. package/fesm2022/sd-angular-core-components-avatar.mjs.map +1 -1
  14. package/fesm2022/sd-angular-core-components-button.mjs.map +1 -1
  15. package/fesm2022/sd-angular-core-components-chart.mjs +40 -40
  16. package/fesm2022/sd-angular-core-components-chart.mjs.map +1 -1
  17. package/fesm2022/sd-angular-core-components-editor.mjs +2 -2
  18. package/fesm2022/sd-angular-core-components-editor.mjs.map +1 -1
  19. package/fesm2022/sd-angular-core-components-form-generic.mjs +2 -2
  20. package/fesm2022/sd-angular-core-components-form-generic.mjs.map +1 -1
  21. package/fesm2022/sd-angular-core-components-inform.mjs +2 -2
  22. package/fesm2022/sd-angular-core-components-inform.mjs.map +1 -1
  23. package/fesm2022/sd-angular-core-components-modal.mjs +2 -2
  24. package/fesm2022/sd-angular-core-components-modal.mjs.map +1 -1
  25. package/fesm2022/sd-angular-core-components-org-chart.mjs +2 -2
  26. package/fesm2022/sd-angular-core-components-org-chart.mjs.map +1 -1
  27. package/fesm2022/sd-angular-core-components-preview.mjs +4 -4
  28. package/fesm2022/sd-angular-core-components-preview.mjs.map +1 -1
  29. package/fesm2022/sd-angular-core-components-query-bar.mjs +10 -10
  30. package/fesm2022/sd-angular-core-components-query-bar.mjs.map +1 -1
  31. package/fesm2022/sd-angular-core-components-query-builder.mjs +2 -2
  32. package/fesm2022/sd-angular-core-components-query-builder.mjs.map +1 -1
  33. package/fesm2022/sd-angular-core-components-quick-action.mjs +2 -2
  34. package/fesm2022/sd-angular-core-components-quick-action.mjs.map +1 -1
  35. package/fesm2022/sd-angular-core-components-section.mjs +2 -2
  36. package/fesm2022/sd-angular-core-components-section.mjs.map +1 -1
  37. package/fesm2022/sd-angular-core-components-side-drawer.mjs +2 -2
  38. package/fesm2022/sd-angular-core-components-side-drawer.mjs.map +1 -1
  39. package/fesm2022/sd-angular-core-components-splitter.mjs +6 -6
  40. package/fesm2022/sd-angular-core-components-splitter.mjs.map +1 -1
  41. package/fesm2022/sd-angular-core-components-stepper.mjs +2 -2
  42. package/fesm2022/sd-angular-core-components-stepper.mjs.map +1 -1
  43. package/fesm2022/sd-angular-core-components-tab-router.mjs +60 -30
  44. package/fesm2022/sd-angular-core-components-tab-router.mjs.map +1 -1
  45. package/fesm2022/sd-angular-core-components-tab.mjs +2 -2
  46. package/fesm2022/sd-angular-core-components-tab.mjs.map +1 -1
  47. package/fesm2022/sd-angular-core-components-table.mjs +31 -31
  48. package/fesm2022/sd-angular-core-components-table.mjs.map +1 -1
  49. package/fesm2022/sd-angular-core-components-tree.mjs +2 -2
  50. package/fesm2022/sd-angular-core-components-tree.mjs.map +1 -1
  51. package/fesm2022/sd-angular-core-components-view.mjs.map +1 -1
  52. package/fesm2022/sd-angular-core-forms-chip-calendar.mjs.map +1 -1
  53. package/fesm2022/sd-angular-core-forms-chip.mjs.map +1 -1
  54. package/fesm2022/sd-angular-core-forms-date-range.mjs +2 -2
  55. package/fesm2022/sd-angular-core-forms-date-range.mjs.map +1 -1
  56. package/fesm2022/sd-angular-core-forms-datetime.mjs +4 -4
  57. package/fesm2022/sd-angular-core-forms-datetime.mjs.map +1 -1
  58. package/fesm2022/sd-angular-core-forms-inline-text.mjs.map +1 -1
  59. package/fesm2022/sd-angular-core-forms-input-number.mjs +2 -2
  60. package/fesm2022/sd-angular-core-forms-input-number.mjs.map +1 -1
  61. package/fesm2022/sd-angular-core-forms-label.mjs +2 -2
  62. package/fesm2022/sd-angular-core-forms-label.mjs.map +1 -1
  63. package/fesm2022/sd-angular-core-forms-models.mjs.map +1 -1
  64. package/fesm2022/sd-angular-core-forms-select.mjs +2 -2
  65. package/fesm2022/sd-angular-core-forms-select.mjs.map +1 -1
  66. package/fesm2022/sd-angular-core-i18n.mjs.map +1 -1
  67. package/fesm2022/sd-angular-core-modules-authom.mjs.map +1 -1
  68. package/fesm2022/sd-angular-core-modules-keycloak.mjs.map +1 -1
  69. package/fesm2022/sd-angular-core-modules-layout.mjs +2 -2
  70. package/fesm2022/sd-angular-core-modules-layout.mjs.map +1 -1
  71. package/fesm2022/sd-angular-core-pipes.mjs.map +1 -1
  72. package/fesm2022/sd-angular-core-services-api.mjs.map +1 -1
  73. package/fesm2022/sd-angular-core-services-confirm.mjs.map +1 -1
  74. package/fesm2022/sd-angular-core-services-excel.mjs.map +1 -1
  75. package/fesm2022/sd-angular-core-services-loading.mjs +23 -14
  76. package/fesm2022/sd-angular-core-services-loading.mjs.map +1 -1
  77. package/fesm2022/sd-angular-core-services-notify.mjs +2 -2
  78. package/fesm2022/sd-angular-core-services-notify.mjs.map +1 -1
  79. package/fesm2022/sd-angular-core-utilities-extensions.mjs.map +1 -1
  80. package/fesm2022/sd-angular-core-utilities-models.mjs.map +1 -1
  81. package/fesm2022/sd-angular-core.mjs.map +1 -1
  82. package/modules/keycloak/htmls/auth-keycloak-error.html +54 -54
  83. package/modules/keycloak/htmls/silent-renew.html +7 -7
  84. package/package.json +67 -67
  85. package/sd-angular-core-19.0.12.tgz +0 -0
  86. package/services/loading/src/loading.service.d.ts +1 -1
  87. package/sd-angular-core-19.0.11.tgz +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"sd-angular-core-pipes.mjs","sources":["../../../projects/sd-angular/pipes/src/format-number.pipe.ts","../../../projects/sd-angular/pipes/src/safe-html.pipe.ts","../../../projects/sd-angular/pipes/src/time-different.pipe.ts","../../../projects/sd-angular/pipes/src/empty.pipe.ts","../../../projects/sd-angular/pipes/sd-angular-core-pipes.ts"],"sourcesContent":["import { inject, Injectable, Pipe, PipeTransform } from '@angular/core';\r\nimport { ISdCoreConfiguration, SD_CORE_CONFIGURATION } from '@sd-angular/core/configurations';\r\nimport { NumberUtilities } from '@sd-angular/core/utilities/extensions';\r\n@Pipe({\r\n name: 'sdFormatNumber',\r\n standalone: true,\r\n})\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class SdFormatNumberPipe implements PipeTransform {\r\n private readonly coreConfiguration: ISdCoreConfiguration | null = inject(SD_CORE_CONFIGURATION, { optional: true });\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n transform(value: any, digits?: number, format?: '1,234,567.89' | '1.234.567,89') {\r\n const resolvedFormat = format ?? this.coreConfiguration?.format?.number;\r\n const fixedValue = NumberUtilities.isNumber(value) ? (+value).toFixed(digits ?? 2) : null;\r\n if (resolvedFormat === '1.234.567,89') {\r\n return NumberUtilities.toVN(fixedValue);\r\n }\r\n return NumberUtilities.toISO(fixedValue);\r\n }\r\n}\r\n","import { Injectable, Pipe, PipeTransform } from '@angular/core';\r\nimport { DomSanitizer } from '@angular/platform-browser';\r\n\r\n@Pipe({\r\n name: 'sdSafeHtml',\r\n standalone: true,\r\n})\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class SdSafeHtmlPipe implements PipeTransform {\r\n constructor(private sanitizer: DomSanitizer) {}\r\n transform(html: string | number | undefined | null) {\r\n if (typeof html === 'number') {\r\n return html;\r\n }\r\n if (!html) {\r\n return undefined;\r\n }\r\n return this.sanitizer.bypassSecurityTrustHtml(html);\r\n }\r\n}\r\n","/* eslint-disable @typescript-eslint/no-explicit-any */\r\nimport { Pipe, PipeTransform } from '@angular/core';\r\nimport { DateUtilities } from '@sd-angular/core/utilities/extensions';\r\nimport { interval, Observable, of } from 'rxjs';\r\nimport { map } from 'rxjs/operators';\r\n@Pipe({\r\n name: 'sdTimeDifferent',\r\n standalone: true,\r\n})\r\nexport class SdTimeDifferentPipe implements PipeTransform {\r\n private maxSecond = 60;\r\n private maxMinute = this.maxSecond * 60;\r\n private maxHour = this.maxMinute * 24;\r\n private maxDay = this.maxHour * 30;\r\n private maxMonth = this.maxHour * 365;\r\n transform(value: any, format: string, different: 'second' | 'minute' | 'hour' | 'day' | 'month'): Observable<string> {\r\n if (!DateUtilities.isDate(value)) {\r\n return of('');\r\n }\r\n if (!different) {\r\n return of(DateUtilities.toFormat(value, format));\r\n }\r\n if (Math.round((new Date().getTime() - new Date(value).getTime()) / 1000) < 0) {\r\n return of(DateUtilities.toFormat(value, format));\r\n }\r\n return interval(1000).pipe(\r\n map(() => {\r\n const timeDifferent = Math.round((new Date().getTime() - new Date(value).getTime()) / 1000);\r\n if (different === 'month' && timeDifferent < this.maxMonth) {\r\n return DateUtilities.timeDifference(value);\r\n }\r\n if (different === 'day' && timeDifferent < this.maxDay) {\r\n return DateUtilities.timeDifference(value);\r\n }\r\n if (different === 'hour' && timeDifferent < this.maxHour) {\r\n return DateUtilities.timeDifference(value);\r\n }\r\n if (different === 'minute' && timeDifferent < this.maxMinute) {\r\n return DateUtilities.timeDifference(value);\r\n }\r\n if (different === 'second' && timeDifferent < this.maxSecond) {\r\n return DateUtilities.timeDifference(value);\r\n }\r\n return DateUtilities.toFormat(value, format);\r\n })\r\n );\r\n }\r\n}\r\n","/* eslint-disable @typescript-eslint/no-explicit-any */\r\nimport { Pipe, PipeTransform } from '@angular/core';\r\nimport { EMPTY_STR } from '@sdcorejs/utils/constants';\r\n@Pipe({\r\n name: 'sdEmpty',\r\n standalone: true,\r\n})\r\nexport class SdEmptyPipe implements PipeTransform {\r\n transform(value: any): string {\r\n if (value === undefined || value === null || value === '') {\r\n return EMPTY_STR;\r\n }\r\n return value;\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
+ {"version":3,"file":"sd-angular-core-pipes.mjs","sources":["../../../projects/sd-angular/pipes/src/format-number.pipe.ts","../../../projects/sd-angular/pipes/src/safe-html.pipe.ts","../../../projects/sd-angular/pipes/src/time-different.pipe.ts","../../../projects/sd-angular/pipes/src/empty.pipe.ts","../../../projects/sd-angular/pipes/sd-angular-core-pipes.ts"],"sourcesContent":["import { inject, Injectable, Pipe, PipeTransform } from '@angular/core';\r\nimport { ISdCoreConfiguration, SD_CORE_CONFIGURATION } from '@sd-angular/core/configurations';\r\nimport { NumberUtilities } from '@sd-angular/core/utilities/extensions';\r\n@Pipe({\r\n name: 'sdFormatNumber',\r\n standalone: true,\r\n})\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class SdFormatNumberPipe implements PipeTransform {\n private readonly coreConfiguration: ISdCoreConfiguration | null = inject(SD_CORE_CONFIGURATION, { optional: true });\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n transform(value: any, digits?: number, format?: '1,234,567.89' | '1.234.567,89') {\r\n const resolvedFormat = format ?? this.coreConfiguration?.format?.number;\r\n const fixedValue = NumberUtilities.isNumber(value) ? (+value).toFixed(digits ?? 2) : null;\r\n if (resolvedFormat === '1.234.567,89') {\r\n return NumberUtilities.toVN(fixedValue);\r\n }\r\n return NumberUtilities.toISO(fixedValue);\r\n }\r\n}\r\n","import { Injectable, Pipe, PipeTransform } from '@angular/core';\r\nimport { DomSanitizer } from '@angular/platform-browser';\r\n\r\n@Pipe({\r\n name: 'sdSafeHtml',\r\n standalone: true,\r\n})\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class SdSafeHtmlPipe implements PipeTransform {\r\n constructor(private sanitizer: DomSanitizer) {}\r\n transform(html: string | number | undefined | null) {\r\n if (typeof html === 'number') {\r\n return html;\r\n }\r\n if (!html) {\r\n return undefined;\r\n }\r\n return this.sanitizer.bypassSecurityTrustHtml(html);\r\n }\r\n}\r\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Pipe, PipeTransform } from '@angular/core';\nimport { DateUtilities } from '@sd-angular/core/utilities/extensions';\nimport { interval, Observable, of } from 'rxjs';\nimport { map } from 'rxjs/operators';\n@Pipe({\n name: 'sdTimeDifferent',\n standalone: true,\n})\nexport class SdTimeDifferentPipe implements PipeTransform {\n private maxSecond = 60;\n private maxMinute = this.maxSecond * 60;\n private maxHour = this.maxMinute * 24;\n private maxDay = this.maxHour * 30;\n private maxMonth = this.maxHour * 365;\n transform(value: any, format: string, different: 'second' | 'minute' | 'hour' | 'day' | 'month'): Observable<string> {\n if (!DateUtilities.isDate(value)) {\n return of('');\n }\n if (!different) {\n return of(DateUtilities.toFormat(value, format));\n }\n if (Math.round((new Date().getTime() - new Date(value).getTime()) / 1000) < 0) {\n return of(DateUtilities.toFormat(value, format));\n }\n return interval(1000).pipe(\n map(() => {\n const timeDifferent = Math.round((new Date().getTime() - new Date(value).getTime()) / 1000);\n if (different === 'month' && timeDifferent < this.maxMonth) {\n return DateUtilities.timeDifference(value);\n }\n if (different === 'day' && timeDifferent < this.maxDay) {\n return DateUtilities.timeDifference(value);\n }\n if (different === 'hour' && timeDifferent < this.maxHour) {\n return DateUtilities.timeDifference(value);\n }\n if (different === 'minute' && timeDifferent < this.maxMinute) {\n return DateUtilities.timeDifference(value);\n }\n if (different === 'second' && timeDifferent < this.maxSecond) {\n return DateUtilities.timeDifference(value);\n }\n return DateUtilities.toFormat(value, format);\n })\n );\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\r\nimport { Pipe, PipeTransform } from '@angular/core';\r\nimport { EMPTY_STR } from '@sdcorejs/utils/constants';\r\n@Pipe({\r\n name: 'sdEmpty',\r\n standalone: true,\r\n})\r\nexport class SdEmptyPipe implements PipeTransform {\r\n transform(value: any): string {\r\n if (value === undefined || value === null || value === '') {\r\n return EMPTY_STR;\r\n }\r\n return value;\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 +1 @@
1
- {"version":3,"file":"sd-angular-core-services-api.mjs","sources":["../../../projects/sd-angular/services/api/src/api.model.ts","../../../projects/sd-angular/services/api/src/api.service.ts","../../../projects/sd-angular/services/api/src/interceptors/api.interceptor.ts","../../../projects/sd-angular/services/api/src/api.module.ts","../../../projects/sd-angular/services/api/sd-angular-core-services-api.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\r\nimport { HttpClient, HttpErrorResponse, HttpRequest, HttpResponse } from '@angular/common/http';\r\nimport { InjectionToken } from '@angular/core';\r\nimport { SdCacheOption } from '@sd-angular/core/services/cache';\r\n// import hash from 'object-hash';\r\n\r\nexport interface SdApiOption {\r\n cacheOption?: SdCacheOption;\r\n timeout?: number; // Default: 30000 (30s)\r\n autoCache?: boolean; // Default: true\r\n}\r\ntype HttpGetOption = Parameters<HttpClient['get']>[1];\r\nexport type SdGetOption = HttpGetOption & SdApiOption;\r\n\r\ntype HttpPostOption = Parameters<HttpClient['post']>[2];\r\nexport type SdPostOption = HttpPostOption & SdApiOption;\r\n\r\ntype HttpPutOption = Parameters<HttpClient['put']>[2];\r\nexport type SdPutOption = HttpPutOption & SdApiOption;\r\n\r\ntype HttpDeleteOption = Parameters<HttpClient['delete']>[1];\r\nexport type SdDeleteOption = HttpDeleteOption & SdApiOption;\r\n\r\nexport interface SdApiHandler {\r\n /** Danh sách host URL mà handler này sẽ xử lý */\r\n hosts: string[];\r\n /** Can thiệp request: gắn header, token, transform body... */\r\n intercept?: (request: HttpRequest<any>) => HttpRequest<any>;\r\n /** Hook chạy TRƯỚC khi gửi request (dùng để log, tracking...) */\r\n beforeRemote?: (request: HttpRequest<any>) => void | Promise<void>;\r\n /** Hook chạy SAU khi nhận response (xử lý lỗi, notify...) */\r\n afterRemote?: (\r\n response: HttpResponse<any> | HttpErrorResponse | Error\r\n ) => void | Promise<void>;\r\n /** Transform response body thành kiểu dữ liệu mong muốn */\r\n mapResponse?: <Tres = any, Tdata = any>(response: Tres) => Tdata;\r\n /** Timeout tính bằng milliseconds. Mặc định: 30000 (30 giây) */\r\n timeout?: number;\r\n}\r\n\r\nexport interface ISdApiConfiguration {\r\n handlers: SdApiHandler[];\r\n}\r\n\r\nexport const SD_API_CONFIG = new InjectionToken<ISdApiConfiguration>('sd-api.configuration');\r\n\r\nexport const SD_API_CONFIGURATION = new InjectionToken<ISdApiConfiguration>('sd-api.configuration');","/* eslint-disable @typescript-eslint/no-explicit-any */\r\nimport { HttpClient } from '@angular/common/http';\r\nimport { inject, Injectable } from '@angular/core';\r\nimport { SdCacheService } from '@sd-angular/core/services/cache';\r\nimport { BrowserUtilities, Utilities } from '@sdcorejs/utils/fns';\r\nimport { lastValueFrom, Observable } from 'rxjs';\r\nimport { catchError, map, shareReplay, timeout } from 'rxjs/operators';\r\nimport { ISdApiConfiguration, SD_API_CONFIG, SdApiHandler, SdDeleteOption, SdGetOption, SdPostOption, SdPutOption } from './api.model';\r\n\r\n// Gom nhóm các Option lại cho gọn\r\ntype SdHttpOptions = SdGetOption & SdPostOption & SdPutOption & SdDeleteOption;\r\ntype HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class SdApiService {\r\n readonly #defaultTimeout = 60000; // 60s\r\n readonly #dedupCacheDuration = 1000; // 1s (Deduplication cache duration)\r\n #httpClient = inject(HttpClient);\r\n #configurations = inject<ISdApiConfiguration[]>(SD_API_CONFIG, { optional: true }) || [];\r\n #cacheService = inject(SdCacheService);\r\n\r\n // Thay đổi cấu trúc Cache: Lưu Observable thay vì Subject phức tạp\r\n // Key: hash string -> Value: { stream$: Observable, expiry: number }\r\n #inFlightRequests: Map<string, { stream$: Observable<any>; expiry: number }> = new Map();\r\n\r\n constructor() {\r\n // Optional: Cơ chế dọn dẹp cache định kỳ (mỗi 1 phút dọn dẹp các key hết hạn)\r\n setInterval(() => this.#cleanupCache(), 60000);\r\n }\r\n\r\n get http() {\r\n return this.#httpClient;\r\n }\r\n\r\n // --- PUBLIC METHODS ---\r\n\r\n get = <T = any>(url: string, option?: SdGetOption): Promise<T> => {\r\n return this.#executeWithLayeredCache<T>(url, 'GET', undefined, option);\r\n };\r\n\r\n post = <T = any>(url: string, body?: any, option?: SdPostOption): Promise<T> => {\r\n return this.#executeWithLayeredCache<T>(url, 'POST', body, option);\r\n };\r\n\r\n put = <T = any>(url: string, body?: any, option?: SdPutOption): Promise<T> => {\r\n return this.#executeWithLayeredCache<T>(url, 'PUT', body, option);\r\n };\r\n\r\n delete = <T = any>(url: string, option?: SdDeleteOption): Promise<T> => {\r\n return this.#executeWithLayeredCache<T>(url, 'DELETE', undefined, option);\r\n };\r\n\r\n // Upload file logic giữ nguyên nhưng refactor nhẹ\r\n upload = async (url: string, option?: { extensions?: string[]; maxSizeInMb?: number }): Promise<any> => {\r\n const file = await BrowserUtilities.upload(option);\r\n if (!Array.isArray(file) && file) {\r\n return this.uploadFile(url, file);\r\n }\r\n };\r\n\r\n uploadFile = async (url: string, file: File): Promise<any> => {\r\n if (!file) return null;\r\n if (file.name.lastIndexOf('.') === -1) throw new Error('Invalid file extension');\r\n\r\n const formData = new FormData();\r\n formData.append('file', file, file.name);\r\n // Upload thường không cần deduplication cache, set autoCache: false\r\n return await this.post(url, formData, { autoCache: false });\r\n };\r\n\r\n // --- PRIVATE CORE LOGIC ---\r\n\r\n /**\r\n * Hàm trung gian xử lý Layer Cache (SdCacheService) trước khi gọi API thực tế\r\n */\r\n #executeWithLayeredCache = async <T>(url: string, method: HttpMethod, body?: any, option?: SdHttpOptions): Promise<T> => {\r\n // Layer 1: Persistent Cache (SdCacheService)\r\n if (option?.cacheOption) {\r\n const key = this.#generateKey(url, method, body, option);\r\n const { get, set, has } = this.#cacheService.create(key, option.cacheOption);\r\n\r\n if (has()) {\r\n return get();\r\n }\r\n\r\n const result = await this.#request<T>(url, method, body, option);\r\n set(result);\r\n return result;\r\n }\r\n\r\n // Không có cache dài hạn thì gọi trực tiếp logic deduplication\r\n return this.#request<T>(url, method, body, option);\r\n };\r\n\r\n /**\r\n * Core Request: Xử lý Deduplication, Timeout, Mapping Response\r\n */\r\n #request = <T>(url: string, method: HttpMethod, body: any, option?: SdHttpOptions): Promise<T> => {\r\n const key = this.#generateKey(url, method, body, option);\r\n\r\n // Layer 2: Deduplication Cache (In-Flight Request / Short-term cache)\r\n const now = Date.now();\r\n const cachedItem = this.#inFlightRequests.get(key);\r\n\r\n // Nếu đã có request đang chạy hoặc mới chạy xong trong vòng 1s -> Trả về stream đó luôn\r\n if (cachedItem && cachedItem.expiry > now) {\r\n return lastValueFrom(cachedItem.stream$);\r\n }\r\n\r\n // Setup request mới\r\n const handler = this.#getHandler(url);\r\n const apiTimeout = option?.timeout ?? handler?.timeout ?? this.#defaultTimeout;\r\n\r\n // Tạo Observable call API\r\n const request$ = this.#httpClient\r\n .request(method, url, {\r\n body,\r\n headers: option?.headers,\r\n params: option?.params,\r\n observe: 'response', // Lấy full response để check status\r\n responseType: option?.responseType,\r\n })\r\n .pipe(\r\n timeout(apiTimeout),\r\n map(res => {\r\n // Normalize Response Logic\r\n const bodyRes = res.body as any;\r\n // Logic check response cũ của bạn\r\n if (bodyRes && typeof bodyRes === 'object' && 'ok' in bodyRes && !bodyRes.ok) {\r\n throw bodyRes; // Giả sử structure trả về { ok: false, ... } là lỗi\r\n }\r\n\r\n if (handler?.mapResponse) {\r\n return handler.mapResponse(bodyRes);\r\n }\r\n\r\n return bodyRes;\r\n }),\r\n catchError(err => {\r\n // Xóa cache ngay lập tức nếu lỗi để user có thể retry\r\n this.#inFlightRequests.delete(key);\r\n throw err;\r\n }),\r\n // QUAN TRỌNG: shareReplay(1) giúp share kết quả cho các subscriber đến sau (trong 1s)\r\n shareReplay(1)\r\n );\r\n\r\n // Lưu vào Map\r\n this.#inFlightRequests.set(key, {\r\n stream$: request$,\r\n expiry: now + this.#dedupCacheDuration,\r\n });\r\n\r\n // Chuyển đổi sang Promise cho đúng return type của bạn\r\n return lastValueFrom(request$);\r\n };\r\n\r\n // --- HELPERS ---\r\n\r\n #getHandler = (url: string): SdApiHandler | undefined => {\r\n const handlers = this.#configurations.flatMap(b => b?.handlers || []);\r\n return handlers.find(e => e.hosts.some(host => url.startsWith(host)));\r\n };\r\n\r\n #generateKey = (url: string, method: HttpMethod, body: any, option?: SdHttpOptions): string => {\r\n // FormData không hash được nội dung file, luôn generate key mới\r\n if (body instanceof FormData || option?.autoCache === false) {\r\n return Utilities.generateUuid();\r\n }\r\n return Utilities.hash({\r\n url,\r\n method,\r\n params: option?.params,\r\n headers: option?.headers,\r\n body,\r\n });\r\n };\r\n\r\n // Dọn dẹp memory leak\r\n #cleanupCache() {\r\n const now = Date.now();\r\n this.#inFlightRequests.forEach((value, key) => {\r\n if (value.expiry < now) {\r\n this.#inFlightRequests.delete(key);\r\n }\r\n });\r\n }\r\n}\r\n","/* eslint-disable @typescript-eslint/no-explicit-any */\r\nimport { HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '@angular/common/http';\r\nimport { inject, Injectable } from '@angular/core';\r\nimport { from, Observable, throwError } from 'rxjs';\r\nimport { catchError, map, switchMap } from 'rxjs/operators';\r\nimport { ISdApiConfiguration, SD_API_CONFIG } from '../api.model';\r\n\r\n@Injectable()\r\nexport class SdHttpInterceptor implements HttpInterceptor {\r\n #configurations = inject<ISdApiConfiguration[]>(SD_API_CONFIG, { optional: true }) || [];\r\n\r\n intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {\r\n const url = request.url;\r\n if (!url) {\r\n throw new Error(`Invalid URL`);\r\n }\r\n const handlers = this.#configurations.flatMap(configuration => configuration?.handlers || []);\r\n const handler = handlers?.find(e => e.hosts.some(host => url.startsWith(host)));\r\n const intercept = handler?.intercept;\r\n if (intercept) {\r\n request = request.clone(intercept(request));\r\n }\r\n if (request.body instanceof FormData) {\r\n request = request.clone({\r\n headers: request.headers.delete('Content-Type'),\r\n });\r\n }\r\n const beforeRemoteHandler = handler?.beforeRemote;\r\n const afterRemoteHandler = handler?.afterRemote;\r\n const beforeRemote = beforeRemoteHandler?.(request);\r\n if (beforeRemote instanceof Promise) {\r\n return from(beforeRemote).pipe(\r\n switchMap(() => next.handle(request)),\r\n map((event: HttpEvent<any>) => {\r\n if (event instanceof HttpResponse) {\r\n afterRemoteHandler?.(event);\r\n }\r\n return event;\r\n }),\r\n catchError((error: HttpErrorResponse) => {\r\n afterRemoteHandler?.(error);\r\n return throwError(() => error);\r\n })\r\n );\r\n }\r\n return next.handle(request).pipe(\r\n map((event: HttpEvent<any>) => {\r\n if (event instanceof HttpResponse) {\r\n afterRemoteHandler?.(event);\r\n }\r\n return event;\r\n }),\r\n catchError((error: HttpErrorResponse) => {\r\n afterRemoteHandler?.(error);\r\n return throwError(() => error);\r\n })\r\n );\r\n }\r\n}\r\n","import { HTTP_INTERCEPTORS, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';\r\nimport { NgModule } from '@angular/core';\r\nimport { SdHttpInterceptor } from './interceptors/api.interceptor';\r\n\r\n@NgModule({\r\n imports: [],\r\n exports: [],\r\n providers: [provideHttpClient(withInterceptorsFromDi()), { provide: HTTP_INTERCEPTORS, useClass: SdHttpInterceptor, multi: true }],\r\n})\r\nexport class SdApiModule {}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sd-angular-core-services-api.mjs","sources":["../../../projects/sd-angular/services/api/src/api.model.ts","../../../projects/sd-angular/services/api/src/api.service.ts","../../../projects/sd-angular/services/api/src/interceptors/api.interceptor.ts","../../../projects/sd-angular/services/api/src/api.module.ts","../../../projects/sd-angular/services/api/sd-angular-core-services-api.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\r\nimport { HttpClient, HttpErrorResponse, HttpRequest, HttpResponse } from '@angular/common/http';\r\nimport { InjectionToken } from '@angular/core';\r\nimport { SdCacheOption } from '@sd-angular/core/services/cache';\r\n// import hash from 'object-hash';\r\n\r\nexport interface SdApiOption {\r\n cacheOption?: SdCacheOption;\r\n timeout?: number; // Default: 30000 (30s)\r\n autoCache?: boolean; // Default: true\r\n}\r\ntype HttpGetOption = Parameters<HttpClient['get']>[1];\r\nexport type SdGetOption = HttpGetOption & SdApiOption;\r\n\r\ntype HttpPostOption = Parameters<HttpClient['post']>[2];\r\nexport type SdPostOption = HttpPostOption & SdApiOption;\r\n\r\ntype HttpPutOption = Parameters<HttpClient['put']>[2];\r\nexport type SdPutOption = HttpPutOption & SdApiOption;\r\n\r\ntype HttpDeleteOption = Parameters<HttpClient['delete']>[1];\r\nexport type SdDeleteOption = HttpDeleteOption & SdApiOption;\r\n\r\nexport interface SdApiHandler {\r\n /** Danh sách host URL mà handler này sẽ xử lý */\r\n hosts: string[];\r\n /** Can thiệp request: gắn header, token, transform body... */\r\n intercept?: (request: HttpRequest<any>) => HttpRequest<any>;\r\n /** Hook chạy TRƯỚC khi gửi request (dùng để log, tracking...) */\r\n beforeRemote?: (request: HttpRequest<any>) => void | Promise<void>;\r\n /** Hook chạy SAU khi nhận response (xử lý lỗi, notify...) */\r\n afterRemote?: (\r\n response: HttpResponse<any> | HttpErrorResponse | Error\r\n ) => void | Promise<void>;\r\n /** Transform response body thành kiểu dữ liệu mong muốn */\r\n mapResponse?: <Tres = any, Tdata = any>(response: Tres) => Tdata;\r\n /** Timeout tính bằng milliseconds. Mặc định: 30000 (30 giây) */\r\n timeout?: number;\r\n}\r\n\r\nexport interface ISdApiConfiguration {\r\n handlers: SdApiHandler[];\r\n}\r\n\r\nexport const SD_API_CONFIG = new InjectionToken<ISdApiConfiguration>('sd-api.configuration');\r\n\r\nexport const SD_API_CONFIGURATION = new InjectionToken<ISdApiConfiguration>('sd-api.configuration');","/* eslint-disable @typescript-eslint/no-explicit-any */\r\nimport { HttpClient } from '@angular/common/http';\r\nimport { inject, Injectable } from '@angular/core';\r\nimport { SdCacheService } from '@sd-angular/core/services/cache';\r\nimport { BrowserUtilities, Utilities } from '@sdcorejs/utils/fns';\r\nimport { lastValueFrom, Observable } from 'rxjs';\r\nimport { catchError, map, shareReplay, timeout } from 'rxjs/operators';\r\nimport { ISdApiConfiguration, SD_API_CONFIG, SdApiHandler, SdDeleteOption, SdGetOption, SdPostOption, SdPutOption } from './api.model';\r\n\r\n// Gom nhóm các Option lại cho gọn\r\ntype SdHttpOptions = SdGetOption & SdPostOption & SdPutOption & SdDeleteOption;\r\ntype HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class SdApiService {\r\n readonly #defaultTimeout = 60000; // 60s\r\n readonly #dedupCacheDuration = 1000; // 1s (Deduplication cache duration)\r\n #httpClient = inject(HttpClient);\r\n #configurations = inject<ISdApiConfiguration[]>(SD_API_CONFIG, { optional: true }) || [];\r\n #cacheService = inject(SdCacheService);\r\n\r\n // Thay đổi cấu trúc Cache: Lưu Observable thay vì Subject phức tạp\r\n // Key: hash string -> Value: { stream$: Observable, expiry: number }\r\n #inFlightRequests: Map<string, { stream$: Observable<any>; expiry: number }> = new Map();\r\n\r\n constructor() {\r\n // Optional: Cơ chế dọn dẹp cache định kỳ (mỗi 1 phút dọn dẹp các key hết hạn)\r\n setInterval(() => this.#cleanupCache(), 60000);\r\n }\r\n\r\n get http() {\r\n return this.#httpClient;\r\n }\r\n\r\n // --- PUBLIC METHODS ---\r\n\r\n get = <T = any>(url: string, option?: SdGetOption): Promise<T> => {\r\n return this.#executeWithLayeredCache<T>(url, 'GET', undefined, option);\r\n };\r\n\r\n post = <T = any>(url: string, body?: any, option?: SdPostOption): Promise<T> => {\r\n return this.#executeWithLayeredCache<T>(url, 'POST', body, option);\r\n };\r\n\r\n put = <T = any>(url: string, body?: any, option?: SdPutOption): Promise<T> => {\r\n return this.#executeWithLayeredCache<T>(url, 'PUT', body, option);\r\n };\r\n\r\n delete = <T = any>(url: string, option?: SdDeleteOption): Promise<T> => {\r\n return this.#executeWithLayeredCache<T>(url, 'DELETE', undefined, option);\r\n };\r\n\r\n // Upload file logic giữ nguyên nhưng refactor nhẹ\r\n upload = async (url: string, option?: { extensions?: string[]; maxSizeInMb?: number }): Promise<any> => {\r\n const file = await BrowserUtilities.upload(option);\r\n if (!Array.isArray(file) && file) {\r\n return this.uploadFile(url, file);\r\n }\r\n };\r\n\r\n uploadFile = async (url: string, file: File): Promise<any> => {\r\n if (!file) return null;\r\n if (file.name.lastIndexOf('.') === -1) throw new Error('Invalid file extension');\r\n\r\n const formData = new FormData();\r\n formData.append('file', file, file.name);\r\n // Upload thường không cần deduplication cache, set autoCache: false\r\n return await this.post(url, formData, { autoCache: false });\r\n };\r\n\r\n // --- PRIVATE CORE LOGIC ---\r\n\r\n /**\r\n * Hàm trung gian xử lý Layer Cache (SdCacheService) trước khi gọi API thực tế\r\n */\r\n #executeWithLayeredCache = async <T>(url: string, method: HttpMethod, body?: any, option?: SdHttpOptions): Promise<T> => {\r\n // Layer 1: Persistent Cache (SdCacheService)\r\n if (option?.cacheOption) {\r\n const key = this.#generateKey(url, method, body, option);\r\n const { get, set, has } = this.#cacheService.create(key, option.cacheOption);\r\n\r\n if (has()) {\r\n return get();\r\n }\r\n\r\n const result = await this.#request<T>(url, method, body, option);\r\n set(result);\r\n return result;\r\n }\r\n\r\n // Không có cache dài hạn thì gọi trực tiếp logic deduplication\r\n return this.#request<T>(url, method, body, option);\r\n };\r\n\r\n /**\r\n * Core Request: Xử lý Deduplication, Timeout, Mapping Response\r\n */\r\n #request = <T>(url: string, method: HttpMethod, body: any, option?: SdHttpOptions): Promise<T> => {\r\n const key = this.#generateKey(url, method, body, option);\r\n\r\n // Layer 2: Deduplication Cache (In-Flight Request / Short-term cache)\r\n const now = Date.now();\r\n const cachedItem = this.#inFlightRequests.get(key);\r\n\r\n // Nếu đã có request đang chạy hoặc mới chạy xong trong vòng 1s -> Trả về stream đó luôn\r\n if (cachedItem && cachedItem.expiry > now) {\r\n return lastValueFrom(cachedItem.stream$);\r\n }\r\n\r\n // Setup request mới\r\n const handler = this.#getHandler(url);\r\n const apiTimeout = option?.timeout ?? handler?.timeout ?? this.#defaultTimeout;\r\n\r\n // Tạo Observable call API\r\n const request$ = this.#httpClient\r\n .request(method, url, {\r\n body,\r\n headers: option?.headers,\r\n params: option?.params,\r\n observe: 'response', // Lấy full response để check status\r\n responseType: option?.responseType,\r\n })\r\n .pipe(\r\n timeout(apiTimeout),\r\n map(res => {\r\n // Normalize Response Logic\r\n const bodyRes = res.body as any;\r\n // Logic check response cũ của bạn\r\n if (bodyRes && typeof bodyRes === 'object' && 'ok' in bodyRes && !bodyRes.ok) {\r\n throw bodyRes; // Giả sử structure trả về { ok: false, ... } là lỗi\r\n }\r\n\r\n if (handler?.mapResponse) {\r\n return handler.mapResponse(bodyRes);\r\n }\r\n\r\n return bodyRes;\r\n }),\r\n catchError(err => {\r\n // Xóa cache ngay lập tức nếu lỗi để user có thể retry\r\n this.#inFlightRequests.delete(key);\r\n throw err;\r\n }),\r\n // QUAN TRỌNG: shareReplay(1) giúp share kết quả cho các subscriber đến sau (trong 1s)\r\n shareReplay(1)\r\n );\r\n\r\n // Lưu vào Map\r\n this.#inFlightRequests.set(key, {\r\n stream$: request$,\r\n expiry: now + this.#dedupCacheDuration,\r\n });\r\n\r\n // Chuyển đổi sang Promise cho đúng return type của bạn\r\n return lastValueFrom(request$);\r\n };\r\n\r\n // --- HELPERS ---\r\n\r\n #getHandler = (url: string): SdApiHandler | undefined => {\r\n const handlers = this.#configurations.flatMap(b => b?.handlers || []);\r\n return handlers.find(e => e.hosts.some(host => url.startsWith(host)));\r\n };\r\n\r\n #generateKey = (url: string, method: HttpMethod, body: any, option?: SdHttpOptions): string => {\r\n // FormData không hash được nội dung file, luôn generate key mới\r\n if (body instanceof FormData || option?.autoCache === false) {\r\n return Utilities.generateUuid();\r\n }\r\n return Utilities.hash({\r\n url,\r\n method,\r\n params: option?.params,\r\n headers: option?.headers,\r\n body,\r\n });\r\n };\r\n\r\n // Dọn dẹp memory leak\r\n #cleanupCache() {\r\n const now = Date.now();\r\n this.#inFlightRequests.forEach((value, key) => {\r\n if (value.expiry < now) {\r\n this.#inFlightRequests.delete(key);\r\n }\r\n });\r\n }\r\n}\r\n","/* eslint-disable @typescript-eslint/no-explicit-any */\r\nimport { HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '@angular/common/http';\r\nimport { inject, Injectable } from '@angular/core';\r\nimport { from, Observable, throwError } from 'rxjs';\r\nimport { catchError, map, switchMap } from 'rxjs/operators';\r\nimport { ISdApiConfiguration, SD_API_CONFIG } from '../api.model';\r\n\r\n@Injectable()\r\nexport class SdHttpInterceptor implements HttpInterceptor {\r\n #configurations = inject<ISdApiConfiguration[]>(SD_API_CONFIG, { optional: true }) || [];\r\n\r\n intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {\r\n const url = request.url;\r\n if (!url) {\r\n throw new Error(`Invalid URL`);\r\n }\r\n const handlers = this.#configurations.flatMap(configuration => configuration?.handlers || []);\r\n const handler = handlers?.find(e => e.hosts.some(host => url.startsWith(host)));\r\n const intercept = handler?.intercept;\r\n if (intercept) {\r\n request = request.clone(intercept(request));\r\n }\r\n if (request.body instanceof FormData) {\r\n request = request.clone({\r\n headers: request.headers.delete('Content-Type'),\r\n });\r\n }\r\n const beforeRemoteHandler = handler?.beforeRemote;\r\n const afterRemoteHandler = handler?.afterRemote;\r\n const beforeRemote = beforeRemoteHandler?.(request);\r\n if (beforeRemote instanceof Promise) {\r\n return from(beforeRemote).pipe(\r\n switchMap(() => next.handle(request)),\r\n map((event: HttpEvent<any>) => {\r\n if (event instanceof HttpResponse) {\r\n afterRemoteHandler?.(event);\r\n }\r\n return event;\r\n }),\r\n catchError((error: HttpErrorResponse) => {\r\n afterRemoteHandler?.(error);\r\n return throwError(() => error);\r\n })\r\n );\r\n }\r\n return next.handle(request).pipe(\r\n map((event: HttpEvent<any>) => {\r\n if (event instanceof HttpResponse) {\r\n afterRemoteHandler?.(event);\r\n }\r\n return event;\r\n }),\r\n catchError((error: HttpErrorResponse) => {\r\n afterRemoteHandler?.(error);\r\n return throwError(() => error);\r\n })\r\n );\r\n }\r\n}\r\n","import { HTTP_INTERCEPTORS, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';\nimport { NgModule } from '@angular/core';\nimport { SdHttpInterceptor } from './interceptors/api.interceptor';\n\n@NgModule({\n imports: [],\n exports: [],\n providers: [provideHttpClient(withInterceptorsFromDi()), { provide: HTTP_INTERCEPTORS, useClass: SdHttpInterceptor, multi: true }],\n})\nexport class SdApiModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;;;MA4Ca,aAAa,GAAG,IAAI,cAAc,CAAsB,sBAAsB;MAE9E,oBAAoB,GAAG,IAAI,cAAc,CAAsB,sBAAsB;;AC9ClG;MAgBa,YAAY,CAAA;AACd,IAAA,eAAe,GAAG,KAAK,CAAC;AACxB,IAAA,mBAAmB,GAAG,IAAI,CAAC;AACpC,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC;AAChC,IAAA,eAAe,GAAG,MAAM,CAAwB,aAAa,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE;AACxF,IAAA,aAAa,GAAG,MAAM,CAAC,cAAc,CAAC;;;AAItC,IAAA,iBAAiB,GAA8D,IAAI,GAAG,EAAE;AAExF,IAAA,WAAA,GAAA;;QAEE,WAAW,CAAC,MAAM,IAAI,CAAC,aAAa,EAAE,EAAE,KAAK,CAAC;IAChD;AAEA,IAAA,IAAI,IAAI,GAAA;QACN,OAAO,IAAI,CAAC,WAAW;IACzB;;AAIA,IAAA,GAAG,GAAG,CAAU,GAAW,EAAE,MAAoB,KAAgB;AAC/D,QAAA,OAAO,IAAI,CAAC,wBAAwB,CAAI,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC;AACxE,IAAA,CAAC;IAED,IAAI,GAAG,CAAU,GAAW,EAAE,IAAU,EAAE,MAAqB,KAAgB;AAC7E,QAAA,OAAO,IAAI,CAAC,wBAAwB,CAAI,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC;AACpE,IAAA,CAAC;IAED,GAAG,GAAG,CAAU,GAAW,EAAE,IAAU,EAAE,MAAoB,KAAgB;AAC3E,QAAA,OAAO,IAAI,CAAC,wBAAwB,CAAI,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC;AACnE,IAAA,CAAC;AAED,IAAA,MAAM,GAAG,CAAU,GAAW,EAAE,MAAuB,KAAgB;AACrE,QAAA,OAAO,IAAI,CAAC,wBAAwB,CAAI,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,CAAC;AAC3E,IAAA,CAAC;;AAGD,IAAA,MAAM,GAAG,OAAO,GAAW,EAAE,MAAwD,KAAkB;QACrG,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC,MAAM,CAAC,MAAM,CAAC;QAClD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE;YAChC,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC;QACnC;AACF,IAAA,CAAC;AAED,IAAA,UAAU,GAAG,OAAO,GAAW,EAAE,IAAU,KAAkB;AAC3D,QAAA,IAAI,CAAC,IAAI;AAAE,YAAA,OAAO,IAAI;QACtB,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAAE,YAAA,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC;AAEhF,QAAA,MAAM,QAAQ,GAAG,IAAI,QAAQ,EAAE;QAC/B,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC;;AAExC,QAAA,OAAO,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;AAC7D,IAAA,CAAC;;AAID;;AAEG;IACH,wBAAwB,GAAG,OAAU,GAAW,EAAE,MAAkB,EAAE,IAAU,EAAE,MAAsB,KAAgB;;AAEtH,QAAA,IAAI,MAAM,EAAE,WAAW,EAAE;AACvB,YAAA,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC;YACxD,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,WAAW,CAAC;YAE5E,IAAI,GAAG,EAAE,EAAE;gBACT,OAAO,GAAG,EAAE;YACd;AAEA,YAAA,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAI,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC;YAChE,GAAG,CAAC,MAAM,CAAC;AACX,YAAA,OAAO,MAAM;QACf;;AAGA,QAAA,OAAO,IAAI,CAAC,QAAQ,CAAI,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC;AACpD,IAAA,CAAC;AAED;;AAEG;IACH,QAAQ,GAAG,CAAI,GAAW,EAAE,MAAkB,EAAE,IAAS,EAAE,MAAsB,KAAgB;AAC/F,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC;;AAGxD,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;QACtB,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC;;QAGlD,IAAI,UAAU,IAAI,UAAU,CAAC,MAAM,GAAG,GAAG,EAAE;AACzC,YAAA,OAAO,aAAa,CAAC,UAAU,CAAC,OAAO,CAAC;QAC1C;;QAGA,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC;AACrC,QAAA,MAAM,UAAU,GAAG,MAAM,EAAE,OAAO,IAAI,OAAO,EAAE,OAAO,IAAI,IAAI,CAAC,eAAe;;AAG9E,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC;AACnB,aAAA,OAAO,CAAC,MAAM,EAAE,GAAG,EAAE;YACpB,IAAI;YACJ,OAAO,EAAE,MAAM,EAAE,OAAO;YACxB,MAAM,EAAE,MAAM,EAAE,MAAM;YACtB,OAAO,EAAE,UAAU;YACnB,YAAY,EAAE,MAAM,EAAE,YAAY;SACnC;aACA,IAAI,CACH,OAAO,CAAC,UAAU,CAAC,EACnB,GAAG,CAAC,GAAG,IAAG;;AAER,YAAA,MAAM,OAAO,GAAG,GAAG,CAAC,IAAW;;AAE/B,YAAA,IAAI,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE;gBAC5E,MAAM,OAAO,CAAC;YAChB;AAEA,YAAA,IAAI,OAAO,EAAE,WAAW,EAAE;AACxB,gBAAA,OAAO,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC;YACrC;AAEA,YAAA,OAAO,OAAO;AAChB,QAAA,CAAC,CAAC,EACF,UAAU,CAAC,GAAG,IAAG;;AAEf,YAAA,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,GAAG,CAAC;AAClC,YAAA,MAAM,GAAG;AACX,QAAA,CAAC,CAAC;;AAEF,QAAA,WAAW,CAAC,CAAC,CAAC,CACf;;AAGH,QAAA,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,GAAG,EAAE;AAC9B,YAAA,OAAO,EAAE,QAAQ;AACjB,YAAA,MAAM,EAAE,GAAG,GAAG,IAAI,CAAC,mBAAmB;AACvC,SAAA,CAAC;;AAGF,QAAA,OAAO,aAAa,CAAC,QAAQ,CAAC;AAChC,IAAA,CAAC;;AAID,IAAA,WAAW,GAAG,CAAC,GAAW,KAA8B;AACtD,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,QAAQ,IAAI,EAAE,CAAC;QACrE,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;AACvE,IAAA,CAAC;IAED,YAAY,GAAG,CAAC,GAAW,EAAE,MAAkB,EAAE,IAAS,EAAE,MAAsB,KAAY;;QAE5F,IAAI,IAAI,YAAY,QAAQ,IAAI,MAAM,EAAE,SAAS,KAAK,KAAK,EAAE;AAC3D,YAAA,OAAO,SAAS,CAAC,YAAY,EAAE;QACjC;QACA,OAAO,SAAS,CAAC,IAAI,CAAC;YACpB,GAAG;YACH,MAAM;YACN,MAAM,EAAE,MAAM,EAAE,MAAM;YACtB,OAAO,EAAE,MAAM,EAAE,OAAO;YACxB,IAAI;AACL,SAAA,CAAC;AACJ,IAAA,CAAC;;IAGD,aAAa,GAAA;AACX,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;QACtB,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,KAAI;AAC5C,YAAA,IAAI,KAAK,CAAC,MAAM,GAAG,GAAG,EAAE;AACtB,gBAAA,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,GAAG,CAAC;YACpC;AACF,QAAA,CAAC,CAAC;IACJ;wGA5KW,YAAY,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAZ,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,YAAY,cAFX,MAAM,EAAA,CAAA;;4FAEP,YAAY,EAAA,UAAA,EAAA,CAAA;kBAHxB,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE,MAAM;AACnB,iBAAA;;;ACfD;MAQa,iBAAiB,CAAA;AAC5B,IAAA,eAAe,GAAG,MAAM,CAAwB,aAAa,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE;IAExF,SAAS,CAAC,OAAyB,EAAE,IAAiB,EAAA;AACpD,QAAA,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG;QACvB,IAAI,CAAC,GAAG,EAAE;AACR,YAAA,MAAM,IAAI,KAAK,CAAC,CAAA,WAAA,CAAa,CAAC;QAChC;AACA,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,aAAa,IAAI,aAAa,EAAE,QAAQ,IAAI,EAAE,CAAC;AAC7F,QAAA,MAAM,OAAO,GAAG,QAAQ,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;AAC/E,QAAA,MAAM,SAAS,GAAG,OAAO,EAAE,SAAS;QACpC,IAAI,SAAS,EAAE;YACb,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAC7C;AACA,QAAA,IAAI,OAAO,CAAC,IAAI,YAAY,QAAQ,EAAE;AACpC,YAAA,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC;gBACtB,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC;AAChD,aAAA,CAAC;QACJ;AACA,QAAA,MAAM,mBAAmB,GAAG,OAAO,EAAE,YAAY;AACjD,QAAA,MAAM,kBAAkB,GAAG,OAAO,EAAE,WAAW;AAC/C,QAAA,MAAM,YAAY,GAAG,mBAAmB,GAAG,OAAO,CAAC;AACnD,QAAA,IAAI,YAAY,YAAY,OAAO,EAAE;YACnC,OAAO,IAAI,CAAC,YAAY,CAAC,CAAC,IAAI,CAC5B,SAAS,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EACrC,GAAG,CAAC,CAAC,KAAqB,KAAI;AAC5B,gBAAA,IAAI,KAAK,YAAY,YAAY,EAAE;AACjC,oBAAA,kBAAkB,GAAG,KAAK,CAAC;gBAC7B;AACA,gBAAA,OAAO,KAAK;AACd,YAAA,CAAC,CAAC,EACF,UAAU,CAAC,CAAC,KAAwB,KAAI;AACtC,gBAAA,kBAAkB,GAAG,KAAK,CAAC;AAC3B,gBAAA,OAAO,UAAU,CAAC,MAAM,KAAK,CAAC;YAChC,CAAC,CAAC,CACH;QACH;AACA,QAAA,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAC9B,GAAG,CAAC,CAAC,KAAqB,KAAI;AAC5B,YAAA,IAAI,KAAK,YAAY,YAAY,EAAE;AACjC,gBAAA,kBAAkB,GAAG,KAAK,CAAC;YAC7B;AACA,YAAA,OAAO,KAAK;AACd,QAAA,CAAC,CAAC,EACF,UAAU,CAAC,CAAC,KAAwB,KAAI;AACtC,YAAA,kBAAkB,GAAG,KAAK,CAAC;AAC3B,YAAA,OAAO,UAAU,CAAC,MAAM,KAAK,CAAC;QAChC,CAAC,CAAC,CACH;IACH;wGAjDW,iBAAiB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;4GAAjB,iBAAiB,EAAA,CAAA;;4FAAjB,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBAD7B;;;MCEY,WAAW,CAAA;wGAAX,WAAW,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,QAAA,EAAA,CAAA;yGAAX,WAAW,EAAA,CAAA;yGAAX,WAAW,EAAA,SAAA,EAFX,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,iBAAiB,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EAAA,CAAA;;4FAEvH,WAAW,EAAA,UAAA,EAAA,CAAA;kBALvB,QAAQ;AAAC,YAAA,IAAA,EAAA,CAAA;AACR,oBAAA,OAAO,EAAE,EAAE;AACX,oBAAA,OAAO,EAAE,EAAE;oBACX,SAAS,EAAE,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,iBAAiB,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACnI,iBAAA;;;ACRD;;AAEG;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"sd-angular-core-services-confirm.mjs","sources":["../../../projects/sd-angular/services/confirm/src/lib/components/dialog-confirm/dialog-confirm.component.ts","../../../projects/sd-angular/services/confirm/src/lib/components/dialog-confirm/dialog-confirm.component.html","../../../projects/sd-angular/services/confirm/src/lib/confirm.service.ts","../../../projects/sd-angular/services/confirm/src/public-api.ts","../../../projects/sd-angular/services/confirm/sd-angular-core-services-confirm.ts"],"sourcesContent":["import { CommonModule } from '@angular/common';\r\nimport { Component, inject } from '@angular/core';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { MatDialogRef, MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';\r\nimport { MatFormFieldModule } from '@angular/material/form-field';\r\nimport { MatIconModule } from '@angular/material/icon';\r\nimport { SdButton } from '@sd-angular/core/components/button';\r\nimport { SdDate } from '@sd-angular/core/forms/date';\r\nimport { SdRadio } from '@sd-angular/core/forms/radio';\r\nimport { SdTextarea } from '@sd-angular/core/forms/textarea';\r\nimport { Color } from '@sdcorejs/utils/models';\r\nimport { Utilities } from '@sdcorejs/utils/fns';\r\n\r\nexport interface DialogData {\r\n icon?: string;\r\n title?: string;\r\n message?: string;\r\n yesTitle?: string;\r\n noTitle?: string;\r\n yesButtonColor?: Color;\r\n noButtonColor?: Color;\r\n input?: {\r\n placeholder?: string;\r\n minlength?: number;\r\n maxlength?: number;\r\n required?: boolean;\r\n defaultValue?: string;\r\n };\r\n date?: {\r\n required?: boolean;\r\n placeholder?: string;\r\n defaultValue?: string | Date;\r\n min?: string | Date;\r\n max?: string | Date;\r\n };\r\n radio?: {\r\n required?: boolean;\r\n defaultValue?: string | number;\r\n items: any[];\r\n valueField: string;\r\n displayField: string;\r\n display?: 'row' | 'column';\r\n };\r\n}\r\n\r\n@Component({\r\n selector: 'sd-dialog-confirm',\r\n templateUrl: 'dialog-confirm.component.html',\r\n styleUrl: './dialog-confirm.component.scss',\r\n imports: [CommonModule, FormsModule, MatDialogModule, MatIconModule, SdButton, SdDate, SdRadio, SdTextarea],\r\n})\r\nexport class DialogConfirmComponent {\r\n value: any;\r\n required = false;\r\n id = `I${Utilities.generateUuid()}`;\r\n public readonly dialogRef = inject(MatDialogRef<DialogConfirmComponent>);\r\n public readonly data = inject<DialogData>(MAT_DIALOG_DATA);\r\n\r\n constructor() {\r\n if (this.data?.input) {\r\n this.value = this.data?.input?.defaultValue ?? '';\r\n this.required = this.data?.input?.required || false;\r\n }\r\n if (this.data?.date) {\r\n this.value = this.data?.date?.defaultValue ?? '';\r\n this.required = this.data?.date?.required || false;\r\n }\r\n if (this.data?.radio) {\r\n this.value = this.data?.radio?.defaultValue ?? '';\r\n this.required = this.data?.radio?.required || false;\r\n }\r\n }\r\n\r\n onCancel = () => {\r\n this.dialogRef.close({ action: 'CANCEL', value: null });\r\n };\r\n\r\n onAccept = () => {\r\n // Always return an object with action and value for consistency\r\n if (this.data?.radio || this.data?.input || this.data?.date) {\r\n this.dialogRef.close({ action: 'ACCEPT', value: this.value });\r\n } else {\r\n this.dialogRef.close({ action: 'ACCEPT', value: null });\r\n }\r\n };\r\n}\r\n","<div mat-dialog-title class=\"\">\r\n @if (data.icon) {\r\n <mat-icon>\r\n {{ data.icon }}\r\n </mat-icon>\r\n }\r\n <span class=\"T24M\" [innerHtml]=\"data.title || 'Confirm'\"></span>\r\n</div>\r\n<div mat-dialog-content>\r\n <div class=\"T14R mb-4\" [innerHtml]=\"data.message\"></div>\r\n @if (data.input) {\r\n <sd-textarea [placeholder]=\"data.input.placeholder\" [(model)]=\"value\" [rows]=\"5\" [maxlength]=\"data.input.maxlength!\" />\r\n }\r\n @if (data.date) {\r\n <sd-date\r\n [placeholder]=\"data.date.placeholder\"\r\n [(model)]=\"value\"\r\n type=\"date\"\r\n [min]=\"data.date.min!\"\r\n [max]=\"data.date.max!\"\r\n [required]=\"data.date.required\">\r\n </sd-date>\r\n }\r\n @if (data.radio) {\r\n <sd-radio\r\n [items]=\"data.radio.items\"\r\n [valueField]=\"data.radio.valueField\"\r\n [displayField]=\"data.radio.displayField\"\r\n [display]=\"data.radio.display || 'column'\"\r\n [(model)]=\"value\"\r\n [required]=\"data.radio.required\">\r\n </sd-radio>\r\n }\r\n</div>\r\n<div mat-dialog-actions align=\"end\">\r\n @if (data.noTitle) {\r\n <sd-button [color]=\"data.noButtonColor || 'secondary'\" [title]=\"data.noTitle\" (click)=\"onCancel()\"></sd-button>\r\n }\r\n @if (data.yesTitle) {\r\n <sd-button\r\n class=\"ml-8\"\r\n type=\"fill\"\r\n [color]=\"data.yesButtonColor || 'primary'\"\r\n [disabled]=\"required && !value\"\r\n cdkFocusInitial\r\n [title]=\"data.yesTitle\"\r\n (click)=\"onAccept()\"></sd-button>\r\n }\r\n</div>\r\n","import { inject, Injectable } from '@angular/core';\r\nimport { MatDialog } from '@angular/material/dialog';\r\nimport { DialogConfirmComponent } from './components/dialog-confirm/dialog-confirm.component';\r\nimport { Color } from '@sdcorejs/utils/models';\r\nimport { I18nService } from '@sd-angular/core/i18n';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class SdConfirmService {\r\n readonly #i18n = inject(I18nService);\r\n\r\n constructor(private dialog: MatDialog) {}\r\n\r\n confirm = (\r\n message: string,\r\n option: {\r\n title?: string;\r\n yesTitle?: string;\r\n noTitle?: string;\r\n yesButtonColor?: Color;\r\n noButtonColor?: Color;\r\n width?: string;\r\n disableBackdropClose?: boolean;\r\n } = {}\r\n ) => {\r\n const dialogRef = this.dialog.open(DialogConfirmComponent, {\r\n width: option?.width || '400px',\r\n disableClose: option?.disableBackdropClose ?? true,\r\n data: {\r\n title: option?.title || this.#i18n.t('core.confirm.title'),\r\n message,\r\n yesTitle: option?.yesTitle || this.#i18n.t('core.confirm.yes'),\r\n noTitle: option?.noTitle || this.#i18n.t('core.confirm.no'),\r\n noButtonColor: option?.noButtonColor || 'secondary',\r\n yesButtonColor: option?.yesButtonColor || 'primary',\r\n },\r\n });\r\n return new Promise((resolve, reject) => {\r\n dialogRef.afterClosed().subscribe(result => {\r\n if (result) {\r\n if (result.action === 'CANCEL') {\r\n reject(result.action);\r\n } else if (result.action === 'ACCEPT') {\r\n resolve(result.value);\r\n }\r\n }\r\n });\r\n });\r\n };\r\n\r\n withInput = (\r\n message?: string,\r\n option?: {\r\n title?: string;\r\n yesTitle?: string;\r\n noTitle?: string;\r\n required?: boolean;\r\n maxlength?: number;\r\n yesButtonColor?: Color;\r\n noButtonColor?: Color;\r\n defaultValue?: string;\r\n disableBackdropClose?: boolean;\r\n }\r\n ): Promise<string> => {\r\n const dialogRef = this.dialog.open(DialogConfirmComponent, {\r\n width: '400px',\r\n disableClose: option?.disableBackdropClose ?? true,\r\n data: {\r\n title: option?.title || this.#i18n.t('core.confirm.title'),\r\n message,\r\n yesTitle: option?.yesTitle || this.#i18n.t('core.confirm.yes-short'),\r\n noTitle: option?.noTitle || this.#i18n.t('core.confirm.no-short'),\r\n noButtonColor: option?.noButtonColor || 'secondary',\r\n yesButtonColor: option?.yesButtonColor || 'primary',\r\n input: {\r\n maxlength: option?.maxlength || 255,\r\n required: option?.required,\r\n defaultValue: option?.defaultValue || '',\r\n },\r\n },\r\n });\r\n return new Promise((resolve, reject) => {\r\n dialogRef.afterClosed().subscribe(result => {\r\n if (result) {\r\n if (result.action === 'CANCEL') {\r\n reject(result.action);\r\n } else if (result.action === 'ACCEPT') {\r\n resolve(result.value);\r\n }\r\n }\r\n });\r\n });\r\n };\r\n\r\n withRadio = (\r\n message?: string,\r\n option?: {\r\n title?: string;\r\n yesTitle?: string;\r\n noTitle?: string;\r\n required?: boolean;\r\n yesButtonColor?: Color;\r\n noButtonColor?: Color;\r\n defaultValue?: string | number;\r\n items: any[];\r\n valueField: string;\r\n displayField: string;\r\n display?: 'row' | 'column';\r\n disableBackdropClose?: boolean;\r\n }\r\n ): Promise<string> => {\r\n const dialogRef = this.dialog.open(DialogConfirmComponent, {\r\n width: '400px',\r\n disableClose: option?.disableBackdropClose ?? true,\r\n data: {\r\n title: option?.title || this.#i18n.t('core.confirm.title'),\r\n message,\r\n yesTitle: option?.yesTitle || this.#i18n.t('core.confirm.yes-short'),\r\n noTitle: option?.noTitle || this.#i18n.t('core.confirm.no-short'),\r\n noButtonColor: option?.noButtonColor || 'secondary',\r\n yesButtonColor: option?.yesButtonColor || 'primary',\r\n radio: {\r\n items: option?.items || [],\r\n valueField: option?.valueField || 'value',\r\n displayField: option?.displayField || 'label',\r\n display: option?.display || 'row',\r\n required: option?.required,\r\n defaultValue: option?.defaultValue,\r\n },\r\n },\r\n });\r\n return new Promise((resolve, reject) => {\r\n dialogRef.afterClosed().subscribe(result => {\r\n if (result) {\r\n if (result.action === 'CANCEL') {\r\n reject(result.action);\r\n } else if (result.action === 'ACCEPT') {\r\n resolve(result.value);\r\n }\r\n }\r\n });\r\n });\r\n };\r\n\r\n withDate = (\r\n message?: string,\r\n option?: {\r\n title?: string;\r\n\r\n yesTitle?: string;\r\n noTitle?: string;\r\n required?: boolean;\r\n yesButtonColor?: Color;\r\n noButtonColor?: Color;\r\n defaultValue?: string | Date;\r\n placeholder?: string;\r\n disableBackdropClose?: boolean;\r\n }\r\n ): Promise<string> => {\r\n const dialogRef = this.dialog.open(DialogConfirmComponent, {\r\n width: '400px',\r\n disableClose: option?.disableBackdropClose ?? true,\r\n data: {\r\n title: option?.title || this.#i18n.t('core.confirm.title'),\r\n message,\r\n yesTitle: option?.yesTitle || this.#i18n.t('core.confirm.yes-short'),\r\n noTitle: option?.noTitle || this.#i18n.t('core.confirm.no-short'),\r\n noButtonColor: option?.noButtonColor || 'secondary',\r\n yesButtonColor: option?.yesButtonColor || 'primary',\r\n date: {\r\n placeholder: option?.placeholder,\r\n required: option?.required,\r\n defaultValue: option?.defaultValue || '',\r\n },\r\n },\r\n });\r\n return new Promise((resolve, reject) => {\r\n dialogRef.afterClosed().subscribe(result => {\r\n if (result) {\r\n if (result.action === 'CANCEL') {\r\n reject(result.action);\r\n } else if (result.action === 'ACCEPT') {\r\n resolve(result.value);\r\n }\r\n }\r\n });\r\n });\r\n };\r\n}\r\n","/*\r\n * Public API Surface of superdev-angular-core\r\n */\r\n\r\nexport * from './lib/components/dialog-confirm/dialog-confirm.component';\r\nexport * from './lib/confirm.service';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sd-angular-core-services-confirm.mjs","sources":["../../../projects/sd-angular/services/confirm/src/lib/components/dialog-confirm/dialog-confirm.component.ts","../../../projects/sd-angular/services/confirm/src/lib/components/dialog-confirm/dialog-confirm.component.html","../../../projects/sd-angular/services/confirm/src/lib/confirm.service.ts","../../../projects/sd-angular/services/confirm/src/public-api.ts","../../../projects/sd-angular/services/confirm/sd-angular-core-services-confirm.ts"],"sourcesContent":["import { CommonModule } from '@angular/common';\r\nimport { Component, inject } from '@angular/core';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { MatDialogRef, MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';\r\nimport { MatFormFieldModule } from '@angular/material/form-field';\r\nimport { MatIconModule } from '@angular/material/icon';\r\nimport { SdButton } from '@sd-angular/core/components/button';\r\nimport { SdDate } from '@sd-angular/core/forms/date';\r\nimport { SdRadio } from '@sd-angular/core/forms/radio';\r\nimport { SdTextarea } from '@sd-angular/core/forms/textarea';\r\nimport { Color } from '@sdcorejs/utils/models';\r\nimport { Utilities } from '@sdcorejs/utils/fns';\r\n\r\nexport interface DialogData {\r\n icon?: string;\r\n title?: string;\r\n message?: string;\r\n yesTitle?: string;\r\n noTitle?: string;\r\n yesButtonColor?: Color;\r\n noButtonColor?: Color;\r\n input?: {\r\n placeholder?: string;\r\n minlength?: number;\r\n maxlength?: number;\r\n required?: boolean;\r\n defaultValue?: string;\r\n };\r\n date?: {\r\n required?: boolean;\r\n placeholder?: string;\r\n defaultValue?: string | Date;\r\n min?: string | Date;\r\n max?: string | Date;\r\n };\r\n radio?: {\r\n required?: boolean;\r\n defaultValue?: string | number;\r\n items: any[];\r\n valueField: string;\r\n displayField: string;\r\n display?: 'row' | 'column';\r\n };\r\n}\r\n\r\n@Component({\r\n selector: 'sd-dialog-confirm',\r\n templateUrl: 'dialog-confirm.component.html',\r\n styleUrl: './dialog-confirm.component.scss',\r\n imports: [CommonModule, FormsModule, MatDialogModule, MatIconModule, SdButton, SdDate, SdRadio, SdTextarea],\r\n})\r\nexport class DialogConfirmComponent {\r\n value: any;\r\n required = false;\r\n id = `I${Utilities.generateUuid()}`;\r\n public readonly dialogRef = inject(MatDialogRef<DialogConfirmComponent>);\r\n public readonly data = inject<DialogData>(MAT_DIALOG_DATA);\r\n\r\n constructor() {\r\n if (this.data?.input) {\r\n this.value = this.data?.input?.defaultValue ?? '';\r\n this.required = this.data?.input?.required || false;\r\n }\r\n if (this.data?.date) {\r\n this.value = this.data?.date?.defaultValue ?? '';\r\n this.required = this.data?.date?.required || false;\r\n }\r\n if (this.data?.radio) {\r\n this.value = this.data?.radio?.defaultValue ?? '';\r\n this.required = this.data?.radio?.required || false;\r\n }\r\n }\r\n\r\n onCancel = () => {\r\n this.dialogRef.close({ action: 'CANCEL', value: null });\r\n };\r\n\r\n onAccept = () => {\r\n // Always return an object with action and value for consistency\r\n if (this.data?.radio || this.data?.input || this.data?.date) {\r\n this.dialogRef.close({ action: 'ACCEPT', value: this.value });\r\n } else {\r\n this.dialogRef.close({ action: 'ACCEPT', value: null });\r\n }\r\n };\r\n}\r\n","<div mat-dialog-title class=\"\">\r\n @if (data.icon) {\r\n <mat-icon>\r\n {{ data.icon }}\r\n </mat-icon>\r\n }\r\n <span class=\"T24M\" [innerHtml]=\"data.title || 'Confirm'\"></span>\r\n</div>\r\n<div mat-dialog-content>\r\n <div class=\"T14R mb-4\" [innerHtml]=\"data.message\"></div>\r\n @if (data.input) {\r\n <sd-textarea [placeholder]=\"data.input.placeholder\" [(model)]=\"value\" [rows]=\"5\" [maxlength]=\"data.input.maxlength!\" />\r\n }\r\n @if (data.date) {\r\n <sd-date\r\n [placeholder]=\"data.date.placeholder\"\r\n [(model)]=\"value\"\r\n type=\"date\"\r\n [min]=\"data.date.min!\"\r\n [max]=\"data.date.max!\"\r\n [required]=\"data.date.required\">\r\n </sd-date>\r\n }\r\n @if (data.radio) {\r\n <sd-radio\r\n [items]=\"data.radio.items\"\r\n [valueField]=\"data.radio.valueField\"\r\n [displayField]=\"data.radio.displayField\"\r\n [display]=\"data.radio.display || 'column'\"\r\n [(model)]=\"value\"\r\n [required]=\"data.radio.required\">\r\n </sd-radio>\r\n }\r\n</div>\r\n<div mat-dialog-actions align=\"end\">\r\n @if (data.noTitle) {\r\n <sd-button [color]=\"data.noButtonColor || 'secondary'\" [title]=\"data.noTitle\" (click)=\"onCancel()\"></sd-button>\r\n }\r\n @if (data.yesTitle) {\r\n <sd-button\r\n class=\"ml-8\"\r\n type=\"fill\"\r\n [color]=\"data.yesButtonColor || 'primary'\"\r\n [disabled]=\"required && !value\"\r\n cdkFocusInitial\r\n [title]=\"data.yesTitle\"\r\n (click)=\"onAccept()\"></sd-button>\r\n }\r\n</div>\r\n","import { inject, Injectable } from '@angular/core';\r\nimport { MatDialog } from '@angular/material/dialog';\r\nimport { DialogConfirmComponent } from './components/dialog-confirm/dialog-confirm.component';\r\nimport { Color } from '@sdcorejs/utils/models';\r\nimport { I18nService } from '@sd-angular/core/i18n';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class SdConfirmService {\r\n readonly #i18n = inject(I18nService);\r\n\r\n constructor(private dialog: MatDialog) {}\r\n\r\n confirm = (\r\n message: string,\r\n option: {\r\n title?: string;\r\n yesTitle?: string;\r\n noTitle?: string;\r\n yesButtonColor?: Color;\r\n noButtonColor?: Color;\r\n width?: string;\r\n disableBackdropClose?: boolean;\r\n } = {}\r\n ) => {\r\n const dialogRef = this.dialog.open(DialogConfirmComponent, {\r\n width: option?.width || '400px',\r\n disableClose: option?.disableBackdropClose ?? true,\r\n data: {\r\n title: option?.title || this.#i18n.t('core.confirm.title'),\r\n message,\r\n yesTitle: option?.yesTitle || this.#i18n.t('core.confirm.yes'),\r\n noTitle: option?.noTitle || this.#i18n.t('core.confirm.no'),\r\n noButtonColor: option?.noButtonColor || 'secondary',\r\n yesButtonColor: option?.yesButtonColor || 'primary',\r\n },\r\n });\r\n return new Promise((resolve, reject) => {\r\n dialogRef.afterClosed().subscribe(result => {\r\n if (result) {\r\n if (result.action === 'CANCEL') {\r\n reject(result.action);\r\n } else if (result.action === 'ACCEPT') {\r\n resolve(result.value);\r\n }\r\n }\r\n });\r\n });\r\n };\r\n\r\n withInput = (\r\n message?: string,\r\n option?: {\r\n title?: string;\r\n yesTitle?: string;\r\n noTitle?: string;\r\n required?: boolean;\r\n maxlength?: number;\r\n yesButtonColor?: Color;\r\n noButtonColor?: Color;\r\n defaultValue?: string;\r\n disableBackdropClose?: boolean;\r\n }\r\n ): Promise<string> => {\r\n const dialogRef = this.dialog.open(DialogConfirmComponent, {\r\n width: '400px',\r\n disableClose: option?.disableBackdropClose ?? true,\r\n data: {\r\n title: option?.title || this.#i18n.t('core.confirm.title'),\r\n message,\r\n yesTitle: option?.yesTitle || this.#i18n.t('core.confirm.yes-short'),\r\n noTitle: option?.noTitle || this.#i18n.t('core.confirm.no-short'),\r\n noButtonColor: option?.noButtonColor || 'secondary',\r\n yesButtonColor: option?.yesButtonColor || 'primary',\r\n input: {\r\n maxlength: option?.maxlength || 255,\r\n required: option?.required,\r\n defaultValue: option?.defaultValue || '',\r\n },\r\n },\r\n });\r\n return new Promise((resolve, reject) => {\r\n dialogRef.afterClosed().subscribe(result => {\r\n if (result) {\r\n if (result.action === 'CANCEL') {\r\n reject(result.action);\r\n } else if (result.action === 'ACCEPT') {\r\n resolve(result.value);\r\n }\r\n }\r\n });\r\n });\r\n };\r\n\r\n withRadio = (\r\n message?: string,\r\n option?: {\r\n title?: string;\r\n yesTitle?: string;\r\n noTitle?: string;\r\n required?: boolean;\r\n yesButtonColor?: Color;\r\n noButtonColor?: Color;\r\n defaultValue?: string | number;\r\n items: any[];\r\n valueField: string;\r\n displayField: string;\r\n display?: 'row' | 'column';\r\n disableBackdropClose?: boolean;\r\n }\r\n ): Promise<string> => {\r\n const dialogRef = this.dialog.open(DialogConfirmComponent, {\r\n width: '400px',\r\n disableClose: option?.disableBackdropClose ?? true,\r\n data: {\r\n title: option?.title || this.#i18n.t('core.confirm.title'),\r\n message,\r\n yesTitle: option?.yesTitle || this.#i18n.t('core.confirm.yes-short'),\r\n noTitle: option?.noTitle || this.#i18n.t('core.confirm.no-short'),\r\n noButtonColor: option?.noButtonColor || 'secondary',\r\n yesButtonColor: option?.yesButtonColor || 'primary',\r\n radio: {\r\n items: option?.items || [],\r\n valueField: option?.valueField || 'value',\r\n displayField: option?.displayField || 'label',\r\n display: option?.display || 'row',\r\n required: option?.required,\r\n defaultValue: option?.defaultValue,\r\n },\r\n },\r\n });\r\n return new Promise((resolve, reject) => {\r\n dialogRef.afterClosed().subscribe(result => {\r\n if (result) {\r\n if (result.action === 'CANCEL') {\r\n reject(result.action);\r\n } else if (result.action === 'ACCEPT') {\r\n resolve(result.value);\r\n }\r\n }\r\n });\r\n });\r\n };\r\n\r\n withDate = (\r\n message?: string,\r\n option?: {\r\n title?: string;\r\n\r\n yesTitle?: string;\r\n noTitle?: string;\r\n required?: boolean;\r\n yesButtonColor?: Color;\r\n noButtonColor?: Color;\r\n defaultValue?: string | Date;\r\n placeholder?: string;\r\n disableBackdropClose?: boolean;\r\n }\r\n ): Promise<string> => {\r\n const dialogRef = this.dialog.open(DialogConfirmComponent, {\r\n width: '400px',\r\n disableClose: option?.disableBackdropClose ?? true,\r\n data: {\r\n title: option?.title || this.#i18n.t('core.confirm.title'),\r\n message,\r\n yesTitle: option?.yesTitle || this.#i18n.t('core.confirm.yes-short'),\r\n noTitle: option?.noTitle || this.#i18n.t('core.confirm.no-short'),\r\n noButtonColor: option?.noButtonColor || 'secondary',\r\n yesButtonColor: option?.yesButtonColor || 'primary',\r\n date: {\r\n placeholder: option?.placeholder,\r\n required: option?.required,\r\n defaultValue: option?.defaultValue || '',\r\n },\r\n },\r\n });\r\n return new Promise((resolve, reject) => {\r\n dialogRef.afterClosed().subscribe(result => {\r\n if (result) {\r\n if (result.action === 'CANCEL') {\r\n reject(result.action);\r\n } else if (result.action === 'ACCEPT') {\r\n resolve(result.value);\r\n }\r\n }\r\n });\r\n });\r\n };\r\n}\r\n","/*\n * Public API Surface of superdev-angular-core\n */\n\nexport * from './lib/components/dialog-confirm/dialog-confirm.component';\nexport * from './lib/confirm.service';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"sd-angular-core-services-excel.mjs","sources":["../../../projects/sd-angular/services/excel/src/lib/spreadsheet-formula-injection.util.ts","../../../projects/sd-angular/services/excel/src/lib/excel.service.ts","../../../projects/sd-angular/services/excel/sd-angular-core-services-excel.ts"],"sourcesContent":["const DANGEROUS_SPREADSHEET_FORMULA_PREFIX = /^[=+\\-@\\t\\r\\n]/;\r\n\r\n/**\r\n * Prefix spreadsheet formula-like strings so exported files treat them as text.\r\n */\r\nexport function neutralizeSpreadsheetFormula(value: string): string;\r\nexport function neutralizeSpreadsheetFormula<T>(value: T): T;\r\nexport function neutralizeSpreadsheetFormula(value: unknown): unknown {\r\n if (typeof value !== 'string' || value === '' || value.startsWith(\"'\")) {\r\n return value;\r\n }\r\n\r\n return DANGEROUS_SPREADSHEET_FORMULA_PREFIX.test(value) ? `'${value}` : value;\r\n}\r\n","import { inject, Injectable } from '@angular/core';\r\nimport type { CellValue, Style } from 'exceljs';\r\n// import hash from 'object-hash';\r\nimport { DateUtilities } from '@sd-angular/core/utilities/extensions';\r\nimport { BrowserUtilities } from '@sdcorejs/utils/fns';\r\nimport { I18nService } from '@sd-angular/core/i18n';\r\nimport { SdExcelExportOption, SdExcelTemplate } from './excel.model';\r\nimport { neutralizeSpreadsheetFormula } from './spreadsheet-formula-injection.util';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class SdExcelService {\r\n readonly #i18n = inject(I18nService);\r\n #fieldStyle: Partial<Style> = {\r\n border: {\r\n bottom: { style: 'thin' },\r\n left: { style: 'thin' },\r\n right: { style: 'thin' },\r\n },\r\n alignment: {\r\n vertical: 'middle',\r\n horizontal: 'center',\r\n wrapText: true,\r\n },\r\n font: {\r\n bold: true,\r\n size: 11,\r\n color: { argb: '000000' },\r\n },\r\n fill: {\r\n type: 'pattern',\r\n pattern: 'solid',\r\n fgColor: {\r\n argb: 'FAFAFA',\r\n },\r\n },\r\n };\r\n #titleColor = 'FFFFFF';\r\n #titleFgColor = '143180';\r\n #titleStyle: Partial<Style> = {\r\n border: {\r\n bottom: { style: 'thin' },\r\n left: { style: 'thin' },\r\n right: { style: 'thin' },\r\n },\r\n alignment: {\r\n vertical: 'middle',\r\n horizontal: 'center',\r\n wrapText: true,\r\n },\r\n font: {\r\n bold: true,\r\n size: 11,\r\n color: { argb: this.#titleColor },\r\n },\r\n fill: {\r\n type: 'pattern',\r\n pattern: 'solid',\r\n fgColor: {\r\n argb: this.#titleFgColor,\r\n },\r\n },\r\n };\r\n\r\n #requiredStyle: Partial<Style> = {\r\n border: {\r\n bottom: { style: 'thin' },\r\n left: { style: 'thin' },\r\n right: { style: 'thin' },\r\n },\r\n alignment: {\r\n vertical: 'middle',\r\n horizontal: 'center',\r\n wrapText: true,\r\n },\r\n font: {\r\n italic: true,\r\n size: 11,\r\n color: { argb: 'FFFFFF' },\r\n },\r\n fill: {\r\n type: 'pattern',\r\n pattern: 'solid',\r\n fgColor: {\r\n argb: 'FF1744',\r\n },\r\n },\r\n };\r\n\r\n #descriptionStyle: Partial<Style> = {\r\n border: {\r\n bottom: { style: 'thin' },\r\n left: { style: 'thin' },\r\n right: { style: 'thin' },\r\n },\r\n alignment: {\r\n wrapText: true,\r\n },\r\n font: {\r\n italic: true,\r\n size: 9,\r\n color: { argb: '000000' },\r\n },\r\n fill: {\r\n type: 'pattern',\r\n pattern: 'solid',\r\n fgColor: {\r\n argb: 'CFD8DC',\r\n },\r\n },\r\n };\r\n\r\n #cellStyle: Partial<Style> = {\r\n alignment: {\r\n vertical: 'middle',\r\n wrapText: true,\r\n },\r\n };\r\n\r\n // exceljs là CJS module — khi dynamic import từ ESM, named export `Workbook`\r\n // có thể nằm trên `mod.Workbook` hoặc bị bọc trong `mod.default.Workbook` tuỳ bundler.\r\n // Helper này chuẩn hoá cả hai trường hợp.\r\n async #loadWorkbook(): Promise<new () => import('exceljs').Workbook> {\r\n const mod = (await import('exceljs')) as typeof import('exceljs') & {\r\n default?: typeof import('exceljs');\r\n };\r\n return mod.Workbook ?? mod.default?.Workbook;\r\n }\r\n\r\n generateTemplate = async (template: SdExcelTemplate) => {\r\n const { fileName, columns, sheets } = template;\r\n if (!Array.isArray(columns)) {\r\n throw new Error('Excel template columns must be an array');\r\n }\r\n for (const [idx, column] of columns.entries()) {\r\n if (!column.field) {\r\n throw new Error(`Column ${idx + 1}: Field is required`);\r\n }\r\n if (!column.title) {\r\n throw new Error(`Column ${idx + 1}: Title is required`);\r\n }\r\n }\r\n const hasDescription = columns.some(column => column.description);\r\n const Workbook = await this.#loadWorkbook();\r\n const workbook = new Workbook();\r\n const firstSheet = workbook.addWorksheet('template'); // Lấy ra sheet đầu tiên\r\n columns.forEach((column, index) => {\r\n const { required, fill, fontColor } = column;\r\n const cellField = firstSheet.getCell(1, index + 1);\r\n const cellTitle = firstSheet.getCell(2, index + 1);\r\n const cellDescription = firstSheet.getCell(3, index + 1);\r\n let width = 120;\r\n if (column.width && column.width.endsWith('px')) {\r\n width = +column.width.replace('px', '');\r\n }\r\n firstSheet.getColumn(index + 1).width = width / 7 || 20;\r\n cellField.style = this.#fieldStyle;\r\n if (required) {\r\n cellField.style = this.#requiredStyle;\r\n } else {\r\n cellField.style = this.#fieldStyle;\r\n }\r\n cellTitle.style = {\r\n ...this.#titleStyle,\r\n font: {\r\n ...this.#titleStyle?.font,\r\n color: {\r\n ...this.#titleStyle?.font?.color,\r\n argb: fontColor || this.#titleStyle?.font?.color?.argb,\r\n },\r\n },\r\n fill: {\r\n type: 'pattern',\r\n pattern: 'solid',\r\n fgColor: {\r\n argb: fill || this.#titleFgColor,\r\n },\r\n },\r\n };\r\n cellField.value = neutralizeSpreadsheetFormula(column.field);\r\n cellTitle.value = neutralizeSpreadsheetFormula(column.title);\r\n if (hasDescription) {\r\n cellDescription.style = this.#descriptionStyle;\r\n cellDescription.value = neutralizeSpreadsheetFormula(column.description || '');\r\n }\r\n });\r\n if (sheets?.length) {\r\n for (const sheet of sheets) {\r\n if (sheet.name && Array.isArray(sheet.items) && Array.isArray(sheet.headers)) {\r\n const newSheet = workbook.addWorksheet(sheet.name);\r\n sheet.headers.forEach((header, index) => {\r\n newSheet.getColumn(index + 1).width = 30;\r\n newSheet.getCell(1, index + 1).style = this.#titleStyle;\r\n newSheet.getCell(1, index + 1).value = neutralizeSpreadsheetFormula(header.value);\r\n newSheet.getCell(2, index + 1).style = this.#titleStyle;\r\n newSheet.getCell(2, index + 1).value = neutralizeSpreadsheetFormula(header.display || header.value);\r\n });\r\n sheet.items.forEach((item, idx1) => {\r\n sheet.headers.forEach((header, idx2) => {\r\n newSheet.getCell(3 + idx1, 1 + idx2).value = neutralizeSpreadsheetFormula(item[header.value]) as CellValue;\r\n newSheet.getCell(3 + idx1, 1 + idx2).style = this.#cellStyle;\r\n });\r\n });\r\n }\r\n }\r\n }\r\n const file = await workbook.xlsx.writeBuffer();\r\n BrowserUtilities.downloadBlob(\r\n new Blob([file], {\r\n type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\r\n }),\r\n fileName\r\n );\r\n };\r\n\r\n exportCSV = async (option: SdExcelExportOption): Promise<void> => {\r\n const { columns, items, fileName } = option;\r\n const filename = `${fileName || 'CSV'}_${DateUtilities.toFormat(new Date(), 'yyyy-MM-dd-HH-mm-ss')}.csv`;\r\n\r\n // Escape CSV cell: bọc trong dấu \" nếu chứa dấu phẩy / xuống dòng / dấu ngoặc kép.\r\n // Dấu \" bên trong được nhân đôi theo chuẩn RFC 4180.\r\n const escape = (v: unknown): string => {\r\n if (v == null) return '';\r\n const s = typeof v === 'string' ? neutralizeSpreadsheetFormula(v) : String(v);\r\n return /[\",\\n\\r]/.test(s) ? `\"${s.replace(/\"/g, '\"\"')}\"` : s;\r\n };\r\n\r\n const headerLine = columns.map(c => escape(c.title)).join(',');\r\n const dataLines = items.map(item => columns.map(c => escape((item as Record<string, unknown>)[c.field])).join(','));\r\n\r\n // Prepend UTF-8 BOM so Excel opens Vietnamese text with the correct encoding.\r\n // Dùng CRLF vì Excel trên Windows ưu tiên, macOS Excel cũng chấp nhận.\r\n const csv = '\\uFEFF' + [headerLine, ...dataLines].join('\\r\\n');\r\n\r\n BrowserUtilities.downloadBlob(new Blob([csv], { type: 'text/csv;charset=utf-8;' }), filename);\r\n };\r\n\r\n export = async (option: SdExcelExportOption) => {\r\n const { columns, items, fileName, sheets } = option;\r\n let hasDescription = false;\r\n for (const [idx, column] of columns.entries()) {\r\n if (!column.field) {\r\n throw new Error(`Column ${idx + 1}: Field is required`);\r\n }\r\n if (!column.title) {\r\n throw new Error(`Column ${idx + 1}: Title is required`);\r\n }\r\n if (column.description) {\r\n hasDescription = true;\r\n }\r\n }\r\n const Workbook = await this.#loadWorkbook();\r\n const workbook = new Workbook(); //await XlsxPopulate.fromBlankAsync(); // Đọc file sau khi đã download\r\n const firstSheet = workbook.addWorksheet('data'); // Lấy ra sheet đầu tiên\r\n columns.forEach((column, index) => {\r\n let width = 120;\r\n if (column.width && column.width.endsWith('px')) {\r\n width = +column.width.replace('px', '');\r\n }\r\n firstSheet.getColumn(index + 1).width = width / 7 || 20;\r\n firstSheet.getCell(1, index + 1).style = this.#fieldStyle;\r\n if (column.required) {\r\n firstSheet.getCell(2, index + 1).style = this.#requiredStyle;\r\n } else {\r\n firstSheet.getCell(2, index + 1).style = this.#titleStyle;\r\n }\r\n firstSheet.getCell(1, index + 1).value = neutralizeSpreadsheetFormula(column.field);\r\n firstSheet.getCell(2, index + 1).value = neutralizeSpreadsheetFormula(column.title);\r\n if (hasDescription) {\r\n firstSheet.getCell(3, index + 1).style = this.#descriptionStyle;\r\n firstSheet.getCell(3, index + 1).value = neutralizeSpreadsheetFormula(column.description || '');\r\n }\r\n });\r\n if (sheets?.length) {\r\n for (const sheet of sheets) {\r\n if (sheet.name && Array.isArray(sheet.items) && Array.isArray(sheet.headers)) {\r\n const newSheet = workbook.addWorksheet(sheet.name);\r\n sheet.headers.forEach((header, index) => {\r\n newSheet.getColumn(index + 1).width = 30;\r\n newSheet.getCell(1, index + 1).style = this.#titleStyle;\r\n newSheet.getCell(1, index + 1).value = neutralizeSpreadsheetFormula(header.value);\r\n newSheet.getCell(2, index + 1).style = this.#titleStyle;\r\n newSheet.getCell(2, index + 1).value = neutralizeSpreadsheetFormula(header.display || header.value);\r\n });\r\n sheet.items.forEach((item, idx1) => {\r\n sheet.headers.forEach((header, idx2) => {\r\n newSheet.getCell(3 + idx1, 1 + idx2).value = neutralizeSpreadsheetFormula(item[header.value]) as CellValue;\r\n newSheet.getCell(3 + idx1, 1 + idx2).style = this.#cellStyle;\r\n });\r\n });\r\n }\r\n }\r\n }\r\n\r\n const fromRow = hasDescription ? 4 : 3;\r\n items.forEach((e, idx1) => {\r\n columns.forEach((column, idx2) => {\r\n if (typeof e[column.field] === 'number') {\r\n // Format mặc định với kiểu số\r\n firstSheet.getCell(fromRow + idx1, 1 + idx2).value = +e[column.field];\r\n firstSheet.getCell(fromRow + idx1, 1 + idx2).numFmt = '#';\r\n } else {\r\n firstSheet.getCell(fromRow + idx1, 1 + idx2).value = neutralizeSpreadsheetFormula(e[column.field]) as CellValue;\r\n }\r\n firstSheet.getCell(fromRow + idx1, 1 + idx2).style = {\r\n ...this.#cellStyle,\r\n };\r\n });\r\n });\r\n const file = await workbook.xlsx.writeBuffer();\r\n BrowserUtilities.downloadBlob(\r\n new Blob([file], {\r\n type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\r\n }),\r\n fileName\r\n );\r\n };\r\n\r\n // Helper để lấy giá trị text chuẩn từ ô Excel (xử lý RichText, Formula, Hyperlink)\r\n #getCellValue = (value: CellValue): string | number | null | undefined | boolean | Date => {\r\n if (value && typeof value === 'object') {\r\n // Xử lý Rich Text (vd: ô bôi đậm)\r\n if ('richText' in value) {\r\n return value.richText.map(t => t.text).join('');\r\n }\r\n // Xử lý Hyperlink\r\n if ('text' in value) {\r\n return value.text as string; // hoặc value.result nếu là công thức\r\n }\r\n // Xử lý Formula\r\n if ('result' in value) {\r\n return value.result as string | number | null | undefined | boolean | Date;\r\n }\r\n }\r\n return value as string | number | null | undefined | boolean | Date;\r\n };\r\n upload = async (): Promise<{ items: Record<string, any>[]; file: File | null }> => {\r\n try {\r\n const fileResult = await BrowserUtilities.upload({\r\n extensions: ['xlsx'],\r\n maxSizeInMb: 10,\r\n });\r\n\r\n // Chuẩn hóa file đầu vào (nếu upload trả về mảng thì lấy phần tử đầu)\r\n const file = Array.isArray(fileResult) ? fileResult[0] : fileResult;\r\n\r\n if (!file) {\r\n return { items: [], file: null };\r\n }\r\n\r\n return await this.parse(file);\r\n } catch (error) {\r\n console.error('Upload error:', error);\r\n throw error; // Hoặc return { items: [], file: null } tùy logic nghiệp vụ\r\n }\r\n };\r\n parse = async (file: File): Promise<{ items: Record<string, any>[]; file: File | null }> => {\r\n return new Promise((resolve, reject) => {\r\n const reader = new FileReader();\r\n reader.onload = async e => {\r\n try {\r\n const buffer = e.target?.result as ArrayBuffer;\r\n if (!buffer) {\r\n throw new Error(this.#i18n.t('core.excel.cannot-read-file'));\r\n }\r\n\r\n const Workbook = await this.#loadWorkbook();\r\n const wb = new Workbook();\r\n await wb.xlsx.load(buffer);\r\n\r\n const sheet = wb.worksheets[0];\r\n if (!sheet) {\r\n throw new Error(this.#i18n.t('core.excel.no-sheet'));\r\n }\r\n\r\n const items: Record<string, any>[] = [];\r\n\r\n // Lấy row Header (Row 1)\r\n const headerRow = sheet.getRow(1);\r\n // Map: Column Index (bắt đầu từ 1) -> Tên trường (Key)\r\n const headerMap: Record<number, string> = {};\r\n\r\n // Duyệt qua các ô có dữ liệu thực tế của dòng Header\r\n headerRow.eachCell((cell, colNumber) => {\r\n const cellValue = this.#getCellValue(cell.value);\r\n if (cellValue) {\r\n // Ép kiểu về string và trim để làm key\r\n headerMap[colNumber] = String(cellValue).trim();\r\n }\r\n });\r\n\r\n // Duyệt dữ liệu từ dòng 2 trở đi\r\n sheet.eachRow((row, rowIndex) => {\r\n if (rowIndex <= 1 || !row.hasValues) return;\r\n\r\n const item: Record<string, any> = {};\r\n\r\n // Chỉ duyệt qua các cột đã định nghĩa trong headerMap\r\n // Cách này an toàn hơn là duyệt mảng values\r\n Object.keys(headerMap).forEach(colKey => {\r\n const colNumber = Number(colKey);\r\n const fieldKey = headerMap[colNumber];\r\n\r\n // Lấy giá trị ô tại cột tương ứng\r\n const rawValue = this.#getCellValue(row.getCell(colNumber).value);\r\n\r\n let finalValue = rawValue;\r\n\r\n // Xử lý string: trim\r\n if (typeof finalValue === 'string') {\r\n finalValue = finalValue.trim();\r\n }\r\n\r\n // Xử lý các keyword đặc biệt\r\n if (finalValue === '' || finalValue === undefined) {\r\n finalValue = null;\r\n } else if (finalValue === 'SET_NULL') {\r\n finalValue = null;\r\n } else if (finalValue === 'SET_EMPTY') {\r\n finalValue = '';\r\n }\r\n\r\n item[fieldKey] = finalValue;\r\n });\r\n\r\n // Chỉ push nếu item có dữ liệu (tùy chọn)\r\n if (Object.keys(item).length > 0) {\r\n items.push(item);\r\n }\r\n });\r\n\r\n resolve({ items, file });\r\n } catch (err) {\r\n reject(err);\r\n }\r\n };\r\n\r\n reader.onerror = error => reject(error);\r\n reader.readAsArrayBuffer(file);\r\n });\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
+ {"version":3,"file":"sd-angular-core-services-excel.mjs","sources":["../../../projects/sd-angular/services/excel/src/lib/spreadsheet-formula-injection.util.ts","../../../projects/sd-angular/services/excel/src/lib/excel.service.ts","../../../projects/sd-angular/services/excel/sd-angular-core-services-excel.ts"],"sourcesContent":["const DANGEROUS_SPREADSHEET_FORMULA_PREFIX = /^[=+\\-@\\t\\r\\n]/;\n\n/**\n * Prefix spreadsheet formula-like strings so exported files treat them as text.\n */\nexport function neutralizeSpreadsheetFormula(value: string): string;\nexport function neutralizeSpreadsheetFormula<T>(value: T): T;\nexport function neutralizeSpreadsheetFormula(value: unknown): unknown {\n if (typeof value !== 'string' || value === '' || value.startsWith(\"'\")) {\n return value;\n }\n\n return DANGEROUS_SPREADSHEET_FORMULA_PREFIX.test(value) ? `'${value}` : value;\n}\n","import { inject, Injectable } from '@angular/core';\r\nimport type { CellValue, Style } from 'exceljs';\r\n// import hash from 'object-hash';\r\nimport { DateUtilities } from '@sd-angular/core/utilities/extensions';\r\nimport { BrowserUtilities } from '@sdcorejs/utils/fns';\r\nimport { I18nService } from '@sd-angular/core/i18n';\r\nimport { SdExcelExportOption, SdExcelTemplate } from './excel.model';\r\nimport { neutralizeSpreadsheetFormula } from './spreadsheet-formula-injection.util';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class SdExcelService {\r\n readonly #i18n = inject(I18nService);\r\n #fieldStyle: Partial<Style> = {\r\n border: {\r\n bottom: { style: 'thin' },\r\n left: { style: 'thin' },\r\n right: { style: 'thin' },\r\n },\r\n alignment: {\r\n vertical: 'middle',\r\n horizontal: 'center',\r\n wrapText: true,\r\n },\r\n font: {\r\n bold: true,\r\n size: 11,\r\n color: { argb: '000000' },\r\n },\r\n fill: {\r\n type: 'pattern',\r\n pattern: 'solid',\r\n fgColor: {\r\n argb: 'FAFAFA',\r\n },\r\n },\r\n };\r\n #titleColor = 'FFFFFF';\r\n #titleFgColor = '143180';\r\n #titleStyle: Partial<Style> = {\r\n border: {\r\n bottom: { style: 'thin' },\r\n left: { style: 'thin' },\r\n right: { style: 'thin' },\r\n },\r\n alignment: {\r\n vertical: 'middle',\r\n horizontal: 'center',\r\n wrapText: true,\r\n },\r\n font: {\r\n bold: true,\r\n size: 11,\r\n color: { argb: this.#titleColor },\r\n },\r\n fill: {\r\n type: 'pattern',\r\n pattern: 'solid',\r\n fgColor: {\r\n argb: this.#titleFgColor,\r\n },\r\n },\r\n };\r\n\r\n #requiredStyle: Partial<Style> = {\r\n border: {\r\n bottom: { style: 'thin' },\r\n left: { style: 'thin' },\r\n right: { style: 'thin' },\r\n },\r\n alignment: {\r\n vertical: 'middle',\r\n horizontal: 'center',\r\n wrapText: true,\r\n },\r\n font: {\r\n italic: true,\r\n size: 11,\r\n color: { argb: 'FFFFFF' },\r\n },\r\n fill: {\r\n type: 'pattern',\r\n pattern: 'solid',\r\n fgColor: {\r\n argb: 'FF1744',\r\n },\r\n },\r\n };\r\n\r\n #descriptionStyle: Partial<Style> = {\r\n border: {\r\n bottom: { style: 'thin' },\r\n left: { style: 'thin' },\r\n right: { style: 'thin' },\r\n },\r\n alignment: {\r\n wrapText: true,\r\n },\r\n font: {\r\n italic: true,\r\n size: 9,\r\n color: { argb: '000000' },\r\n },\r\n fill: {\r\n type: 'pattern',\r\n pattern: 'solid',\r\n fgColor: {\r\n argb: 'CFD8DC',\r\n },\r\n },\r\n };\r\n\r\n #cellStyle: Partial<Style> = {\r\n alignment: {\r\n vertical: 'middle',\r\n wrapText: true,\r\n },\r\n };\r\n\r\n // exceljs là CJS module — khi dynamic import từ ESM, named export `Workbook`\r\n // có thể nằm trên `mod.Workbook` hoặc bị bọc trong `mod.default.Workbook` tuỳ bundler.\r\n // Helper này chuẩn hoá cả hai trường hợp.\r\n async #loadWorkbook(): Promise<new () => import('exceljs').Workbook> {\r\n const mod = (await import('exceljs')) as typeof import('exceljs') & {\r\n default?: typeof import('exceljs');\r\n };\r\n return mod.Workbook ?? mod.default?.Workbook;\r\n }\r\n\r\n generateTemplate = async (template: SdExcelTemplate) => {\r\n const { fileName, columns, sheets } = template;\r\n if (!Array.isArray(columns)) {\r\n throw new Error('Excel template columns must be an array');\r\n }\r\n for (const [idx, column] of columns.entries()) {\r\n if (!column.field) {\r\n throw new Error(`Column ${idx + 1}: Field is required`);\r\n }\r\n if (!column.title) {\r\n throw new Error(`Column ${idx + 1}: Title is required`);\r\n }\r\n }\r\n const hasDescription = columns.some(column => column.description);\r\n const Workbook = await this.#loadWorkbook();\r\n const workbook = new Workbook();\r\n const firstSheet = workbook.addWorksheet('template'); // Lấy ra sheet đầu tiên\r\n columns.forEach((column, index) => {\r\n const { required, fill, fontColor } = column;\r\n const cellField = firstSheet.getCell(1, index + 1);\r\n const cellTitle = firstSheet.getCell(2, index + 1);\r\n const cellDescription = firstSheet.getCell(3, index + 1);\r\n let width = 120;\r\n if (column.width && column.width.endsWith('px')) {\r\n width = +column.width.replace('px', '');\r\n }\r\n firstSheet.getColumn(index + 1).width = width / 7 || 20;\r\n cellField.style = this.#fieldStyle;\r\n if (required) {\r\n cellField.style = this.#requiredStyle;\r\n } else {\r\n cellField.style = this.#fieldStyle;\r\n }\r\n cellTitle.style = {\r\n ...this.#titleStyle,\r\n font: {\r\n ...this.#titleStyle?.font,\r\n color: {\r\n ...this.#titleStyle?.font?.color,\r\n argb: fontColor || this.#titleStyle?.font?.color?.argb,\r\n },\r\n },\r\n fill: {\r\n type: 'pattern',\r\n pattern: 'solid',\r\n fgColor: {\r\n argb: fill || this.#titleFgColor,\r\n },\r\n },\r\n };\r\n cellField.value = neutralizeSpreadsheetFormula(column.field);\r\n cellTitle.value = neutralizeSpreadsheetFormula(column.title);\r\n if (hasDescription) {\r\n cellDescription.style = this.#descriptionStyle;\r\n cellDescription.value = neutralizeSpreadsheetFormula(column.description || '');\r\n }\r\n });\r\n if (sheets?.length) {\r\n for (const sheet of sheets) {\r\n if (sheet.name && Array.isArray(sheet.items) && Array.isArray(sheet.headers)) {\r\n const newSheet = workbook.addWorksheet(sheet.name);\r\n sheet.headers.forEach((header, index) => {\r\n newSheet.getColumn(index + 1).width = 30;\r\n newSheet.getCell(1, index + 1).style = this.#titleStyle;\r\n newSheet.getCell(1, index + 1).value = neutralizeSpreadsheetFormula(header.value);\r\n newSheet.getCell(2, index + 1).style = this.#titleStyle;\r\n newSheet.getCell(2, index + 1).value = neutralizeSpreadsheetFormula(header.display || header.value);\r\n });\r\n sheet.items.forEach((item, idx1) => {\r\n sheet.headers.forEach((header, idx2) => {\r\n newSheet.getCell(3 + idx1, 1 + idx2).value = neutralizeSpreadsheetFormula(item[header.value]) as CellValue;\r\n newSheet.getCell(3 + idx1, 1 + idx2).style = this.#cellStyle;\r\n });\r\n });\r\n }\r\n }\r\n }\r\n const file = await workbook.xlsx.writeBuffer();\r\n BrowserUtilities.downloadBlob(\r\n new Blob([file], {\r\n type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\r\n }),\r\n fileName\r\n );\r\n };\r\n\r\n exportCSV = async (option: SdExcelExportOption): Promise<void> => {\r\n const { columns, items, fileName } = option;\r\n const filename = `${fileName || 'CSV'}_${DateUtilities.toFormat(new Date(), 'yyyy-MM-dd-HH-mm-ss')}.csv`;\r\n\r\n // Escape CSV cell: bọc trong dấu \" nếu chứa dấu phẩy / xuống dòng / dấu ngoặc kép.\r\n // Dấu \" bên trong được nhân đôi theo chuẩn RFC 4180.\r\n const escape = (v: unknown): string => {\r\n if (v == null) return '';\r\n const s = typeof v === 'string' ? neutralizeSpreadsheetFormula(v) : String(v);\r\n return /[\",\\n\\r]/.test(s) ? `\"${s.replace(/\"/g, '\"\"')}\"` : s;\r\n };\r\n\r\n const headerLine = columns.map(c => escape(c.title)).join(',');\r\n const dataLines = items.map(item => columns.map(c => escape((item as Record<string, unknown>)[c.field])).join(','));\r\n\r\n // Prepend UTF-8 BOM so Excel opens Vietnamese text with the correct encoding.\r\n // Dùng CRLF vì Excel trên Windows ưu tiên, macOS Excel cũng chấp nhận.\r\n const csv = '\\uFEFF' + [headerLine, ...dataLines].join('\\r\\n');\r\n\r\n BrowserUtilities.downloadBlob(new Blob([csv], { type: 'text/csv;charset=utf-8;' }), filename);\r\n };\r\n\r\n export = async (option: SdExcelExportOption) => {\r\n const { columns, items, fileName, sheets } = option;\r\n let hasDescription = false;\r\n for (const [idx, column] of columns.entries()) {\r\n if (!column.field) {\r\n throw new Error(`Column ${idx + 1}: Field is required`);\r\n }\r\n if (!column.title) {\r\n throw new Error(`Column ${idx + 1}: Title is required`);\r\n }\r\n if (column.description) {\r\n hasDescription = true;\r\n }\r\n }\r\n const Workbook = await this.#loadWorkbook();\r\n const workbook = new Workbook(); //await XlsxPopulate.fromBlankAsync(); // Đọc file sau khi đã download\r\n const firstSheet = workbook.addWorksheet('data'); // Lấy ra sheet đầu tiên\r\n columns.forEach((column, index) => {\r\n let width = 120;\r\n if (column.width && column.width.endsWith('px')) {\r\n width = +column.width.replace('px', '');\r\n }\r\n firstSheet.getColumn(index + 1).width = width / 7 || 20;\r\n firstSheet.getCell(1, index + 1).style = this.#fieldStyle;\r\n if (column.required) {\r\n firstSheet.getCell(2, index + 1).style = this.#requiredStyle;\r\n } else {\r\n firstSheet.getCell(2, index + 1).style = this.#titleStyle;\r\n }\r\n firstSheet.getCell(1, index + 1).value = neutralizeSpreadsheetFormula(column.field);\r\n firstSheet.getCell(2, index + 1).value = neutralizeSpreadsheetFormula(column.title);\r\n if (hasDescription) {\r\n firstSheet.getCell(3, index + 1).style = this.#descriptionStyle;\r\n firstSheet.getCell(3, index + 1).value = neutralizeSpreadsheetFormula(column.description || '');\r\n }\r\n });\r\n if (sheets?.length) {\r\n for (const sheet of sheets) {\r\n if (sheet.name && Array.isArray(sheet.items) && Array.isArray(sheet.headers)) {\r\n const newSheet = workbook.addWorksheet(sheet.name);\r\n sheet.headers.forEach((header, index) => {\r\n newSheet.getColumn(index + 1).width = 30;\r\n newSheet.getCell(1, index + 1).style = this.#titleStyle;\r\n newSheet.getCell(1, index + 1).value = neutralizeSpreadsheetFormula(header.value);\r\n newSheet.getCell(2, index + 1).style = this.#titleStyle;\r\n newSheet.getCell(2, index + 1).value = neutralizeSpreadsheetFormula(header.display || header.value);\r\n });\r\n sheet.items.forEach((item, idx1) => {\r\n sheet.headers.forEach((header, idx2) => {\r\n newSheet.getCell(3 + idx1, 1 + idx2).value = neutralizeSpreadsheetFormula(item[header.value]) as CellValue;\r\n newSheet.getCell(3 + idx1, 1 + idx2).style = this.#cellStyle;\r\n });\r\n });\r\n }\r\n }\r\n }\r\n\r\n const fromRow = hasDescription ? 4 : 3;\r\n items.forEach((e, idx1) => {\r\n columns.forEach((column, idx2) => {\r\n if (typeof e[column.field] === 'number') {\r\n // Format mặc định với kiểu số\r\n firstSheet.getCell(fromRow + idx1, 1 + idx2).value = +e[column.field];\r\n firstSheet.getCell(fromRow + idx1, 1 + idx2).numFmt = '#';\r\n } else {\r\n firstSheet.getCell(fromRow + idx1, 1 + idx2).value = neutralizeSpreadsheetFormula(e[column.field]) as CellValue;\r\n }\r\n firstSheet.getCell(fromRow + idx1, 1 + idx2).style = {\r\n ...this.#cellStyle,\r\n };\r\n });\r\n });\r\n const file = await workbook.xlsx.writeBuffer();\r\n BrowserUtilities.downloadBlob(\r\n new Blob([file], {\r\n type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\r\n }),\r\n fileName\r\n );\r\n };\r\n\r\n // Helper để lấy giá trị text chuẩn từ ô Excel (xử lý RichText, Formula, Hyperlink)\r\n #getCellValue = (value: CellValue): string | number | null | undefined | boolean | Date => {\r\n if (value && typeof value === 'object') {\r\n // Xử lý Rich Text (vd: ô bôi đậm)\r\n if ('richText' in value) {\r\n return value.richText.map(t => t.text).join('');\r\n }\r\n // Xử lý Hyperlink\r\n if ('text' in value) {\r\n return value.text as string; // hoặc value.result nếu là công thức\r\n }\r\n // Xử lý Formula\r\n if ('result' in value) {\r\n return value.result as string | number | null | undefined | boolean | Date;\r\n }\r\n }\r\n return value as string | number | null | undefined | boolean | Date;\r\n };\r\n upload = async (): Promise<{ items: Record<string, any>[]; file: File | null }> => {\r\n try {\r\n const fileResult = await BrowserUtilities.upload({\r\n extensions: ['xlsx'],\r\n maxSizeInMb: 10,\r\n });\r\n\r\n // Chuẩn hóa file đầu vào (nếu upload trả về mảng thì lấy phần tử đầu)\r\n const file = Array.isArray(fileResult) ? fileResult[0] : fileResult;\r\n\r\n if (!file) {\r\n return { items: [], file: null };\r\n }\r\n\r\n return await this.parse(file);\r\n } catch (error) {\r\n console.error('Upload error:', error);\r\n throw error; // Hoặc return { items: [], file: null } tùy logic nghiệp vụ\r\n }\r\n };\r\n parse = async (file: File): Promise<{ items: Record<string, any>[]; file: File | null }> => {\r\n return new Promise((resolve, reject) => {\r\n const reader = new FileReader();\r\n reader.onload = async e => {\r\n try {\r\n const buffer = e.target?.result as ArrayBuffer;\r\n if (!buffer) {\r\n throw new Error(this.#i18n.t('core.excel.cannot-read-file'));\r\n }\r\n\r\n const Workbook = await this.#loadWorkbook();\r\n const wb = new Workbook();\r\n await wb.xlsx.load(buffer);\r\n\r\n const sheet = wb.worksheets[0];\r\n if (!sheet) {\r\n throw new Error(this.#i18n.t('core.excel.no-sheet'));\r\n }\r\n\r\n const items: Record<string, any>[] = [];\r\n\r\n // Lấy row Header (Row 1)\r\n const headerRow = sheet.getRow(1);\r\n // Map: Column Index (bắt đầu từ 1) -> Tên trường (Key)\r\n const headerMap: Record<number, string> = {};\r\n\r\n // Duyệt qua các ô có dữ liệu thực tế của dòng Header\r\n headerRow.eachCell((cell, colNumber) => {\r\n const cellValue = this.#getCellValue(cell.value);\r\n if (cellValue) {\r\n // Ép kiểu về string và trim để làm key\r\n headerMap[colNumber] = String(cellValue).trim();\r\n }\r\n });\r\n\r\n // Duyệt dữ liệu từ dòng 2 trở đi\r\n sheet.eachRow((row, rowIndex) => {\r\n if (rowIndex <= 1 || !row.hasValues) return;\r\n\r\n const item: Record<string, any> = {};\r\n\r\n // Chỉ duyệt qua các cột đã định nghĩa trong headerMap\r\n // Cách này an toàn hơn là duyệt mảng values\r\n Object.keys(headerMap).forEach(colKey => {\r\n const colNumber = Number(colKey);\r\n const fieldKey = headerMap[colNumber];\r\n\r\n // Lấy giá trị ô tại cột tương ứng\r\n const rawValue = this.#getCellValue(row.getCell(colNumber).value);\r\n\r\n let finalValue = rawValue;\r\n\r\n // Xử lý string: trim\r\n if (typeof finalValue === 'string') {\r\n finalValue = finalValue.trim();\r\n }\r\n\r\n // Xử lý các keyword đặc biệt\r\n if (finalValue === '' || finalValue === undefined) {\r\n finalValue = null;\r\n } else if (finalValue === 'SET_NULL') {\r\n finalValue = null;\r\n } else if (finalValue === 'SET_EMPTY') {\r\n finalValue = '';\r\n }\r\n\r\n item[fieldKey] = finalValue;\r\n });\r\n\r\n // Chỉ push nếu item có dữ liệu (tùy chọn)\r\n if (Object.keys(item).length > 0) {\r\n items.push(item);\r\n }\r\n });\r\n\r\n resolve({ items, file });\r\n } catch (err) {\r\n reject(err);\r\n }\r\n };\r\n\r\n reader.onerror = error => reject(error);\r\n reader.readAsArrayBuffer(file);\r\n });\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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"}
@@ -9,24 +9,33 @@ class SdLoadingService {
9
9
  this.renderer = rendererFactory.createRenderer(null, null);
10
10
  }
11
11
  start = (element = 'body') => {
12
- const ele = document.querySelector(element);
13
- if (ele && !this.loadingMap.has(ele)) {
14
- const loadingElement = this.#createLoading();
15
- ele.appendChild(loadingElement);
16
- this.loadingMap.set(ele, loadingElement);
17
- }
12
+ // why: router tabs can leave multiple hosts with the same selector in the DOM;
13
+ // querySelector would only overlay the first match.
14
+ document.querySelectorAll(element).forEach(ele => {
15
+ if (!this.loadingMap.has(ele)) {
16
+ const loadingElement = this.#createLoading();
17
+ ele.appendChild(loadingElement);
18
+ this.loadingMap.set(ele, loadingElement);
19
+ }
20
+ });
18
21
  };
19
22
  isLoading = (element = 'body') => {
20
- const ele = document.querySelector(element);
21
- return ele && this.loadingMap.has(ele);
23
+ const nodes = document.querySelectorAll(element);
24
+ if (!nodes.length)
25
+ return null;
26
+ for (const ele of Array.from(nodes)) {
27
+ if (this.loadingMap.has(ele))
28
+ return ele;
29
+ }
30
+ return false;
22
31
  };
23
32
  stop = (element = 'body') => {
24
- const ele = document.querySelector(element);
25
- if (ele && this.loadingMap.has(ele)) {
26
- const loadingElement = this.loadingMap.get(ele);
27
- loadingElement?.remove();
28
- this.loadingMap.delete(ele);
29
- }
33
+ document.querySelectorAll(element).forEach(ele => {
34
+ if (this.loadingMap.has(ele)) {
35
+ this.loadingMap.get(ele)?.remove();
36
+ this.loadingMap.delete(ele);
37
+ }
38
+ });
30
39
  };
31
40
  #createLoading = () => {
32
41
  const renderer = this.renderer;
@@ -1 +1 @@
1
- {"version":3,"file":"sd-angular-core-services-loading.mjs","sources":["../../../projects/sd-angular/services/loading/src/loading.service.ts","../../../projects/sd-angular/services/loading/sd-angular-core-services-loading.ts"],"sourcesContent":["import { Injectable, Renderer2, RendererFactory2 } from '@angular/core';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class SdLoadingService {\r\n private loadingId = 'L8d556b9b-f6dd-46e9-9710-757e65d82839';\r\n\r\n private renderer: Renderer2;\r\n\r\n private loadingMap = new WeakMap<Element, HTMLElement>();\r\n constructor(rendererFactory: RendererFactory2) {\r\n this.renderer = rendererFactory.createRenderer(null, null);\r\n }\r\n\r\n start = (element = 'body') => {\r\n const ele = document.querySelector(element);\r\n if (ele && !this.loadingMap.has(ele)) {\r\n const loadingElement = this.#createLoading();\r\n ele.appendChild(loadingElement);\r\n this.loadingMap.set(ele, loadingElement);\r\n }\r\n };\r\n\r\n isLoading = (element = 'body') => {\r\n const ele = document.querySelector(element);\r\n return ele && this.loadingMap.has(ele);\r\n };\r\n\r\n stop = (element = 'body') => {\r\n const ele = document.querySelector(element);\r\n if (ele && this.loadingMap.has(ele)) {\r\n const loadingElement = this.loadingMap.get(ele);\r\n loadingElement?.remove();\r\n this.loadingMap.delete(ele);\r\n }\r\n };\r\n\r\n #createLoading = (): HTMLElement => {\r\n const renderer = this.renderer;\r\n const container: HTMLElement = this.renderer.createElement('div');\r\n const spinner: HTMLElement = this.renderer.createElement('div');\r\n const containerStyle = {\r\n position: 'absolute',\r\n top: 0,\r\n left: 0,\r\n height: '100%',\r\n width: '100%',\r\n opacity: 0.6,\r\n background: '#FFFFFF',\r\n 'z-index': 99999,\r\n };\r\n const spinnerStyle = {\r\n position: 'absolute',\r\n top: 'calc(50% - 2.5rem)',\r\n left: 'calc(50% - 2.5rem)',\r\n width: '5rem',\r\n height: '5rem',\r\n border: '0.5rem solid var(--sd-primary)',\r\n 'border-top': '0.5rem solid var(--sd-black200)',\r\n 'border-radius': '50%',\r\n animation: 'spin 1s linear infinite',\r\n };\r\n const keyframes = `\r\n @keyframes spin {\r\n 0% { transform: rotate(0deg); }\r\n 100% { transform: rotate(360deg); }\r\n }\r\n `;\r\n\r\n renderer.addClass(container, 'sd-loading');\r\n renderer.setAttribute(container, 'id', this.loadingId);\r\n\r\n Object.entries(containerStyle).forEach(entry => {\r\n renderer.setStyle(container, entry[0], entry[1]);\r\n });\r\n\r\n renderer.addClass(spinner, 'sd-loading-spinner');\r\n Object.entries(spinnerStyle).forEach(entry => {\r\n renderer.setStyle(spinner, entry[0], entry[1]);\r\n });\r\n\r\n const styleElement = this.renderer.createElement('style');\r\n this.renderer.appendChild(styleElement, this.renderer.createText(keyframes));\r\n document.head.appendChild(styleElement);\r\n\r\n container.appendChild(spinner);\r\n return container;\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
+ {"version":3,"file":"sd-angular-core-services-loading.mjs","sources":["../../../projects/sd-angular/services/loading/src/loading.service.ts","../../../projects/sd-angular/services/loading/sd-angular-core-services-loading.ts"],"sourcesContent":["import { Injectable, Renderer2, RendererFactory2 } from '@angular/core';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class SdLoadingService {\r\n private loadingId = 'L8d556b9b-f6dd-46e9-9710-757e65d82839';\r\n\r\n private renderer: Renderer2;\r\n\r\n private loadingMap = new WeakMap<Element, HTMLElement>();\r\n constructor(rendererFactory: RendererFactory2) {\r\n this.renderer = rendererFactory.createRenderer(null, null);\r\n }\r\n\r\n start = (element = 'body') => {\r\n // why: router tabs can leave multiple hosts with the same selector in the DOM;\r\n // querySelector would only overlay the first match.\r\n document.querySelectorAll(element).forEach(ele => {\r\n if (!this.loadingMap.has(ele)) {\r\n const loadingElement = this.#createLoading();\r\n ele.appendChild(loadingElement);\r\n this.loadingMap.set(ele, loadingElement);\r\n }\r\n });\r\n };\r\n\r\n isLoading = (element = 'body') => {\r\n const nodes = document.querySelectorAll(element);\r\n if (!nodes.length) return null;\r\n for (const ele of Array.from(nodes)) {\r\n if (this.loadingMap.has(ele)) return ele;\r\n }\r\n return false;\r\n };\r\n\r\n stop = (element = 'body') => {\r\n document.querySelectorAll(element).forEach(ele => {\r\n if (this.loadingMap.has(ele)) {\r\n this.loadingMap.get(ele)?.remove();\r\n this.loadingMap.delete(ele);\r\n }\r\n });\r\n };\r\n\r\n #createLoading = (): HTMLElement => {\r\n const renderer = this.renderer;\r\n const container: HTMLElement = this.renderer.createElement('div');\r\n const spinner: HTMLElement = this.renderer.createElement('div');\r\n const containerStyle = {\r\n position: 'absolute',\r\n top: 0,\r\n left: 0,\r\n height: '100%',\r\n width: '100%',\r\n opacity: 0.6,\r\n background: '#FFFFFF',\r\n 'z-index': 99999,\r\n };\r\n const spinnerStyle = {\r\n position: 'absolute',\r\n top: 'calc(50% - 2.5rem)',\r\n left: 'calc(50% - 2.5rem)',\r\n width: '5rem',\r\n height: '5rem',\r\n border: '0.5rem solid var(--sd-primary)',\r\n 'border-top': '0.5rem solid var(--sd-black200)',\r\n 'border-radius': '50%',\r\n animation: 'spin 1s linear infinite',\r\n };\r\n const keyframes = `\r\n @keyframes spin {\r\n 0% { transform: rotate(0deg); }\r\n 100% { transform: rotate(360deg); }\r\n }\r\n `;\r\n\r\n renderer.addClass(container, 'sd-loading');\r\n renderer.setAttribute(container, 'id', this.loadingId);\r\n\r\n Object.entries(containerStyle).forEach(entry => {\r\n renderer.setStyle(container, entry[0], entry[1]);\r\n });\r\n\r\n renderer.addClass(spinner, 'sd-loading-spinner');\r\n Object.entries(spinnerStyle).forEach(entry => {\r\n renderer.setStyle(spinner, entry[0], entry[1]);\r\n });\r\n\r\n const styleElement = this.renderer.createElement('style');\r\n this.renderer.appendChild(styleElement, this.renderer.createText(keyframes));\r\n document.head.appendChild(styleElement);\r\n\r\n container.appendChild(spinner);\r\n return container;\r\n };\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;MAKa,gBAAgB,CAAA;IACnB,SAAS,GAAG,uCAAuC;AAEnD,IAAA,QAAQ;AAER,IAAA,UAAU,GAAG,IAAI,OAAO,EAAwB;AACxD,IAAA,WAAA,CAAY,eAAiC,EAAA;QAC3C,IAAI,CAAC,QAAQ,GAAG,eAAe,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC;IAC5D;AAEA,IAAA,KAAK,GAAG,CAAC,OAAO,GAAG,MAAM,KAAI;;;QAG3B,QAAQ,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,GAAG,IAAG;YAC/C,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;AAC7B,gBAAA,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,EAAE;AAC5C,gBAAA,GAAG,CAAC,WAAW,CAAC,cAAc,CAAC;gBAC/B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,cAAc,CAAC;YAC1C;AACF,QAAA,CAAC,CAAC;AACJ,IAAA,CAAC;AAED,IAAA,SAAS,GAAG,CAAC,OAAO,GAAG,MAAM,KAAI;QAC/B,MAAM,KAAK,GAAG,QAAQ,CAAC,gBAAgB,CAAC,OAAO,CAAC;QAChD,IAAI,CAAC,KAAK,CAAC,MAAM;AAAE,YAAA,OAAO,IAAI;QAC9B,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;AACnC,YAAA,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC;AAAE,gBAAA,OAAO,GAAG;QAC1C;AACA,QAAA,OAAO,KAAK;AACd,IAAA,CAAC;AAED,IAAA,IAAI,GAAG,CAAC,OAAO,GAAG,MAAM,KAAI;QAC1B,QAAQ,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,GAAG,IAAG;YAC/C,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;gBAC5B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE;AAClC,gBAAA,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC;YAC7B;AACF,QAAA,CAAC,CAAC;AACJ,IAAA,CAAC;IAED,cAAc,GAAG,MAAkB;AACjC,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ;QAC9B,MAAM,SAAS,GAAgB,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC;QACjE,MAAM,OAAO,GAAgB,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC;AAC/D,QAAA,MAAM,cAAc,GAAG;AACrB,YAAA,QAAQ,EAAE,UAAU;AACpB,YAAA,GAAG,EAAE,CAAC;AACN,YAAA,IAAI,EAAE,CAAC;AACP,YAAA,MAAM,EAAE,MAAM;AACd,YAAA,KAAK,EAAE,MAAM;AACb,YAAA,OAAO,EAAE,GAAG;AACZ,YAAA,UAAU,EAAE,SAAS;AACrB,YAAA,SAAS,EAAE,KAAK;SACjB;AACD,QAAA,MAAM,YAAY,GAAG;AACnB,YAAA,QAAQ,EAAE,UAAU;AACpB,YAAA,GAAG,EAAE,oBAAoB;AACzB,YAAA,IAAI,EAAE,oBAAoB;AAC1B,YAAA,KAAK,EAAE,MAAM;AACb,YAAA,MAAM,EAAE,MAAM;AACd,YAAA,MAAM,EAAE,gCAAgC;AACxC,YAAA,YAAY,EAAE,iCAAiC;AAC/C,YAAA,eAAe,EAAE,KAAK;AACtB,YAAA,SAAS,EAAE,yBAAyB;SACrC;AACD,QAAA,MAAM,SAAS,GAAG,CAAA;;;;;KAKjB;AAED,QAAA,QAAQ,CAAC,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC;QAC1C,QAAQ,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;QAEtD,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,KAAK,IAAG;AAC7C,YAAA,QAAQ,CAAC,QAAQ,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;AAClD,QAAA,CAAC,CAAC;AAEF,QAAA,QAAQ,CAAC,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAC;QAChD,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,KAAK,IAAG;AAC3C,YAAA,QAAQ,CAAC,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;AAChD,QAAA,CAAC,CAAC;QAEF,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC;AACzD,QAAA,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,YAAY,EAAE,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;AAC5E,QAAA,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC;AAEvC,QAAA,SAAS,CAAC,WAAW,CAAC,OAAO,CAAC;AAC9B,QAAA,OAAO,SAAS;AAClB,IAAA,CAAC;wGA1FU,gBAAgB,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAA,EAAA,CAAA,gBAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAhB,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,gBAAgB,cAFf,MAAM,EAAA,CAAA;;4FAEP,gBAAgB,EAAA,UAAA,EAAA,CAAA;kBAH5B,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE,MAAM;AACnB,iBAAA;;;ACJD;;AAEG;;;;"}
@@ -109,7 +109,7 @@ class ToastComponent {
109
109
  this.closeTimer = null;
110
110
  }
111
111
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: ToastComponent, deps: [{ token: SdNotifyService }, { token: i2.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component });
112
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: ToastComponent, isStandalone: true, selector: "toast", inputs: { data: "data" }, host: { listeners: { "mouseenter": "pauseTimer()", "mouseleave": "resumeTimer()" }, properties: { "class": "hostClasses()", "attr.data-autoid": "autoId", "attr.data-type": "data.type", "attr.data-title": "data.title ?? null", "attr.data-message": "dataMessage" } }, ngImport: i0, template: "<div class=\"sd-toast__bar\" [class]=\"'bg-' + data.type\"></div>\r\n\r\n<div class=\"sd-toast__icon\" [class]=\"'text-' + data.type\">\r\n @switch (data.type) {\r\n @case ('success') {\r\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z\"/></svg>\r\n }\r\n @case ('info') {\r\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z\"/></svg>\r\n }\r\n @case ('warning') {\r\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z\"/></svg>\r\n }\r\n @case ('error') {\r\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z\"/></svg>\r\n }\r\n }\r\n</div>\r\n\r\n<div class=\"sd-toast__content\">\r\n <div class=\"sd-toast__header\">\r\n <strong class=\"sd-toast__title\">{{ data.title || ('core.notify.type.' + data.type | translate) }}</strong>\r\n <button class=\"sd-toast__close\" (click)=\"close()\">&times;</button>\r\n </div>\r\n\r\n <div class=\"sd-toast__body\">\r\n @if (!isMultiMessage) {\r\n <!-- Text rendering is the default safe path; HTML is opt-in and sanitized. -->\r\n @if (data.html) {\r\n <div [innerHTML]=\"sanitizeHtml(singleMessage)\"></div>\r\n } @else {\r\n <div>{{ singleMessage }}</div>\r\n }\r\n } @else {\r\n <ul class=\"msg-list\">\r\n @for (msg of displayMessages; track msg) {\r\n @if (data.html) {\r\n <li [innerHTML]=\"sanitizeHtml('- ' + msg)\"></li>\r\n } @else {\r\n <li>{{ '- ' + msg }}</li>\r\n }\r\n }\r\n </ul>\r\n\r\n @if (hasMore) {\r\n <button\r\n type=\"button\"\r\n class=\"toggle-more btn-link\"\r\n [class]=\"'text-' + data.type\"\r\n (click)=\"toggleExpand()\">\r\n {{ isExpanded() ? ('core.notify.show-less' | translate) : ('core.notify.show-more' | translate: { count: restCount }) }}\r\n </button>\r\n }\r\n }\r\n </div>\r\n\r\n @if (data.actionLabel) {\r\n <div class=\"sd-toast__actions\">\r\n <button\r\n class=\"btn-action\"\r\n [class]=\"'bg-' + data.type + '-light text-' + data.type\"\r\n (click)=\"onActionClick()\">\r\n {{ data.actionLabel }}\r\n </button>\r\n </div>\r\n }\r\n</div>\r\n", styles: [":host{display:flex;width:350px;border-radius:8px;box-shadow:0 4px 12px #00000026;margin-bottom:12px;overflow:hidden;position:relative;font-family:Roboto,sans-serif;pointer-events:auto;animation:sd-toast-enter .3s ease-out}:host(.sd-toast--closing){pointer-events:none;animation:sd-toast-leave .2s ease-in forwards}@keyframes sd-toast-enter{0%{transform:translate(100%);opacity:0}to{transform:translate(0);opacity:1}}@keyframes sd-toast-leave{0%{transform:translate(0);opacity:1}to{transform:translate(100%);opacity:0}}@media(prefers-reduced-motion:reduce){:host,:host(.sd-toast--closing){animation:none}}.sd-toast__bar{width:6px;flex-shrink:0}.sd-toast__icon{padding:12px 0 0 12px;flex-shrink:0}.sd-toast__icon svg{width:24px;height:24px}.sd-toast__content{flex-grow:1;padding:12px;display:flex;flex-direction:column}.sd-toast__header{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:4px}.sd-toast__title{font-size:16px;font-weight:600}.sd-toast__close{background:none;border:none;font-size:16px;cursor:pointer;line-height:1;padding:0;opacity:.5;transition:opacity .2s}.sd-toast__close:hover{opacity:1}.sd-toast__body{font-size:14px;line-height:1.4;word-break:break-word}.sd-toast__actions{display:flex;justify-content:flex-end;margin-top:8px}.msg-list{padding-left:0;list-style:none;margin:0}.toggle-more{background:none;border:none;padding:0;font:inherit;cursor:pointer;font-size:13px;margin-top:4px;font-weight:500;text-align:left}.toggle-more:hover{text-decoration:underline}.toggle-more:focus-visible{outline:2px solid currentColor;outline-offset:2px}.btn-action{border:none;padding:6px 12px;border-radius:4px;font-weight:600;cursor:pointer;font-size:13px;transition:filter .2s}.btn-action:hover{filter:brightness(.95)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
112
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: ToastComponent, isStandalone: true, selector: "toast", inputs: { data: "data" }, host: { listeners: { "mouseenter": "pauseTimer()", "mouseleave": "resumeTimer()" }, properties: { "class": "hostClasses()", "attr.data-autoid": "autoId", "attr.data-type": "data.type", "attr.data-title": "data.title ?? null", "attr.data-message": "dataMessage" } }, ngImport: i0, template: "<div class=\"sd-toast__bar\" [class]=\"'bg-' + data.type\"></div>\n\n<div class=\"sd-toast__icon\" [class]=\"'text-' + data.type\">\n @switch (data.type) {\n @case ('success') {\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z\"/></svg>\n }\n @case ('info') {\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z\"/></svg>\n }\n @case ('warning') {\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z\"/></svg>\n }\n @case ('error') {\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z\"/></svg>\n }\n }\n</div>\n\n<div class=\"sd-toast__content\">\n <div class=\"sd-toast__header\">\n <strong class=\"sd-toast__title\">{{ data.title || ('core.notify.type.' + data.type | translate) }}</strong>\n <button class=\"sd-toast__close\" (click)=\"close()\">&times;</button>\n </div>\n\n <div class=\"sd-toast__body\">\n @if (!isMultiMessage) {\n <!-- Text rendering is the default safe path; HTML is opt-in and sanitized. -->\n @if (data.html) {\n <div [innerHTML]=\"sanitizeHtml(singleMessage)\"></div>\n } @else {\n <div>{{ singleMessage }}</div>\n }\n } @else {\n <ul class=\"msg-list\">\n @for (msg of displayMessages; track msg) {\n @if (data.html) {\n <li [innerHTML]=\"sanitizeHtml('- ' + msg)\"></li>\n } @else {\n <li>{{ '- ' + msg }}</li>\n }\n }\n </ul>\n\n @if (hasMore) {\n <button\n type=\"button\"\n class=\"toggle-more btn-link\"\n [class]=\"'text-' + data.type\"\n (click)=\"toggleExpand()\">\n {{ isExpanded() ? ('core.notify.show-less' | translate) : ('core.notify.show-more' | translate: { count: restCount }) }}\n </button>\n }\n }\n </div>\n\n @if (data.actionLabel) {\n <div class=\"sd-toast__actions\">\n <button\n class=\"btn-action\"\n [class]=\"'bg-' + data.type + '-light text-' + data.type\"\n (click)=\"onActionClick()\">\n {{ data.actionLabel }}\n </button>\n </div>\n }\n</div>\n", styles: [":host{display:flex;width:350px;border-radius:8px;box-shadow:0 4px 12px #00000026;margin-bottom:12px;overflow:hidden;position:relative;font-family:Roboto,sans-serif;pointer-events:auto;animation:sd-toast-enter .3s ease-out}:host(.sd-toast--closing){pointer-events:none;animation:sd-toast-leave .2s ease-in forwards}@keyframes sd-toast-enter{0%{transform:translate(100%);opacity:0}to{transform:translate(0);opacity:1}}@keyframes sd-toast-leave{0%{transform:translate(0);opacity:1}to{transform:translate(100%);opacity:0}}@media(prefers-reduced-motion:reduce){:host,:host(.sd-toast--closing){animation:none}}.sd-toast__bar{width:6px;flex-shrink:0}.sd-toast__icon{padding:12px 0 0 12px;flex-shrink:0}.sd-toast__icon svg{width:24px;height:24px}.sd-toast__content{flex-grow:1;padding:12px;display:flex;flex-direction:column}.sd-toast__header{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:4px}.sd-toast__title{font-size:16px;font-weight:600}.sd-toast__close{background:none;border:none;font-size:16px;cursor:pointer;line-height:1;padding:0;opacity:.5;transition:opacity .2s}.sd-toast__close:hover{opacity:1}.sd-toast__body{font-size:14px;line-height:1.4;word-break:break-word}.sd-toast__actions{display:flex;justify-content:flex-end;margin-top:8px}.msg-list{padding-left:0;list-style:none;margin:0}.toggle-more{background:none;border:none;padding:0;font:inherit;cursor:pointer;font-size:13px;margin-top:4px;font-weight:500;text-align:left}.toggle-more:hover{text-decoration:underline}.toggle-more:focus-visible{outline:2px solid currentColor;outline-offset:2px}.btn-action{border:none;padding:6px 12px;border-radius:4px;font-weight:600;cursor:pointer;font-size:13px;transition:filter .2s}.btn-action:hover{filter:brightness(.95)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
113
113
  }
114
114
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: ToastComponent, decorators: [{
115
115
  type: Component,
@@ -119,7 +119,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
119
119
  '[attr.data-type]': 'data.type',
120
120
  '[attr.data-title]': 'data.title ?? null',
121
121
  '[attr.data-message]': 'dataMessage',
122
- }, template: "<div class=\"sd-toast__bar\" [class]=\"'bg-' + data.type\"></div>\r\n\r\n<div class=\"sd-toast__icon\" [class]=\"'text-' + data.type\">\r\n @switch (data.type) {\r\n @case ('success') {\r\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z\"/></svg>\r\n }\r\n @case ('info') {\r\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z\"/></svg>\r\n }\r\n @case ('warning') {\r\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z\"/></svg>\r\n }\r\n @case ('error') {\r\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z\"/></svg>\r\n }\r\n }\r\n</div>\r\n\r\n<div class=\"sd-toast__content\">\r\n <div class=\"sd-toast__header\">\r\n <strong class=\"sd-toast__title\">{{ data.title || ('core.notify.type.' + data.type | translate) }}</strong>\r\n <button class=\"sd-toast__close\" (click)=\"close()\">&times;</button>\r\n </div>\r\n\r\n <div class=\"sd-toast__body\">\r\n @if (!isMultiMessage) {\r\n <!-- Text rendering is the default safe path; HTML is opt-in and sanitized. -->\r\n @if (data.html) {\r\n <div [innerHTML]=\"sanitizeHtml(singleMessage)\"></div>\r\n } @else {\r\n <div>{{ singleMessage }}</div>\r\n }\r\n } @else {\r\n <ul class=\"msg-list\">\r\n @for (msg of displayMessages; track msg) {\r\n @if (data.html) {\r\n <li [innerHTML]=\"sanitizeHtml('- ' + msg)\"></li>\r\n } @else {\r\n <li>{{ '- ' + msg }}</li>\r\n }\r\n }\r\n </ul>\r\n\r\n @if (hasMore) {\r\n <button\r\n type=\"button\"\r\n class=\"toggle-more btn-link\"\r\n [class]=\"'text-' + data.type\"\r\n (click)=\"toggleExpand()\">\r\n {{ isExpanded() ? ('core.notify.show-less' | translate) : ('core.notify.show-more' | translate: { count: restCount }) }}\r\n </button>\r\n }\r\n }\r\n </div>\r\n\r\n @if (data.actionLabel) {\r\n <div class=\"sd-toast__actions\">\r\n <button\r\n class=\"btn-action\"\r\n [class]=\"'bg-' + data.type + '-light text-' + data.type\"\r\n (click)=\"onActionClick()\">\r\n {{ data.actionLabel }}\r\n </button>\r\n </div>\r\n }\r\n</div>\r\n", styles: [":host{display:flex;width:350px;border-radius:8px;box-shadow:0 4px 12px #00000026;margin-bottom:12px;overflow:hidden;position:relative;font-family:Roboto,sans-serif;pointer-events:auto;animation:sd-toast-enter .3s ease-out}:host(.sd-toast--closing){pointer-events:none;animation:sd-toast-leave .2s ease-in forwards}@keyframes sd-toast-enter{0%{transform:translate(100%);opacity:0}to{transform:translate(0);opacity:1}}@keyframes sd-toast-leave{0%{transform:translate(0);opacity:1}to{transform:translate(100%);opacity:0}}@media(prefers-reduced-motion:reduce){:host,:host(.sd-toast--closing){animation:none}}.sd-toast__bar{width:6px;flex-shrink:0}.sd-toast__icon{padding:12px 0 0 12px;flex-shrink:0}.sd-toast__icon svg{width:24px;height:24px}.sd-toast__content{flex-grow:1;padding:12px;display:flex;flex-direction:column}.sd-toast__header{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:4px}.sd-toast__title{font-size:16px;font-weight:600}.sd-toast__close{background:none;border:none;font-size:16px;cursor:pointer;line-height:1;padding:0;opacity:.5;transition:opacity .2s}.sd-toast__close:hover{opacity:1}.sd-toast__body{font-size:14px;line-height:1.4;word-break:break-word}.sd-toast__actions{display:flex;justify-content:flex-end;margin-top:8px}.msg-list{padding-left:0;list-style:none;margin:0}.toggle-more{background:none;border:none;padding:0;font:inherit;cursor:pointer;font-size:13px;margin-top:4px;font-weight:500;text-align:left}.toggle-more:hover{text-decoration:underline}.toggle-more:focus-visible{outline:2px solid currentColor;outline-offset:2px}.btn-action{border:none;padding:6px 12px;border-radius:4px;font-weight:600;cursor:pointer;font-size:13px;transition:filter .2s}.btn-action:hover{filter:brightness(.95)}\n"] }]
122
+ }, template: "<div class=\"sd-toast__bar\" [class]=\"'bg-' + data.type\"></div>\n\n<div class=\"sd-toast__icon\" [class]=\"'text-' + data.type\">\n @switch (data.type) {\n @case ('success') {\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z\"/></svg>\n }\n @case ('info') {\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z\"/></svg>\n }\n @case ('warning') {\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z\"/></svg>\n }\n @case ('error') {\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z\"/></svg>\n }\n }\n</div>\n\n<div class=\"sd-toast__content\">\n <div class=\"sd-toast__header\">\n <strong class=\"sd-toast__title\">{{ data.title || ('core.notify.type.' + data.type | translate) }}</strong>\n <button class=\"sd-toast__close\" (click)=\"close()\">&times;</button>\n </div>\n\n <div class=\"sd-toast__body\">\n @if (!isMultiMessage) {\n <!-- Text rendering is the default safe path; HTML is opt-in and sanitized. -->\n @if (data.html) {\n <div [innerHTML]=\"sanitizeHtml(singleMessage)\"></div>\n } @else {\n <div>{{ singleMessage }}</div>\n }\n } @else {\n <ul class=\"msg-list\">\n @for (msg of displayMessages; track msg) {\n @if (data.html) {\n <li [innerHTML]=\"sanitizeHtml('- ' + msg)\"></li>\n } @else {\n <li>{{ '- ' + msg }}</li>\n }\n }\n </ul>\n\n @if (hasMore) {\n <button\n type=\"button\"\n class=\"toggle-more btn-link\"\n [class]=\"'text-' + data.type\"\n (click)=\"toggleExpand()\">\n {{ isExpanded() ? ('core.notify.show-less' | translate) : ('core.notify.show-more' | translate: { count: restCount }) }}\n </button>\n }\n }\n </div>\n\n @if (data.actionLabel) {\n <div class=\"sd-toast__actions\">\n <button\n class=\"btn-action\"\n [class]=\"'bg-' + data.type + '-light text-' + data.type\"\n (click)=\"onActionClick()\">\n {{ data.actionLabel }}\n </button>\n </div>\n }\n</div>\n", styles: [":host{display:flex;width:350px;border-radius:8px;box-shadow:0 4px 12px #00000026;margin-bottom:12px;overflow:hidden;position:relative;font-family:Roboto,sans-serif;pointer-events:auto;animation:sd-toast-enter .3s ease-out}:host(.sd-toast--closing){pointer-events:none;animation:sd-toast-leave .2s ease-in forwards}@keyframes sd-toast-enter{0%{transform:translate(100%);opacity:0}to{transform:translate(0);opacity:1}}@keyframes sd-toast-leave{0%{transform:translate(0);opacity:1}to{transform:translate(100%);opacity:0}}@media(prefers-reduced-motion:reduce){:host,:host(.sd-toast--closing){animation:none}}.sd-toast__bar{width:6px;flex-shrink:0}.sd-toast__icon{padding:12px 0 0 12px;flex-shrink:0}.sd-toast__icon svg{width:24px;height:24px}.sd-toast__content{flex-grow:1;padding:12px;display:flex;flex-direction:column}.sd-toast__header{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:4px}.sd-toast__title{font-size:16px;font-weight:600}.sd-toast__close{background:none;border:none;font-size:16px;cursor:pointer;line-height:1;padding:0;opacity:.5;transition:opacity .2s}.sd-toast__close:hover{opacity:1}.sd-toast__body{font-size:14px;line-height:1.4;word-break:break-word}.sd-toast__actions{display:flex;justify-content:flex-end;margin-top:8px}.msg-list{padding-left:0;list-style:none;margin:0}.toggle-more{background:none;border:none;padding:0;font:inherit;cursor:pointer;font-size:13px;margin-top:4px;font-weight:500;text-align:left}.toggle-more:hover{text-decoration:underline}.toggle-more:focus-visible{outline:2px solid currentColor;outline-offset:2px}.btn-action{border:none;padding:6px 12px;border-radius:4px;font-weight:600;cursor:pointer;font-size:13px;transition:filter .2s}.btn-action:hover{filter:brightness(.95)}\n"] }]
123
123
  }], ctorParameters: () => [{ type: SdNotifyService }, { type: i2.DomSanitizer }], propDecorators: { data: [{
124
124
  type: Input,
125
125
  args: [{ required: true }]