@sd-angular/core 19.0.12 → 19.0.14

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 (167) hide show
  1. package/README.md +712 -712
  2. package/assets/STYLE-GUIDE.md +601 -601
  3. package/assets/images/coming-soon.svg +22 -22
  4. package/assets/images/data-empty.svg +20 -20
  5. package/assets/images/expired.svg +21 -21
  6. package/assets/images/file-error.svg +27 -27
  7. package/assets/images/filter-empty.svg +19 -19
  8. package/assets/images/filter-required.svg +20 -20
  9. package/assets/images/forbidden.svg +14 -14
  10. package/assets/images/image-error.svg +26 -26
  11. package/assets/images/maintenance.svg +22 -22
  12. package/assets/images/not-found.svg +19 -19
  13. package/assets/images/offline.svg +19 -19
  14. package/assets/images/submitted.svg +17 -17
  15. package/assets/images/success.svg +17 -17
  16. package/assets/images/unauthorized.svg +21 -21
  17. package/assets/images/unknown-error.svg +17 -17
  18. package/assets/scss/ckeditor5.scss +88 -88
  19. package/assets/scss/core/_inline-edit.scss +105 -105
  20. package/assets/scss/core/color.scss +73 -73
  21. package/assets/scss/core/form.scss +317 -317
  22. package/assets/scss/core/image.scss +35 -35
  23. package/assets/scss/core/utilities/_base.scss +333 -333
  24. package/assets/scss/core/utilities/_border.scss +22 -22
  25. package/assets/scss/core/utilities/_display.scss +10 -10
  26. package/assets/scss/core/utilities/_elevation.scss +80 -80
  27. package/assets/scss/core/utilities/_flexbox.scss +54 -54
  28. package/assets/scss/core/utilities/_gap.scss +9 -9
  29. package/assets/scss/core/utilities/_index.scss +17 -17
  30. package/assets/scss/core/utilities/_misc.scss +20 -20
  31. package/assets/scss/core/utilities/_overflow.scss +9 -9
  32. package/assets/scss/core/utilities/_position.scss +8 -8
  33. package/assets/scss/core/utilities/_sizing.scss +28 -28
  34. package/assets/scss/core/utilities/_spacing.scss +31 -31
  35. package/assets/scss/core/utilities/_typography.scss +99 -99
  36. package/assets/scss/sd-core.scss +16 -16
  37. package/assets/scss/themes/default.scss +45 -45
  38. package/assets/scss/themes/material-theme.scss +101 -101
  39. package/components/preview/src/preview-pdf/pdf-worker-inline.generated.d.ts +7 -0
  40. package/components/table/src/services/table-export/table-export.service.d.ts +3 -1
  41. package/components/table/src/table.component.d.ts +1 -1
  42. package/fesm2022/sd-angular-core-components-anchor.mjs +6 -6
  43. package/fesm2022/sd-angular-core-components-anchor.mjs.map +1 -1
  44. package/fesm2022/sd-angular-core-components-autoid-inspector.mjs +2 -2
  45. package/fesm2022/sd-angular-core-components-autoid-inspector.mjs.map +1 -1
  46. package/fesm2022/sd-angular-core-components-badge.mjs +2 -2
  47. package/fesm2022/sd-angular-core-components-badge.mjs.map +1 -1
  48. package/fesm2022/sd-angular-core-components-base.mjs.map +1 -1
  49. package/fesm2022/sd-angular-core-components-button.mjs +2 -2
  50. package/fesm2022/sd-angular-core-components-button.mjs.map +1 -1
  51. package/fesm2022/sd-angular-core-components-chart.mjs +40 -40
  52. package/fesm2022/sd-angular-core-components-chart.mjs.map +1 -1
  53. package/fesm2022/sd-angular-core-components-ckeditor-styles.mjs.map +1 -1
  54. package/fesm2022/sd-angular-core-components-code-editor.mjs +2 -2
  55. package/fesm2022/sd-angular-core-components-code-editor.mjs.map +1 -1
  56. package/fesm2022/sd-angular-core-components-document-builder.mjs +77 -77
  57. package/fesm2022/sd-angular-core-components-document-builder.mjs.map +1 -1
  58. package/fesm2022/sd-angular-core-components-editor.mjs +2 -2
  59. package/fesm2022/sd-angular-core-components-editor.mjs.map +1 -1
  60. package/fesm2022/sd-angular-core-components-form-generic.mjs +106 -106
  61. package/fesm2022/sd-angular-core-components-form-generic.mjs.map +1 -1
  62. package/fesm2022/sd-angular-core-components-history.mjs +2 -2
  63. package/fesm2022/sd-angular-core-components-history.mjs.map +1 -1
  64. package/fesm2022/sd-angular-core-components-import-excel.mjs +2 -2
  65. package/fesm2022/sd-angular-core-components-import-excel.mjs.map +1 -1
  66. package/fesm2022/sd-angular-core-components-inform.mjs.map +1 -1
  67. package/fesm2022/sd-angular-core-components-mini-editor.mjs +2 -2
  68. package/fesm2022/sd-angular-core-components-mini-editor.mjs.map +1 -1
  69. package/fesm2022/sd-angular-core-components-modal-resizable.mjs +2 -2
  70. package/fesm2022/sd-angular-core-components-modal-resizable.mjs.map +1 -1
  71. package/fesm2022/sd-angular-core-components-modal.mjs +2 -2
  72. package/fesm2022/sd-angular-core-components-modal.mjs.map +1 -1
  73. package/fesm2022/sd-angular-core-components-operator.mjs +2 -2
  74. package/fesm2022/sd-angular-core-components-operator.mjs.map +1 -1
  75. package/fesm2022/sd-angular-core-components-org-chart.mjs +2 -2
  76. package/fesm2022/sd-angular-core-components-org-chart.mjs.map +1 -1
  77. package/fesm2022/sd-angular-core-components-preview.mjs +32 -6
  78. package/fesm2022/sd-angular-core-components-preview.mjs.map +1 -1
  79. package/fesm2022/sd-angular-core-components-query-bar.mjs +10 -10
  80. package/fesm2022/sd-angular-core-components-query-bar.mjs.map +1 -1
  81. package/fesm2022/sd-angular-core-components-query-builder.mjs +2 -2
  82. package/fesm2022/sd-angular-core-components-query-builder.mjs.map +1 -1
  83. package/fesm2022/sd-angular-core-components-section.mjs +4 -4
  84. package/fesm2022/sd-angular-core-components-section.mjs.map +1 -1
  85. package/fesm2022/sd-angular-core-components-side-drawer.mjs +2 -2
  86. package/fesm2022/sd-angular-core-components-side-drawer.mjs.map +1 -1
  87. package/fesm2022/sd-angular-core-components-stepper.mjs +2 -2
  88. package/fesm2022/sd-angular-core-components-stepper.mjs.map +1 -1
  89. package/fesm2022/sd-angular-core-components-tab-router.mjs +6 -6
  90. package/fesm2022/sd-angular-core-components-tab-router.mjs.map +1 -1
  91. package/fesm2022/sd-angular-core-components-tab.mjs +2 -2
  92. package/fesm2022/sd-angular-core-components-tab.mjs.map +1 -1
  93. package/fesm2022/sd-angular-core-components-table.mjs +32 -17
  94. package/fesm2022/sd-angular-core-components-table.mjs.map +1 -1
  95. package/fesm2022/sd-angular-core-components-upload-file.mjs +4 -4
  96. package/fesm2022/sd-angular-core-components-upload-file.mjs.map +1 -1
  97. package/fesm2022/sd-angular-core-components-view.mjs +2 -2
  98. package/fesm2022/sd-angular-core-components-view.mjs.map +1 -1
  99. package/fesm2022/sd-angular-core-configurations.mjs.map +1 -1
  100. package/fesm2022/sd-angular-core-directives.mjs +20 -20
  101. package/fesm2022/sd-angular-core-directives.mjs.map +1 -1
  102. package/fesm2022/sd-angular-core-forms-autocomplete.mjs +2 -2
  103. package/fesm2022/sd-angular-core-forms-autocomplete.mjs.map +1 -1
  104. package/fesm2022/sd-angular-core-forms-checkbox.mjs +2 -2
  105. package/fesm2022/sd-angular-core-forms-checkbox.mjs.map +1 -1
  106. package/fesm2022/sd-angular-core-forms-chip-calendar.mjs +2 -2
  107. package/fesm2022/sd-angular-core-forms-chip-calendar.mjs.map +1 -1
  108. package/fesm2022/sd-angular-core-forms-chip.mjs +2 -2
  109. package/fesm2022/sd-angular-core-forms-chip.mjs.map +1 -1
  110. package/fesm2022/sd-angular-core-forms-date-range.mjs +2 -2
  111. package/fesm2022/sd-angular-core-forms-date-range.mjs.map +1 -1
  112. package/fesm2022/sd-angular-core-forms-date.mjs +114 -35
  113. package/fesm2022/sd-angular-core-forms-date.mjs.map +1 -1
  114. package/fesm2022/sd-angular-core-forms-datetime.mjs +6 -6
  115. package/fesm2022/sd-angular-core-forms-datetime.mjs.map +1 -1
  116. package/fesm2022/sd-angular-core-forms-directives.mjs.map +1 -1
  117. package/fesm2022/sd-angular-core-forms-inline-text.mjs +2 -2
  118. package/fesm2022/sd-angular-core-forms-inline-text.mjs.map +1 -1
  119. package/fesm2022/sd-angular-core-forms-input-color.mjs +2 -2
  120. package/fesm2022/sd-angular-core-forms-input-color.mjs.map +1 -1
  121. package/fesm2022/sd-angular-core-forms-input-number.mjs.map +1 -1
  122. package/fesm2022/sd-angular-core-forms-input.mjs +2 -2
  123. package/fesm2022/sd-angular-core-forms-input.mjs.map +1 -1
  124. package/fesm2022/sd-angular-core-forms-label.mjs +2 -2
  125. package/fesm2022/sd-angular-core-forms-label.mjs.map +1 -1
  126. package/fesm2022/sd-angular-core-forms-models.mjs.map +1 -1
  127. package/fesm2022/sd-angular-core-forms-radio.mjs +2 -2
  128. package/fesm2022/sd-angular-core-forms-radio.mjs.map +1 -1
  129. package/fesm2022/sd-angular-core-forms-select.mjs +2 -2
  130. package/fesm2022/sd-angular-core-forms-select.mjs.map +1 -1
  131. package/fesm2022/sd-angular-core-forms-switch.mjs +2 -2
  132. package/fesm2022/sd-angular-core-forms-switch.mjs.map +1 -1
  133. package/fesm2022/sd-angular-core-forms-textarea.mjs +2 -2
  134. package/fesm2022/sd-angular-core-forms-textarea.mjs.map +1 -1
  135. package/fesm2022/sd-angular-core-handlers.mjs.map +1 -1
  136. package/fesm2022/sd-angular-core-i18n.mjs +20 -0
  137. package/fesm2022/sd-angular-core-i18n.mjs.map +1 -1
  138. package/fesm2022/sd-angular-core-interceptors.mjs.map +1 -1
  139. package/fesm2022/sd-angular-core-modules-auth.mjs.map +1 -1
  140. package/fesm2022/sd-angular-core-modules-authom.mjs.map +1 -1
  141. package/fesm2022/sd-angular-core-modules-keycloak.mjs.map +1 -1
  142. package/fesm2022/sd-angular-core-modules-layout.mjs +145 -46
  143. package/fesm2022/sd-angular-core-modules-layout.mjs.map +1 -1
  144. package/fesm2022/sd-angular-core-modules-permission.mjs.map +1 -1
  145. package/fesm2022/sd-angular-core-pipes.mjs.map +1 -1
  146. package/fesm2022/sd-angular-core-services-api.mjs.map +1 -1
  147. package/fesm2022/sd-angular-core-services-cache.mjs.map +1 -1
  148. package/fesm2022/sd-angular-core-services-confirm.mjs +2 -2
  149. package/fesm2022/sd-angular-core-services-confirm.mjs.map +1 -1
  150. package/fesm2022/sd-angular-core-services-docx.mjs.map +1 -1
  151. package/fesm2022/sd-angular-core-services-excel.mjs.map +1 -1
  152. package/fesm2022/sd-angular-core-services-license.mjs.map +1 -1
  153. package/fesm2022/sd-angular-core-services-loading.mjs +5 -5
  154. package/fesm2022/sd-angular-core-services-loading.mjs.map +1 -1
  155. package/fesm2022/sd-angular-core-services-notify.mjs +12 -12
  156. package/fesm2022/sd-angular-core-services-notify.mjs.map +1 -1
  157. package/fesm2022/sd-angular-core-services-storage.mjs.map +1 -1
  158. package/fesm2022/sd-angular-core-utilities-data-state.mjs.map +1 -1
  159. package/fesm2022/sd-angular-core-utilities-extensions.mjs.map +1 -1
  160. package/forms/date/src/date.component.d.ts +9 -1
  161. package/i18n/src/en.d.ts +4 -0
  162. package/modules/layout/components/sidebar-v1/main.component.d.ts +1 -0
  163. package/modules/layout/index.d.ts +1 -0
  164. package/modules/layout/utils/index.d.ts +1 -0
  165. package/modules/layout/utils/tab-name.util.d.ts +8 -0
  166. package/package.json +41 -41
  167. package/sd-angular-core-19.0.12.tgz +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"sd-angular-core-services-docx.mjs","sources":["../../../projects/sd-angular/services/docx/src/lib/pandoc-core.ts","../../../projects/sd-angular/services/docx/src/lib/docx.service.ts","../../../projects/sd-angular/services/docx/sd-angular-core-services-docx.ts"],"sourcesContent":["/* Pandoc WASM core logic — adapted from pandoc-wasm/src/core.js\r\n *\r\n * This file is a local copy of the environment-agnostic pandoc core.\r\n * It imports @bjorn3/browser_wasi_shim directly, avoiding the pandoc-wasm\r\n * package entry points which use top-level await (incompatible with\r\n * Angular's esbuild/Vite build pipeline).\r\n *\r\n * Source: https://github.com/pandoc/pandoc-wasm (GPL-2.0-or-later)\r\n */\r\n\r\n// @ts-nocheck\r\nimport {\r\n ConsoleStdout,\r\n File,\r\n OpenFile,\r\n PreopenDirectory,\r\n WASI,\r\n} from '@bjorn3/browser_wasi_shim';\r\n\r\nexport interface PandocConvertResult {\r\n stdout: string;\r\n stderr: string;\r\n warnings: any[];\r\n files: Record<string, any>;\r\n mediaFiles: Record<string, any>;\r\n}\r\n\r\nexport interface PandocInstance {\r\n convert(\r\n options: Record<string, any>,\r\n stdin: string | null,\r\n files: Record<string, Blob | string>\r\n ): Promise<PandocConvertResult>;\r\n}\r\n\r\nexport function createPandocInstance(wasmBinary: ArrayBuffer): Promise<PandocInstance> {\r\n const args = ['pandoc.wasm', '+RTS', '-H64m', '-RTS'];\r\n const env: string[] = [];\r\n const fileSystem = new Map();\r\n const fds = [\r\n new OpenFile(new File(new Uint8Array(), { readonly: true })),\r\n ConsoleStdout.lineBuffered(() => undefined),\r\n ConsoleStdout.lineBuffered((msg: string) => console.warn(`[WASI stderr] ${msg}`)),\r\n new PreopenDirectory('/', fileSystem),\r\n ];\r\n const options = { debug: false };\r\n const wasi = new WASI(args, env, fds, options);\r\n\r\n return WebAssembly.instantiate(wasmBinary, {\r\n wasi_snapshot_preview1: wasi.wasiImport,\r\n }).then(({ instance }: any) => {\r\n wasi.initialize(instance);\r\n instance.exports.__wasm_call_ctors();\r\n\r\n function memory_data_view() {\r\n return new DataView(instance.exports.memory.buffer);\r\n }\r\n\r\n const argc_ptr = instance.exports.malloc(4);\r\n memory_data_view().setUint32(argc_ptr, args.length, true);\r\n const argv = instance.exports.malloc(4 * (args.length + 1));\r\n for (let i = 0; i < args.length; ++i) {\r\n const arg = instance.exports.malloc(args[i].length + 1);\r\n new TextEncoder().encodeInto(\r\n args[i],\r\n new Uint8Array(instance.exports.memory.buffer, arg, args[i].length)\r\n );\r\n memory_data_view().setUint8(arg + args[i].length, 0);\r\n memory_data_view().setUint32(argv + 4 * i, arg, true);\r\n }\r\n memory_data_view().setUint32(argv + 4 * args.length, 0, true);\r\n const argv_ptr = instance.exports.malloc(4);\r\n memory_data_view().setUint32(argv_ptr, argv, true);\r\n\r\n instance.exports.hs_init_with_rtsopts(argc_ptr, argv_ptr);\r\n\r\n async function addFile(filename: string, data: Blob | string, readonly: boolean) {\r\n let uint8Array: Uint8Array;\r\n if (typeof data === 'string') {\r\n uint8Array = new TextEncoder().encode(data);\r\n } else {\r\n const buffer = await data.arrayBuffer();\r\n uint8Array = new Uint8Array(buffer);\r\n }\r\n const file = new File(uint8Array, { readonly });\r\n fileSystem.set(filename, file);\r\n }\r\n\r\n async function convert(\r\n options: Record<string, any>,\r\n stdin: string | null,\r\n files: Record<string, Blob | string>\r\n ): Promise<PandocConvertResult> {\r\n const opts_str = JSON.stringify(options);\r\n const encoded = new TextEncoder().encode(opts_str);\r\n const opts_ptr = instance.exports.malloc(encoded.length);\r\n new TextEncoder().encodeInto(\r\n opts_str,\r\n new Uint8Array(instance.exports.memory.buffer, opts_ptr, encoded.length)\r\n );\r\n\r\n files = { ...files };\r\n\r\n fileSystem.clear();\r\n const in_file = new File(new Uint8Array(), { readonly: true });\r\n const out_file = new File(new Uint8Array(), { readonly: false });\r\n const err_file = new File(new Uint8Array(), { readonly: false });\r\n const warnings_file = new File(new Uint8Array(), { readonly: false });\r\n fileSystem.set('stdin', in_file);\r\n fileSystem.set('stdout', out_file);\r\n fileSystem.set('stderr', err_file);\r\n fileSystem.set('warnings', warnings_file);\r\n\r\n const knownFiles = new Set(['stdin', 'stdout', 'stderr', 'warnings']);\r\n\r\n for (const filename in files) {\r\n await addFile(filename, files[filename], true);\r\n knownFiles.add(filename);\r\n }\r\n\r\n const outputFileName = options['output-file'] || null;\r\n const extractMediaPath = options['extract-media'] || null;\r\n\r\n if (outputFileName) {\r\n await addFile(outputFileName, new Blob(), false);\r\n knownFiles.add(outputFileName);\r\n }\r\n\r\n if (extractMediaPath) {\r\n await addFile(extractMediaPath, new Blob(), false);\r\n if (extractMediaPath.endsWith('.zip')) {\r\n knownFiles.add(extractMediaPath);\r\n }\r\n }\r\n\r\n if (stdin) {\r\n in_file.data = new TextEncoder().encode(stdin);\r\n }\r\n\r\n instance.exports.convert(opts_ptr, encoded.length);\r\n\r\n if (options['output-file']) {\r\n const outputFile = fileSystem.get(options['output-file']);\r\n if (outputFile && outputFile.data && outputFile.data.length > 0) {\r\n files[options['output-file']] = new Blob([outputFile.data]);\r\n }\r\n }\r\n\r\n if (options['extract-media']) {\r\n const mediaFile = fileSystem.get(options['extract-media']);\r\n if (mediaFile && mediaFile.data && mediaFile.data.length > 0) {\r\n files[options['extract-media']] = new Blob([mediaFile.data], { type: 'application/zip' });\r\n }\r\n }\r\n\r\n const mediaFiles: Record<string, Blob> = {};\r\n for (const [name, fileData] of fileSystem.entries()) {\r\n if (!knownFiles.has(name) && fileData && fileData.data && fileData.data.length > 0) {\r\n const blob = new Blob([fileData.data]);\r\n files[name] = blob;\r\n if (name !== outputFileName && name !== extractMediaPath) {\r\n mediaFiles[name] = blob;\r\n }\r\n }\r\n }\r\n\r\n const rawWarnings = new TextDecoder('utf-8', { fatal: true }).decode(warnings_file.data);\r\n let warnings: any[] = [];\r\n if (rawWarnings) {\r\n try {\r\n warnings = JSON.parse(rawWarnings);\r\n } catch (e) {\r\n console.warn('Failed to parse warnings:', e);\r\n }\r\n }\r\n\r\n return {\r\n stdout: new TextDecoder('utf-8', { fatal: true }).decode(out_file.data),\r\n stderr: new TextDecoder('utf-8', { fatal: true }).decode(err_file.data),\r\n warnings,\r\n files,\r\n mediaFiles,\r\n };\r\n }\r\n\r\n return { convert } as PandocInstance;\r\n });\r\n}\r\n","import { inject, Injectable } from '@angular/core';\r\nimport { SdNotifyService } from '@sd-angular/core/services/notify';\r\nimport { SdLoadingService } from '@sd-angular/core/services/loading';\r\nimport { I18nService } from '@sd-angular/core/i18n';\r\n\r\nimport { SdDocxConvertOptions, SdDocxConvertResult } from './docx.model';\r\nimport { createPandocInstance, PandocInstance } from './pandoc-core';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class SdDocxService {\r\n readonly #i18n = inject(I18nService);\r\n\r\n readonly #DEFAULT_MAX_SIZE_MB = 50;\r\n readonly #VALID_EXTENSIONS = ['.doc', '.docx'];\r\n\r\n readonly #PANDOC_WASM_URL = 'https://pandoc.github.io/pandoc-wasm/pandoc.wasm';\r\n\r\n #fileInput: HTMLInputElement | null = null;\r\n #pandocInstance: PandocInstance | null = null;\r\n\r\n constructor(\r\n private notifyService: SdNotifyService,\r\n private loadingService: SdLoadingService\r\n ) {}\r\n\r\n async open(options?: SdDocxConvertOptions): Promise<SdDocxConvertResult | null> {\r\n return new Promise(resolve => {\r\n this.#createFileInput();\r\n if (!this.#fileInput) {\r\n resolve(null);\r\n return;\r\n }\r\n\r\n const handleChange = async (event: Event) => {\r\n const input = event.target as HTMLInputElement;\r\n const file = input.files?.[0];\r\n\r\n if (!file) {\r\n resolve(null);\r\n return;\r\n }\r\n\r\n this.loadingService.start();\r\n try {\r\n const result = await this.convertToHtml(file, options);\r\n resolve(result);\r\n } catch (error) {\r\n console.error('[SdDocxService] DocX conversion error:', error);\r\n this.notifyService.error(this.#i18n.t('core.docx.convert-error'));\r\n resolve(null);\r\n } finally {\r\n input.value = '';\r\n input.removeEventListener('change', handleChange);\r\n this.loadingService.stop();\r\n }\r\n };\r\n\r\n this.#fileInput.addEventListener('change', handleChange, { once: true });\r\n this.#fileInput.click();\r\n });\r\n }\r\n\r\n #createFileInput(): void {\r\n if (this.#fileInput) {\r\n return;\r\n }\r\n\r\n this.#fileInput = document.createElement('input');\r\n this.#fileInput.type = 'file';\r\n this.#fileInput.accept = '.doc,.docx';\r\n this.#fileInput.style.display = 'none';\r\n document.body.appendChild(this.#fileInput);\r\n }\r\n\r\n async #getPandocInstance(): Promise<PandocInstance> {\r\n if (this.#pandocInstance) {\r\n return this.#pandocInstance;\r\n }\r\n\r\n const wasmResponse = await fetch(this.#PANDOC_WASM_URL);\r\n if (!wasmResponse.ok) {\r\n throw new Error(`Failed to fetch pandoc.wasm: ${wasmResponse.status} ${wasmResponse.statusText}`);\r\n }\r\n const wasmBinary = await wasmResponse.arrayBuffer();\r\n this.#pandocInstance = await createPandocInstance(wasmBinary);\r\n return this.#pandocInstance;\r\n }\r\n\r\n async convertToHtml(input: File | Blob | ArrayBuffer, options?: SdDocxConvertOptions): Promise<SdDocxConvertResult | null> {\r\n const opts = {\r\n validateFormat: true,\r\n validateSize: true,\r\n maxSizeInMb: this.#DEFAULT_MAX_SIZE_MB,\r\n ...options,\r\n };\r\n\r\n try {\r\n let fileName: string | undefined;\r\n let fileSize: number | undefined;\r\n let blob: Blob;\r\n\r\n if (input instanceof File) {\r\n fileName = input.name;\r\n fileSize = input.size;\r\n blob = input;\r\n } else if (input instanceof Blob) {\r\n fileSize = input.size;\r\n blob = input;\r\n } else {\r\n blob = new Blob([input], {\r\n type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\r\n });\r\n }\r\n\r\n if (opts.validateFormat && fileName) {\r\n if (!this.#isValidFormat(fileName)) {\r\n this.notifyService.error(this.#i18n.t('core.docx.invalid-format'));\r\n return null;\r\n }\r\n }\r\n\r\n if (opts.validateSize && fileSize !== undefined) {\r\n const maxSizeInBytes = opts.maxSizeInMb! * 1024 * 1024;\r\n if (fileSize > maxSizeInBytes) {\r\n this.notifyService.error(this.#i18n.t('core.docx.size-exceeded'));\r\n return null;\r\n }\r\n }\r\n\r\n const pandoc = await this.#getPandocInstance();\r\n\r\n const pandocOpts: Record<string, any> = {\r\n from: 'docx',\r\n to: 'html',\r\n 'input-files': ['document.docx'],\r\n standalone: true,\r\n 'embed-resources': true,\r\n };\r\n\r\n const result = await pandoc.convert(pandocOpts, null, { 'document.docx': blob });\r\n\r\n return {\r\n html: result.stdout,\r\n messages: result.warnings.map((w: any) => String(w)),\r\n };\r\n } catch (error) {\r\n console.error('[SdDocxService] DocX conversion error:', error);\r\n this.notifyService.error(this.#i18n.t('core.docx.convert-error'));\r\n return null;\r\n }\r\n }\r\n\r\n async convertToHtmlString(input: File | Blob | ArrayBuffer, options?: SdDocxConvertOptions): Promise<string | null> {\r\n const result = await this.convertToHtml(input, options);\r\n return result?.html ?? null;\r\n }\r\n\r\n #isValidFormat(fileName: string): boolean {\r\n const lowerCaseName = fileName.toLowerCase();\r\n return this.#VALID_EXTENSIONS.some(ext => lowerCaseName.endsWith(ext));\r\n }\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["File"],"mappings":"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"}
1
+ {"version":3,"file":"sd-angular-core-services-docx.mjs","sources":["../../../projects/sd-angular/services/docx/src/lib/pandoc-core.ts","../../../projects/sd-angular/services/docx/src/lib/docx.service.ts","../../../projects/sd-angular/services/docx/sd-angular-core-services-docx.ts"],"sourcesContent":["/* Pandoc WASM core logic — adapted from pandoc-wasm/src/core.js\n *\n * This file is a local copy of the environment-agnostic pandoc core.\n * It imports @bjorn3/browser_wasi_shim directly, avoiding the pandoc-wasm\n * package entry points which use top-level await (incompatible with\n * Angular's esbuild/Vite build pipeline).\n *\n * Source: https://github.com/pandoc/pandoc-wasm (GPL-2.0-or-later)\n */\n\n// @ts-nocheck\nimport {\n ConsoleStdout,\n File,\n OpenFile,\n PreopenDirectory,\n WASI,\n} from '@bjorn3/browser_wasi_shim';\n\nexport interface PandocConvertResult {\n stdout: string;\n stderr: string;\n warnings: any[];\n files: Record<string, any>;\n mediaFiles: Record<string, any>;\n}\n\nexport interface PandocInstance {\n convert(\n options: Record<string, any>,\n stdin: string | null,\n files: Record<string, Blob | string>\n ): Promise<PandocConvertResult>;\n}\n\nexport function createPandocInstance(wasmBinary: ArrayBuffer): Promise<PandocInstance> {\n const args = ['pandoc.wasm', '+RTS', '-H64m', '-RTS'];\n const env: string[] = [];\n const fileSystem = new Map();\n const fds = [\n new OpenFile(new File(new Uint8Array(), { readonly: true })),\n ConsoleStdout.lineBuffered(() => undefined),\n ConsoleStdout.lineBuffered((msg: string) => console.warn(`[WASI stderr] ${msg}`)),\n new PreopenDirectory('/', fileSystem),\n ];\n const options = { debug: false };\n const wasi = new WASI(args, env, fds, options);\n\n return WebAssembly.instantiate(wasmBinary, {\n wasi_snapshot_preview1: wasi.wasiImport,\n }).then(({ instance }: any) => {\n wasi.initialize(instance);\n instance.exports.__wasm_call_ctors();\n\n function memory_data_view() {\n return new DataView(instance.exports.memory.buffer);\n }\n\n const argc_ptr = instance.exports.malloc(4);\n memory_data_view().setUint32(argc_ptr, args.length, true);\n const argv = instance.exports.malloc(4 * (args.length + 1));\n for (let i = 0; i < args.length; ++i) {\n const arg = instance.exports.malloc(args[i].length + 1);\n new TextEncoder().encodeInto(\n args[i],\n new Uint8Array(instance.exports.memory.buffer, arg, args[i].length)\n );\n memory_data_view().setUint8(arg + args[i].length, 0);\n memory_data_view().setUint32(argv + 4 * i, arg, true);\n }\n memory_data_view().setUint32(argv + 4 * args.length, 0, true);\n const argv_ptr = instance.exports.malloc(4);\n memory_data_view().setUint32(argv_ptr, argv, true);\n\n instance.exports.hs_init_with_rtsopts(argc_ptr, argv_ptr);\n\n async function addFile(filename: string, data: Blob | string, readonly: boolean) {\n let uint8Array: Uint8Array;\n if (typeof data === 'string') {\n uint8Array = new TextEncoder().encode(data);\n } else {\n const buffer = await data.arrayBuffer();\n uint8Array = new Uint8Array(buffer);\n }\n const file = new File(uint8Array, { readonly });\n fileSystem.set(filename, file);\n }\n\n async function convert(\n options: Record<string, any>,\n stdin: string | null,\n files: Record<string, Blob | string>\n ): Promise<PandocConvertResult> {\n const opts_str = JSON.stringify(options);\n const encoded = new TextEncoder().encode(opts_str);\n const opts_ptr = instance.exports.malloc(encoded.length);\n new TextEncoder().encodeInto(\n opts_str,\n new Uint8Array(instance.exports.memory.buffer, opts_ptr, encoded.length)\n );\n\n files = { ...files };\n\n fileSystem.clear();\n const in_file = new File(new Uint8Array(), { readonly: true });\n const out_file = new File(new Uint8Array(), { readonly: false });\n const err_file = new File(new Uint8Array(), { readonly: false });\n const warnings_file = new File(new Uint8Array(), { readonly: false });\n fileSystem.set('stdin', in_file);\n fileSystem.set('stdout', out_file);\n fileSystem.set('stderr', err_file);\n fileSystem.set('warnings', warnings_file);\n\n const knownFiles = new Set(['stdin', 'stdout', 'stderr', 'warnings']);\n\n for (const filename in files) {\n await addFile(filename, files[filename], true);\n knownFiles.add(filename);\n }\n\n const outputFileName = options['output-file'] || null;\n const extractMediaPath = options['extract-media'] || null;\n\n if (outputFileName) {\n await addFile(outputFileName, new Blob(), false);\n knownFiles.add(outputFileName);\n }\n\n if (extractMediaPath) {\n await addFile(extractMediaPath, new Blob(), false);\n if (extractMediaPath.endsWith('.zip')) {\n knownFiles.add(extractMediaPath);\n }\n }\n\n if (stdin) {\n in_file.data = new TextEncoder().encode(stdin);\n }\n\n instance.exports.convert(opts_ptr, encoded.length);\n\n if (options['output-file']) {\n const outputFile = fileSystem.get(options['output-file']);\n if (outputFile && outputFile.data && outputFile.data.length > 0) {\n files[options['output-file']] = new Blob([outputFile.data]);\n }\n }\n\n if (options['extract-media']) {\n const mediaFile = fileSystem.get(options['extract-media']);\n if (mediaFile && mediaFile.data && mediaFile.data.length > 0) {\n files[options['extract-media']] = new Blob([mediaFile.data], { type: 'application/zip' });\n }\n }\n\n const mediaFiles: Record<string, Blob> = {};\n for (const [name, fileData] of fileSystem.entries()) {\n if (!knownFiles.has(name) && fileData && fileData.data && fileData.data.length > 0) {\n const blob = new Blob([fileData.data]);\n files[name] = blob;\n if (name !== outputFileName && name !== extractMediaPath) {\n mediaFiles[name] = blob;\n }\n }\n }\n\n const rawWarnings = new TextDecoder('utf-8', { fatal: true }).decode(warnings_file.data);\n let warnings: any[] = [];\n if (rawWarnings) {\n try {\n warnings = JSON.parse(rawWarnings);\n } catch (e) {\n console.warn('Failed to parse warnings:', e);\n }\n }\n\n return {\n stdout: new TextDecoder('utf-8', { fatal: true }).decode(out_file.data),\n stderr: new TextDecoder('utf-8', { fatal: true }).decode(err_file.data),\n warnings,\n files,\n mediaFiles,\n };\n }\n\n return { convert } as PandocInstance;\n });\n}\n","import { inject, Injectable } from '@angular/core';\nimport { SdNotifyService } from '@sd-angular/core/services/notify';\nimport { SdLoadingService } from '@sd-angular/core/services/loading';\nimport { I18nService } from '@sd-angular/core/i18n';\n\nimport { SdDocxConvertOptions, SdDocxConvertResult } from './docx.model';\nimport { createPandocInstance, PandocInstance } from './pandoc-core';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class SdDocxService {\n readonly #i18n = inject(I18nService);\n\n readonly #DEFAULT_MAX_SIZE_MB = 50;\n readonly #VALID_EXTENSIONS = ['.doc', '.docx'];\n\n readonly #PANDOC_WASM_URL = 'https://pandoc.github.io/pandoc-wasm/pandoc.wasm';\n\n #fileInput: HTMLInputElement | null = null;\n #pandocInstance: PandocInstance | null = null;\n\n constructor(\n private notifyService: SdNotifyService,\n private loadingService: SdLoadingService\n ) {}\n\n async open(options?: SdDocxConvertOptions): Promise<SdDocxConvertResult | null> {\n return new Promise(resolve => {\n this.#createFileInput();\n if (!this.#fileInput) {\n resolve(null);\n return;\n }\n\n const handleChange = async (event: Event) => {\n const input = event.target as HTMLInputElement;\n const file = input.files?.[0];\n\n if (!file) {\n resolve(null);\n return;\n }\n\n this.loadingService.start();\n try {\n const result = await this.convertToHtml(file, options);\n resolve(result);\n } catch (error) {\n console.error('[SdDocxService] DocX conversion error:', error);\n this.notifyService.error(this.#i18n.t('core.docx.convert-error'));\n resolve(null);\n } finally {\n input.value = '';\n input.removeEventListener('change', handleChange);\n this.loadingService.stop();\n }\n };\n\n this.#fileInput.addEventListener('change', handleChange, { once: true });\n this.#fileInput.click();\n });\n }\n\n #createFileInput(): void {\n if (this.#fileInput) {\n return;\n }\n\n this.#fileInput = document.createElement('input');\n this.#fileInput.type = 'file';\n this.#fileInput.accept = '.doc,.docx';\n this.#fileInput.style.display = 'none';\n document.body.appendChild(this.#fileInput);\n }\n\n async #getPandocInstance(): Promise<PandocInstance> {\n if (this.#pandocInstance) {\n return this.#pandocInstance;\n }\n\n const wasmResponse = await fetch(this.#PANDOC_WASM_URL);\n if (!wasmResponse.ok) {\n throw new Error(`Failed to fetch pandoc.wasm: ${wasmResponse.status} ${wasmResponse.statusText}`);\n }\n const wasmBinary = await wasmResponse.arrayBuffer();\n this.#pandocInstance = await createPandocInstance(wasmBinary);\n return this.#pandocInstance;\n }\n\n async convertToHtml(input: File | Blob | ArrayBuffer, options?: SdDocxConvertOptions): Promise<SdDocxConvertResult | null> {\n const opts = {\n validateFormat: true,\n validateSize: true,\n maxSizeInMb: this.#DEFAULT_MAX_SIZE_MB,\n ...options,\n };\n\n try {\n let fileName: string | undefined;\n let fileSize: number | undefined;\n let blob: Blob;\n\n if (input instanceof File) {\n fileName = input.name;\n fileSize = input.size;\n blob = input;\n } else if (input instanceof Blob) {\n fileSize = input.size;\n blob = input;\n } else {\n blob = new Blob([input], {\n type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n });\n }\n\n if (opts.validateFormat && fileName) {\n if (!this.#isValidFormat(fileName)) {\n this.notifyService.error(this.#i18n.t('core.docx.invalid-format'));\n return null;\n }\n }\n\n if (opts.validateSize && fileSize !== undefined) {\n const maxSizeInBytes = opts.maxSizeInMb! * 1024 * 1024;\n if (fileSize > maxSizeInBytes) {\n this.notifyService.error(this.#i18n.t('core.docx.size-exceeded'));\n return null;\n }\n }\n\n const pandoc = await this.#getPandocInstance();\n\n const pandocOpts: Record<string, any> = {\n from: 'docx',\n to: 'html',\n 'input-files': ['document.docx'],\n standalone: true,\n 'embed-resources': true,\n };\n\n const result = await pandoc.convert(pandocOpts, null, { 'document.docx': blob });\n\n return {\n html: result.stdout,\n messages: result.warnings.map((w: any) => String(w)),\n };\n } catch (error) {\n console.error('[SdDocxService] DocX conversion error:', error);\n this.notifyService.error(this.#i18n.t('core.docx.convert-error'));\n return null;\n }\n }\n\n async convertToHtmlString(input: File | Blob | ArrayBuffer, options?: SdDocxConvertOptions): Promise<string | null> {\n const result = await this.convertToHtml(input, options);\n return result?.html ?? null;\n }\n\n #isValidFormat(fileName: string): boolean {\n const lowerCaseName = fileName.toLowerCase();\n return this.#VALID_EXTENSIONS.some(ext => lowerCaseName.endsWith(ext));\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["File"],"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]/;\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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"}
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';\nimport type { CellValue, Style } from 'exceljs';\n// import hash from 'object-hash';\nimport { DateUtilities } from '@sd-angular/core/utilities/extensions';\nimport { BrowserUtilities } from '@sdcorejs/utils/fns';\nimport { I18nService } from '@sd-angular/core/i18n';\nimport { SdExcelExportOption, SdExcelTemplate } from './excel.model';\nimport { neutralizeSpreadsheetFormula } from './spreadsheet-formula-injection.util';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class SdExcelService {\n readonly #i18n = inject(I18nService);\n #fieldStyle: Partial<Style> = {\n border: {\n bottom: { style: 'thin' },\n left: { style: 'thin' },\n right: { style: 'thin' },\n },\n alignment: {\n vertical: 'middle',\n horizontal: 'center',\n wrapText: true,\n },\n font: {\n bold: true,\n size: 11,\n color: { argb: '000000' },\n },\n fill: {\n type: 'pattern',\n pattern: 'solid',\n fgColor: {\n argb: 'FAFAFA',\n },\n },\n };\n #titleColor = 'FFFFFF';\n #titleFgColor = '143180';\n #titleStyle: Partial<Style> = {\n border: {\n bottom: { style: 'thin' },\n left: { style: 'thin' },\n right: { style: 'thin' },\n },\n alignment: {\n vertical: 'middle',\n horizontal: 'center',\n wrapText: true,\n },\n font: {\n bold: true,\n size: 11,\n color: { argb: this.#titleColor },\n },\n fill: {\n type: 'pattern',\n pattern: 'solid',\n fgColor: {\n argb: this.#titleFgColor,\n },\n },\n };\n\n #requiredStyle: Partial<Style> = {\n border: {\n bottom: { style: 'thin' },\n left: { style: 'thin' },\n right: { style: 'thin' },\n },\n alignment: {\n vertical: 'middle',\n horizontal: 'center',\n wrapText: true,\n },\n font: {\n italic: true,\n size: 11,\n color: { argb: 'FFFFFF' },\n },\n fill: {\n type: 'pattern',\n pattern: 'solid',\n fgColor: {\n argb: 'FF1744',\n },\n },\n };\n\n #descriptionStyle: Partial<Style> = {\n border: {\n bottom: { style: 'thin' },\n left: { style: 'thin' },\n right: { style: 'thin' },\n },\n alignment: {\n wrapText: true,\n },\n font: {\n italic: true,\n size: 9,\n color: { argb: '000000' },\n },\n fill: {\n type: 'pattern',\n pattern: 'solid',\n fgColor: {\n argb: 'CFD8DC',\n },\n },\n };\n\n #cellStyle: Partial<Style> = {\n alignment: {\n vertical: 'middle',\n wrapText: true,\n },\n };\n\n // exceljs là CJS module — khi dynamic import từ ESM, named export `Workbook`\n // có thể nằm trên `mod.Workbook` hoặc bị bọc trong `mod.default.Workbook` tuỳ bundler.\n // Helper này chuẩn hoá cả hai trường hợp.\n async #loadWorkbook(): Promise<new () => import('exceljs').Workbook> {\n const mod = (await import('exceljs')) as typeof import('exceljs') & {\n default?: typeof import('exceljs');\n };\n return mod.Workbook ?? mod.default?.Workbook;\n }\n\n generateTemplate = async (template: SdExcelTemplate) => {\n const { fileName, columns, sheets } = template;\n if (!Array.isArray(columns)) {\n throw new Error('Excel template columns must be an array');\n }\n for (const [idx, column] of columns.entries()) {\n if (!column.field) {\n throw new Error(`Column ${idx + 1}: Field is required`);\n }\n if (!column.title) {\n throw new Error(`Column ${idx + 1}: Title is required`);\n }\n }\n const hasDescription = columns.some(column => column.description);\n const Workbook = await this.#loadWorkbook();\n const workbook = new Workbook();\n const firstSheet = workbook.addWorksheet('template'); // Lấy ra sheet đầu tiên\n columns.forEach((column, index) => {\n const { required, fill, fontColor } = column;\n const cellField = firstSheet.getCell(1, index + 1);\n const cellTitle = firstSheet.getCell(2, index + 1);\n const cellDescription = firstSheet.getCell(3, index + 1);\n let width = 120;\n if (column.width && column.width.endsWith('px')) {\n width = +column.width.replace('px', '');\n }\n firstSheet.getColumn(index + 1).width = width / 7 || 20;\n cellField.style = this.#fieldStyle;\n if (required) {\n cellField.style = this.#requiredStyle;\n } else {\n cellField.style = this.#fieldStyle;\n }\n cellTitle.style = {\n ...this.#titleStyle,\n font: {\n ...this.#titleStyle?.font,\n color: {\n ...this.#titleStyle?.font?.color,\n argb: fontColor || this.#titleStyle?.font?.color?.argb,\n },\n },\n fill: {\n type: 'pattern',\n pattern: 'solid',\n fgColor: {\n argb: fill || this.#titleFgColor,\n },\n },\n };\n cellField.value = neutralizeSpreadsheetFormula(column.field);\n cellTitle.value = neutralizeSpreadsheetFormula(column.title);\n if (hasDescription) {\n cellDescription.style = this.#descriptionStyle;\n cellDescription.value = neutralizeSpreadsheetFormula(column.description || '');\n }\n });\n if (sheets?.length) {\n for (const sheet of sheets) {\n if (sheet.name && Array.isArray(sheet.items) && Array.isArray(sheet.headers)) {\n const newSheet = workbook.addWorksheet(sheet.name);\n sheet.headers.forEach((header, index) => {\n newSheet.getColumn(index + 1).width = 30;\n newSheet.getCell(1, index + 1).style = this.#titleStyle;\n newSheet.getCell(1, index + 1).value = neutralizeSpreadsheetFormula(header.value);\n newSheet.getCell(2, index + 1).style = this.#titleStyle;\n newSheet.getCell(2, index + 1).value = neutralizeSpreadsheetFormula(header.display || header.value);\n });\n sheet.items.forEach((item, idx1) => {\n sheet.headers.forEach((header, idx2) => {\n newSheet.getCell(3 + idx1, 1 + idx2).value = neutralizeSpreadsheetFormula(item[header.value]) as CellValue;\n newSheet.getCell(3 + idx1, 1 + idx2).style = this.#cellStyle;\n });\n });\n }\n }\n }\n const file = await workbook.xlsx.writeBuffer();\n BrowserUtilities.downloadBlob(\n new Blob([file], {\n type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n }),\n fileName\n );\n };\n\n exportCSV = async (option: SdExcelExportOption): Promise<void> => {\n const { columns, items, fileName } = option;\n const filename = `${fileName || 'CSV'}_${DateUtilities.toFormat(new Date(), 'yyyy-MM-dd-HH-mm-ss')}.csv`;\n\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.\n // Dấu \" bên trong được nhân đôi theo chuẩn RFC 4180.\n const escape = (v: unknown): string => {\n if (v == null) return '';\n const s = typeof v === 'string' ? neutralizeSpreadsheetFormula(v) : String(v);\n return /[\",\\n\\r]/.test(s) ? `\"${s.replace(/\"/g, '\"\"')}\"` : s;\n };\n\n const headerLine = columns.map(c => escape(c.title)).join(',');\n const dataLines = items.map(item => columns.map(c => escape((item as Record<string, unknown>)[c.field])).join(','));\n\n // Prepend UTF-8 BOM so Excel opens Vietnamese text with the correct encoding.\n // Dùng CRLF vì Excel trên Windows ưu tiên, macOS Excel cũng chấp nhận.\n const csv = '\\uFEFF' + [headerLine, ...dataLines].join('\\r\\n');\n\n BrowserUtilities.downloadBlob(new Blob([csv], { type: 'text/csv;charset=utf-8;' }), filename);\n };\n\n export = async (option: SdExcelExportOption) => {\n const { columns, items, fileName, sheets } = option;\n let hasDescription = false;\n for (const [idx, column] of columns.entries()) {\n if (!column.field) {\n throw new Error(`Column ${idx + 1}: Field is required`);\n }\n if (!column.title) {\n throw new Error(`Column ${idx + 1}: Title is required`);\n }\n if (column.description) {\n hasDescription = true;\n }\n }\n const Workbook = await this.#loadWorkbook();\n const workbook = new Workbook(); //await XlsxPopulate.fromBlankAsync(); // Đọc file sau khi đã download\n const firstSheet = workbook.addWorksheet('data'); // Lấy ra sheet đầu tiên\n columns.forEach((column, index) => {\n let width = 120;\n if (column.width && column.width.endsWith('px')) {\n width = +column.width.replace('px', '');\n }\n firstSheet.getColumn(index + 1).width = width / 7 || 20;\n firstSheet.getCell(1, index + 1).style = this.#fieldStyle;\n if (column.required) {\n firstSheet.getCell(2, index + 1).style = this.#requiredStyle;\n } else {\n firstSheet.getCell(2, index + 1).style = this.#titleStyle;\n }\n firstSheet.getCell(1, index + 1).value = neutralizeSpreadsheetFormula(column.field);\n firstSheet.getCell(2, index + 1).value = neutralizeSpreadsheetFormula(column.title);\n if (hasDescription) {\n firstSheet.getCell(3, index + 1).style = this.#descriptionStyle;\n firstSheet.getCell(3, index + 1).value = neutralizeSpreadsheetFormula(column.description || '');\n }\n });\n if (sheets?.length) {\n for (const sheet of sheets) {\n if (sheet.name && Array.isArray(sheet.items) && Array.isArray(sheet.headers)) {\n const newSheet = workbook.addWorksheet(sheet.name);\n sheet.headers.forEach((header, index) => {\n newSheet.getColumn(index + 1).width = 30;\n newSheet.getCell(1, index + 1).style = this.#titleStyle;\n newSheet.getCell(1, index + 1).value = neutralizeSpreadsheetFormula(header.value);\n newSheet.getCell(2, index + 1).style = this.#titleStyle;\n newSheet.getCell(2, index + 1).value = neutralizeSpreadsheetFormula(header.display || header.value);\n });\n sheet.items.forEach((item, idx1) => {\n sheet.headers.forEach((header, idx2) => {\n newSheet.getCell(3 + idx1, 1 + idx2).value = neutralizeSpreadsheetFormula(item[header.value]) as CellValue;\n newSheet.getCell(3 + idx1, 1 + idx2).style = this.#cellStyle;\n });\n });\n }\n }\n }\n\n const fromRow = hasDescription ? 4 : 3;\n items.forEach((e, idx1) => {\n columns.forEach((column, idx2) => {\n if (typeof e[column.field] === 'number') {\n // Format mặc định với kiểu số\n firstSheet.getCell(fromRow + idx1, 1 + idx2).value = +e[column.field];\n firstSheet.getCell(fromRow + idx1, 1 + idx2).numFmt = '#';\n } else {\n firstSheet.getCell(fromRow + idx1, 1 + idx2).value = neutralizeSpreadsheetFormula(e[column.field]) as CellValue;\n }\n firstSheet.getCell(fromRow + idx1, 1 + idx2).style = {\n ...this.#cellStyle,\n };\n });\n });\n const file = await workbook.xlsx.writeBuffer();\n BrowserUtilities.downloadBlob(\n new Blob([file], {\n type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n }),\n fileName\n );\n };\n\n // Helper để lấy giá trị text chuẩn từ ô Excel (xử lý RichText, Formula, Hyperlink)\n #getCellValue = (value: CellValue): string | number | null | undefined | boolean | Date => {\n if (value && typeof value === 'object') {\n // Xử lý Rich Text (vd: ô bôi đậm)\n if ('richText' in value) {\n return value.richText.map(t => t.text).join('');\n }\n // Xử lý Hyperlink\n if ('text' in value) {\n return value.text as string; // hoặc value.result nếu là công thức\n }\n // Xử lý Formula\n if ('result' in value) {\n return value.result as string | number | null | undefined | boolean | Date;\n }\n }\n return value as string | number | null | undefined | boolean | Date;\n };\n upload = async (): Promise<{ items: Record<string, any>[]; file: File | null }> => {\n try {\n const fileResult = await BrowserUtilities.upload({\n extensions: ['xlsx'],\n maxSizeInMb: 10,\n });\n\n // Chuẩn hóa file đầu vào (nếu upload trả về mảng thì lấy phần tử đầu)\n const file = Array.isArray(fileResult) ? fileResult[0] : fileResult;\n\n if (!file) {\n return { items: [], file: null };\n }\n\n return await this.parse(file);\n } catch (error) {\n console.error('Upload error:', error);\n throw error; // Hoặc return { items: [], file: null } tùy logic nghiệp vụ\n }\n };\n parse = async (file: File): Promise<{ items: Record<string, any>[]; file: File | null }> => {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = async e => {\n try {\n const buffer = e.target?.result as ArrayBuffer;\n if (!buffer) {\n throw new Error(this.#i18n.t('core.excel.cannot-read-file'));\n }\n\n const Workbook = await this.#loadWorkbook();\n const wb = new Workbook();\n await wb.xlsx.load(buffer);\n\n const sheet = wb.worksheets[0];\n if (!sheet) {\n throw new Error(this.#i18n.t('core.excel.no-sheet'));\n }\n\n const items: Record<string, any>[] = [];\n\n // Lấy row Header (Row 1)\n const headerRow = sheet.getRow(1);\n // Map: Column Index (bắt đầu từ 1) -> Tên trường (Key)\n const headerMap: Record<number, string> = {};\n\n // Duyệt qua các ô có dữ liệu thực tế của dòng Header\n headerRow.eachCell((cell, colNumber) => {\n const cellValue = this.#getCellValue(cell.value);\n if (cellValue) {\n // Ép kiểu về string và trim để làm key\n headerMap[colNumber] = String(cellValue).trim();\n }\n });\n\n // Duyệt dữ liệu từ dòng 2 trở đi\n sheet.eachRow((row, rowIndex) => {\n if (rowIndex <= 1 || !row.hasValues) return;\n\n const item: Record<string, any> = {};\n\n // Chỉ duyệt qua các cột đã định nghĩa trong headerMap\n // Cách này an toàn hơn là duyệt mảng values\n Object.keys(headerMap).forEach(colKey => {\n const colNumber = Number(colKey);\n const fieldKey = headerMap[colNumber];\n\n // Lấy giá trị ô tại cột tương ứng\n const rawValue = this.#getCellValue(row.getCell(colNumber).value);\n\n let finalValue = rawValue;\n\n // Xử lý string: trim\n if (typeof finalValue === 'string') {\n finalValue = finalValue.trim();\n }\n\n // Xử lý các keyword đặc biệt\n if (finalValue === '' || finalValue === undefined) {\n finalValue = null;\n } else if (finalValue === 'SET_NULL') {\n finalValue = null;\n } else if (finalValue === 'SET_EMPTY') {\n finalValue = '';\n }\n\n item[fieldKey] = finalValue;\n });\n\n // Chỉ push nếu item có dữ liệu (tùy chọn)\n if (Object.keys(item).length > 0) {\n items.push(item);\n }\n });\n\n resolve({ items, file });\n } catch (err) {\n reject(err);\n }\n };\n\n reader.onerror = error => reject(error);\n reader.readAsArrayBuffer(file);\n });\n };\n}\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-license.mjs","sources":["../../../projects/sd-angular/services/license/src/license.service.ts","../../../projects/sd-angular/services/license/sd-angular-core-services-license.ts"],"sourcesContent":["import { inject, Injectable } from '@angular/core';\r\nimport { ISdCoreConfiguration, SD_CORE_CONFIGURATION } from '@sd-angular/core/configurations';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class SdLicenseService {\r\n readonly #SALT = 'angular-core-976e2fa6f8b44dadbc63f87b057a331f';\r\n #isValid = false;\r\n private readonly coreConfiguration: ISdCoreConfiguration | null = inject(SD_CORE_CONFIGURATION, { optional: true });\r\n\r\n constructor() {\r\n this.#verify();\r\n }\r\n\r\n enforceLicense = () => {\r\n if (!this.#isValid) {\r\n this.#throwSecurityError();\r\n }\r\n };\r\n\r\n #verify = () => {\r\n const hostname = window.location.hostname; // Ví dụ: store.uat.nexa.mobi\r\n\r\n // 1. Bypass Localhost\r\n if (this.#isLocalhost(hostname)) {\r\n this.#isValid = true;\r\n return;\r\n }\r\n\r\n const configKeys = this.#getConfiguredKeys();\r\n if (configKeys.length === 0) {\r\n this.#isValid = false;\r\n this.#throwSecurityError();\r\n return;\r\n }\r\n\r\n // 2. CHECK EXACT MATCH (Ưu tiên khớp chính xác 100%)\r\n // Hash chuỗi: \"store.uat.nexa.mobi\" + SALT\r\n if (this.#checkMatch(hostname, configKeys)) {\r\n this.#isValid = true;\r\n return;\r\n }\r\n\r\n // 3. CHECK WILDCARD MATCH (Thử các trường hợp có dấu *)\r\n const parts = hostname.split('.'); // [\"store\", \"uat\", \"nexa\", \"mobi\"]\r\n\r\n // Lặp để cắt dần subdomain bên trái và thêm \"*.\" vào\r\n // Điều kiện > 2 để đảm bảo không check các case vô nghĩa như *.mobi hay *.com\r\n while (parts.length > 2) {\r\n parts.shift(); // Bỏ phần đầu: [\"uat\", \"nexa\", \"mobi\"]\r\n \r\n // Tạo domain wildcard: \"*.uat.nexa.mobi\"\r\n const wildcardDomain = '*.' + parts.join('.'); \r\n \r\n // Hash chuỗi: \"*.uat.nexa.mobi\" + SALT\r\n if (this.#checkMatch(wildcardDomain, configKeys)) {\r\n this.#isValid = true;\r\n return;\r\n }\r\n }\r\n\r\n // Nếu chạy hết vòng lặp mà không khớp cái nào\r\n this.#isValid = false;\r\n this.#throwSecurityError();\r\n };\r\n\r\n // Helper để check xem hash của input có nằm trong list key không\r\n #checkMatch = (inputString: string, validKeys: string[]): boolean => {\r\n const hash = this.#generateHash(inputString + this.#SALT);\r\n return validKeys.includes(hash);\r\n };\r\n\r\n #getConfiguredKeys = (): string[] => {\r\n const keyOrKeys = this.coreConfiguration?.licenseKey;\r\n if (!keyOrKeys) return [];\r\n return Array.isArray(keyOrKeys) ? keyOrKeys : [keyOrKeys];\r\n };\r\n\r\n #isLocalhost = (domain: string) => {\r\n return domain === 'localhost' || domain === '127.0.0.1' || domain.includes('localhost');\r\n };\r\n\r\n #generateHash = (input: string): string => {\r\n let hash = 0;\r\n if (input.length === 0) return hash.toString();\r\n for (let i = 0; i < input.length; i++) {\r\n const char = input.charCodeAt(i);\r\n hash = (hash << 5) - hash + char;\r\n hash = hash & hash;\r\n }\r\n return btoa(hash.toString() + 'signed');\r\n };\r\n\r\n #throwSecurityError = () => {\r\n throw new Error(`[Security] Unauthorized usage of UI Lib on domain: ${window.location.hostname}`);\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-license.mjs","sources":["../../../projects/sd-angular/services/license/src/license.service.ts","../../../projects/sd-angular/services/license/sd-angular-core-services-license.ts"],"sourcesContent":["import { inject, Injectable } from '@angular/core';\nimport { ISdCoreConfiguration, SD_CORE_CONFIGURATION } from '@sd-angular/core/configurations';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class SdLicenseService {\n readonly #SALT = 'angular-core-976e2fa6f8b44dadbc63f87b057a331f';\n #isValid = false;\n private readonly coreConfiguration: ISdCoreConfiguration | null = inject(SD_CORE_CONFIGURATION, { optional: true });\n\n constructor() {\n this.#verify();\n }\n\n enforceLicense = () => {\n if (!this.#isValid) {\n this.#throwSecurityError();\n }\n };\n\n #verify = () => {\n const hostname = window.location.hostname; // Ví dụ: store.uat.nexa.mobi\n\n // 1. Bypass Localhost\n if (this.#isLocalhost(hostname)) {\n this.#isValid = true;\n return;\n }\n\n const configKeys = this.#getConfiguredKeys();\n if (configKeys.length === 0) {\n this.#isValid = false;\n this.#throwSecurityError();\n return;\n }\n\n // 2. CHECK EXACT MATCH (Ưu tiên khớp chính xác 100%)\n // Hash chuỗi: \"store.uat.nexa.mobi\" + SALT\n if (this.#checkMatch(hostname, configKeys)) {\n this.#isValid = true;\n return;\n }\n\n // 3. CHECK WILDCARD MATCH (Thử các trường hợp có dấu *)\n const parts = hostname.split('.'); // [\"store\", \"uat\", \"nexa\", \"mobi\"]\n\n // Lặp để cắt dần subdomain bên trái và thêm \"*.\" vào\n // Điều kiện > 2 để đảm bảo không check các case vô nghĩa như *.mobi hay *.com\n while (parts.length > 2) {\n parts.shift(); // Bỏ phần đầu: [\"uat\", \"nexa\", \"mobi\"]\n \n // Tạo domain wildcard: \"*.uat.nexa.mobi\"\n const wildcardDomain = '*.' + parts.join('.'); \n \n // Hash chuỗi: \"*.uat.nexa.mobi\" + SALT\n if (this.#checkMatch(wildcardDomain, configKeys)) {\n this.#isValid = true;\n return;\n }\n }\n\n // Nếu chạy hết vòng lặp mà không khớp cái nào\n this.#isValid = false;\n this.#throwSecurityError();\n };\n\n // Helper để check xem hash của input có nằm trong list key không\n #checkMatch = (inputString: string, validKeys: string[]): boolean => {\n const hash = this.#generateHash(inputString + this.#SALT);\n return validKeys.includes(hash);\n };\n\n #getConfiguredKeys = (): string[] => {\n const keyOrKeys = this.coreConfiguration?.licenseKey;\n if (!keyOrKeys) return [];\n return Array.isArray(keyOrKeys) ? keyOrKeys : [keyOrKeys];\n };\n\n #isLocalhost = (domain: string) => {\n return domain === 'localhost' || domain === '127.0.0.1' || domain.includes('localhost');\n };\n\n #generateHash = (input: string): string => {\n let hash = 0;\n if (input.length === 0) return hash.toString();\n for (let i = 0; i < input.length; i++) {\n const char = input.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash;\n }\n return btoa(hash.toString() + 'signed');\n };\n\n #throwSecurityError = () => {\n throw new Error(`[Security] Unauthorized usage of UI Lib on domain: ${window.location.hostname}`);\n };\n}","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -62,11 +62,11 @@ class SdLoadingService {
62
62
  'border-radius': '50%',
63
63
  animation: 'spin 1s linear infinite',
64
64
  };
65
- const keyframes = `
66
- @keyframes spin {
67
- 0% { transform: rotate(0deg); }
68
- 100% { transform: rotate(360deg); }
69
- }
65
+ const keyframes = `
66
+ @keyframes spin {
67
+ 0% { transform: rotate(0deg); }
68
+ 100% { transform: rotate(360deg); }
69
+ }
70
70
  `;
71
71
  renderer.addClass(container, 'sd-loading');
72
72
  renderer.setAttribute(container, 'id', this.loadingId);
@@ -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 // 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":"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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';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class SdLoadingService {\n private loadingId = 'L8d556b9b-f6dd-46e9-9710-757e65d82839';\n\n private renderer: Renderer2;\n\n private loadingMap = new WeakMap<Element, HTMLElement>();\n constructor(rendererFactory: RendererFactory2) {\n this.renderer = rendererFactory.createRenderer(null, null);\n }\n\n start = (element = 'body') => {\n // why: router tabs can leave multiple hosts with the same selector in the DOM;\n // querySelector would only overlay the first match.\n document.querySelectorAll(element).forEach(ele => {\n if (!this.loadingMap.has(ele)) {\n const loadingElement = this.#createLoading();\n ele.appendChild(loadingElement);\n this.loadingMap.set(ele, loadingElement);\n }\n });\n };\n\n isLoading = (element = 'body') => {\n const nodes = document.querySelectorAll(element);\n if (!nodes.length) return null;\n for (const ele of Array.from(nodes)) {\n if (this.loadingMap.has(ele)) return ele;\n }\n return false;\n };\n\n stop = (element = 'body') => {\n document.querySelectorAll(element).forEach(ele => {\n if (this.loadingMap.has(ele)) {\n this.loadingMap.get(ele)?.remove();\n this.loadingMap.delete(ele);\n }\n });\n };\n\n #createLoading = (): HTMLElement => {\n const renderer = this.renderer;\n const container: HTMLElement = this.renderer.createElement('div');\n const spinner: HTMLElement = this.renderer.createElement('div');\n const containerStyle = {\n position: 'absolute',\n top: 0,\n left: 0,\n height: '100%',\n width: '100%',\n opacity: 0.6,\n background: '#FFFFFF',\n 'z-index': 99999,\n };\n const spinnerStyle = {\n position: 'absolute',\n top: 'calc(50% - 2.5rem)',\n left: 'calc(50% - 2.5rem)',\n width: '5rem',\n height: '5rem',\n border: '0.5rem solid var(--sd-primary)',\n 'border-top': '0.5rem solid var(--sd-black200)',\n 'border-radius': '50%',\n animation: 'spin 1s linear infinite',\n };\n const keyframes = `\n @keyframes spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n `;\n\n renderer.addClass(container, 'sd-loading');\n renderer.setAttribute(container, 'id', this.loadingId);\n\n Object.entries(containerStyle).forEach(entry => {\n renderer.setStyle(container, entry[0], entry[1]);\n });\n\n renderer.addClass(spinner, 'sd-loading-spinner');\n Object.entries(spinnerStyle).forEach(entry => {\n renderer.setStyle(spinner, entry[0], entry[1]);\n });\n\n const styleElement = this.renderer.createElement('style');\n this.renderer.appendChild(styleElement, this.renderer.createText(keyframes));\n document.head.appendChild(styleElement);\n\n container.appendChild(spinner);\n return container;\n };\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -134,22 +134,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
134
134
  class ToastContainerComponent {
135
135
  toasts = signal([]);
136
136
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: ToastContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
137
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: ToastContainerComponent, isStandalone: true, selector: "toast-container", ngImport: i0, template: `
138
- <div class="toast-container">
139
- @for (toast of toasts(); track toast.id) {
140
- <toast [data]="toast"> </toast>
141
- }
142
- </div>
137
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: ToastContainerComponent, isStandalone: true, selector: "toast-container", ngImport: i0, template: `
138
+ <div class="toast-container">
139
+ @for (toast of toasts(); track toast.id) {
140
+ <toast [data]="toast"> </toast>
141
+ }
142
+ </div>
143
143
  `, isInline: true, styles: [".toast-container{position:fixed;top:20px;right:20px;z-index:9999;display:flex;flex-direction:column;pointer-events:none}sd-toast{pointer-events:auto}\n"], dependencies: [{ kind: "component", type: ToastComponent, selector: "toast", inputs: ["data"] }] });
144
144
  }
