@sd-angular/core 19.0.0-beta.90 → 19.0.0-beta.91

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 (257) hide show
  1. package/assets/scss/README.md +524 -0
  2. package/assets/scss/core/bootstrap.scss +0 -125
  3. package/assets/scss/core/utilities/_base.scss +333 -0
  4. package/assets/scss/core/utilities/_border.scss +22 -0
  5. package/assets/scss/core/utilities/_display.scss +10 -0
  6. package/assets/scss/core/utilities/_elevation.scss +80 -0
  7. package/assets/scss/core/utilities/_flexbox.scss +54 -0
  8. package/assets/scss/core/utilities/_gap.scss +9 -0
  9. package/assets/scss/core/utilities/_grid.scss +142 -0
  10. package/assets/scss/core/utilities/_index.scss +17 -0
  11. package/assets/scss/core/utilities/_misc.scss +20 -0
  12. package/assets/scss/core/utilities/_overflow.scss +9 -0
  13. package/assets/scss/core/utilities/_position.scss +8 -0
  14. package/assets/scss/core/utilities/_sizing.scss +28 -0
  15. package/assets/scss/core/utilities/_spacing.scss +31 -0
  16. package/assets/scss/core/utilities/_typography.scss +99 -0
  17. package/assets/scss/sd-core.scss +4 -6
  18. package/fesm2022/sd-angular-core-components-import-excel.mjs +2 -2
  19. package/fesm2022/sd-angular-core-components-import-excel.mjs.map +1 -1
  20. package/fesm2022/sd-angular-core-components-modal.mjs +2 -2
  21. package/fesm2022/sd-angular-core-components-modal.mjs.map +1 -1
  22. package/fesm2022/sd-angular-core-components-table.mjs +3 -3
  23. package/fesm2022/sd-angular-core-components-table.mjs.map +1 -1
  24. package/fesm2022/sd-angular-core-components-upload-file.mjs +4 -4
  25. package/fesm2022/sd-angular-core-components-upload-file.mjs.map +1 -1
  26. package/fesm2022/sd-angular-core-components-workflow.mjs +6 -6
  27. package/fesm2022/sd-angular-core-components-workflow.mjs.map +1 -1
  28. package/fesm2022/sd-angular-core-forms-autocomplete.mjs +2 -2
  29. package/fesm2022/sd-angular-core-forms-autocomplete.mjs.map +1 -1
  30. package/fesm2022/sd-angular-core-forms-date-range.mjs +2 -2
  31. package/fesm2022/sd-angular-core-forms-date-range.mjs.map +1 -1
  32. package/fesm2022/sd-angular-core-forms-date.mjs +2 -2
  33. package/fesm2022/sd-angular-core-forms-date.mjs.map +1 -1
  34. package/fesm2022/sd-angular-core-forms-datetime.mjs +428 -70
  35. package/fesm2022/sd-angular-core-forms-datetime.mjs.map +1 -1
  36. package/fesm2022/sd-angular-core-forms-select.mjs +2 -2
  37. package/fesm2022/sd-angular-core-forms-select.mjs.map +1 -1
  38. package/fesm2022/sd-angular-core-modules-layout.mjs +1 -1
  39. package/fesm2022/sd-angular-core-modules-layout.mjs.map +1 -1
  40. package/forms/datetime/src/datetime.component.d.ts +16 -6
  41. package/forms/datetime/src/popup/sd-datetime-picker.component.d.ts +38 -0
  42. package/forms/datetime/src/popup/sd-time-spinner.component.d.ts +41 -0
  43. package/package.json +53 -53
  44. package/sd-angular-core-19.0.0-beta.91.tgz +0 -0
  45. package/assets/img/1D UX System.zip +0 -0
  46. package/assets/img/Popup/Vector.png +0 -0
  47. package/assets/img/empty.png +0 -0
  48. package/assets/img/empty.svg +0 -27
  49. package/assets/img/file-types/eps/001-file.eps +0 -143
  50. package/assets/img/file-types/eps/002-file-1.eps +0 -136
  51. package/assets/img/file-types/eps/003-file-2.eps +0 -130
  52. package/assets/img/file-types/eps/004-file-3.eps +0 -127
  53. package/assets/img/file-types/eps/005-file-4.eps +0 -120
  54. package/assets/img/file-types/eps/006-file-5.eps +0 -133
  55. package/assets/img/file-types/eps/007-file-6.eps +0 -133
  56. package/assets/img/file-types/eps/008-file-7.eps +0 -144
  57. package/assets/img/file-types/eps/009-file-8.eps +0 -150
  58. package/assets/img/file-types/eps/010-file-9.eps +0 -155
  59. package/assets/img/file-types/eps/011-file-10.eps +0 -124
  60. package/assets/img/file-types/eps/012-file-11.eps +0 -147
  61. package/assets/img/file-types/eps/013-file-12.eps +0 -125
  62. package/assets/img/file-types/eps/014-file-13.eps +0 -129
  63. package/assets/img/file-types/eps/015-file-14.eps +0 -143
  64. package/assets/img/file-types/eps/016-file-15.eps +0 -130
  65. package/assets/img/file-types/eps/017-file-16.eps +0 -197
  66. package/assets/img/file-types/eps/018-file-17.eps +0 -146
  67. package/assets/img/file-types/eps/019-file-18.eps +0 -131
  68. package/assets/img/file-types/eps/020-file-19.eps +0 -137
  69. package/assets/img/file-types/eps/021-file-20.eps +0 -134
  70. package/assets/img/file-types/eps/022-file-21.eps +0 -130
  71. package/assets/img/file-types/eps/023-file-22.eps +0 -161
  72. package/assets/img/file-types/eps/024-file-23.eps +0 -144
  73. package/assets/img/file-types/eps/025-file-24.eps +0 -164
  74. package/assets/img/file-types/eps/026-file-25.eps +0 -135
  75. package/assets/img/file-types/eps/027-file-26.eps +0 -124
  76. package/assets/img/file-types/eps/028-file-27.eps +0 -120
  77. package/assets/img/file-types/eps/029-file-28.eps +0 -141
  78. package/assets/img/file-types/eps/030-file-29.eps +0 -130
  79. package/assets/img/file-types/eps/031-file-30.eps +0 -157
  80. package/assets/img/file-types/eps/032-file-31.eps +0 -139
  81. package/assets/img/file-types/eps/033-file-32.eps +0 -139
  82. package/assets/img/file-types/eps/034-file-33.eps +0 -189
  83. package/assets/img/file-types/eps/035-file-34.eps +0 -162
  84. package/assets/img/file-types/eps/036-file-35.eps +0 -142
  85. package/assets/img/file-types/eps/037-file-36.eps +0 -123
  86. package/assets/img/file-types/eps/038-file-37.eps +0 -127
  87. package/assets/img/file-types/eps/039-file-38.eps +0 -146
  88. package/assets/img/file-types/eps/040-file-39.eps +0 -126
  89. package/assets/img/file-types/eps/041-file-40.eps +0 -117
  90. package/assets/img/file-types/eps/042-file-41.eps +0 -156
  91. package/assets/img/file-types/eps/043-file-42.eps +0 -118
  92. package/assets/img/file-types/eps/044-file-43.eps +0 -172
  93. package/assets/img/file-types/eps/045-file-44.eps +0 -201
  94. package/assets/img/file-types/eps/046-file-45.eps +0 -94
  95. package/assets/img/file-types/eps/047-file-46.eps +0 -176
  96. package/assets/img/file-types/eps/048-file-47.eps +0 -238
  97. package/assets/img/file-types/eps/049-file-48.eps +0 -187
  98. package/assets/img/file-types/eps/050-file-49.eps +0 -137
  99. package/assets/img/file-types/license/license.pdf +0 -0
  100. package/assets/img/file-types/png/3ds.png +0 -0
  101. package/assets/img/file-types/png/ai.png +0 -0
  102. package/assets/img/file-types/png/asp.png +0 -0
  103. package/assets/img/file-types/png/avi.png +0 -0
  104. package/assets/img/file-types/png/bin.png +0 -0
  105. package/assets/img/file-types/png/com.png +0 -0
  106. package/assets/img/file-types/png/css.png +0 -0
  107. package/assets/img/file-types/png/csv.png +0 -0
  108. package/assets/img/file-types/png/dbf.png +0 -0
  109. package/assets/img/file-types/png/dll.png +0 -0
  110. package/assets/img/file-types/png/doc.png +0 -0
  111. package/assets/img/file-types/png/docx.png +0 -0
  112. package/assets/img/file-types/png/dwg.png +0 -0
  113. package/assets/img/file-types/png/eml.png +0 -0
  114. package/assets/img/file-types/png/eps.png +0 -0
  115. package/assets/img/file-types/png/exe.png +0 -0
  116. package/assets/img/file-types/png/file.png +0 -0
  117. package/assets/img/file-types/png/fla.png +0 -0
  118. package/assets/img/file-types/png/gif.png +0 -0
  119. package/assets/img/file-types/png/htm.png +0 -0
  120. package/assets/img/file-types/png/ico.png +0 -0
  121. package/assets/img/file-types/png/ini.png +0 -0
  122. package/assets/img/file-types/png/iso.png +0 -0
  123. package/assets/img/file-types/png/jar.png +0 -0
  124. package/assets/img/file-types/png/jpg.png +0 -0
  125. package/assets/img/file-types/png/js.png +0 -0
  126. package/assets/img/file-types/png/mkv.png +0 -0
  127. package/assets/img/file-types/png/mov.png +0 -0
  128. package/assets/img/file-types/png/mp3.png +0 -0
  129. package/assets/img/file-types/png/mp4.png +0 -0
  130. package/assets/img/file-types/png/nfo.png +0 -0
  131. package/assets/img/file-types/png/obj.png +0 -0
  132. package/assets/img/file-types/png/otf.png +0 -0
  133. package/assets/img/file-types/png/pdf.png +0 -0
  134. package/assets/img/file-types/png/pkg.png +0 -0
  135. package/assets/img/file-types/png/png.png +0 -0
  136. package/assets/img/file-types/png/ppt.png +0 -0
  137. package/assets/img/file-types/png/pptx.png +0 -0
  138. package/assets/img/file-types/png/psd.png +0 -0
  139. package/assets/img/file-types/png/rtf.png +0 -0
  140. package/assets/img/file-types/png/svg.png +0 -0
  141. package/assets/img/file-types/png/tiff.png +0 -0
  142. package/assets/img/file-types/png/ttf.png +0 -0
  143. package/assets/img/file-types/png/txt.png +0 -0
  144. package/assets/img/file-types/png/vcf.png +0 -0
  145. package/assets/img/file-types/png/wav.png +0 -0
  146. package/assets/img/file-types/png/wmv.png +0 -0
  147. package/assets/img/file-types/png/xls.png +0 -0
  148. package/assets/img/file-types/png/xlsx.png +0 -0
  149. package/assets/img/file-types/png/xml.png +0 -0
  150. package/assets/img/file-types/png/zip.png +0 -0
  151. package/assets/img/file-types/psd/001-file.psd +0 -0
  152. package/assets/img/file-types/psd/002-file-1.psd +0 -0
  153. package/assets/img/file-types/psd/003-file-2.psd +0 -0
  154. package/assets/img/file-types/psd/004-file-3.psd +0 -0
  155. package/assets/img/file-types/psd/005-file-4.psd +0 -0
  156. package/assets/img/file-types/psd/006-file-5.psd +0 -0
  157. package/assets/img/file-types/psd/007-file-6.psd +0 -0
  158. package/assets/img/file-types/psd/008-file-7.psd +0 -0
  159. package/assets/img/file-types/psd/009-file-8.psd +0 -0
  160. package/assets/img/file-types/psd/010-file-9.psd +0 -0
  161. package/assets/img/file-types/psd/011-file-10.psd +0 -0
  162. package/assets/img/file-types/psd/012-file-11.psd +0 -0
  163. package/assets/img/file-types/psd/013-file-12.psd +0 -0
  164. package/assets/img/file-types/psd/014-file-13.psd +0 -0
  165. package/assets/img/file-types/psd/015-file-14.psd +0 -0
  166. package/assets/img/file-types/psd/016-file-15.psd +0 -0
  167. package/assets/img/file-types/psd/017-file-16.psd +0 -0
  168. package/assets/img/file-types/psd/018-file-17.psd +0 -0
  169. package/assets/img/file-types/psd/019-file-18.psd +0 -0
  170. package/assets/img/file-types/psd/020-file-19.psd +0 -0
  171. package/assets/img/file-types/psd/021-file-20.psd +0 -0
  172. package/assets/img/file-types/psd/022-file-21.psd +0 -0
  173. package/assets/img/file-types/psd/023-file-22.psd +0 -0
  174. package/assets/img/file-types/psd/024-file-23.psd +0 -0
  175. package/assets/img/file-types/psd/025-file-24.psd +0 -0
  176. package/assets/img/file-types/psd/026-file-25.psd +0 -0
  177. package/assets/img/file-types/psd/027-file-26.psd +0 -0
  178. package/assets/img/file-types/psd/028-file-27.psd +0 -0
  179. package/assets/img/file-types/psd/029-file-28.psd +0 -0
  180. package/assets/img/file-types/psd/030-file-29.psd +0 -0
  181. package/assets/img/file-types/psd/031-file-30.psd +0 -0
  182. package/assets/img/file-types/psd/032-file-31.psd +0 -0
  183. package/assets/img/file-types/psd/033-file-32.psd +0 -0
  184. package/assets/img/file-types/psd/034-file-33.psd +0 -0
  185. package/assets/img/file-types/psd/035-file-34.psd +0 -0
  186. package/assets/img/file-types/psd/036-file-35.psd +0 -0
  187. package/assets/img/file-types/psd/037-file-36.psd +0 -0
  188. package/assets/img/file-types/psd/038-file-37.psd +0 -0
  189. package/assets/img/file-types/psd/039-file-38.psd +0 -0
  190. package/assets/img/file-types/psd/040-file-39.psd +0 -0
  191. package/assets/img/file-types/psd/041-file-40.psd +0 -0
  192. package/assets/img/file-types/psd/042-file-41.psd +0 -0
  193. package/assets/img/file-types/psd/043-file-42.psd +0 -0
  194. package/assets/img/file-types/psd/044-file-43.psd +0 -0
  195. package/assets/img/file-types/psd/045-file-44.psd +0 -0
  196. package/assets/img/file-types/psd/046-file-45.psd +0 -0
  197. package/assets/img/file-types/psd/047-file-46.psd +0 -0
  198. package/assets/img/file-types/psd/048-file-47.psd +0 -0
  199. package/assets/img/file-types/psd/049-file-48.psd +0 -0
  200. package/assets/img/file-types/psd/050-file-49.psd +0 -0
  201. package/assets/img/file-types/svg/001-file.svg +0 -1
  202. package/assets/img/file-types/svg/002-file-1.svg +0 -1
  203. package/assets/img/file-types/svg/003-file-2.svg +0 -1
  204. package/assets/img/file-types/svg/004-file-3.svg +0 -1
  205. package/assets/img/file-types/svg/005-file-4.svg +0 -1
  206. package/assets/img/file-types/svg/006-file-5.svg +0 -1
  207. package/assets/img/file-types/svg/007-file-6.svg +0 -1
  208. package/assets/img/file-types/svg/008-file-7.svg +0 -1
  209. package/assets/img/file-types/svg/009-file-8.svg +0 -1
  210. package/assets/img/file-types/svg/010-file-9.svg +0 -1
  211. package/assets/img/file-types/svg/011-file-10.svg +0 -1
  212. package/assets/img/file-types/svg/012-file-11.svg +0 -1
  213. package/assets/img/file-types/svg/013-file-12.svg +0 -1
  214. package/assets/img/file-types/svg/014-file-13.svg +0 -1
  215. package/assets/img/file-types/svg/015-file-14.svg +0 -1
  216. package/assets/img/file-types/svg/016-file-15.svg +0 -1
  217. package/assets/img/file-types/svg/017-file-16.svg +0 -1
  218. package/assets/img/file-types/svg/018-file-17.svg +0 -1
  219. package/assets/img/file-types/svg/019-file-18.svg +0 -1
  220. package/assets/img/file-types/svg/020-file-19.svg +0 -1
  221. package/assets/img/file-types/svg/021-file-20.svg +0 -1
  222. package/assets/img/file-types/svg/022-file-21.svg +0 -1
  223. package/assets/img/file-types/svg/023-file-22.svg +0 -1
  224. package/assets/img/file-types/svg/024-file-23.svg +0 -1
  225. package/assets/img/file-types/svg/025-file-24.svg +0 -1
  226. package/assets/img/file-types/svg/026-file-25.svg +0 -1
  227. package/assets/img/file-types/svg/027-file-26.svg +0 -1
  228. package/assets/img/file-types/svg/028-file-27.svg +0 -1
  229. package/assets/img/file-types/svg/029-file-28.svg +0 -1
  230. package/assets/img/file-types/svg/030-file-29.svg +0 -1
  231. package/assets/img/file-types/svg/031-file-30.svg +0 -1
  232. package/assets/img/file-types/svg/032-file-31.svg +0 -1
  233. package/assets/img/file-types/svg/033-file-32.svg +0 -1
  234. package/assets/img/file-types/svg/034-file-33.svg +0 -1
  235. package/assets/img/file-types/svg/035-file-34.svg +0 -1
  236. package/assets/img/file-types/svg/036-file-35.svg +0 -1
  237. package/assets/img/file-types/svg/037-file-36.svg +0 -1
  238. package/assets/img/file-types/svg/038-file-37.svg +0 -1
  239. package/assets/img/file-types/svg/039-file-38.svg +0 -1
  240. package/assets/img/file-types/svg/040-file-39.svg +0 -1
  241. package/assets/img/file-types/svg/041-file-40.svg +0 -1
  242. package/assets/img/file-types/svg/042-file-41.svg +0 -1
  243. package/assets/img/file-types/svg/043-file-42.svg +0 -1
  244. package/assets/img/file-types/svg/044-file-43.svg +0 -1
  245. package/assets/img/file-types/svg/045-file-44.svg +0 -1
  246. package/assets/img/file-types/svg/046-file-45.svg +0 -1
  247. package/assets/img/file-types/svg/047-file-46.svg +0 -1
  248. package/assets/img/file-types/svg/048-file-47.svg +0 -1
  249. package/assets/img/file-types/svg/049-file-48.svg +0 -1
  250. package/assets/img/file-types/svg/050-file-49.svg +0 -1
  251. package/assets/img/plus-search-zoom-white.png +0 -0
  252. package/assets/scss/core/cursor.scss +0 -3
  253. package/assets/scss/core/elevation.scss +0 -57
  254. package/assets/scss/core/grid.scss +0 -40
  255. package/assets/scss/core/print.scss +0 -47
  256. package/assets/scss/core/typography.scss +0 -121
  257. package/sd-angular-core-19.0.0-beta.90.tgz +0 -0
