@sd-angular/core 19.0.0-beta.93 → 19.0.0-beta.94

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 (92) hide show
  1. package/components/document-builder/src/components/header-footer-builder/header-footer-builder.component.d.ts +4 -1
  2. package/components/document-builder/src/document-builder.model.d.ts +2 -0
  3. package/components/editor/src/models/editor.model.d.ts +2 -0
  4. package/components/editor/src/plugins/image-upload/utils/validate.utils.d.ts +2 -1
  5. package/components/splitter/src/splitter.component.d.ts +15 -2
  6. package/components/table/src/components/selector-action/selector-action.component.d.ts +1 -0
  7. package/components/table/src/table.component.d.ts +1 -0
  8. package/configurations/src/sd-core.configuration.d.ts +1 -0
  9. package/fesm2022/sd-angular-core-components-code-editor.mjs +3 -2
  10. package/fesm2022/sd-angular-core-components-code-editor.mjs.map +1 -1
  11. package/fesm2022/sd-angular-core-components-document-builder.mjs +29 -8
  12. package/fesm2022/sd-angular-core-components-document-builder.mjs.map +1 -1
  13. package/fesm2022/sd-angular-core-components-editor.mjs +31 -16
  14. package/fesm2022/sd-angular-core-components-editor.mjs.map +1 -1
  15. package/fesm2022/sd-angular-core-components-form-generic.mjs +68 -61
  16. package/fesm2022/sd-angular-core-components-form-generic.mjs.map +1 -1
  17. package/fesm2022/sd-angular-core-components-history.mjs +3 -2
  18. package/fesm2022/sd-angular-core-components-history.mjs.map +1 -1
  19. package/fesm2022/sd-angular-core-components-import-excel.mjs +25 -23
  20. package/fesm2022/sd-angular-core-components-import-excel.mjs.map +1 -1
  21. package/fesm2022/sd-angular-core-components-preview.mjs +6 -4
  22. package/fesm2022/sd-angular-core-components-preview.mjs.map +1 -1
  23. package/fesm2022/sd-angular-core-components-splitter.mjs +188 -18
  24. package/fesm2022/sd-angular-core-components-splitter.mjs.map +1 -1
  25. package/fesm2022/sd-angular-core-components-tab-router.mjs +3 -1
  26. package/fesm2022/sd-angular-core-components-tab-router.mjs.map +1 -1
  27. package/fesm2022/sd-angular-core-components-table.mjs +30 -23
  28. package/fesm2022/sd-angular-core-components-table.mjs.map +1 -1
  29. package/fesm2022/sd-angular-core-components-upload-file.mjs +24 -21
  30. package/fesm2022/sd-angular-core-components-upload-file.mjs.map +1 -1
  31. package/fesm2022/sd-angular-core-configurations.mjs.map +1 -1
  32. package/fesm2022/sd-angular-core-directives.mjs +6 -2
  33. package/fesm2022/sd-angular-core-directives.mjs.map +1 -1
  34. package/fesm2022/sd-angular-core-forms-autocomplete.mjs +3 -1
  35. package/fesm2022/sd-angular-core-forms-autocomplete.mjs.map +1 -1
  36. package/fesm2022/sd-angular-core-forms-chip-calendar.mjs +5 -3
  37. package/fesm2022/sd-angular-core-forms-chip-calendar.mjs.map +1 -1
  38. package/fesm2022/sd-angular-core-forms-chip.mjs +5 -3
  39. package/fesm2022/sd-angular-core-forms-chip.mjs.map +1 -1
  40. package/fesm2022/sd-angular-core-forms-date-range.mjs +8 -5
  41. package/fesm2022/sd-angular-core-forms-date-range.mjs.map +1 -1
  42. package/fesm2022/sd-angular-core-forms-date.mjs +7 -5
  43. package/fesm2022/sd-angular-core-forms-date.mjs.map +1 -1
  44. package/fesm2022/sd-angular-core-forms-datetime.mjs +10 -8
  45. package/fesm2022/sd-angular-core-forms-datetime.mjs.map +1 -1
  46. package/fesm2022/sd-angular-core-forms-input-number.mjs +5 -3
  47. package/fesm2022/sd-angular-core-forms-input-number.mjs.map +1 -1
  48. package/fesm2022/sd-angular-core-forms-input.mjs +13 -6
  49. package/fesm2022/sd-angular-core-forms-input.mjs.map +1 -1
  50. package/fesm2022/sd-angular-core-forms-radio.mjs +3 -2
  51. package/fesm2022/sd-angular-core-forms-radio.mjs.map +1 -1
  52. package/fesm2022/sd-angular-core-forms-select.mjs +5 -3
  53. package/fesm2022/sd-angular-core-forms-select.mjs.map +1 -1
  54. package/fesm2022/sd-angular-core-forms-textarea.mjs +8 -5
  55. package/fesm2022/sd-angular-core-forms-textarea.mjs.map +1 -1
  56. package/fesm2022/sd-angular-core-handlers.mjs +7 -6
  57. package/fesm2022/sd-angular-core-handlers.mjs.map +1 -1
  58. package/fesm2022/sd-angular-core-i18n.mjs +790 -0
  59. package/fesm2022/sd-angular-core-i18n.mjs.map +1 -0
  60. package/fesm2022/sd-angular-core-interceptors.mjs +10 -6
  61. package/fesm2022/sd-angular-core-interceptors.mjs.map +1 -1
  62. package/fesm2022/sd-angular-core-modules-authom.mjs +1 -0
  63. package/fesm2022/sd-angular-core-modules-authom.mjs.map +1 -1
  64. package/fesm2022/sd-angular-core-modules-keycloak.mjs +1 -0
  65. package/fesm2022/sd-angular-core-modules-keycloak.mjs.map +1 -1
  66. package/fesm2022/sd-angular-core-modules-layout.mjs +47 -46
  67. package/fesm2022/sd-angular-core-modules-layout.mjs.map +1 -1
  68. package/fesm2022/sd-angular-core-services-confirm.mjs +15 -13
  69. package/fesm2022/sd-angular-core-services-confirm.mjs.map +1 -1
  70. package/fesm2022/sd-angular-core-services-docx.mjs +7 -7
  71. package/fesm2022/sd-angular-core-services-docx.mjs.map +1 -1
  72. package/fesm2022/sd-angular-core-services-excel.mjs +5 -3
  73. package/fesm2022/sd-angular-core-services-excel.mjs.map +1 -1
  74. package/fesm2022/sd-angular-core-utilities-extensions.mjs +18 -11
  75. package/fesm2022/sd-angular-core-utilities-extensions.mjs.map +1 -1
  76. package/fesm2022/sd-angular-core-utilities-models.mjs +30 -28
  77. package/fesm2022/sd-angular-core-utilities-models.mjs.map +1 -1
  78. package/fesm2022/sd-angular-core.mjs +1 -0
  79. package/fesm2022/sd-angular-core.mjs.map +1 -1
  80. package/i18n/index.d.ts +5 -0
  81. package/i18n/src/en.d.ts +2 -0
  82. package/i18n/src/sd-i18n.messages.d.ts +2 -0
  83. package/i18n/src/sd-i18n.pipe.d.ts +9 -0
  84. package/i18n/src/sd-i18n.service.d.ts +12 -0
  85. package/i18n/src/sd-i18n.token.d.ts +1 -0
  86. package/i18n/src/sd-i18n.types.d.ts +5 -0
  87. package/i18n/src/vi.d.ts +312 -0
  88. package/package.json +53 -49
  89. package/public-api.d.ts +1 -0
  90. package/sd-angular-core-19.0.0-beta.94.tgz +0 -0
  91. package/services/confirm/src/lib/confirm.service.d.ts +1 -0
  92. package/sd-angular-core-19.0.0-beta.93.tgz +0 -0