145
145
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: ToastContainerComponent, decorators: [{
146
146
  type: Component,
147
- args: [{ selector: 'toast-container', standalone: true, imports: [ToastComponent], template: `
148
- <div class="toast-container">
149
- @for (toast of toasts(); track toast.id) {
150
- <toast [data]="toast"> </toast>
151
- }
152
- </div>
147
+ args: [{ selector: 'toast-container', standalone: true, imports: [ToastComponent], template: `
148
+ <div class="toast-container">
149
+ @for (toast of toasts(); track toast.id) {
150
+ <toast [data]="toast"> </toast>
151
+ }
152
+ </div>
153
153
  `, styles: [".toast-container{position:fixed;top:20px;right:20px;z-index:9999;display:flex;flex-direction:column;pointer-events:none}sd-toast{pointer-events:auto}\n"] }]
154
154
  }] });
155
155
 
@@ -1 +1 @@
1
- {"version":3,"file":"sd-angular-core-services-notify.mjs","sources":["../../../projects/sd-angular/services/notify/src/components/toast/toast.component.ts","../../../projects/sd-angular/services/notify/src/components/toast/toast.component.html","../../../projects/sd-angular/services/notify/src/components/toast-container.component.ts","../../../projects/sd-angular/services/notify/src/notify.service.ts","../../../projects/sd-angular/services/notify/sd-angular-core-services-notify.ts"],"sourcesContent":["import { CommonModule } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n HostListener,\n Input,\n OnDestroy,\n OnInit,\n SecurityContext,\n computed,\n signal,\n} from '@angular/core';\nimport { DomSanitizer } from '@angular/platform-browser';\nimport { TranslatePipe } from '@sd-angular/core/i18n';\n\nimport { ToastData } from '../../notify.model';\nimport { SdNotifyService } from '../../notify.service';\n\nconst TOAST_EXIT_ANIMATION_MS = 200;\n\n@Component({\n selector: 'toast',\n standalone: true,\n imports: [CommonModule, TranslatePipe],\n templateUrl: './toast.component.html',\n styleUrl: './toast.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class]': 'hostClasses()',\n '[attr.data-autoid]': 'autoId',\n '[attr.data-type]': 'data.type',\n '[attr.data-title]': 'data.title ?? null',\n '[attr.data-message]': 'dataMessage',\n },\n})\nexport class ToastComponent implements OnInit, OnDestroy {\n @Input({ required: true }) data!: ToastData;\n\n readonly isExpanded = signal(false);\n readonly isClosing = signal(false);\n readonly hostClasses = computed(() => (this.isClosing() ? 'bg-white sd-toast sd-toast--closing' : 'bg-white sd-toast'));\n readonly MAX_SHOW = 2;\n\n private timer: ReturnType<typeof setTimeout> | null = null;\n private closeTimer: ReturnType<typeof setTimeout> | null = null;\n private start = 0;\n private remaining = 0;\n\n constructor(\n private notifyService: SdNotifyService,\n private sanitizer: DomSanitizer\n ) {}\n\n ngOnInit(): void {\n this.remaining = this.data.duration;\n this.resumeTimer();\n }\n\n ngOnDestroy(): void {\n this.clearAutoDismissTimer();\n this.clearCloseTimer();\n }\n\n @HostListener('mouseenter')\n pauseTimer(): void {\n if (!this.timer || this.isClosing()) {\n return;\n }\n\n clearTimeout(this.timer);\n this.timer = null;\n this.remaining = Math.max(this.remaining - (Date.now() - this.start), 0);\n }\n\n @HostListener('mouseleave')\n resumeTimer(): void {\n if (this.remaining <= 0 || this.timer || this.isClosing()) {\n return;\n }\n\n this.start = Date.now();\n this.timer = setTimeout(() => {\n this.close();\n }, this.remaining);\n }\n\n close(): void {\n if (this.isClosing()) {\n return;\n }\n\n this.clearAutoDismissTimer();\n this.isClosing.set(true);\n this.closeTimer = setTimeout(() => {\n this.closeTimer = null;\n this.notifyService.remove(this.data.id);\n }, TOAST_EXIT_ANIMATION_MS);\n }\n\n onActionClick(): void {\n this.data.onAction?.();\n }\n\n toggleExpand(): void {\n this.isExpanded.update(v => !v);\n }\n\n sanitizeHtml(value: string): string {\n return this.sanitizer.sanitize(SecurityContext.HTML, value) ?? '';\n }\n\n get singleMessage(): string {\n return this.data.message as string;\n }\n\n get isMultiMessage(): boolean {\n return Array.isArray(this.data.message);\n }\n\n get messages(): string[] {\n return this.data.message as string[];\n }\n\n get displayMessages(): string[] {\n const msgs = this.messages;\n if (this.isExpanded()) return msgs;\n return msgs.slice(0, this.MAX_SHOW);\n }\n\n get restCount(): number {\n return this.messages.length - this.MAX_SHOW;\n }\n\n get hasMore(): boolean {\n return this.isMultiMessage && this.messages.length > this.MAX_SHOW;\n }\n\n get autoId(): string {\n return `services-notify-toast-${this.data.type}`;\n }\n\n get dataMessage(): string {\n return Array.isArray(this.data.message) ? this.data.message.join(' | ') : this.data.message;\n }\n\n private clearAutoDismissTimer(): void {\n if (!this.timer) {\n return;\n }\n\n clearTimeout(this.timer);\n this.timer = null;\n }\n\n private clearCloseTimer(): void {\n if (!this.closeTimer) {\n return;\n }\n\n clearTimeout(this.closeTimer);\n this.closeTimer = null;\n }\n}\n","<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","import { Component, signal, WritableSignal } from '@angular/core';\r\nimport { ToastData } from '../notify.model';\r\nimport { ToastComponent } from './toast/toast.component';\r\n\r\n@Component({\r\n selector: 'toast-container',\r\n standalone: true,\r\n imports: [ToastComponent],\r\n template: `\r\n <div class=\"toast-container\">\r\n @for (toast of toasts(); track toast.id) {\r\n <toast [data]=\"toast\"> </toast>\r\n }\r\n </div>\r\n `,\r\n styles: [\r\n `\r\n .toast-container {\r\n position: fixed;\r\n top: 20px;\r\n right: 20px;\r\n z-index: 9999;\r\n display: flex;\r\n flex-direction: column;\r\n pointer-events: none; /* Cho phép click xuyên qua vùng trống */\r\n }\r\n sd-toast {\r\n pointer-events: auto; /* Bật lại click cho toast */\r\n }\r\n `,\r\n ],\r\n})\r\nexport class ToastContainerComponent {\r\n toasts: WritableSignal<ToastData[]> = signal([]);\r\n}\r\n","import { DOCUMENT } from '@angular/common';\r\nimport { ApplicationRef, createComponent, EnvironmentInjector, inject, Injectable, signal } from '@angular/core';\r\nimport { Utilities } from '@sdcorejs/utils/fns';\r\n\r\nimport { I18nService } from '@sd-angular/core/i18n';\r\n\r\nimport { ToastContainerComponent } from './components/toast-container.component';\r\nimport { NotifyOption, ToastData, ToastType } from './notify.model';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class SdNotifyService {\r\n readonly toasts = signal<ToastData[]>([]);\r\n\r\n // Constants\r\n readonly #DEBOUNCE_TIME = 500;\r\n readonly #DEFAULT_SUCCESS_DURATION = 3000;\r\n readonly #DEFAULT_BUFFERED_DURATION = 5000;\r\n readonly #MAX_TOASTS = 5;\r\n\r\n // State\r\n #buffer: Record<string, string[]> = {};\r\n #timers: Record<string, ReturnType<typeof setTimeout> | null> = {};\r\n private readonly appRef = inject(ApplicationRef);\r\n private readonly injector = inject(EnvironmentInjector);\r\n private readonly document = inject(DOCUMENT);\r\n readonly #i18n = inject(I18nService);\r\n\r\n constructor() {\r\n this.#initContainer();\r\n }\r\n\r\n #initContainer() {\r\n const componentRef = createComponent(ToastContainerComponent, {\r\n environmentInjector: this.injector,\r\n });\r\n componentRef.instance.toasts = this.toasts;\r\n this.appRef.attachView(componentRef.hostView);\r\n const domElem = (componentRef.hostView as any).rootNodes[0] as HTMLElement;\r\n this.document.body.appendChild(domElem);\r\n }\r\n\r\n // Public API\r\n success(message: string, option?: NotifyOption) {\r\n this.#addImmediate('success', message, option);\r\n }\r\n\r\n info(message: string, option?: NotifyOption) {\r\n this.#addImmediate('info', message, option);\r\n }\r\n\r\n warning(message: string | string[], option?: NotifyOption) {\r\n this.#addToBuffer('warning', message, option);\r\n }\r\n\r\n error(message: string | string[], option?: NotifyOption) {\r\n this.#addToBuffer('error', message, option);\r\n }\r\n\r\n remove(id: string) {\r\n this.toasts.update(current => current.filter(t => t.id !== id));\r\n }\r\n\r\n clearAll() {\r\n this.toasts.set([]);\r\n this.#clearAllTimers();\r\n }\r\n\r\n clearByType(type: ToastType) {\r\n this.toasts.update(current => current.filter(t => t.type !== type));\r\n }\r\n\r\n // Private helpers\r\n #addImmediate(type: ToastType, message: string, option?: NotifyOption) {\r\n const newToast: ToastData = {\r\n id: Utilities.generateUuid(),\r\n type,\r\n message,\r\n title: option?.title,\r\n duration: option?.duration ?? this.#DEFAULT_SUCCESS_DURATION,\r\n actionLabel: option?.actionLabel,\r\n onAction: option?.onAction,\r\n html: option?.html,\r\n };\r\n\r\n this.toasts.update(current => {\r\n const updated = [newToast, ...current];\r\n return updated.slice(0, this.#MAX_TOASTS);\r\n });\r\n }\r\n\r\n #addToBuffer(type: ToastType, message: string | string[], option?: NotifyOption) {\r\n if (!this.#buffer[type]) {\r\n this.#buffer[type] = [];\r\n }\r\n\r\n const msgs = Array.isArray(message) ? message : [message];\r\n this.#buffer[type].push(...msgs);\r\n\r\n // Clear existing timer and set new one\r\n if (this.#timers[type]) {\r\n clearTimeout(this.#timers[type]!);\r\n }\r\n\r\n this.#timers[type] = setTimeout(() => {\r\n this.#flushBuffer(type, option);\r\n }, this.#DEBOUNCE_TIME);\r\n }\r\n\r\n #flushBuffer(type: ToastType, option?: NotifyOption) {\r\n const messages = [...new Set(this.#buffer[type])];\r\n\r\n // Cleanup\r\n this.#buffer[type] = [];\r\n this.#timers[type] = null;\r\n\r\n if (messages.length === 0) return;\r\n\r\n const title = option?.title ?? this.#i18n.t(`core.notify.type.${type}`);\r\n const finalTitle = messages.length > 1 ? `${title} (${messages.length})` : title;\r\n\r\n const newToast: ToastData = {\r\n id: Utilities.generateUuid(),\r\n type,\r\n message: messages.length === 1 ? messages[0] : messages,\r\n title: finalTitle,\r\n duration: option?.duration ?? this.#DEFAULT_BUFFERED_DURATION,\r\n actionLabel: option?.actionLabel,\r\n onAction: option?.onAction,\r\n html: option?.html,\r\n };\r\n\r\n this.toasts.update(current => {\r\n const updated = [newToast, ...current];\r\n return updated.slice(0, this.#MAX_TOASTS);\r\n });\r\n }\r\n\r\n #clearAllTimers() {\r\n Object.values(this.#timers).forEach(timer => {\r\n if (timer) clearTimeout(timer);\r\n });\r\n this.#timers = {};\r\n }\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1.SdNotifyService"],"mappings":"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"}
1
+ {"version":3,"file":"sd-angular-core-services-notify.mjs","sources":["../../../projects/sd-angular/services/notify/src/components/toast/toast.component.ts","../../../projects/sd-angular/services/notify/src/components/toast/toast.component.html","../../../projects/sd-angular/services/notify/src/components/toast-container.component.ts","../../../projects/sd-angular/services/notify/src/notify.service.ts","../../../projects/sd-angular/services/notify/sd-angular-core-services-notify.ts"],"sourcesContent":["import { CommonModule } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n HostListener,\n Input,\n OnDestroy,\n OnInit,\n SecurityContext,\n computed,\n signal,\n} from '@angular/core';\nimport { DomSanitizer } from '@angular/platform-browser';\nimport { TranslatePipe } from '@sd-angular/core/i18n';\n\nimport { ToastData } from '../../notify.model';\nimport { SdNotifyService } from '../../notify.service';\n\nconst TOAST_EXIT_ANIMATION_MS = 200;\n\n@Component({\n selector: 'toast',\n standalone: true,\n imports: [CommonModule, TranslatePipe],\n templateUrl: './toast.component.html',\n styleUrl: './toast.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class]': 'hostClasses()',\n '[attr.data-autoid]': 'autoId',\n '[attr.data-type]': 'data.type',\n '[attr.data-title]': 'data.title ?? null',\n '[attr.data-message]': 'dataMessage',\n },\n})\nexport class ToastComponent implements OnInit, OnDestroy {\n @Input({ required: true }) data!: ToastData;\n\n readonly isExpanded = signal(false);\n readonly isClosing = signal(false);\n readonly hostClasses = computed(() => (this.isClosing() ? 'bg-white sd-toast sd-toast--closing' : 'bg-white sd-toast'));\n readonly MAX_SHOW = 2;\n\n private timer: ReturnType<typeof setTimeout> | null = null;\n private closeTimer: ReturnType<typeof setTimeout> | null = null;\n private start = 0;\n private remaining = 0;\n\n constructor(\n private notifyService: SdNotifyService,\n private sanitizer: DomSanitizer\n ) {}\n\n ngOnInit(): void {\n this.remaining = this.data.duration;\n this.resumeTimer();\n }\n\n ngOnDestroy(): void {\n this.clearAutoDismissTimer();\n this.clearCloseTimer();\n }\n\n @HostListener('mouseenter')\n pauseTimer(): void {\n if (!this.timer || this.isClosing()) {\n return;\n }\n\n clearTimeout(this.timer);\n this.timer = null;\n this.remaining = Math.max(this.remaining - (Date.now() - this.start), 0);\n }\n\n @HostListener('mouseleave')\n resumeTimer(): void {\n if (this.remaining <= 0 || this.timer || this.isClosing()) {\n return;\n }\n\n this.start = Date.now();\n this.timer = setTimeout(() => {\n this.close();\n }, this.remaining);\n }\n\n close(): void {\n if (this.isClosing()) {\n return;\n }\n\n this.clearAutoDismissTimer();\n this.isClosing.set(true);\n this.closeTimer = setTimeout(() => {\n this.closeTimer = null;\n this.notifyService.remove(this.data.id);\n }, TOAST_EXIT_ANIMATION_MS);\n }\n\n onActionClick(): void {\n this.data.onAction?.();\n }\n\n toggleExpand(): void {\n this.isExpanded.update(v => !v);\n }\n\n sanitizeHtml(value: string): string {\n return this.sanitizer.sanitize(SecurityContext.HTML, value) ?? '';\n }\n\n get singleMessage(): string {\n return this.data.message as string;\n }\n\n get isMultiMessage(): boolean {\n return Array.isArray(this.data.message);\n }\n\n get messages(): string[] {\n return this.data.message as string[];\n }\n\n get displayMessages(): string[] {\n const msgs = this.messages;\n if (this.isExpanded()) return msgs;\n return msgs.slice(0, this.MAX_SHOW);\n }\n\n get restCount(): number {\n return this.messages.length - this.MAX_SHOW;\n }\n\n get hasMore(): boolean {\n return this.isMultiMessage && this.messages.length > this.MAX_SHOW;\n }\n\n get autoId(): string {\n return `services-notify-toast-${this.data.type}`;\n }\n\n get dataMessage(): string {\n return Array.isArray(this.data.message) ? this.data.message.join(' | ') : this.data.message;\n }\n\n private clearAutoDismissTimer(): void {\n if (!this.timer) {\n return;\n }\n\n clearTimeout(this.timer);\n this.timer = null;\n }\n\n private clearCloseTimer(): void {\n if (!this.closeTimer) {\n return;\n }\n\n clearTimeout(this.closeTimer);\n this.closeTimer = null;\n }\n}\n","<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","import { Component, signal, WritableSignal } from '@angular/core';\nimport { ToastData } from '../notify.model';\nimport { ToastComponent } from './toast/toast.component';\n\n@Component({\n selector: 'toast-container',\n standalone: true,\n imports: [ToastComponent],\n template: `\n <div class=\"toast-container\">\n @for (toast of toasts(); track toast.id) {\n <toast [data]=\"toast\"> </toast>\n }\n </div>\n `,\n styles: [\n `\n .toast-container {\n position: fixed;\n top: 20px;\n right: 20px;\n z-index: 9999;\n display: flex;\n flex-direction: column;\n pointer-events: none; /* Cho phép click xuyên qua vùng trống */\n }\n sd-toast {\n pointer-events: auto; /* Bật lại click cho toast */\n }\n `,\n ],\n})\nexport class ToastContainerComponent {\n toasts: WritableSignal<ToastData[]> = signal([]);\n}\n","import { DOCUMENT } from '@angular/common';\nimport { ApplicationRef, createComponent, EnvironmentInjector, inject, Injectable, signal } from '@angular/core';\nimport { Utilities } from '@sdcorejs/utils/fns';\n\nimport { I18nService } from '@sd-angular/core/i18n';\n\nimport { ToastContainerComponent } from './components/toast-container.component';\nimport { NotifyOption, ToastData, ToastType } from './notify.model';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class SdNotifyService {\n readonly toasts = signal<ToastData[]>([]);\n\n // Constants\n readonly #DEBOUNCE_TIME = 500;\n readonly #DEFAULT_SUCCESS_DURATION = 3000;\n readonly #DEFAULT_BUFFERED_DURATION = 5000;\n readonly #MAX_TOASTS = 5;\n\n // State\n #buffer: Record<string, string[]> = {};\n #timers: Record<string, ReturnType<typeof setTimeout> | null> = {};\n private readonly appRef = inject(ApplicationRef);\n private readonly injector = inject(EnvironmentInjector);\n private readonly document = inject(DOCUMENT);\n readonly #i18n = inject(I18nService);\n\n constructor() {\n this.#initContainer();\n }\n\n #initContainer() {\n const componentRef = createComponent(ToastContainerComponent, {\n environmentInjector: this.injector,\n });\n componentRef.instance.toasts = this.toasts;\n this.appRef.attachView(componentRef.hostView);\n const domElem = (componentRef.hostView as any).rootNodes[0] as HTMLElement;\n this.document.body.appendChild(domElem);\n }\n\n // Public API\n success(message: string, option?: NotifyOption) {\n this.#addImmediate('success', message, option);\n }\n\n info(message: string, option?: NotifyOption) {\n this.#addImmediate('info', message, option);\n }\n\n warning(message: string | string[], option?: NotifyOption) {\n this.#addToBuffer('warning', message, option);\n }\n\n error(message: string | string[], option?: NotifyOption) {\n this.#addToBuffer('error', message, option);\n }\n\n remove(id: string) {\n this.toasts.update(current => current.filter(t => t.id !== id));\n }\n\n clearAll() {\n this.toasts.set([]);\n this.#clearAllTimers();\n }\n\n clearByType(type: ToastType) {\n this.toasts.update(current => current.filter(t => t.type !== type));\n }\n\n // Private helpers\n #addImmediate(type: ToastType, message: string, option?: NotifyOption) {\n const newToast: ToastData = {\n id: Utilities.generateUuid(),\n type,\n message,\n title: option?.title,\n duration: option?.duration ?? this.#DEFAULT_SUCCESS_DURATION,\n actionLabel: option?.actionLabel,\n onAction: option?.onAction,\n html: option?.html,\n };\n\n this.toasts.update(current => {\n const updated = [newToast, ...current];\n return updated.slice(0, this.#MAX_TOASTS);\n });\n }\n\n #addToBuffer(type: ToastType, message: string | string[], option?: NotifyOption) {\n if (!this.#buffer[type]) {\n this.#buffer[type] = [];\n }\n\n const msgs = Array.isArray(message) ? message : [message];\n this.#buffer[type].push(...msgs);\n\n // Clear existing timer and set new one\n if (this.#timers[type]) {\n clearTimeout(this.#timers[type]!);\n }\n\n this.#timers[type] = setTimeout(() => {\n this.#flushBuffer(type, option);\n }, this.#DEBOUNCE_TIME);\n }\n\n #flushBuffer(type: ToastType, option?: NotifyOption) {\n const messages = [...new Set(this.#buffer[type])];\n\n // Cleanup\n this.#buffer[type] = [];\n this.#timers[type] = null;\n\n if (messages.length === 0) return;\n\n const title = option?.title ?? this.#i18n.t(`core.notify.type.${type}`);\n const finalTitle = messages.length > 1 ? `${title} (${messages.length})` : title;\n\n const newToast: ToastData = {\n id: Utilities.generateUuid(),\n type,\n message: messages.length === 1 ? messages[0] : messages,\n title: finalTitle,\n duration: option?.duration ?? this.#DEFAULT_BUFFERED_DURATION,\n actionLabel: option?.actionLabel,\n onAction: option?.onAction,\n html: option?.html,\n };\n\n this.toasts.update(current => {\n const updated = [newToast, ...current];\n return updated.slice(0, this.#MAX_TOASTS);\n });\n }\n\n #clearAllTimers() {\n Object.values(this.#timers).forEach(timer => {\n if (timer) clearTimeout(timer);\n });\n this.#timers = {};\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1.SdNotifyService"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"sd-angular-core-services-storage.mjs","sources":["../../../projects/sd-angular/services/storage/src/storage.model.ts","../../../projects/sd-angular/services/storage/src/storage.service.ts","../../../projects/sd-angular/services/storage/sd-angular-core-services-storage.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\r\nimport { BehaviorSubject, Observable } from 'rxjs';\r\n\r\nexport interface SdStorageOption<T = any> {\r\n type?: 'session';\r\n default?: T;\r\n args?: Record<string, any>;\r\n}\r\n\r\nexport interface SdStorage<T = any> {\r\n get: () => T;\r\n set: (data: T) => void;\r\n // Ghi vào storage nhưng KHÔNG emit subject. Dùng cho thay đổi UI-only\r\n // (vd: column width) để tránh re-trigger các subscriber gây reload data.\r\n setSilent: (data: T) => void;\r\n has: () => boolean;\r\n remove: () => void;\r\n subject: BehaviorSubject<T>;\r\n observer: Observable<T>;\r\n}\r\n\r\nexport interface ISdStorageConfiguration {\r\n key?: (key: string) => string;\r\n}\r\n\r\nexport const SD_STORAGE_CONFIG = new InjectionToken<ISdStorageConfiguration>('storage.configuration');\r\n","/* eslint-disable @typescript-eslint/no-explicit-any */\r\nimport { inject, Injectable } from '@angular/core';\r\nimport { Utilities } from '@sdcorejs/utils/fns';\r\nimport { BehaviorSubject } from 'rxjs';\r\nimport { map } from 'rxjs/operators';\r\nimport { ISdStorageConfiguration, SD_STORAGE_CONFIG, SdStorage, SdStorageOption } from './storage.model';\r\n\r\ninterface StorageCacheEntry<T> {\r\n data: T;\r\n createdOn: Date;\r\n}\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class SdStorageService {\r\n // Dùng Map để quản lý bộ nhớ tốt hơn Record\r\n #memoryCache = new Map<string, StorageCacheEntry<any>>();\r\n #subjects = new Map<string, BehaviorSubject<any>>();\r\n private readonly configuration: ISdStorageConfiguration | null = inject(SD_STORAGE_CONFIG, { optional: true });\r\n\r\n create<T = any>(key: string | object, option?: SdStorageOption<T>): SdStorage<T> {\r\n if (!key) throw new Error('Key is required');\r\n\r\n // 1. Xử lý Key\r\n let hashKey: string;\r\n if (typeof key === 'string') {\r\n hashKey = key;\r\n } else if (typeof key === 'object') {\r\n hashKey = Utilities.hash(key);\r\n } else {\r\n throw new Error('Invalid key type');\r\n }\r\n\r\n if (this.configuration?.key) {\r\n hashKey = this.configuration.key(hashKey);\r\n }\r\n\r\n // 2. Init Subject: Đọc dữ liệu từ Storage ngay lập tức để Subject có giá trị đúng\r\n if (!this.#subjects.has(hashKey)) {\r\n const existingData = this.#internalGet<T>(hashKey, option);\r\n // Fix Type: as T | undefined\r\n this.#subjects.set(hashKey, new BehaviorSubject<T | undefined>(existingData ?? option?.default));\r\n }\r\n\r\n const subject = this.#subjects.get(hashKey)!;\r\n\r\n // 3. Define Helpers\r\n const get = () => {\r\n const val = this.#internalGet<T>(hashKey, option);\r\n return (val ?? option?.default) as T;\r\n };\r\n\r\n const set = (data: T) => {\r\n this.#internalSet(hashKey, data, option);\r\n subject.next(data);\r\n };\r\n\r\n const setSilent = (data: T) => {\r\n this.#internalSet(hashKey, data, option);\r\n // Cố tình KHÔNG gọi subject.next — consumer dùng kênh riêng để thông báo\r\n };\r\n\r\n const has = () => {\r\n return this.#internalGet<T>(hashKey, option) !== undefined;\r\n };\r\n\r\n const remove = () => {\r\n this.#internalRemove(hashKey, option);\r\n subject.next(undefined);\r\n };\r\n\r\n // Hàm dọn dẹp bộ nhớ (quan trọng)\r\n const destroy = () => {\r\n subject.complete();\r\n this.#subjects.delete(hashKey);\r\n this.#memoryCache.delete(hashKey);\r\n };\r\n\r\n return {\r\n get,\r\n set,\r\n setSilent,\r\n has,\r\n remove,\r\n // @ts-ignore: Bổ sung vào interface nếu cần\r\n destroy,\r\n subject: subject,\r\n observer: subject.asObservable().pipe(map(() => get())),\r\n };\r\n }\r\n\r\n // --- PRIVATE CORE LOGIC ---\r\n\r\n /**\r\n * Helper xác định loại Storage đang dùng\r\n */\r\n #getStorage(option?: SdStorageOption<any>): Storage {\r\n return option?.type === 'session' ? sessionStorage : localStorage;\r\n }\r\n\r\n /**\r\n * Đọc dữ liệu: Memory -> Storage -> Parse\r\n */\r\n #internalGet<T>(key: string, option?: SdStorageOption<T>): T | undefined {\r\n // 1. Check Memory (Nhanh nhất)\r\n let entry = this.#memoryCache.get(key);\r\n\r\n // 2. Check Storage (Nếu memory chưa có hoặc mới F5)\r\n if (!entry) {\r\n const storage = this.#getStorage(option);\r\n const raw = storage.getItem(key);\r\n if (raw) {\r\n try {\r\n const parsed = JSON.parse(raw);\r\n // Convert string date back to Date object nếu cần\r\n entry = {\r\n data: parsed.data,\r\n createdOn: new Date(parsed.createdOn)\r\n };\r\n // Sync ngược vào RAM\r\n this.#memoryCache.set(key, entry);\r\n } catch (e) {\r\n console.warn('Storage parse error', e);\r\n this.#internalRemove(key, option); // Dữ liệu lỗi -> Xóa\r\n }\r\n }\r\n }\r\n\r\n if (!entry) return undefined;\r\n\r\n return this.#deepClone(entry.data);\r\n }\r\n\r\n /**\r\n * Ghi dữ liệu: Memory -> Storage\r\n */\r\n #internalSet<T>(key: string, data: T, option?: SdStorageOption<T>): void {\r\n const clonedData = this.#deepClone(data);\r\n\r\n const entry: StorageCacheEntry<T> = {\r\n data: clonedData,\r\n createdOn: new Date(),\r\n };\r\n\r\n // 1. Lưu Memory\r\n this.#memoryCache.set(key, entry);\r\n\r\n // 2. Lưu Storage\r\n const storage = this.#getStorage(option);\r\n try {\r\n storage.setItem(key, JSON.stringify(entry));\r\n } catch (e) {\r\n console.error('Storage quota exceeded', e);\r\n }\r\n }\r\n\r\n /**\r\n * Xóa dữ liệu\r\n */\r\n #internalRemove(key: string, option?: SdStorageOption<any>): void {\r\n this.#memoryCache.delete(key);\r\n const storage = this.#getStorage(option);\r\n storage.removeItem(key);\r\n }\r\n\r\n /**\r\n * Deep Clone an toàn\r\n */\r\n #deepClone<T>(val: T): T {\r\n if (val === undefined || val === null) return val;\r\n return JSON.parse(JSON.stringify(val));\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-storage.mjs","sources":["../../../projects/sd-angular/services/storage/src/storage.model.ts","../../../projects/sd-angular/services/storage/src/storage.service.ts","../../../projects/sd-angular/services/storage/sd-angular-core-services-storage.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\nimport { BehaviorSubject, Observable } from 'rxjs';\n\nexport interface SdStorageOption<T = any> {\n type?: 'session';\n default?: T;\n args?: Record<string, any>;\n}\n\nexport interface SdStorage<T = any> {\n get: () => T;\n set: (data: T) => void;\n // Ghi vào storage nhưng KHÔNG emit subject. Dùng cho thay đổi UI-only\n // (vd: column width) để tránh re-trigger các subscriber gây reload data.\n setSilent: (data: T) => void;\n has: () => boolean;\n remove: () => void;\n subject: BehaviorSubject<T>;\n observer: Observable<T>;\n}\n\nexport interface ISdStorageConfiguration {\n key?: (key: string) => string;\n}\n\nexport const SD_STORAGE_CONFIG = new InjectionToken<ISdStorageConfiguration>('storage.configuration');\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { inject, Injectable } from '@angular/core';\nimport { Utilities } from '@sdcorejs/utils/fns';\nimport { BehaviorSubject } from 'rxjs';\nimport { map } from 'rxjs/operators';\nimport { ISdStorageConfiguration, SD_STORAGE_CONFIG, SdStorage, SdStorageOption } from './storage.model';\n\ninterface StorageCacheEntry<T> {\n data: T;\n createdOn: Date;\n}\n\n@Injectable({\n providedIn: 'root',\n})\nexport class SdStorageService {\n // Dùng Map để quản lý bộ nhớ tốt hơn Record\n #memoryCache = new Map<string, StorageCacheEntry<any>>();\n #subjects = new Map<string, BehaviorSubject<any>>();\n private readonly configuration: ISdStorageConfiguration | null = inject(SD_STORAGE_CONFIG, { optional: true });\n\n create<T = any>(key: string | object, option?: SdStorageOption<T>): SdStorage<T> {\n if (!key) throw new Error('Key is required');\n\n // 1. Xử lý Key\n let hashKey: string;\n if (typeof key === 'string') {\n hashKey = key;\n } else if (typeof key === 'object') {\n hashKey = Utilities.hash(key);\n } else {\n throw new Error('Invalid key type');\n }\n\n if (this.configuration?.key) {\n hashKey = this.configuration.key(hashKey);\n }\n\n // 2. Init Subject: Đọc dữ liệu từ Storage ngay lập tức để Subject có giá trị đúng\n if (!this.#subjects.has(hashKey)) {\n const existingData = this.#internalGet<T>(hashKey, option);\n // Fix Type: as T | undefined\n this.#subjects.set(hashKey, new BehaviorSubject<T | undefined>(existingData ?? option?.default));\n }\n\n const subject = this.#subjects.get(hashKey)!;\n\n // 3. Define Helpers\n const get = () => {\n const val = this.#internalGet<T>(hashKey, option);\n return (val ?? option?.default) as T;\n };\n\n const set = (data: T) => {\n this.#internalSet(hashKey, data, option);\n subject.next(data);\n };\n\n const setSilent = (data: T) => {\n this.#internalSet(hashKey, data, option);\n // Cố tình KHÔNG gọi subject.next — consumer dùng kênh riêng để thông báo\n };\n\n const has = () => {\n return this.#internalGet<T>(hashKey, option) !== undefined;\n };\n\n const remove = () => {\n this.#internalRemove(hashKey, option);\n subject.next(undefined);\n };\n\n // Hàm dọn dẹp bộ nhớ (quan trọng)\n const destroy = () => {\n subject.complete();\n this.#subjects.delete(hashKey);\n this.#memoryCache.delete(hashKey);\n };\n\n return {\n get,\n set,\n setSilent,\n has,\n remove,\n // @ts-ignore: Bổ sung vào interface nếu cần\n destroy,\n subject: subject,\n observer: subject.asObservable().pipe(map(() => get())),\n };\n }\n\n // --- PRIVATE CORE LOGIC ---\n\n /**\n * Helper xác định loại Storage đang dùng\n */\n #getStorage(option?: SdStorageOption<any>): Storage {\n return option?.type === 'session' ? sessionStorage : localStorage;\n }\n\n /**\n * Đọc dữ liệu: Memory -> Storage -> Parse\n */\n #internalGet<T>(key: string, option?: SdStorageOption<T>): T | undefined {\n // 1. Check Memory (Nhanh nhất)\n let entry = this.#memoryCache.get(key);\n\n // 2. Check Storage (Nếu memory chưa có hoặc mới F5)\n if (!entry) {\n const storage = this.#getStorage(option);\n const raw = storage.getItem(key);\n if (raw) {\n try {\n const parsed = JSON.parse(raw);\n // Convert string date back to Date object nếu cần\n entry = {\n data: parsed.data,\n createdOn: new Date(parsed.createdOn)\n };\n // Sync ngược vào RAM\n this.#memoryCache.set(key, entry);\n } catch (e) {\n console.warn('Storage parse error', e);\n this.#internalRemove(key, option); // Dữ liệu lỗi -> Xóa\n }\n }\n }\n\n if (!entry) return undefined;\n\n return this.#deepClone(entry.data);\n }\n\n /**\n * Ghi dữ liệu: Memory -> Storage\n */\n #internalSet<T>(key: string, data: T, option?: SdStorageOption<T>): void {\n const clonedData = this.#deepClone(data);\n\n const entry: StorageCacheEntry<T> = {\n data: clonedData,\n createdOn: new Date(),\n };\n\n // 1. Lưu Memory\n this.#memoryCache.set(key, entry);\n\n // 2. Lưu Storage\n const storage = this.#getStorage(option);\n try {\n storage.setItem(key, JSON.stringify(entry));\n } catch (e) {\n console.error('Storage quota exceeded', e);\n }\n }\n\n /**\n * Xóa dữ liệu\n */\n #internalRemove(key: string, option?: SdStorageOption<any>): void {\n this.#memoryCache.delete(key);\n const storage = this.#getStorage(option);\n storage.removeItem(key);\n }\n\n /**\n * Deep Clone an toàn\n */\n #deepClone<T>(val: T): T {\n if (val === undefined || val === null) return val;\n return JSON.parse(JSON.stringify(val));\n }\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-utilities-data-state.mjs","sources":["../../../projects/sd-angular/utilities/data-state/src/data-state.ts","../../../projects/sd-angular/utilities/data-state/sd-angular-core-utilities-data-state.ts"],"sourcesContent":["/**\r\n * Serialize a value for the `data-value` attribute consumed by QA automation.\r\n *\r\n * null/undefined/empty-string → ''.\r\n * Date → ISO string.\r\n * Array / object → JSON.stringify, '' on failure (circular refs).\r\n * Primitives → String().\r\n */\r\nexport function sdSerializeDataValue(value: unknown): string {\r\n if (value === null || value === undefined || value === '') return '';\r\n if (value instanceof Date) return value.toISOString();\r\n if (Array.isArray(value) || (typeof value === 'object' && value !== null)) {\r\n try { return JSON.stringify(value); } catch { return ''; }\r\n }\r\n return String(value);\r\n}\r\n\r\n/** True when the value should drive `data-empty=\"true\"` on a form control. */\r\nexport function sdIsEmpty(value: unknown): boolean {\r\n if (value === null || value === undefined || value === '') return true;\r\n if (Array.isArray(value)) return value.length === 0;\r\n return false;\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"AAAA;;;;;;;AAOG;AACG,SAAU,oBAAoB,CAAC,KAAc,EAAA;IACjD,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE;AAAE,QAAA,OAAO,EAAE;IACpE,IAAI,KAAK,YAAY,IAAI;AAAE,QAAA,OAAO,KAAK,CAAC,WAAW,EAAE;AACrD,IAAA,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC,EAAE;AACzE,QAAA,IAAI;AAAE,YAAA,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;QAAE;AAAE,QAAA,MAAM;AAAE,YAAA,OAAO,EAAE;QAAE;IAC3D;AACA,IAAA,OAAO,MAAM,CAAC,KAAK,CAAC;AACtB;AAEA;AACM,SAAU,SAAS,CAAC,KAAc,EAAA;IACtC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE;AAAE,QAAA,OAAO,IAAI;AACtE,IAAA,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;AAAE,QAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACnD,IAAA,OAAO,KAAK;AACd;;ACtBA;;AAEG;;;;"}
1
+ {"version":3,"file":"sd-angular-core-utilities-data-state.mjs","sources":["../../../projects/sd-angular/utilities/data-state/src/data-state.ts","../../../projects/sd-angular/utilities/data-state/sd-angular-core-utilities-data-state.ts"],"sourcesContent":["/**\n * Serialize a value for the `data-value` attribute consumed by QA automation.\n *\n * null/undefined/empty-string → ''.\n * Date → ISO string.\n * Array / object → JSON.stringify, '' on failure (circular refs).\n * Primitives → String().\n */\nexport function sdSerializeDataValue(value: unknown): string {\n if (value === null || value === undefined || value === '') return '';\n if (value instanceof Date) return value.toISOString();\n if (Array.isArray(value) || (typeof value === 'object' && value !== null)) {\n try { return JSON.stringify(value); } catch { return ''; }\n }\n return String(value);\n}\n\n/** True when the value should drive `data-empty=\"true\"` on a form control. */\nexport function sdIsEmpty(value: unknown): boolean {\n if (value === null || value === undefined || value === '') return true;\n if (Array.isArray(value)) return value.length === 0;\n return false;\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"AAAA;;;;;;;AAOG;AACG,SAAU,oBAAoB,CAAC,KAAc,EAAA;IACjD,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE;AAAE,QAAA,OAAO,EAAE;IACpE,IAAI,KAAK,YAAY,IAAI;AAAE,QAAA,OAAO,KAAK,CAAC,WAAW,EAAE;AACrD,IAAA,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC,EAAE;AACzE,QAAA,IAAI;AAAE,YAAA,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;QAAE;AAAE,QAAA,MAAM;AAAE,YAAA,OAAO,EAAE;QAAE;IAC3D;AACA,IAAA,OAAO,MAAM,CAAC,KAAK,CAAC;AACtB;AAEA;AACM,SAAU,SAAS,CAAC,KAAc,EAAA;IACtC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE;AAAE,QAAA,OAAO,IAAI;AACtE,IAAA,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;AAAE,QAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACnD,IAAA,OAAO,KAAK;AACd;;ACtBA;;AAEG;;;;"}