@@ -0,0 +1,8 @@
1
+ // --------------------------------------------------------------------------
2
+ // Position
3
+ // --------------------------------------------------------------------------
4
+ .position-relative { position: relative !important; }
5
+ .position-absolute { position: absolute !important; }
6
+ .position-fixed { position: fixed !important; }
7
+ .position-sticky { position: sticky !important; }
8
+ .position-static { position: static !important; }
@@ -0,0 +1,28 @@
1
+ // --------------------------------------------------------------------------
2
+ // Sizing – Width & Height (px-based, 0–200)
3
+ // w-0 … w-200 | h-0 … h-200
4
+ // --------------------------------------------------------------------------
5
+ @for $i from 0 through 200 {
6
+ .w-#{$i} { width: #{$i}px !important; }
7
+ .h-#{$i} { height: #{$i}px !important; }
8
+ }
9
+
10
+ // Percentage / keyword shorthands
11
+ .w-full { width: 100% !important; }
12
+ .w-100 { width: 100% !important; } // Bootstrap compat alias
13
+ .w-auto { width: auto !important; }
14
+ .w-screen { width: 100vw !important; }
15
+ .w-fit { width: fit-content !important; }
16
+
17
+ .h-full { height: 100% !important; }
18
+ .h-100 { height: 100% !important; } // Bootstrap compat alias
19
+ .h-auto { height: auto !important; }
20
+ .h-screen { height: 100vh !important; }
21
+ .h-fit { height: fit-content !important; }
22
+
23
+ .min-h-full { min-height: 100% !important; }
24
+ .min-h-screen { min-height: 100vh !important; }
25
+ .min-w-full { min-width: 100% !important; }
26
+
27
+ .max-h-full { max-height: 100% !important; }
28
+ .max-w-full { max-width: 100% !important; }
@@ -0,0 +1,31 @@
1
+ // --------------------------------------------------------------------------
2
+ // Spacing – Margin & Padding (px-based, 0–200)
3
+ // m-0 … m-200 | mt-* | mr-* | mb-* | ml-* | mx-* | my-*
4
+ // p-0 … p-200 | pt-* | pr-* | pb-* | pl-* | px-* | py-*
5
+ // --------------------------------------------------------------------------
6
+ @for $i from 0 through 200 {
7
+ .m-#{$i} { margin: #{$i}px !important; }
8
+ .mt-#{$i} { margin-top: #{$i}px !important; }
9
+ .mr-#{$i} { margin-right: #{$i}px !important; }
10
+ .mb-#{$i} { margin-bottom: #{$i}px !important; }
11
+ .ml-#{$i} { margin-left: #{$i}px !important; }
12
+ .mx-#{$i} { margin-left: #{$i}px !important; margin-right: #{$i}px !important; }
13
+ .my-#{$i} { margin-top: #{$i}px !important; margin-bottom: #{$i}px !important; }
14
+
15
+ .p-#{$i} { padding: #{$i}px !important; }
16
+ .pt-#{$i} { padding-top: #{$i}px !important; }
17
+ .pr-#{$i} { padding-right: #{$i}px !important; }
18
+ .pb-#{$i} { padding-bottom: #{$i}px !important; }
19
+ .pl-#{$i} { padding-left: #{$i}px !important; }
20
+ .px-#{$i} { padding-left: #{$i}px !important; padding-right: #{$i}px !important; }
21
+ .py-#{$i} { padding-top: #{$i}px !important; padding-bottom: #{$i}px !important; }
22
+ }
23
+
24
+ // Auto margin helpers
25
+ .m-auto { margin: auto !important; }
26
+ .mt-auto { margin-top: auto !important; }
27
+ .mr-auto { margin-right: auto !important; }
28
+ .mb-auto { margin-bottom: auto !important; }
29
+ .ml-auto { margin-left: auto !important; }
30
+ .mx-auto { margin-left: auto !important; margin-right: auto !important; }
31
+ .my-auto { margin-top: auto !important; margin-bottom: auto !important; }
@@ -0,0 +1,99 @@
1
+ // --------------------------------------------------------------------------
2
+ // SCSS variables — dùng nội bộ trong scss, không output CSS
3
+ // Đặt tên theo thang đọc được: fw = font-weight, fs = font-size
4
+ // --------------------------------------------------------------------------
5
+ $fw-lighter: 400;
6
+ $fw-normal: 500;
7
+ $fw-bold: 600;
8
+
9
+ $fs-xs: 11.2px;
10
+ $fs-small: 14px;
11
+ $fs-normal: 16px;
12
+ $fs-regular: 18px;
13
+ $fs-medium: 21px;
14
+ $fs-large: 24px;
15
+ $fs-xl: 28px;
16
+ $fs-xxl: 38px;
17
+ $fs-xxxl: 42px;
18
+
19
+ // --------------------------------------------------------------------------
20
+ // Design token classes — hệ thống typography của SD Angular
21
+ // Quy ước: T{size}{weight} | M = Medium (500), R = Regular (400)
22
+ // Mỗi class bao gồm font-size + font-weight + line-height chuẩn hóa
23
+ // --------------------------------------------------------------------------
24
+ .T48M { font-size: 48px; font-weight: 500; line-height: 56px; }
25
+ .T48R { font-size: 48px; font-weight: 400; line-height: 56px; }
26
+
27
+ .T32M { font-size: 32px; font-weight: 500; line-height: 48px; }
28
+ .T32R { font-size: 32px; font-weight: 400; line-height: 48px; }
29
+
30
+ .T24M { font-size: 24px; font-weight: 500; line-height: 28px; }
31
+ .T24R { font-size: 20px; font-weight: 400; line-height: 28px; }
32
+
33
+ .T20M { font-size: 20px; font-weight: 500; line-height: 28px; }
34
+ .T20R { font-size: 20px; font-weight: 400; line-height: 28px; }
35
+
36
+ .T18M { font-size: 18px; font-weight: 500; line-height: 28px; }
37
+ .T18R { font-size: 18px; font-weight: 400; line-height: 28px; }
38
+
39
+ .T16M { font-size: 16px; font-weight: 500; line-height: 24px; }
40
+ .T16R { font-size: 16px; font-weight: 400; line-height: 24px; }
41
+
42
+ .T14M { font-size: 14px; font-weight: 500; line-height: 20px; }
43
+ .T14R { font-size: 14px; font-weight: 400; line-height: 20px; }
44
+
45
+ .T12M { font-size: 12px; font-weight: 500; line-height: 16px; }
46
+ // !important vì T12R thường bị override bởi material components
47
+ .T12R { font-size: 12px !important; font-weight: 400; line-height: 16px; }
48
+
49
+ .T10M { font-size: 10px; font-weight: 500; line-height: 12px; }
50
+ .T10R { font-size: 10px; font-weight: 400; line-height: 12px; }
51
+
52
+ // --------------------------------------------------------------------------
53
+ // Font-size utilities (px-based, 0–200)
54
+ // fs-0 … fs-200 — dùng khi cần ghi đè nhanh, không dùng thay token
55
+ // --------------------------------------------------------------------------
56
+ @for $i from 0 through 200 {
57
+ .fs-#{$i} { font-size: #{$i}px !important; }
58
+ }
59
+
60
+ // --------------------------------------------------------------------------
61
+ // Font-weight utilities
62
+ // --------------------------------------------------------------------------
63
+ .font-weight-light { font-weight: 300 !important; }
64
+ .font-weight-normal { font-weight: 400 !important; }
65
+ .font-weight-medium { font-weight: 500 !important; }
66
+ .font-weight-bold { font-weight: 600 !important; }
67
+ .font-weight-bolder { font-weight: 700 !important; }
68
+
69
+ // --------------------------------------------------------------------------
70
+ // Text alignment
71
+ // --------------------------------------------------------------------------
72
+ .text-left { text-align: left !important; }
73
+ .text-center { text-align: center !important; }
74
+ .text-right { text-align: right !important; }
75
+ .text-justify { text-align: justify !important; }
76
+
77
+ // --------------------------------------------------------------------------
78
+ // Text wrapping & overflow
79
+ // --------------------------------------------------------------------------
80
+ .text-wrap { white-space: normal !important; }
81
+ .text-nowrap { white-space: nowrap !important; }
82
+ .text-ellipsis {
83
+ // Hiển thị "..." khi text tràn — cần container có width cố định
84
+ white-space: nowrap !important;
85
+ overflow: hidden !important;
86
+ text-overflow: ellipsis !important;
87
+ }
88
+ .text-break {
89
+ // Xuống dòng từng ký tự khi tràn — dùng cho URL, hash, code dài
90
+ overflow-wrap: break-word !important;
91
+ word-break: break-word !important;
92
+ }
93
+
94
+ // --------------------------------------------------------------------------
95
+ // Text transform
96
+ // --------------------------------------------------------------------------
97
+ .text-uppercase { text-transform: uppercase !important; }
98
+ .text-lowercase { text-transform: lowercase !important; }
99
+ .text-capitalize { text-transform: capitalize !important; }
@@ -1,13 +1,11 @@
1
1
  @use '../fonts/fonts.scss';