@@ -4,6 +4,7 @@ import * as i0 from '@angular/core';
4
4
  import { Pipe, Injectable, Input, Component } from '@angular/core';
5
5
  import { SdBadge } from '@sd-angular/core/components/badge';
6
6
  import { DateUtilities, SD_EMPTY_STR } from '@sd-angular/core/utilities';
7
+ import { SdTPipe } from '@sd-angular/core/i18n';
7
8
 
8
9
  class ViewDateTimePipe {
9
10
  transform(value) {
@@ -32,11 +33,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
32
33
  class SdHistoryItem {
33
34
  items = [];
34
35
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdHistoryItem, deps: [], target: i0.ɵɵFactoryTarget.Component });
35
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: SdHistoryItem, isStandalone: true, selector: "sd-history", inputs: { items: "items" }, ngImport: i0, template: "<div class=\"sd-history\">\r\n <div class=\"history-container\">\r\n <div class=\"history-line\"></div>\r\n <div *ngFor=\"let item of items; let i = index\" class=\"history-item\">\r\n <div class=\"dot\"></div>\r\n <div class=\"card\">\r\n <div class=\"header\">\r\n <div class=\"title-wrapper\">\r\n <span class=\"title\">{{ item.title }}</span>\r\n <span class=\"status\">\r\n @if (item?.status) {\r\n <sd-badge\r\n [icon]=\"item.status?.icon\"\r\n [title]=\"item.status?.title\"\r\n [color]=\"item.status?.color\"></sd-badge>\r\n }\r\n </span>\r\n </div>\r\n <span class=\"date\">{{ item?.date | viewDateTime }}</span>\r\n </div>\r\n <div class=\"meta\">\r\n @if (item?.actor) {\r\n <span>B\u1EDFi <strong>&#64;{{ item.actor }}</strong></span>\r\n }\r\n @if (item?.source) {\r\n <span> &#183; {{ item.source }}</span>\r\n }\r\n </div>\r\n <div class=\"description\">\r\n {{ item?.description }}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".sd-history{padding:16px}.history-container{position:relative;padding-left:20px;font-size:14px;line-height:20px;min-width:470px;max-width:100%}.history-line{position:absolute;left:8px;top:0;bottom:0;width:2px;background-color:#94b0ff}.history-item{position:relative;margin-bottom:16px;padding-left:10px}.history-item .dot{position:absolute;left:-16px;top:12px;width:12px;height:12px;background-color:#94b0ff;border-radius:50%}.history-item .card{background:#fff;border-radius:6px;box-shadow:0 2px 4px #0000001a;padding:8px 8px 8px 16px}.history-item .card .header{display:flex;justify-content:space-between;align-items:center}.history-item .card .header .title-wrapper{display:flex;align-items:flex-start;padding-right:8px}.history-item .card .header .title{margin-right:8px;color:#757575}.history-item .card .header .status{display:flex;align-items:center}.history-item .card .header .status mat-icon{margin-right:4px}.history-item .card .header .date{color:#757575;font-size:12px;line-height:16px}.history-item .card .meta{color:#757575;margin-top:4px}.history-item .card .meta strong{color:#000}.history-item .card .description{margin-top:4px;color:#000;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: SdBadge, selector: "sd-badge", inputs: ["type", "color", "primary", "secondary", "success", "info", "warning", "error", "fontSet", "title", "description", "tooltip", "icon", "size"], outputs: ["click"] }, { kind: "pipe", type: ViewDateTimePipe, name: "viewDateTime" }] });
36
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: SdHistoryItem, isStandalone: true, selector: "sd-history", inputs: { items: "items" }, ngImport: i0, template: "<div class=\"sd-history\">\r\n <div class=\"history-container\">\r\n <div class=\"history-line\"></div>\r\n <div *ngFor=\"let item of items; let i = index\" class=\"history-item\">\r\n <div class=\"dot\"></div>\r\n <div class=\"card\">\r\n <div class=\"header\">\r\n <div class=\"title-wrapper\">\r\n <span class=\"title\">{{ item.title }}</span>\r\n <span class=\"status\">\r\n @if (item?.status) {\r\n <sd-badge\r\n [icon]=\"item.status?.icon\"\r\n [title]=\"item.status?.title\"\r\n [color]=\"item.status?.color\"></sd-badge>\r\n }\r\n </span>\r\n </div>\r\n <span class=\"date\">{{ item?.date | viewDateTime }}</span>\r\n </div>\r\n <div class=\"meta\">\r\n @if (item?.actor) {\r\n <span>{{ 'core.component.history.by' | sdT }} <strong>&#64;{{ item.actor }}</strong></span>\r\n }\r\n @if (item?.source) {\r\n <span> &#183; {{ item.source }}</span>\r\n }\r\n </div>\r\n <div class=\"description\">\r\n {{ item?.description }}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".sd-history{padding:16px}.history-container{position:relative;padding-left:20px;font-size:14px;line-height:20px;min-width:470px;max-width:100%}.history-line{position:absolute;left:8px;top:0;bottom:0;width:2px;background-color:#94b0ff}.history-item{position:relative;margin-bottom:16px;padding-left:10px}.history-item .dot{position:absolute;left:-16px;top:12px;width:12px;height:12px;background-color:#94b0ff;border-radius:50%}.history-item .card{background:#fff;border-radius:6px;box-shadow:0 2px 4px #0000001a;padding:8px 8px 8px 16px}.history-item .card .header{display:flex;justify-content:space-between;align-items:center}.history-item .card .header .title-wrapper{display:flex;align-items:flex-start;padding-right:8px}.history-item .card .header .title{margin-right:8px;color:#757575}.history-item .card .header .status{display:flex;align-items:center}.history-item .card .header .status mat-icon{margin-right:4px}.history-item .card .header .date{color:#757575;font-size:12px;line-height:16px}.history-item .card .meta{color:#757575;margin-top:4px}.history-item .card .meta strong{color:#000}.history-item .card .description{margin-top:4px;color:#000;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: SdBadge, selector: "sd-badge", inputs: ["type", "color", "primary", "secondary", "success", "info", "warning", "error", "fontSet", "title", "description", "tooltip", "icon", "size"], outputs: ["click"] }, { kind: "pipe", type: ViewDateTimePipe, name: "viewDateTime" }, { kind: "pipe", type: SdTPipe, name: "sdT" }] });
36
37
  }
37
38
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdHistoryItem, decorators: [{
38
39
  type: Component,
39
- args: [{ selector: 'sd-history', imports: [CommonModule, SdBadge, ViewDateTimePipe], template: "<div class=\"sd-history\">\r\n <div class=\"history-container\">\r\n <div class=\"history-line\"></div>\r\n <div *ngFor=\"let item of items; let i = index\" class=\"history-item\">\r\n <div class=\"dot\"></div>\r\n <div class=\"card\">\r\n <div class=\"header\">\r\n <div class=\"title-wrapper\">\r\n <span class=\"title\">{{ item.title }}</span>\r\n <span class=\"status\">\r\n @if (item?.status) {\r\n <sd-badge\r\n [icon]=\"item.status?.icon\"\r\n [title]=\"item.status?.title\"\r\n [color]=\"item.status?.color\"></sd-badge>\r\n }\r\n </span>\r\n </div>\r\n <span class=\"date\">{{ item?.date | viewDateTime }}</span>\r\n </div>\r\n <div class=\"meta\">\r\n @if (item?.actor) {\r\n <span>B\u1EDFi <strong>&#64;{{ item.actor }}</strong></span>\r\n }\r\n @if (item?.source) {\r\n <span> &#183; {{ item.source }}</span>\r\n }\r\n </div>\r\n <div class=\"description\">\r\n {{ item?.description }}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".sd-history{padding:16px}.history-container{position:relative;padding-left:20px;font-size:14px;line-height:20px;min-width:470px;max-width:100%}.history-line{position:absolute;left:8px;top:0;bottom:0;width:2px;background-color:#94b0ff}.history-item{position:relative;margin-bottom:16px;padding-left:10px}.history-item .dot{position:absolute;left:-16px;top:12px;width:12px;height:12px;background-color:#94b0ff;border-radius:50%}.history-item .card{background:#fff;border-radius:6px;box-shadow:0 2px 4px #0000001a;padding:8px 8px 8px 16px}.history-item .card .header{display:flex;justify-content:space-between;align-items:center}.history-item .card .header .title-wrapper{display:flex;align-items:flex-start;padding-right:8px}.history-item .card .header .title{margin-right:8px;color:#757575}.history-item .card .header .status{display:flex;align-items:center}.history-item .card .header .status mat-icon{margin-right:4px}.history-item .card .header .date{color:#757575;font-size:12px;line-height:16px}.history-item .card .meta{color:#757575;margin-top:4px}.history-item .card .meta strong{color:#000}.history-item .card .description{margin-top:4px;color:#000;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis}\n"] }]
40
+ args: [{ selector: 'sd-history', imports: [CommonModule, SdBadge, ViewDateTimePipe, SdTPipe], template: "<div class=\"sd-history\">\r\n <div class=\"history-container\">\r\n <div class=\"history-line\"></div>\r\n <div *ngFor=\"let item of items; let i = index\" class=\"history-item\">\r\n <div class=\"dot\"></div>\r\n <div class=\"card\">\r\n <div class=\"header\">\r\n <div class=\"title-wrapper\">\r\n <span class=\"title\">{{ item.title }}</span>\r\n <span class=\"status\">\r\n @if (item?.status) {\r\n <sd-badge\r\n [icon]=\"item.status?.icon\"\r\n [title]=\"item.status?.title\"\r\n [color]=\"item.status?.color\"></sd-badge>\r\n }\r\n </span>\r\n </div>\r\n <span class=\"date\">{{ item?.date | viewDateTime }}</span>\r\n </div>\r\n <div class=\"meta\">\r\n @if (item?.actor) {\r\n <span>{{ 'core.component.history.by' | sdT }} <strong>&#64;{{ item.actor }}</strong></span>\r\n }\r\n @if (item?.source) {\r\n <span> &#183; {{ item.source }}</span>\r\n }\r\n </div>\r\n <div class=\"description\">\r\n {{ item?.description }}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".sd-history{padding:16px}.history-container{position:relative;padding-left:20px;font-size:14px;line-height:20px;min-width:470px;max-width:100%}.history-line{position:absolute;left:8px;top:0;bottom:0;width:2px;background-color:#94b0ff}.history-item{position:relative;margin-bottom:16px;padding-left:10px}.history-item .dot{position:absolute;left:-16px;top:12px;width:12px;height:12px;background-color:#94b0ff;border-radius:50%}.history-item .card{background:#fff;border-radius:6px;box-shadow:0 2px 4px #0000001a;padding:8px 8px 8px 16px}.history-item .card .header{display:flex;justify-content:space-between;align-items:center}.history-item .card .header .title-wrapper{display:flex;align-items:flex-start;padding-right:8px}.history-item .card .header .title{margin-right:8px;color:#757575}.history-item .card .header .status{display:flex;align-items:center}.history-item .card .header .status mat-icon{margin-right:4px}.history-item .card .header .date{color:#757575;font-size:12px;line-height:16px}.history-item .card .meta{color:#757575;margin-top:4px}.history-item .card .meta strong{color:#000}.history-item .card .description{margin-top:4px;color:#000;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis}\n"] }]
40
41
  }], propDecorators: { items: [{
41
42
  type: Input
42
43
  }] } });
@@ -1 +1 @@
1
- {"version":3,"file":"sd-angular-core-components-history.mjs","sources":["../../../projects/sd-angular/components/history/pipes/view-date.pipe.ts","../../../projects/sd-angular/components/history/src/history.component.ts","../../../projects/sd-angular/components/history/src/history.component.html","../../../projects/sd-angular/components/history/sd-angular-core-components-history.ts"],"sourcesContent":["import { Injectable, Pipe, PipeTransform } from '@angular/core';\r\nimport { DateUtilities, SD_EMPTY_STR } from '@sd-angular/core/utilities';\r\n\r\n@Pipe({\r\n name: 'viewDateTime',\r\n standalone: true,\r\n})\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class ViewDateTimePipe implements PipeTransform {\r\n transform(value: any): string {\r\n if (!value || !DateUtilities.isDate(value)) {\r\n return SD_EMPTY_STR;\r\n }\r\n return DateUtilities.toFormat(value, 'HH:mm dd/MM/yyyy');\r\n }\r\n}\r\n","import { CommonModule } from '@angular/common';\r\nimport { Component, Input } from '@angular/core';\r\nimport { SdBadge } from '@sd-angular/core/components/badge';\r\nimport { SdHistoryItemType } from '../models/history.model';\r\nimport { ViewDateTimePipe } from '../pipes/view-date.pipe';\r\n\r\n@Component({\r\n selector: 'sd-history',\r\n imports: [CommonModule, SdBadge, ViewDateTimePipe],\r\n templateUrl: './history.component.html',\r\n styleUrl: './history.component.scss',\r\n})\r\nexport class SdHistoryItem {\r\n @Input() items: SdHistoryItemType[] = [];\r\n}\r\n","<div class=\"sd-history\">\r\n <div class=\"history-container\">\r\n <div class=\"history-line\"></div>\r\n <div *ngFor=\"let item of items; let i = index\" class=\"history-item\">\r\n <div class=\"dot\"></div>\r\n <div class=\"card\">\r\n <div class=\"header\">\r\n <div class=\"title-wrapper\">\r\n <span class=\"title\">{{ item.title }}</span>\r\n <span class=\"status\">\r\n @if (item?.status) {\r\n <sd-badge\r\n [icon]=\"item.status?.icon\"\r\n [title]=\"item.status?.title\"\r\n [color]=\"item.status?.color\"></sd-badge>\r\n }\r\n </span>\r\n </div>\r\n <span class=\"date\">{{ item?.date | viewDateTime }}</span>\r\n </div>\r\n <div class=\"meta\">\r\n @if (item?.actor) {\r\n <span>Bởi <strong>&#64;{{ item.actor }}</strong></span>\r\n }\r\n @if (item?.source) {\r\n <span> &#183; {{ item.source }}</span>\r\n }\r\n </div>\r\n <div class=\"description\">\r\n {{ item?.description }}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;;MAUa,gBAAgB,CAAA;AAC3B,IAAA,SAAS,CAAC,KAAU,EAAA;QAClB,IAAI,CAAC,KAAK,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;AAC1C,YAAA,OAAO,YAAY;QACrB;QACA,OAAO,aAAa,CAAC,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;IAC1D;wGANW,gBAAgB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,IAAA,EAAA,CAAA;sGAAhB,gBAAgB,EAAA,YAAA,EAAA,IAAA,EAAA,IAAA,EAAA,cAAA,EAAA,CAAA;AAAhB,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,gBAAgB,cAFf,MAAM,EAAA,CAAA;;4FAEP,gBAAgB,EAAA,UAAA,EAAA,CAAA;kBAP5B,IAAI;AAAC,YAAA,IAAA,EAAA,CAAA;AACJ,oBAAA,IAAI,EAAE,cAAc;AACpB,oBAAA,UAAU,EAAE,IAAI;AACjB,iBAAA;;kBACA,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE,MAAM;AACnB,iBAAA;;;MCGY,aAAa,CAAA;IACf,KAAK,GAAwB,EAAE;wGAD7B,aAAa,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAb,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,aAAa,kGCZ1B,ouCAmCA,EAAA,MAAA,EAAA,CAAA,qvCAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,ED3BY,YAAY,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,kBAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,cAAA,EAAA,eAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,OAAO,4NAAE,gBAAgB,EAAA,IAAA,EAAA,cAAA,EAAA,CAAA,EAAA,CAAA;;4FAItC,aAAa,EAAA,UAAA,EAAA,CAAA;kBANzB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,YAAY,WACb,CAAC,YAAY,EAAE,OAAO,EAAE,gBAAgB,CAAC,EAAA,QAAA,EAAA,ouCAAA,EAAA,MAAA,EAAA,CAAA,qvCAAA,CAAA,EAAA;8BAKzC,KAAK,EAAA,CAAA;sBAAb;;;AEbH;;AAEG;;;;"}
1
+ {"version":3,"file":"sd-angular-core-components-history.mjs","sources":["../../../projects/sd-angular/components/history/pipes/view-date.pipe.ts","../../../projects/sd-angular/components/history/src/history.component.ts","../../../projects/sd-angular/components/history/src/history.component.html","../../../projects/sd-angular/components/history/sd-angular-core-components-history.ts"],"sourcesContent":["import { Injectable, Pipe, PipeTransform } from '@angular/core';\r\nimport { DateUtilities, SD_EMPTY_STR } from '@sd-angular/core/utilities';\r\n\r\n@Pipe({\r\n name: 'viewDateTime',\r\n standalone: true,\r\n})\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class ViewDateTimePipe implements PipeTransform {\r\n transform(value: any): string {\r\n if (!value || !DateUtilities.isDate(value)) {\r\n return SD_EMPTY_STR;\r\n }\r\n return DateUtilities.toFormat(value, 'HH:mm dd/MM/yyyy');\r\n }\r\n}\r\n","import { CommonModule } from '@angular/common';\r\nimport { Component, Input } from '@angular/core';\r\nimport { SdBadge } from '@sd-angular/core/components/badge';\r\nimport { SdHistoryItemType } from '../models/history.model';\r\nimport { ViewDateTimePipe } from '../pipes/view-date.pipe';\nimport { SdTPipe } from '@sd-angular/core/i18n';\r\n\r\n@Component({\r\n selector: 'sd-history',\r\n imports: [CommonModule, SdBadge, ViewDateTimePipe, SdTPipe],\r\n templateUrl: './history.component.html',\r\n styleUrl: './history.component.scss',\r\n})\r\nexport class SdHistoryItem {\r\n @Input() items: SdHistoryItemType[] = [];\r\n}\r\n","<div class=\"sd-history\">\r\n <div class=\"history-container\">\r\n <div class=\"history-line\"></div>\r\n <div *ngFor=\"let item of items; let i = index\" class=\"history-item\">\r\n <div class=\"dot\"></div>\r\n <div class=\"card\">\r\n <div class=\"header\">\r\n <div class=\"title-wrapper\">\r\n <span class=\"title\">{{ item.title }}</span>\r\n <span class=\"status\">\r\n @if (item?.status) {\r\n <sd-badge\r\n [icon]=\"item.status?.icon\"\r\n [title]=\"item.status?.title\"\r\n [color]=\"item.status?.color\"></sd-badge>\r\n }\r\n </span>\r\n </div>\r\n <span class=\"date\">{{ item?.date | viewDateTime }}</span>\r\n </div>\r\n <div class=\"meta\">\r\n @if (item?.actor) {\r\n <span>{{ 'core.component.history.by' | sdT }} <strong>&#64;{{ item.actor }}</strong></span>\r\n }\r\n @if (item?.source) {\r\n <span> &#183; {{ item.source }}</span>\r\n }\r\n </div>\r\n <div class=\"description\">\r\n {{ item?.description }}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;;;MAUa,gBAAgB,CAAA;AAC3B,IAAA,SAAS,CAAC,KAAU,EAAA;QAClB,IAAI,CAAC,KAAK,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;AAC1C,YAAA,OAAO,YAAY;QACrB;QACA,OAAO,aAAa,CAAC,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;IAC1D;wGANW,gBAAgB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,IAAA,EAAA,CAAA;sGAAhB,gBAAgB,EAAA,YAAA,EAAA,IAAA,EAAA,IAAA,EAAA,cAAA,EAAA,CAAA;AAAhB,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,gBAAgB,cAFf,MAAM,EAAA,CAAA;;4FAEP,gBAAgB,EAAA,UAAA,EAAA,CAAA;kBAP5B,IAAI;AAAC,YAAA,IAAA,EAAA,CAAA;AACJ,oBAAA,IAAI,EAAE,cAAc;AACpB,oBAAA,UAAU,EAAE,IAAI;AACjB,iBAAA;;kBACA,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE,MAAM;AACnB,iBAAA;;;MCIY,aAAa,CAAA;IACf,KAAK,GAAwB,EAAE;wGAD7B,aAAa,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;4FAAb,aAAa,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,OAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECb1B,mwCAmCA,EAAA,MAAA,EAAA,CAAA,qvCAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,ED1BY,YAAY,4JAAE,OAAO,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,OAAA,EAAA,SAAA,EAAA,WAAA,EAAA,SAAA,EAAA,MAAA,EAAA,SAAA,EAAA,OAAA,EAAA,SAAA,EAAA,OAAA,EAAA,aAAA,EAAA,SAAA,EAAA,MAAA,EAAA,MAAA,CAAA,EAAA,OAAA,EAAA,CAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAE,gBAAgB,EAAA,IAAA,EAAA,cAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAE,OAAO,EAAA,IAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA;;4FAI/C,aAAa,EAAA,UAAA,EAAA,CAAA;kBANzB,SAAS;+BACE,YAAY,EAAA,OAAA,EACb,CAAC,YAAY,EAAE,OAAO,EAAE,gBAAgB,EAAE,OAAO,CAAC,EAAA,QAAA,EAAA,mwCAAA,EAAA,MAAA,EAAA,CAAA,qvCAAA,CAAA,EAAA;8BAKlD,KAAK,EAAA,CAAA;sBAAb;;;AEdH;;AAEG;;;;"}
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Pipe, Injectable, EventEmitter, Output, ViewChild, Input, Component } from '@angular/core';
2
+ import { Pipe, Injectable, EventEmitter, inject, Output, ViewChild, Input, Component } from '@angular/core';
3
3
  import * as i7 from '@angular/material/paginator';
4
4
  import { MatPaginatorModule, MatPaginator } from '@angular/material/paginator';
5
5
  import { Subscription } from 'rxjs';
@@ -19,6 +19,7 @@ import { DateUtilities, NumberUtilities } from '@sd-angular/core/utilities';
19
19
  import * as i1 from '@angular/platform-browser';
20
20
  import { MatProgressSpinner } from '@angular/material/progress-spinner';
21
21
  import { SdBadge } from '@sd-angular/core/components/badge';
22
+ import { SdI18nService, SdTPipe } from '@sd-angular/core/i18n';
22
23
  import * as i1$1 from '@sd-angular/core/services/excel';
23
24
  import * as i2 from '@sd-angular/core/services/notify';
24
25
  import * as i4 from '@sd-angular/core/services/loading';
@@ -138,6 +139,7 @@ class SdImportExcel {
138
139
  isUploaded = false;
139
140
  isDownloadTemplate = false;
140
141
  sdClosed = new EventEmitter();
142
+ #i18n = inject(SdI18nService);
141
143
  constructor(ref, excelService, notifyService, columnHiddenPipe, loadingService) {
142
144
  this.ref = ref;
143
145
  this.excelService = excelService;
@@ -199,12 +201,12 @@ class SdImportExcel {
199
201
  const offset = this.hasDescription ? 2 : 1;
200
202
  items.splice(0, offset);
201
203
  if (items.length === 0) {
202
- this.notifyService.warning(`Tệp tin không có dữ liệu`);
204
+ this.notifyService.warning(this.#i18n.t('core.component.import-excel.no-data-in-file'));
203
205
  return;
204
206
  }
205
207
  const limit = this.option.limit || 1000;
206
208
  if (items.length > limit) {
207
- this.notifyService.warning(`Giới hạn tải lên ${limit} dòng`);
209
+ this.notifyService.warning(this.#i18n.t('core.component.import-excel.row-limit', { limit }));
208
210
  return;
209
211
  }
210
212
  this.#reset();
@@ -271,19 +273,19 @@ class SdImportExcel {
271
273
  item[column.field] = item[column.field] ?? column.defaultValue;
272
274
  }
273
275
  else if (column.required && !item[column.field] && item[column.field] !== 0) {
274
- error[column.field] = `Dữ liệu bắt buộc`;
276
+ error[column.field] = this.#i18n.t('core.component.import-excel.required');
275
277
  errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);
276
278
  continue;
277
279
  }
278
280
  if (column.type === 'string') {
279
281
  const value = (item[column.field] || '').toString();
280
282
  if (column.minlength !== undefined && value.length < column.minlength) {
281
- error[column.field] = `Độ dài chuỗi tối thiểu: ${column.minlength}`;
283
+ error[column.field] = this.#i18n.t('core.component.import-excel.min-length', { min: column.minlength });
282
284
  errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);
283
285
  continue;
284
286
  }
285
287
  if (column.maxlength !== undefined && value.length > column.maxlength) {
286
- error[column.field] = `Độ dài chuỗi tối đa: ${column.maxlength}`;
288
+ error[column.field] = this.#i18n.t('core.component.import-excel.max-length', { max: column.maxlength });
287
289
  errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);
288
290
  continue;
289
291
  }
@@ -293,7 +295,7 @@ class SdImportExcel {
293
295
  if (item[column.field]) {
294
296
  const value = +item[column.field];
295
297
  if (!NumberUtilities.isNumber(item[column.field])) {
296
- error[column.field] = `${item[column.field]} không phải số hợp lệ`;
298
+ error[column.field] = this.#i18n.t('core.component.import-excel.not-a-number', { value: item[column.field] });
297
299
  errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);
298
300
  continue;
299
301
  }
@@ -303,12 +305,12 @@ class SdImportExcel {
303
305
  item[column.field] = undefined;
304
306
  }
305
307
  if (column.min !== undefined && item[column.field] < column.min) {
306
- error[column.field] = `${item[column.field]} không thỏa giá trị tối thiểu: ${column.min}`;
308
+ error[column.field] = this.#i18n.t('core.component.import-excel.below-min', { value: item[column.field], min: column.min });
307
309
  errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);
308
310
  continue;
309
311
  }
310
312
  if (column.max !== undefined && item[column.field] > column.max) {
311
- error[column.field] = `${item[column.field]} không thỏa giá trị tối đa: ${column.max}`;
313
+ error[column.field] = this.#i18n.t('core.component.import-excel.above-max', { value: item[column.field], max: column.max });
312
314
  errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);
313
315
  continue;
314
316
  }
@@ -329,18 +331,18 @@ class SdImportExcel {
329
331
  else if (item[column.field] === '')
330
332
  item[column.field] = undefined;
331
333
  if (typeof item[column.field] !== 'boolean' && item[column.field] !== undefined && item[column.field] !== null) {
332
- error[column.field] = `Vui lòng nhập giá trị hợp lệ true, false, 1, 0`;
334
+ error[column.field] = this.#i18n.t('core.component.import-excel.invalid-bool');
333
335
  errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);
334
336
  }
335
337
  }
336
338
  else if (column.type === 'values') {
337
339
  if (item[column.field] && typeof item[column.field] !== 'number' && typeof item[column.field] !== 'string') {
338
- error[column.field] = `Giá trị ${item[column.field]} không hợp lệ`;
340
+ error[column.field] = this.#i18n.t('core.component.import-excel.invalid-value', { value: item[column.field] });
339
341
  errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);
340
342
  continue;
341
343
  }
342
344
  if (column.checkValueInArray && item[column.field] && !column.values.some(e => e.toString() === item[column.field].toString())) {
343
- error[column.field] = `Giá trị ${item[column.field]} không thuộc danh sách cho phép [${column.values.join()}]`;
345
+ error[column.field] = this.#i18n.t('core.component.import-excel.value-not-in-list', { value: item[column.field], list: column.values.join() });
344
346
  errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);
345
347
  continue;
346
348
  }
@@ -354,29 +356,29 @@ class SdImportExcel {
354
356
  }
355
357
  if (format && item[column.field]) {
356
358
  if (typeof val !== 'string') {
357
- error[column.field] = `Ngày ${val} không đúng định dạng ${column.format}`;
359
+ error[column.field] = this.#i18n.t('core.component.import-excel.invalid-date-format', { value: val ?? '', format: column.format ?? '' });
358
360
  errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);
359
361
  continue;
360
362
  }
361
363
  if (type === 'date' && !this.#isValidDate(format, val)) {
362
- error[column.field] = `Ngày ${val} không đúng định dạng ${column.format}`;
364
+ error[column.field] = this.#i18n.t('core.component.import-excel.invalid-date-format', { value: val ?? '', format: column.format ?? '' });
363
365
  errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);
364
366
  continue;
365
367
  }
366
368
  if (type === 'time' && !this.#isValidTime(format, val)) {
367
- error[column.field] = `Ngày ${val} không đúng định dạng ${column.format}`;
369
+ error[column.field] = this.#i18n.t('core.component.import-excel.invalid-date-format', { value: val ?? '', format: column.format ?? '' });
368
370
  errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);
369
371
  continue;
370
372
  }
371
373
  if (type === 'datetime' && !this.#isValidDateTime(format, val)) {
372
- error[column.field] = `Ngày ${val} không đúng định dạng ${column.format}`;
374
+ error[column.field] = this.#i18n.t('core.component.import-excel.invalid-date-format', { value: val ?? '', format: column.format ?? '' });
373
375
  errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);
374
376
  continue;
375
377
  }
376
378
  item[column.field] = DateUtilities.parseFrom(val, format);
377
379
  }
378
380
  if (item[column.field] && !DateUtilities.isDate(item[column.field])) {
379
- error[column.field] = `Ngày ${val} không đúng định dạng ${column.format}`;
381
+ error[column.field] = this.#i18n.t('core.component.import-excel.invalid-date-format', { value: val ?? '', format: column.format ?? '' });
380
382
  errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);
381
383
  continue;
382
384
  }
@@ -391,7 +393,7 @@ class SdImportExcel {
391
393
  }
392
394
  }
393
395
  catch (ex) {
394
- error[column.field] = `${ex?.message || ex?.error || ex || 'Có lỗi xảy ra'}`;
396
+ error[column.field] = `${ex?.message || ex?.error || ex || this.#i18n.t('core.component.import-excel.generic-error')}`;
395
397
  errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);
396
398
  }
397
399
  }
@@ -475,7 +477,7 @@ class SdImportExcel {
475
477
  const columns = [
476
478
  {
477
479
  field: 'sdMessage',
478
- title: 'Thông báo',
480
+ title: this.#i18n.t('core.component.import-excel.message-column'),
479
481
  width: '250px',
480
482
  required: false,
481
483
  },
@@ -494,7 +496,7 @@ class SdImportExcel {
494
496
  }
495
497
  return {
496
498
  ...result,
497
- sdMessage: (e.meta.errorMessages.join(', ') || e.meta.warningMessages.join(', ') || 'Thành công')
499
+ sdMessage: (e.meta.errorMessages.join(', ') || e.meta.warningMessages.join(', ') || this.#i18n.t('core.component.import-excel.success'))
498
500
  ?.replace(/<strong>/g, '')
499
501
  .replace(/<\/strong>/g, '')
500
502
  .replace(/<br>/g, '\n'),
@@ -538,7 +540,7 @@ class SdImportExcel {
538
540
  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
541
  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
542
  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=\"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"] }] });
543
+ ], 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 || ('core.component.import-excel.title' | sdT)\" (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]=\"'core.component.import-excel.see-all' | sdT\" 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]=\"'core.component.import-excel.valid-rows' | sdT\"\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]=\"'core.component.import-excel.error-rows' | sdT\"\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]=\"'core.component.import-excel.warning-rows' | sdT\"\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\">{{ 'core.component.import-excel.status' | sdT }}</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\\'>' + ('core.component.import-excel.valid-data' | sdT) + '</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]=\"'core.component.import-excel.download-template-tooltip' | sdT\"\r\n aria-hidden=\"true\">\r\n <mat-icon class=\"empty-icon\">cloud_download</mat-icon>\r\n\r\n <h4>{{ 'core.component.import-excel.no-data-upload' | sdT }}</h4>\r\n <span class=\"text-small text-link\"> {{ 'core.component.import-excel.click-here-template' | sdT }} </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]=\"'core.component.import-excel.upload' | sdT\" 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]=\"'core.component.import-excel.download' | sdT\" size=\"sm\" color=\"success\" type=\"outline\">\r\n </sd-button>\r\n }\r\n <sd-button\r\n (click)=\"accept()\"\r\n [title]=\"'core.component.import-excel.confirm-save' | sdT\"\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"] }, { kind: "pipe", type: SdTPipe, name: "sdT" }] });
542
544
  }