2
- @use './core/bootstrap.scss';
3
- @use './core/cursor.scss';
2
+ // Tạm thời giữ bootstrap.scss để so sánh — xóa sau khi confirm _base.scss OK
3
+ // @use './core/bootstrap.scss';
4
+ @use './core/utilities/base'; // Reset / Reboot — phải load trước tất cả
5
+ @use './core/utilities';
4
6
  @use './core/color.scss';
5
7
  @use './core/form.scss';
6
8
  @use './core/scrollbar.scss';
7
- @use './core/typography.scss';
8
- @use './core/print.scss';
9
- @use './core/elevation.scss';
10
- @use './core/grid.scss';
11
9
  @use './themes/default.scss';
12
10
  @use './themes/material-theme.scss';
13
11
 
@@ -538,7 +538,7 @@ class SdImportExcel {
538
538
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdImportExcel, deps: [{ token: i0.ChangeDetectorRef }, { token: i1$1.SdExcelService }, { token: i2.SdNotifyService }, { token: ColumnHiddenPipe }, { token: i4.SdLoadingService }], target: i0.ɵɵFactoryTarget.Component });
539
539
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: SdImportExcel, isStandalone: true, selector: "sd-import-excel", inputs: { option: "option" }, outputs: { sdClosed: "sdClosed" }, providers: [
540
540
  ColumnHiddenPipe
541
- ], viewQueries: [{ propertyName: "modal", first: true, predicate: SdModal, descendants: true }, { propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true }], ngImport: i0, template: "@if (option) {\r\n <sd-modal [title]=\"option.title || 'Nh\u1EADp d\u1EEF li\u1EC7u Excel'\" (sdClosed)=\"onClosed()\" #modal>\r\n <div class=\"row mx-0 mb-3 align-items-center\" style=\"min-height: 32px\">\r\n @if (excelItems.length) {\r\n <div class=\"d-flex\">\r\n <sd-button class=\"mr-2\" (click)=\"view('ALL')\" icon=\"cached\" title=\"Xem t\u1EA5t c\u1EA3\" size=\"sm\" type=\"outline\"></sd-button>\r\n\r\n <sd-button\r\n class=\"mr-2\"\r\n (click)=\"view('SUCCESS')\"\r\n icon=\"done\"\r\n title=\"{{ numberOfSuccess }}\"\r\n tooltip=\"S\u1ED1 d\u00F2ng d\u1EEF li\u1EC7u h\u1EE3p l\u1EC7\"\r\n size=\"sm\"\r\n color=\"success\">\r\n </sd-button>\r\n\r\n <sd-button\r\n class=\"mr-2\"\r\n (click)=\"view('WARNING')\"\r\n icon=\"warning\"\r\n title=\"{{ numberOfWarning }}\"\r\n tooltip=\"S\u1ED1 d\u00F2ng d\u1EEF li\u1EC7u c\u00F3 l\u1ED7i\"\r\n size=\"sm\"\r\n color=\"warning\">\r\n </sd-button>\r\n\r\n <sd-button\r\n (click)=\"view('ERROR')\"\r\n icon=\"error\"\r\n title=\"{{ numberOfError }}\"\r\n color=\"error\"\r\n tooltip=\"S\u1ED1 d\u00F2ng d\u1EEF li\u1EC7u c\u00F3 c\u1EA3nh b\u00E1o\"\r\n size=\"sm\">\r\n </sd-button>\r\n </div>\r\n }\r\n </div>\r\n\r\n <div class=\"sd-box border rounded\">\r\n <div class=\"sd-box-body p-0\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-striped table-sm table-hover table-bordered mb-0\">\r\n <thead class=\"thead-light\">\r\n <tr>\r\n <th class=\"text-center c-sticky-left\" style=\"width: 50px\">#</th>\r\n @if (filteredItems.length) {\r\n <th class=\"text-center\" style=\"min-width: 250px; width: 250px\">Tr\u1EA1ng th\u00E1i</th>\r\n }\r\n @for (column of option.columns; track column.field) {\r\n @if (column | columnHidden) {\r\n <th [ngStyle]=\"{ 'min-width': column.width || '300px', width: column.width || '300px' }\" [matTooltip]=\"column.title\">\r\n <span class=\"c-ellipsis\">\r\n {{ column.title }}\r\n </span>\r\n </th>\r\n }\r\n }\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n @if (viewItems.length) {\r\n @for (item of viewItems; track item.meta.excelIndex) {\r\n <tr>\r\n <td class=\"text-center c-sticky-left px-4\">\r\n <sd-badge\r\n type=\"tag\"\r\n [title]=\"item.meta.excelIndex\"\r\n [success]=\"!item.meta.warningMessages.length && !item.meta.errorMessages.length\"\r\n [warning]=\"!!item.meta.warningMessages.length && !item.meta.errorMessages.length\"\r\n [error]=\"!!item.meta.errorMessages.length\" />\r\n </td>\r\n\r\n <td style=\"min-width: 250px; width: 250px\">\r\n <div\r\n class=\"text-wrap\"\r\n [innerHTML]=\"\r\n item.meta.errorMessages[0] || item.meta.warningMessages[0] || '<span class=\\'text-success\\'>D\u1EEF li\u1EC7u h\u1EE3p l\u1EC7</span>'\r\n \"></div>\r\n </td>\r\n\r\n @for (column of option.columns; track column.field) {\r\n @if (column | columnHidden) {\r\n <td\r\n class=\"align-middle\"\r\n [ngClass]=\"{\r\n 'bg-warning-light': item.meta.warning[column.field] && !item.meta.error[column.field],\r\n 'bg-error-light': item.meta.error[column.field]\r\n }\"\r\n [matTooltip]=\"item.meta.error[column.field] || item.meta.warning[column.field]\"\r\n [ngStyle]=\"{ 'min-width': column.width || '300px' }\"\r\n matTooltipPosition=\"above\">\r\n <div class=\"c-ellipsis\">\r\n @if (column.type !== 'array') {\r\n <span [innerHTML]=\"item | columnTransform: column | async\"></span>\r\n }\r\n\r\n @if (column.type === 'array') {\r\n @let arrayItems = item.data[column.field]?.split(column.divideString);\r\n\r\n <div class=\"d-flex align-items-center justify-content-between\">\r\n <span>{{ arrayItems?.length || 0 }} {{ column.unitString }}</span>\r\n\r\n @if (arrayItems?.length) {\r\n <button\r\n mat-icon-button\r\n [matMenuTriggerFor]=\"menu\"\r\n class=\"c-mat-menu\"\r\n style=\"width: 24px; height: 24px; line-height: 24px\">\r\n <mat-icon style=\"font-size: 18px\">open_in_new</mat-icon>\r\n </button>\r\n\r\n <mat-menu #menu=\"matMenu\">\r\n <div\r\n class=\"px-3 py-2\"\r\n style=\"max-width: 300px; max-height: 250px; overflow: auto\"\r\n (click)=\"$event.stopPropagation()\"\r\n aria-hidden=\"true\">\r\n @for (val of arrayItems; track $index) {\r\n <div class=\"border-bottom py-2 text-wrap\" [innerHTML]=\"val\"></div>\r\n }\r\n </div>\r\n </mat-menu>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </td>\r\n }\r\n }\r\n </tr>\r\n }\r\n } @else {\r\n <tr>\r\n <td [attr.colspan]=\"option.columns.length + 2\" class=\"p-0 border-0 bg-white\">\r\n <div\r\n class=\"empty-state-wrapper\"\r\n (click)=\"downloadTemplate()\"\r\n matTooltip=\"Nh\u1EA5n \u0111\u1EC3 t\u1EA3i t\u1EC7p m\u1EABu v\u1EC1 m\u00E1y\"\r\n aria-hidden=\"true\">\r\n <mat-icon class=\"empty-icon\">cloud_download</mat-icon>\r\n\r\n <h4>Ch\u01B0a c\u00F3 d\u1EEF li\u1EC7u t\u1EA3i l\u00EAn</h4>\r\n <span class=\"text-small text-link\"> Nh\u1EA5n v\u00E0o \u0111\u00E2y \u0111\u1EC3 t\u1EA3i t\u1EC7p m\u1EABu </span>\r\n\r\n @if (isDownloadTemplate) {\r\n <div class=\"mt-3\">\r\n <mat-spinner diameter=\"24\" mode=\"indeterminate\"></mat-spinner>\r\n </div>\r\n }\r\n </div>\r\n </td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n\r\n <div class=\"sd-box-footer border-top\">\r\n <div class=\"d-flex align-items-center justify-content-end\">\r\n <mat-paginator [length]=\"filteredItems.length || 0\" hidePageSize showFirstLastButtons></mat-paginator>\r\n </div>\r\n </div>\r\n </div>\r\n <sd-button sdFooterLeft (click)=\"upload()\" prefixIcon=\"file_upload\" title=\"T\u1EA3i l\u00EAn\" size=\"sm\" color=\"info\" [loading]=\"uploading\">\r\n </sd-button>\r\n <div class=\"d-flex align-items-center\" sdFooter>\r\n @if (filteredItems.length) {\r\n <sd-button class=\"mr-4\" (click)=\"export()\" prefixIcon=\"get_app\" title=\"T\u1EA3i v\u1EC1\" size=\"sm\" color=\"success\" type=\"outline\">\r\n </sd-button>\r\n }\r\n <sd-button\r\n (click)=\"accept()\"\r\n title=\"X\u00E1c nh\u1EADn & L\u01B0u\"\r\n [disabled]=\"(numberOfSuccess === 0 && numberOfWarning === 0) || numberOfError > 0 || isUploaded\"\r\n color=\"primary\"\r\n type=\"fill\"\r\n size=\"sm\">\r\n </sd-button>\r\n </div>\r\n </sd-modal>\r\n}\r\n", styles: [".table-responsive{position:relative;min-height:50vh;height:50vh;overflow:auto;border:1px solid #dee2e6}.table{margin-bottom:0}.table thead th{position:sticky;top:0;background-color:#f8f9fa;border-bottom:2px solid #dee2e6;padding-top:8px;padding-bottom:8px;white-space:nowrap;z-index:10}.table thead th.c-sticky-left{z-index:20}.table tbody td{vertical-align:middle;padding-top:6px;padding-bottom:6px}.c-sticky-left{position:sticky;left:0;border-right:1px solid #dee2e6!important;border-left:none!important;z-index:5}.table-striped tbody tr:nth-of-type(odd) .c-sticky-left{background-color:#f2f2f2}.table-striped tbody tr:nth-of-type(2n) .c-sticky-left{background-color:#fff}.table-hover tbody tr:hover .c-sticky-left{background-color:#ececec}.table-striped tbody tr:nth-of-type(odd){background-color:#0000000d}.table-striped tbody tr:nth-of-type(2n){background-color:#fff}.empty-state-wrapper{height:100%;min-height:40vh;display:flex;flex-direction:column;align-items:center;justify-content:center;cursor:pointer;background-color:#f8f9fa;border:2px dashed #cbd5e0;border-radius:8px;margin:16px;transition:all .2s ease-in-out;color:#6c757d}.empty-state-wrapper:hover{background-color:#e3f2fd;border-color:#2196f3;color:#1976d2}.empty-state-wrapper:hover .empty-icon{transform:scale(1.1);color:#1976d2}.empty-state-wrapper:hover .text-link{text-decoration:underline}.empty-state-wrapper .empty-icon{font-size:64px;height:64px;width:64px;margin-bottom:16px;color:#a0aec0;transition:transform .2s}.empty-state-wrapper h4{font-weight:500;margin-bottom:4px}.c-ellipsis{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;padding:0 4px}.c-mat-menu{border:none;min-width:unset;padding:0 8px}.c-mat-menu mat-icon{font-size:18px;width:18px;height:18px;line-height:18px;vertical-align:middle}.cursor-pointer{cursor:pointer}:host ::ng-deep .mat-paginator-container{min-height:36px;height:36px;padding:0 8px}:host ::ng-deep .mat-paginator-range-label{margin:0 10px}:host ::ng-deep .mat-icon-button{width:32px;height:32px;line-height:32px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i6.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatPaginatorModule }, { kind: "component", type: i7.MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "component", type: SdButton, selector: "sd-button", inputs: ["autoId", "type", "color", "size", "fontSet", "title", "width", "tooltip", "prefixIcon", "suffixIcon", "disabled", "loading", "block", "htmlType"], outputs: ["click"] }, { kind: "component", type: SdModal, selector: "sd-modal", inputs: ["title", "color", "width", "height", "view", "modalClass", "lazyLoadContent", "hideClose", "disableBackdropClose"], outputs: ["sdClosed"] }, { kind: "pipe", type: ColumnTransformPipe, name: "columnTransform" }, { kind: "pipe", type: ColumnHiddenPipe, name: "columnHidden" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i9.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "directive", type: i9.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: SdBadge, selector: "sd-badge", inputs: ["type", "color", "primary", "secondary", "success", "info", "warning", "error", "fontSet", "title", "description", "tooltip", "icon", "size"], outputs: ["click"] }] });
541
+ ], viewQueries: [{ propertyName: "modal", first: true, predicate: SdModal, descendants: true }, { propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true }], ngImport: i0, template: "@if (option) {\r\n <sd-modal [title]=\"option.title || 'Nh\u1EADp d\u1EEF li\u1EC7u Excel'\" (sdClosed)=\"onClosed()\" #modal>\r\n <div class=\"d-flex align-items-center mb-12\" style=\"min-height: 32px\">\r\n @if (excelItems.length) {\r\n <div class=\"d-flex\">\r\n <sd-button class=\"mr-2\" (click)=\"view('ALL')\" icon=\"cached\" title=\"Xem t\u1EA5t c\u1EA3\" size=\"sm\" type=\"outline\"></sd-button>\r\n\r\n <sd-button\r\n class=\"mr-2\"\r\n (click)=\"view('SUCCESS')\"\r\n icon=\"done\"\r\n title=\"{{ numberOfSuccess }}\"\r\n tooltip=\"S\u1ED1 d\u00F2ng d\u1EEF li\u1EC7u h\u1EE3p l\u1EC7\"\r\n size=\"sm\"\r\n color=\"success\">\r\n </sd-button>\r\n\r\n <sd-button\r\n class=\"mr-2\"\r\n (click)=\"view('WARNING')\"\r\n icon=\"warning\"\r\n title=\"{{ numberOfWarning }}\"\r\n tooltip=\"S\u1ED1 d\u00F2ng d\u1EEF li\u1EC7u c\u00F3 l\u1ED7i\"\r\n size=\"sm\"\r\n color=\"warning\">\r\n </sd-button>\r\n\r\n <sd-button\r\n (click)=\"view('ERROR')\"\r\n icon=\"error\"\r\n title=\"{{ numberOfError }}\"\r\n color=\"error\"\r\n tooltip=\"S\u1ED1 d\u00F2ng d\u1EEF li\u1EC7u c\u00F3 c\u1EA3nh b\u00E1o\"\r\n size=\"sm\">\r\n </sd-button>\r\n </div>\r\n }\r\n </div>\r\n\r\n <div class=\"sd-box border rounded\">\r\n <div class=\"sd-box-body p-0\">\r\n <div class=\"table-responsive\">\r\n <table class=\"sd-table\">\r\n <thead>\r\n <tr>\r\n <th class=\"text-center c-sticky-left\" style=\"width: 50px\">#</th>\r\n @if (filteredItems.length) {\r\n <th class=\"text-center\" style=\"min-width: 250px; width: 250px\">Tr\u1EA1ng th\u00E1i</th>\r\n }\r\n @for (column of option.columns; track column.field) {\r\n @if (column | columnHidden) {\r\n <th [ngStyle]=\"{ 'min-width': column.width || '300px', width: column.width || '300px' }\" [matTooltip]=\"column.title\">\r\n <span class=\"c-ellipsis\">\r\n {{ column.title }}\r\n </span>\r\n </th>\r\n }\r\n }\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n @if (viewItems.length) {\r\n @for (item of viewItems; track item.meta.excelIndex) {\r\n <tr>\r\n <td class=\"text-center c-sticky-left px-4\">\r\n <sd-badge\r\n type=\"tag\"\r\n [title]=\"item.meta.excelIndex\"\r\n [success]=\"!item.meta.warningMessages.length && !item.meta.errorMessages.length\"\r\n [warning]=\"!!item.meta.warningMessages.length && !item.meta.errorMessages.length\"\r\n [error]=\"!!item.meta.errorMessages.length\" />\r\n </td>\r\n\r\n <td style=\"min-width: 250px; width: 250px\">\r\n <div\r\n class=\"text-wrap\"\r\n [innerHTML]=\"\r\n item.meta.errorMessages[0] || item.meta.warningMessages[0] || '<span class=\\'text-success\\'>D\u1EEF li\u1EC7u h\u1EE3p l\u1EC7</span>'\r\n \"></div>\r\n </td>\r\n\r\n @for (column of option.columns; track column.field) {\r\n @if (column | columnHidden) {\r\n <td\r\n class=\"align-middle\"\r\n [ngClass]=\"{\r\n 'bg-warning-light': item.meta.warning[column.field] && !item.meta.error[column.field],\r\n 'bg-error-light': item.meta.error[column.field]\r\n }\"\r\n [matTooltip]=\"item.meta.error[column.field] || item.meta.warning[column.field]\"\r\n [ngStyle]=\"{ 'min-width': column.width || '300px' }\"\r\n matTooltipPosition=\"above\">\r\n <div class=\"c-ellipsis\">\r\n @if (column.type !== 'array') {\r\n <span [innerHTML]=\"item | columnTransform: column | async\"></span>\r\n }\r\n\r\n @if (column.type === 'array') {\r\n @let arrayItems = item.data[column.field]?.split(column.divideString);\r\n\r\n <div class=\"d-flex align-items-center justify-content-between\">\r\n <span>{{ arrayItems?.length || 0 }} {{ column.unitString }}</span>\r\n\r\n @if (arrayItems?.length) {\r\n <button\r\n mat-icon-button\r\n [matMenuTriggerFor]=\"menu\"\r\n class=\"c-mat-menu\"\r\n style=\"width: 24px; height: 24px; line-height: 24px\">\r\n <mat-icon style=\"font-size: 18px\">open_in_new</mat-icon>\r\n </button>\r\n\r\n <mat-menu #menu=\"matMenu\">\r\n <div\r\n class=\"px-3 py-2\"\r\n style=\"max-width: 300px; max-height: 250px; overflow: auto\"\r\n (click)=\"$event.stopPropagation()\"\r\n aria-hidden=\"true\">\r\n @for (val of arrayItems; track $index) {\r\n <div class=\"border-bottom py-2 text-wrap\" [innerHTML]=\"val\"></div>\r\n }\r\n </div>\r\n </mat-menu>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </td>\r\n }\r\n }\r\n </tr>\r\n }\r\n } @else {\r\n <tr>\r\n <td [attr.colspan]=\"option.columns.length + 2\" class=\"p-0 border-0 bg-white\">\r\n <div\r\n class=\"empty-state-wrapper\"\r\n (click)=\"downloadTemplate()\"\r\n matTooltip=\"Nh\u1EA5n \u0111\u1EC3 t\u1EA3i t\u1EC7p m\u1EABu v\u1EC1 m\u00E1y\"\r\n aria-hidden=\"true\">\r\n <mat-icon class=\"empty-icon\">cloud_download</mat-icon>\r\n\r\n <h4>Ch\u01B0a c\u00F3 d\u1EEF li\u1EC7u t\u1EA3i l\u00EAn</h4>\r\n <span class=\"text-small text-link\"> Nh\u1EA5n v\u00E0o \u0111\u00E2y \u0111\u1EC3 t\u1EA3i t\u1EC7p m\u1EABu </span>\r\n\r\n @if (isDownloadTemplate) {\r\n <div class=\"mt-3\">\r\n <mat-spinner diameter=\"24\" mode=\"indeterminate\"></mat-spinner>\r\n </div>\r\n }\r\n </div>\r\n </td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n\r\n <div class=\"sd-box-footer border-top\">\r\n <div class=\"d-flex align-items-center justify-content-end\">\r\n <mat-paginator [length]=\"filteredItems.length || 0\" hidePageSize showFirstLastButtons></mat-paginator>\r\n </div>\r\n </div>\r\n </div>\r\n <sd-button sdFooterLeft (click)=\"upload()\" prefixIcon=\"file_upload\" title=\"T\u1EA3i l\u00EAn\" size=\"sm\" color=\"info\" [loading]=\"uploading\">\r\n </sd-button>\r\n <div class=\"d-flex align-items-center\" sdFooter>\r\n @if (filteredItems.length) {\r\n <sd-button class=\"mr-4\" (click)=\"export()\" prefixIcon=\"get_app\" title=\"T\u1EA3i v\u1EC1\" size=\"sm\" color=\"success\" type=\"outline\">\r\n </sd-button>\r\n }\r\n <sd-button\r\n (click)=\"accept()\"\r\n title=\"X\u00E1c nh\u1EADn & L\u01B0u\"\r\n [disabled]=\"(numberOfSuccess === 0 && numberOfWarning === 0) || numberOfError > 0 || isUploaded\"\r\n color=\"primary\"\r\n type=\"fill\"\r\n size=\"sm\">\r\n </sd-button>\r\n </div>\r\n </sd-modal>\r\n}\r\n", styles: [".table-responsive{position:relative;min-height:50vh;height:50vh;overflow:auto;border:1px solid #dee2e6}.sd-table{width:100%;border-collapse:collapse;margin-bottom:0;font-size:14px}.sd-table thead th{position:sticky;top:0;background-color:#f8f9fa;border-bottom:2px solid #dee2e6;border-top:1px solid #dee2e6;padding:8px 6px;white-space:nowrap;z-index:10;font-weight:600}.sd-table thead th.c-sticky-left{z-index:20}.sd-table tbody td{vertical-align:middle;padding:6px;border-top:1px solid #dee2e6}.sd-table tbody tr:nth-of-type(odd){background-color:#0000000a}.sd-table tbody tr:nth-of-type(2n){background-color:#fff}.sd-table tbody tr:hover,.sd-table tbody tr:hover .c-sticky-left{background-color:#ececec}.sd-table tbody tr:nth-of-type(odd) .c-sticky-left{background-color:#f2f2f2}.sd-table tbody tr:nth-of-type(2n) .c-sticky-left{background-color:#fff}.c-sticky-left{position:sticky;left:0;border-right:1px solid #dee2e6!important;border-left:none!important;z-index:5}.empty-state-wrapper{height:100%;min-height:40vh;display:flex;flex-direction:column;align-items:center;justify-content:center;cursor:pointer;background-color:#f8f9fa;border:2px dashed #cbd5e0;border-radius:8px;margin:16px;transition:all .2s ease-in-out;color:#6c757d}.empty-state-wrapper:hover{background-color:#e3f2fd;border-color:#2196f3;color:#1976d2}.empty-state-wrapper:hover .empty-icon{transform:scale(1.1);color:#1976d2}.empty-state-wrapper:hover .text-link{text-decoration:underline}.empty-state-wrapper .empty-icon{font-size:64px;height:64px;width:64px;margin-bottom:16px;color:#a0aec0;transition:transform .2s}.empty-state-wrapper h4{font-weight:500;margin-bottom:4px}.c-ellipsis{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;padding:0 4px}.c-mat-menu{border:none;min-width:unset;padding:0 8px}.c-mat-menu mat-icon{font-size:18px;width:18px;height:18px;line-height:18px;vertical-align:middle}.cursor-pointer{cursor:pointer}:host ::ng-deep .mat-paginator-container{min-height:36px;height:36px;padding:0 8px}:host ::ng-deep .mat-paginator-range-label{margin:0 10px}:host ::ng-deep .mat-icon-button{width:32px;height:32px;line-height:32px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i6.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatPaginatorModule }, { kind: "component", type: i7.MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "component", type: SdButton, selector: "sd-button", inputs: ["autoId", "type", "color", "size", "fontSet", "title", "width", "tooltip", "prefixIcon", "suffixIcon", "disabled", "loading", "block", "htmlType"], outputs: ["click"] }, { kind: "component", type: SdModal, selector: "sd-modal", inputs: ["title", "color", "width", "height", "view", "modalClass", "lazyLoadContent", "hideClose", "disableBackdropClose"], outputs: ["sdClosed"] }, { kind: "pipe", type: ColumnTransformPipe, name: "columnTransform" }, { kind: "pipe", type: ColumnHiddenPipe, name: "columnHidden" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i9.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "directive", type: i9.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: SdBadge, selector: "sd-badge", inputs: ["type", "color", "primary", "secondary", "success", "info", "warning", "error", "fontSet", "title", "description", "tooltip", "icon", "size"], outputs: ["click"] }] });
542
542
  }