543
545
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdImportExcel, decorators: [{
544
546
  type: Component,
@@ -556,10 +558,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
556
558
  MatIconModule,
557
559
  MatMenuModule,
558
560
  MatProgressSpinner,
559
- SdBadge
561
+ SdBadge, SdTPipe
560
562
  ], providers: [
561
563
  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=\"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"] }]
564
+ ], template: "@if (option) {\r\n <sd-modal [title]=\"option.title || ('core.component.import-excel.title' | sdT)\" (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]=\"'core.component.import-excel.see-all' | sdT\" 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]=\"'core.component.import-excel.valid-rows' | sdT\"\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]=\"'core.component.import-excel.error-rows' | sdT\"\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]=\"'core.component.import-excel.warning-rows' | sdT\"\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\">{{ 'core.component.import-excel.status' | sdT }}</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\\'>' + ('core.component.import-excel.valid-data' | sdT) + '</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]=\"'core.component.import-excel.download-template-tooltip' | sdT\"\r\n aria-hidden=\"true\">\r\n <mat-icon class=\"empty-icon\">cloud_download</mat-icon>\r\n\r\n <h4>{{ 'core.component.import-excel.no-data-upload' | sdT }}</h4>\r\n <span class=\"text-small text-link\"> {{ 'core.component.import-excel.click-here-template' | sdT }} </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]=\"'core.component.import-excel.upload' | sdT\" 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]=\"'core.component.import-excel.download' | sdT\" size=\"sm\" color=\"success\" type=\"outline\">\r\n </sd-button>\r\n }\r\n <sd-button\r\n (click)=\"accept()\"\r\n [title]=\"'core.component.import-excel.confirm-save' | sdT\"\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
565
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1$1.SdExcelService }, { type: i2.SdNotifyService }, { type: ColumnHiddenPipe }, { type: i4.SdLoadingService }], propDecorators: { option: [{
564
566
  type: Input,
565
567
  args: [{ required: true }]