543
543
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdImportExcel, decorators: [{
544
544
  type: Component,
@@ -559,7 +559,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
559
559
  SdBadge
560
560
  ], providers: [
561
561
  ColumnHiddenPipe
562
- ], template: "@if (option) {\r\n <sd-modal [title]=\"option.title || 'Nh\u1EADp d\u1EEF li\u1EC7u Excel'\" (sdClosed)=\"onClosed()\" #modal>\r\n <div class=\"row mx-0 mb-3 align-items-center\" style=\"min-height: 32px\">\r\n @if (excelItems.length) {\r\n <div class=\"d-flex\">\r\n <sd-button class=\"mr-2\" (click)=\"view('ALL')\" icon=\"cached\" title=\"Xem t\u1EA5t c\u1EA3\" size=\"sm\" type=\"outline\"></sd-button>\r\n\r\n <sd-button\r\n class=\"mr-2\"\r\n (click)=\"view('SUCCESS')\"\r\n icon=\"done\"\r\n title=\"{{ numberOfSuccess }}\"\r\n tooltip=\"S\u1ED1 d\u00F2ng d\u1EEF li\u1EC7u h\u1EE3p l\u1EC7\"\r\n size=\"sm\"\r\n color=\"success\">\r\n </sd-button>\r\n\r\n <sd-button\r\n class=\"mr-2\"\r\n (click)=\"view('WARNING')\"\r\n icon=\"warning\"\r\n title=\"{{ numberOfWarning }}\"\r\n tooltip=\"S\u1ED1 d\u00F2ng d\u1EEF li\u1EC7u c\u00F3 l\u1ED7i\"\r\n size=\"sm\"\r\n color=\"warning\">\r\n </sd-button>\r\n\r\n <sd-button\r\n (click)=\"view('ERROR')\"\r\n icon=\"error\"\r\n title=\"{{ numberOfError }}\"\r\n color=\"error\"\r\n tooltip=\"S\u1ED1 d\u00F2ng d\u1EEF li\u1EC7u c\u00F3 c\u1EA3nh b\u00E1o\"\r\n size=\"sm\">\r\n </sd-button>\r\n </div>\r\n }\r\n </div>\r\n\r\n <div class=\"sd-box border rounded\">\r\n <div class=\"sd-box-body p-0\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-striped table-sm table-hover table-bordered mb-0\">\r\n <thead class=\"thead-light\">\r\n <tr>\r\n <th class=\"text-center c-sticky-left\" style=\"width: 50px\">#</th>\r\n @if (filteredItems.length) {\r\n <th class=\"text-center\" style=\"min-width: 250px; width: 250px\">Tr\u1EA1ng th\u00E1i</th>\r\n }\r\n @for (column of option.columns; track column.field) {\r\n @if (column | columnHidden) {\r\n <th [ngStyle]=\"{ 'min-width': column.width || '300px', width: column.width || '300px' }\" [matTooltip]=\"column.title\">\r\n <span class=\"c-ellipsis\">\r\n {{ column.title }}\r\n </span>\r\n </th>\r\n }\r\n }\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n @if (viewItems.length) {\r\n @for (item of viewItems; track item.meta.excelIndex) {\r\n <tr>\r\n <td class=\"text-center c-sticky-left px-4\">\r\n <sd-badge\r\n type=\"tag\"\r\n [title]=\"item.meta.excelIndex\"\r\n [success]=\"!item.meta.warningMessages.length && !item.meta.errorMessages.length\"\r\n [warning]=\"!!item.meta.warningMessages.length && !item.meta.errorMessages.length\"\r\n [error]=\"!!item.meta.errorMessages.length\" />\r\n </td>\r\n\r\n <td style=\"min-width: 250px; width: 250px\">\r\n <div\r\n class=\"text-wrap\"\r\n [innerHTML]=\"\r\n item.meta.errorMessages[0] || item.meta.warningMessages[0] || '<span class=\\'text-success\\'>D\u1EEF li\u1EC7u h\u1EE3p l\u1EC7</span>'\r\n \"></div>\r\n </td>\r\n\r\n @for (column of option.columns; track column.field) {\r\n @if (column | columnHidden) {\r\n <td\r\n class=\"align-middle\"\r\n [ngClass]=\"{\r\n 'bg-warning-light': item.meta.warning[column.field] && !item.meta.error[column.field],\r\n 'bg-error-light': item.meta.error[column.field]\r\n }\"\r\n [matTooltip]=\"item.meta.error[column.field] || item.meta.warning[column.field]\"\r\n [ngStyle]=\"{ 'min-width': column.width || '300px' }\"\r\n matTooltipPosition=\"above\">\r\n <div class=\"c-ellipsis\">\r\n @if (column.type !== 'array') {\r\n <span [innerHTML]=\"item | columnTransform: column | async\"></span>\r\n }\r\n\r\n @if (column.type === 'array') {\r\n @let arrayItems = item.data[column.field]?.split(column.divideString);\r\n\r\n <div class=\"d-flex align-items-center justify-content-between\">\r\n <span>{{ arrayItems?.length || 0 }} {{ column.unitString }}</span>\r\n\r\n @if (arrayItems?.length) {\r\n <button\r\n mat-icon-button\r\n [matMenuTriggerFor]=\"menu\"\r\n class=\"c-mat-menu\"\r\n style=\"width: 24px; height: 24px; line-height: 24px\">\r\n <mat-icon style=\"font-size: 18px\">open_in_new</mat-icon>\r\n </button>\r\n\r\n <mat-menu #menu=\"matMenu\">\r\n <div\r\n class=\"px-3 py-2\"\r\n style=\"max-width: 300px; max-height: 250px; overflow: auto\"\r\n (click)=\"$event.stopPropagation()\"\r\n aria-hidden=\"true\">\r\n @for (val of arrayItems; track $index) {\r\n <div class=\"border-bottom py-2 text-wrap\" [innerHTML]=\"val\"></div>\r\n }\r\n </div>\r\n </mat-menu>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </td>\r\n }\r\n }\r\n </tr>\r\n }\r\n } @else {\r\n <tr>\r\n <td [attr.colspan]=\"option.columns.length + 2\" class=\"p-0 border-0 bg-white\">\r\n <div\r\n class=\"empty-state-wrapper\"\r\n (click)=\"downloadTemplate()\"\r\n matTooltip=\"Nh\u1EA5n \u0111\u1EC3 t\u1EA3i t\u1EC7p m\u1EABu v\u1EC1 m\u00E1y\"\r\n aria-hidden=\"true\">\r\n <mat-icon class=\"empty-icon\">cloud_download</mat-icon>\r\n\r\n <h4>Ch\u01B0a c\u00F3 d\u1EEF li\u1EC7u t\u1EA3i l\u00EAn</h4>\r\n <span class=\"text-small text-link\"> Nh\u1EA5n v\u00E0o \u0111\u00E2y \u0111\u1EC3 t\u1EA3i t\u1EC7p m\u1EABu </span>\r\n\r\n @if (isDownloadTemplate) {\r\n <div class=\"mt-3\">\r\n <mat-spinner diameter=\"24\" mode=\"indeterminate\"></mat-spinner>\r\n </div>\r\n }\r\n </div>\r\n </td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n\r\n <div class=\"sd-box-footer border-top\">\r\n <div class=\"d-flex align-items-center justify-content-end\">\r\n <mat-paginator [length]=\"filteredItems.length || 0\" hidePageSize showFirstLastButtons></mat-paginator>\r\n </div>\r\n </div>\r\n </div>\r\n <sd-button sdFooterLeft (click)=\"upload()\" prefixIcon=\"file_upload\" title=\"T\u1EA3i l\u00EAn\" size=\"sm\" color=\"info\" [loading]=\"uploading\">\r\n </sd-button>\r\n <div class=\"d-flex align-items-center\" sdFooter>\r\n @if (filteredItems.length) {\r\n <sd-button class=\"mr-4\" (click)=\"export()\" prefixIcon=\"get_app\" title=\"T\u1EA3i v\u1EC1\" size=\"sm\" color=\"success\" type=\"outline\">\r\n </sd-button>\r\n }\r\n <sd-button\r\n (click)=\"accept()\"\r\n title=\"X\u00E1c nh\u1EADn & L\u01B0u\"\r\n [disabled]=\"(numberOfSuccess === 0 && numberOfWarning === 0) || numberOfError > 0 || isUploaded\"\r\n color=\"primary\"\r\n type=\"fill\"\r\n size=\"sm\">\r\n </sd-button>\r\n </div>\r\n </sd-modal>\r\n}\r\n", styles: [".table-responsive{position:relative;min-height:50vh;height:50vh;overflow:auto;border:1px solid #dee2e6}.table{margin-bottom:0}.table thead th{position:sticky;top:0;background-color:#f8f9fa;border-bottom:2px solid #dee2e6;padding-top:8px;padding-bottom:8px;white-space:nowrap;z-index:10}.table thead th.c-sticky-left{z-index:20}.table tbody td{vertical-align:middle;padding-top:6px;padding-bottom:6px}.c-sticky-left{position:sticky;left:0;border-right:1px solid #dee2e6!important;border-left:none!important;z-index:5}.table-striped tbody tr:nth-of-type(odd) .c-sticky-left{background-color:#f2f2f2}.table-striped tbody tr:nth-of-type(2n) .c-sticky-left{background-color:#fff}.table-hover tbody tr:hover .c-sticky-left{background-color:#ececec}.table-striped tbody tr:nth-of-type(odd){background-color:#0000000d}.table-striped tbody tr:nth-of-type(2n){background-color:#fff}.empty-state-wrapper{height:100%;min-height:40vh;display:flex;flex-direction:column;align-items:center;justify-content:center;cursor:pointer;background-color:#f8f9fa;border:2px dashed #cbd5e0;border-radius:8px;margin:16px;transition:all .2s ease-in-out;color:#6c757d}.empty-state-wrapper:hover{background-color:#e3f2fd;border-color:#2196f3;color:#1976d2}.empty-state-wrapper:hover .empty-icon{transform:scale(1.1);color:#1976d2}.empty-state-wrapper:hover .text-link{text-decoration:underline}.empty-state-wrapper .empty-icon{font-size:64px;height:64px;width:64px;margin-bottom:16px;color:#a0aec0;transition:transform .2s}.empty-state-wrapper h4{font-weight:500;margin-bottom:4px}.c-ellipsis{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;padding:0 4px}.c-mat-menu{border:none;min-width:unset;padding:0 8px}.c-mat-menu mat-icon{font-size:18px;width:18px;height:18px;line-height:18px;vertical-align:middle}.cursor-pointer{cursor:pointer}:host ::ng-deep .mat-paginator-container{min-height:36px;height:36px;padding:0 8px}:host ::ng-deep .mat-paginator-range-label{margin:0 10px}:host ::ng-deep .mat-icon-button{width:32px;height:32px;line-height:32px}\n"] }]
562
+ ], template: "@if (option) {\r\n <sd-modal [title]=\"option.title || 'Nh\u1EADp d\u1EEF li\u1EC7u Excel'\" (sdClosed)=\"onClosed()\" #modal>\r\n <div class=\"d-flex align-items-center mb-12\" style=\"min-height: 32px\">\r\n @if (excelItems.length) {\r\n <div class=\"d-flex\">\r\n <sd-button class=\"mr-2\" (click)=\"view('ALL')\" icon=\"cached\" title=\"Xem t\u1EA5t c\u1EA3\" size=\"sm\" type=\"outline\"></sd-button>\r\n\r\n <sd-button\r\n class=\"mr-2\"\r\n (click)=\"view('SUCCESS')\"\r\n icon=\"done\"\r\n title=\"{{ numberOfSuccess }}\"\r\n tooltip=\"S\u1ED1 d\u00F2ng d\u1EEF li\u1EC7u h\u1EE3p l\u1EC7\"\r\n size=\"sm\"\r\n color=\"success\">\r\n </sd-button>\r\n\r\n <sd-button\r\n class=\"mr-2\"\r\n (click)=\"view('WARNING')\"\r\n icon=\"warning\"\r\n title=\"{{ numberOfWarning }}\"\r\n tooltip=\"S\u1ED1 d\u00F2ng d\u1EEF li\u1EC7u c\u00F3 l\u1ED7i\"\r\n size=\"sm\"\r\n color=\"warning\">\r\n </sd-button>\r\n\r\n <sd-button\r\n (click)=\"view('ERROR')\"\r\n icon=\"error\"\r\n title=\"{{ numberOfError }}\"\r\n color=\"error\"\r\n tooltip=\"S\u1ED1 d\u00F2ng d\u1EEF li\u1EC7u c\u00F3 c\u1EA3nh b\u00E1o\"\r\n size=\"sm\">\r\n </sd-button>\r\n </div>\r\n }\r\n </div>\r\n\r\n <div class=\"sd-box border rounded\">\r\n <div class=\"sd-box-body p-0\">\r\n <div class=\"table-responsive\">\r\n <table class=\"sd-table\">\r\n <thead>\r\n <tr>\r\n <th class=\"text-center c-sticky-left\" style=\"width: 50px\">#</th>\r\n @if (filteredItems.length) {\r\n <th class=\"text-center\" style=\"min-width: 250px; width: 250px\">Tr\u1EA1ng th\u00E1i</th>\r\n }\r\n @for (column of option.columns; track column.field) {\r\n @if (column | columnHidden) {\r\n <th [ngStyle]=\"{ 'min-width': column.width || '300px', width: column.width || '300px' }\" [matTooltip]=\"column.title\">\r\n <span class=\"c-ellipsis\">\r\n {{ column.title }}\r\n </span>\r\n </th>\r\n }\r\n }\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n @if (viewItems.length) {\r\n @for (item of viewItems; track item.meta.excelIndex) {\r\n <tr>\r\n <td class=\"text-center c-sticky-left px-4\">\r\n <sd-badge\r\n type=\"tag\"\r\n [title]=\"item.meta.excelIndex\"\r\n [success]=\"!item.meta.warningMessages.length && !item.meta.errorMessages.length\"\r\n [warning]=\"!!item.meta.warningMessages.length && !item.meta.errorMessages.length\"\r\n [error]=\"!!item.meta.errorMessages.length\" />\r\n </td>\r\n\r\n <td style=\"min-width: 250px; width: 250px\">\r\n <div\r\n class=\"text-wrap\"\r\n [innerHTML]=\"\r\n item.meta.errorMessages[0] || item.meta.warningMessages[0] || '<span class=\\'text-success\\'>D\u1EEF li\u1EC7u h\u1EE3p l\u1EC7</span>'\r\n \"></div>\r\n </td>\r\n\r\n @for (column of option.columns; track column.field) {\r\n @if (column | columnHidden) {\r\n <td\r\n class=\"align-middle\"\r\n [ngClass]=\"{\r\n 'bg-warning-light': item.meta.warning[column.field] && !item.meta.error[column.field],\r\n 'bg-error-light': item.meta.error[column.field]\r\n }\"\r\n [matTooltip]=\"item.meta.error[column.field] || item.meta.warning[column.field]\"\r\n [ngStyle]=\"{ 'min-width': column.width || '300px' }\"\r\n matTooltipPosition=\"above\">\r\n <div class=\"c-ellipsis\">\r\n @if (column.type !== 'array') {\r\n <span [innerHTML]=\"item | columnTransform: column | async\"></span>\r\n }\r\n\r\n @if (column.type === 'array') {\r\n @let arrayItems = item.data[column.field]?.split(column.divideString);\r\n\r\n <div class=\"d-flex align-items-center justify-content-between\">\r\n <span>{{ arrayItems?.length || 0 }} {{ column.unitString }}</span>\r\n\r\n @if (arrayItems?.length) {\r\n <button\r\n mat-icon-button\r\n [matMenuTriggerFor]=\"menu\"\r\n class=\"c-mat-menu\"\r\n style=\"width: 24px; height: 24px; line-height: 24px\">\r\n <mat-icon style=\"font-size: 18px\">open_in_new</mat-icon>\r\n </button>\r\n\r\n <mat-menu #menu=\"matMenu\">\r\n <div\r\n class=\"px-3 py-2\"\r\n style=\"max-width: 300px; max-height: 250px; overflow: auto\"\r\n (click)=\"$event.stopPropagation()\"\r\n aria-hidden=\"true\">\r\n @for (val of arrayItems; track $index) {\r\n <div class=\"border-bottom py-2 text-wrap\" [innerHTML]=\"val\"></div>\r\n }\r\n </div>\r\n </mat-menu>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </td>\r\n }\r\n }\r\n </tr>\r\n }\r\n } @else {\r\n <tr>\r\n <td [attr.colspan]=\"option.columns.length + 2\" class=\"p-0 border-0 bg-white\">\r\n <div\r\n class=\"empty-state-wrapper\"\r\n (click)=\"downloadTemplate()\"\r\n matTooltip=\"Nh\u1EA5n \u0111\u1EC3 t\u1EA3i t\u1EC7p m\u1EABu v\u1EC1 m\u00E1y\"\r\n aria-hidden=\"true\">\r\n <mat-icon class=\"empty-icon\">cloud_download</mat-icon>\r\n\r\n <h4>Ch\u01B0a c\u00F3 d\u1EEF li\u1EC7u t\u1EA3i l\u00EAn</h4>\r\n <span class=\"text-small text-link\"> Nh\u1EA5n v\u00E0o \u0111\u00E2y \u0111\u1EC3 t\u1EA3i t\u1EC7p m\u1EABu </span>\r\n\r\n @if (isDownloadTemplate) {\r\n <div class=\"mt-3\">\r\n <mat-spinner diameter=\"24\" mode=\"indeterminate\"></mat-spinner>\r\n </div>\r\n }\r\n </div>\r\n </td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n\r\n <div class=\"sd-box-footer border-top\">\r\n <div class=\"d-flex align-items-center justify-content-end\">\r\n <mat-paginator [length]=\"filteredItems.length || 0\" hidePageSize showFirstLastButtons></mat-paginator>\r\n </div>\r\n </div>\r\n </div>\r\n <sd-button sdFooterLeft (click)=\"upload()\" prefixIcon=\"file_upload\" title=\"T\u1EA3i l\u00EAn\" size=\"sm\" color=\"info\" [loading]=\"uploading\">\r\n </sd-button>\r\n <div class=\"d-flex align-items-center\" sdFooter>\r\n @if (filteredItems.length) {\r\n <sd-button class=\"mr-4\" (click)=\"export()\" prefixIcon=\"get_app\" title=\"T\u1EA3i v\u1EC1\" size=\"sm\" color=\"success\" type=\"outline\">\r\n </sd-button>\r\n }\r\n <sd-button\r\n (click)=\"accept()\"\r\n title=\"X\u00E1c nh\u1EADn & L\u01B0u\"\r\n [disabled]=\"(numberOfSuccess === 0 && numberOfWarning === 0) || numberOfError > 0 || isUploaded\"\r\n color=\"primary\"\r\n type=\"fill\"\r\n size=\"sm\">\r\n </sd-button>\r\n </div>\r\n </sd-modal>\r\n}\r\n", styles: [".table-responsive{position:relative;min-height:50vh;height:50vh;overflow:auto;border:1px solid #dee2e6}.sd-table{width:100%;border-collapse:collapse;margin-bottom:0;font-size:14px}.sd-table thead th{position:sticky;top:0;background-color:#f8f9fa;border-bottom:2px solid #dee2e6;border-top:1px solid #dee2e6;padding:8px 6px;white-space:nowrap;z-index:10;font-weight:600}.sd-table thead th.c-sticky-left{z-index:20}.sd-table tbody td{vertical-align:middle;padding:6px;border-top:1px solid #dee2e6}.sd-table tbody tr:nth-of-type(odd){background-color:#0000000a}.sd-table tbody tr:nth-of-type(2n){background-color:#fff}.sd-table tbody tr:hover,.sd-table tbody tr:hover .c-sticky-left{background-color:#ececec}.sd-table tbody tr:nth-of-type(odd) .c-sticky-left{background-color:#f2f2f2}.sd-table tbody tr:nth-of-type(2n) .c-sticky-left{background-color:#fff}.c-sticky-left{position:sticky;left:0;border-right:1px solid #dee2e6!important;border-left:none!important;z-index:5}.empty-state-wrapper{height:100%;min-height:40vh;display:flex;flex-direction:column;align-items:center;justify-content:center;cursor:pointer;background-color:#f8f9fa;border:2px dashed #cbd5e0;border-radius:8px;margin:16px;transition:all .2s ease-in-out;color:#6c757d}.empty-state-wrapper:hover{background-color:#e3f2fd;border-color:#2196f3;color:#1976d2}.empty-state-wrapper:hover .empty-icon{transform:scale(1.1);color:#1976d2}.empty-state-wrapper:hover .text-link{text-decoration:underline}.empty-state-wrapper .empty-icon{font-size:64px;height:64px;width:64px;margin-bottom:16px;color:#a0aec0;transition:transform .2s}.empty-state-wrapper h4{font-weight:500;margin-bottom:4px}.c-ellipsis{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;padding:0 4px}.c-mat-menu{border:none;min-width:unset;padding:0 8px}.c-mat-menu mat-icon{font-size:18px;width:18px;height:18px;line-height:18px;vertical-align:middle}.cursor-pointer{cursor:pointer}:host ::ng-deep .mat-paginator-container{min-height:36px;height:36px;padding:0 8px}:host ::ng-deep .mat-paginator-range-label{margin:0 10px}:host ::ng-deep .mat-icon-button{width:32px;height:32px;line-height:32px}\n"] }]
563
563
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1$1.SdExcelService }, { type: i2.SdNotifyService }, { type: ColumnHiddenPipe }, { type: i4.SdLoadingService }], propDecorators: { option: [{
564
564
  type: Input,
565
565
  args: [{ required: true }]