@sd-angular/core 19.0.0-beta.8 → 19.0.0-beta.81
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +686 -33
- package/assets/scss/ckeditor5.scss +61 -4
- package/assets/scss/core/bootstrap.scss +17 -0
- package/assets/scss/core/form.scss +32 -6
- package/assets/scss/core/grid.scss +40 -0
- package/assets/scss/sd-core.scss +5 -0
- package/assets/scss/themes/material-theme.scss +82 -40
- package/components/anchor-v2/src/components/anchor-item-v2/anchor-item-v2.component.d.ts +5 -5
- package/components/anchor-v2/src/components/anchor-v2/anchor-v2.component.d.ts +12 -18
- package/components/anchor-v2/src/components/anchor-vertical-v2/anchor-vertical-list-v2.component.d.ts +9 -10
- package/components/anchor-v2/src/models/sd-anchor-v2.model.d.ts +3 -3
- package/components/avatar/index.d.ts +1 -0
- package/components/avatar/src/avatar.component.d.ts +19 -0
- package/components/badge/src/badge.component.d.ts +77 -19
- package/components/button/src/button.component.d.ts +30 -28
- package/components/chart/index.d.ts +4 -0
- package/components/chart/src/bar-chart.component.d.ts +18 -0
- package/components/chart/src/doughnut-chart.component.d.ts +16 -0
- package/components/chart/src/line-chart.component.d.ts +18 -0
- package/components/chart/src/pie-chart.component.d.ts +16 -0
- package/components/code-editor/index.d.ts +1 -0
- package/components/code-editor/src/code-editor.component.d.ts +25 -0
- package/components/document-builder/index.d.ts +1 -0
- package/components/document-builder/src/document-builder.component.d.ts +13 -42
- package/components/document-builder/src/document-builder.model.d.ts +15 -12
- package/components/document-builder/src/plugins/block-space/block-space.plugin.d.ts +9 -0
- package/components/document-builder/src/plugins/ck-comment/ck-comment.plugin.d.ts +44 -0
- package/components/document-builder/src/plugins/ck-comment/ck-comment.plugin.model.d.ts +57 -0
- package/components/document-builder/src/plugins/heading/heading.plugin.d.ts +1 -0
- package/components/document-builder/src/plugins/highlight-range/highlight-range.plugin.d.ts +4 -0
- package/components/document-builder/src/plugins/image-custom/image-custom.plugin.d.ts +31 -0
- package/components/document-builder/src/plugins/index.d.ts +7 -2
- package/components/document-builder/src/plugins/page-orientation/page-orientation.plugin.d.ts +2 -2
- package/components/document-builder/src/plugins/paste-handler/filters/bookmark.d.ts +14 -0
- package/components/document-builder/src/plugins/paste-handler/filters/br.d.ts +15 -0
- package/components/document-builder/src/plugins/paste-handler/filters/image.d.ts +25 -0
- package/components/document-builder/src/plugins/paste-handler/filters/list.d.ts +29 -0
- package/components/document-builder/src/plugins/paste-handler/filters/parse.d.ts +35 -0
- package/components/document-builder/src/plugins/paste-handler/filters/removeboldwrapper.d.ts +15 -0
- package/components/document-builder/src/plugins/paste-handler/filters/removegooglesheetstag.d.ts +15 -0
- package/components/document-builder/src/plugins/paste-handler/filters/removeinvalidtablewidth.d.ts +15 -0
- package/components/document-builder/src/plugins/paste-handler/filters/removemsattributes.d.ts +15 -0
- package/components/document-builder/src/plugins/paste-handler/filters/removestyleblock.d.ts +15 -0
- package/components/document-builder/src/plugins/paste-handler/filters/removexmlns.d.ts +15 -0
- package/components/document-builder/src/plugins/paste-handler/filters/replacemsfootnotes.d.ts +54 -0
- package/components/document-builder/src/plugins/paste-handler/filters/replacetabswithinprewithspaces.d.ts +24 -0
- package/components/document-builder/src/plugins/paste-handler/filters/space.d.ts +27 -0
- package/components/document-builder/src/plugins/paste-handler/filters/table.d.ts +16 -0
- package/components/document-builder/src/plugins/paste-handler/filters/utils.d.ts +25 -0
- package/components/document-builder/src/plugins/paste-handler/index.d.ts +35 -0
- package/components/document-builder/src/plugins/paste-handler/normalizers/googledocsnormalizer.d.ts +31 -0
- package/components/document-builder/src/plugins/paste-handler/normalizers/googlesheetsnormalizer.d.ts +31 -0
- package/components/document-builder/src/plugins/paste-handler/normalizers/mswordnormalizer.d.ts +29 -0
- package/components/document-builder/src/plugins/paste-handler/types.d.ts +30 -0
- package/components/document-builder/src/plugins/table-custom/index.d.ts +34 -0
- package/components/document-builder/src/plugins/variable/variable.plugin.d.ts +39 -0
- package/components/editor/index.d.ts +3 -0
- package/components/editor/src/configurations/editor.configuration.d.ts +12 -0
- package/components/editor/src/configurations/index.d.ts +1 -0
- package/components/editor/src/editor.component.d.ts +42 -0
- package/components/editor/src/models/editor.model.d.ts +8 -0
- package/components/editor/src/models/image-upload.plugin.model.d.ts +20 -0
- package/components/editor/src/models/index.d.ts +2 -0
- package/components/editor/src/plugins/image-upload/image-upload.plugin.d.ts +22 -0
- package/components/editor/src/plugins/image-upload/utils/batch.utils.d.ts +14 -0
- package/components/editor/src/plugins/image-upload/utils/index.d.ts +3 -0
- package/components/editor/src/plugins/image-upload/utils/style.utils.d.ts +2 -0
- package/components/editor/src/plugins/image-upload/utils/validate.utils.d.ts +3 -0
- package/components/index.d.ts +6 -0
- package/components/mini-editor/index.d.ts +2 -0
- package/components/mini-editor/src/mini-editor.component.d.ts +91 -0
- package/components/mini-editor/src/mini-editor.model.d.ts +44 -0
- package/components/modal/index.d.ts +1 -1
- package/components/modal/src/modal.component.d.ts +26 -0
- package/components/section/index.d.ts +1 -0
- package/components/section/src/section-item/section-item.component.d.ts +7 -0
- package/components/section/src/section.component.d.ts +11 -11
- package/components/side-drawer/src/side-drawer.component.d.ts +11 -24
- package/components/tab-router/src/components/tab-router-item/tab-router-item.component.d.ts +4 -1
- package/components/tab-router/src/components/tab-router-outlet/tab-router-outlet.component.d.ts +3 -15
- package/components/table/index.d.ts +2 -0
- package/components/table/src/components/column-filter/column-filter.component.d.ts +3 -3
- package/components/table/src/components/column-title/column-title.component.d.ts +10 -0
- package/components/table/src/components/desktop-cell/desktop-cell.component.d.ts +18 -11
- package/components/table/src/components/desktop-cell/view/view.component.d.ts +24 -0
- package/components/table/src/components/external-filter/external-filter.component.d.ts +1 -1
- package/components/table/src/components/index.d.ts +1 -0
- package/components/table/src/components/selector-action/action-filter.pipe.d.ts +11 -10
- package/components/table/src/components/selector-action/selector-action.component.d.ts +5 -3
- package/components/table/src/directives/index.d.ts +4 -0
- package/components/table/src/directives/sd-table-cell-def.directive.d.ts +2 -3
- package/components/table/src/directives/sd-table-column-filter-def.directive.d.ts +8 -0
- package/components/table/src/directives/sd-table-expand-def.directive.d.ts +0 -1
- package/components/table/src/directives/sd-table-filter-def.directive.d.ts +4 -6
- package/components/table/src/directives/sd-table-footer-def.directive.d.ts +2 -3
- package/components/table/src/directives/sd-table-title-def.directive.d.ts +8 -0
- package/components/table/src/directives/sticky-shadow.directive.d.ts +17 -0
- package/components/table/src/models/table-column.model.d.ts +49 -40
- package/components/table/src/models/table-command.model.d.ts +7 -3
- package/components/table/src/models/table-item.model.d.ts +5 -4
- package/components/table/src/models/table-option-config.model.d.ts +3 -0
- package/components/table/src/models/table-option-export.model.d.ts +3 -2
- package/components/table/src/models/table-option-selector.model.d.ts +17 -10
- package/components/table/src/models/table-option.model.d.ts +15 -8
- package/components/table/src/services/index.d.ts +3 -0
- package/components/table/src/services/table-export/table-export.service.d.ts +26 -0
- package/components/table/src/services/table-filter/table-filter.model.d.ts +6 -5
- package/components/table/src/services/table-format/table-format.service.d.ts +16 -0
- package/components/table/src/table.component.d.ts +46 -53
- package/components/upload-file/src/configurations/upload-file.configuration.d.ts +34 -1
- package/components/upload-file/src/services/upload-file.service.d.ts +0 -1
- package/components/upload-file/src/upload-file.component.d.ts +52 -54
- package/components/view/index.d.ts +1 -0
- package/components/view/src/view.component.d.ts +16 -0
- package/components/workflow/src/models/form-generic-component.model.d.ts +5 -4
- package/components/workflow/src/models/form-generic-expression.model.d.ts +1 -0
- package/components/workflow/src/models/index.d.ts +1 -0
- package/components/workflow/src/pipes/html.pipe.d.ts +4 -4
- package/directives/index.d.ts +2 -0
- package/directives/src/sd-href.directive.d.ts +9 -0
- package/directives/src/sd-tooltip.directive.d.ts +26 -0
- package/fesm2022/sd-angular-core-components-anchor-v2.mjs +79 -154
- package/fesm2022/sd-angular-core-components-anchor-v2.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-avatar.mjs +103 -0
- package/fesm2022/sd-angular-core-components-avatar.mjs.map +1 -0
- package/fesm2022/sd-angular-core-components-badge.mjs +101 -91
- package/fesm2022/sd-angular-core-components-badge.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-button.mjs +70 -96
- package/fesm2022/sd-angular-core-components-button.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-chart.mjs +290 -0
- package/fesm2022/sd-angular-core-components-chart.mjs.map +1 -0
- package/fesm2022/sd-angular-core-components-code-editor.mjs +127 -0
- package/fesm2022/sd-angular-core-components-code-editor.mjs.map +1 -0
- package/fesm2022/sd-angular-core-components-document-builder.mjs +4005 -611
- package/fesm2022/sd-angular-core-components-document-builder.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-editor.mjs +933 -0
- package/fesm2022/sd-angular-core-components-editor.mjs.map +1 -0
- package/fesm2022/sd-angular-core-components-history.mjs +1 -1
- package/fesm2022/sd-angular-core-components-history.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-import-excel.mjs +1 -1
- package/fesm2022/sd-angular-core-components-import-excel.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-mini-editor.mjs +332 -0
- package/fesm2022/sd-angular-core-components-mini-editor.mjs.map +1 -0
- package/fesm2022/sd-angular-core-components-modal.mjs +63 -92
- package/fesm2022/sd-angular-core-components-modal.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-preview.mjs +1 -1
- package/fesm2022/sd-angular-core-components-preview.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-quick-action.mjs +2 -2
- package/fesm2022/sd-angular-core-components-quick-action.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-section.mjs +41 -43
- package/fesm2022/sd-angular-core-components-section.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-side-drawer.mjs +78 -84
- package/fesm2022/sd-angular-core-components-side-drawer.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-tab-router.mjs +151 -241
- package/fesm2022/sd-angular-core-components-tab-router.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-table.mjs +1394 -1254
- package/fesm2022/sd-angular-core-components-table.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-upload-file.mjs +390 -443
- package/fesm2022/sd-angular-core-components-upload-file.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-view.mjs +45 -0
- package/fesm2022/sd-angular-core-components-view.mjs.map +1 -0
- package/fesm2022/sd-angular-core-components-workflow.mjs +165 -168
- package/fesm2022/sd-angular-core-components-workflow.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components.mjs +6 -0
- package/fesm2022/sd-angular-core-components.mjs.map +1 -1
- package/fesm2022/sd-angular-core-directives.mjs +286 -27
- package/fesm2022/sd-angular-core-directives.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-autocomplete.mjs +289 -363
- package/fesm2022/sd-angular-core-forms-autocomplete.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-chip-calendar.mjs +170 -189
- package/fesm2022/sd-angular-core-forms-chip-calendar.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-chip.mjs +184 -194
- package/fesm2022/sd-angular-core-forms-chip.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-date-range.mjs +180 -242
- package/fesm2022/sd-angular-core-forms-date-range.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-date.mjs +178 -270
- package/fesm2022/sd-angular-core-forms-date.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-datetime.mjs +177 -285
- package/fesm2022/sd-angular-core-forms-datetime.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-input-number.mjs +210 -337
- package/fesm2022/sd-angular-core-forms-input-number.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-input.mjs +169 -286
- package/fesm2022/sd-angular-core-forms-input.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-radio.mjs +3 -2
- package/fesm2022/sd-angular-core-forms-radio.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-select.mjs +390 -447
- package/fesm2022/sd-angular-core-forms-select.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-textarea.mjs +167 -226
- package/fesm2022/sd-angular-core-forms-textarea.mjs.map +1 -1
- package/fesm2022/sd-angular-core-modules-authom.mjs +359 -0
- package/fesm2022/sd-angular-core-modules-authom.mjs.map +1 -0
- package/fesm2022/sd-angular-core-modules-keycloak.mjs +126 -0
- package/fesm2022/sd-angular-core-modules-keycloak.mjs.map +1 -0
- package/fesm2022/sd-angular-core-modules-layout.mjs +709 -456
- package/fesm2022/sd-angular-core-modules-layout.mjs.map +1 -1
- package/fesm2022/sd-angular-core-modules-permission.mjs +160 -74
- package/fesm2022/sd-angular-core-modules-permission.mjs.map +1 -1
- package/fesm2022/sd-angular-core-modules.mjs +2 -1
- package/fesm2022/sd-angular-core-modules.mjs.map +1 -1
- package/fesm2022/sd-angular-core-services-api.mjs +5 -10
- package/fesm2022/sd-angular-core-services-api.mjs.map +1 -1
- package/fesm2022/sd-angular-core-services-confirm.mjs +9 -7
- package/fesm2022/sd-angular-core-services-confirm.mjs.map +1 -1
- package/fesm2022/sd-angular-core-services-docx.mjs +173 -0
- package/fesm2022/sd-angular-core-services-docx.mjs.map +1 -0
- package/fesm2022/sd-angular-core-services-notify.mjs +2 -2
- package/fesm2022/sd-angular-core-services-notify.mjs.map +1 -1
- package/fesm2022/sd-angular-core-services.mjs +1 -0
- package/fesm2022/sd-angular-core-services.mjs.map +1 -1
- package/fesm2022/sd-angular-core-utilities-extensions.mjs +58 -80
- package/fesm2022/sd-angular-core-utilities-extensions.mjs.map +1 -1
- package/fesm2022/sd-angular-core-utilities-models.mjs +15 -1
- package/fesm2022/sd-angular-core-utilities-models.mjs.map +1 -1
- package/fesm2022/sd-angular-core.mjs +0 -1
- package/fesm2022/sd-angular-core.mjs.map +1 -1
- package/forms/autocomplete/src/autocomplete.component.d.ts +55 -55
- package/forms/chip/src/chip.component.d.ts +37 -40
- package/forms/chip-calendar/src/chip-calendar.component.d.ts +37 -38
- package/forms/date/src/date.component.d.ts +48 -46
- package/forms/date-range/src/date-range.component.d.ts +35 -34
- package/forms/datetime/src/datetime.component.d.ts +48 -49
- package/forms/input/src/input.component.d.ts +54 -57
- package/forms/input-number/src/input-number.component.d.ts +53 -54
- package/forms/select/src/select.component.d.ts +67 -64
- package/forms/textarea/src/textarea.component.d.ts +40 -43
- package/modules/authom/authom.configuration.d.ts +17 -0
- package/modules/authom/authom.interceptor.d.ts +3 -0
- package/modules/authom/authom.module.d.ts +16 -0
- package/modules/authom/authom.service.d.ts +32 -0
- package/modules/authom/index.d.ts +35 -0
- package/modules/index.d.ts +2 -1
- package/modules/keycloak/index.d.ts +4 -0
- package/modules/keycloak/keycloak.configuration.d.ts +11 -0
- package/modules/keycloak/keycloak.interceptor.d.ts +2 -0
- package/modules/keycloak/keycloak.module.d.ts +18 -0
- package/modules/keycloak/keycloak.service.d.ts +14 -0
- package/modules/layout/components/index.d.ts +2 -0
- package/modules/layout/components/layout-main/layout-main.component.d.ts +8 -12
- package/modules/layout/components/page/page.component.d.ts +5 -7
- package/modules/layout/components/sidebar-mobile-v1/components/sidebar/sidebar.component.d.ts +35 -0
- package/modules/layout/components/sidebar-mobile-v1/components/user/user.component.d.ts +24 -0
- package/modules/layout/components/sidebar-mobile-v1/main.component.d.ts +21 -0
- package/modules/layout/components/sidebar-v1/components/sidebar/sidebar.component.d.ts +22 -29
- package/modules/layout/components/sidebar-v1/components/user/user.component.d.ts +11 -17
- package/modules/layout/components/sidebar-v1/main.component.d.ts +14 -14
- package/modules/layout/configurations/layout.configuration.d.ts +46 -3
- package/modules/layout/modules/forbidden/pages/root/root.component.d.ts +3 -8
- package/modules/layout/modules/home/components/home-page/home-page.component.d.ts +2 -5
- package/modules/layout/modules/not-found/pages/root/root.component.d.ts +3 -8
- package/modules/layout/pipes/high-light-search.pipe.d.ts +1 -1
- package/modules/layout/services/index.d.ts +1 -0
- package/modules/layout/services/layout.service.d.ts +10 -0
- package/modules/layout/services/menu/menu.model.d.ts +4 -1
- package/modules/layout/services/storage/storage.service.d.ts +0 -3
- package/modules/permission/src/configurations/permission.configuration.d.ts +56 -2
- package/modules/permission/src/directives/permission.directive.d.ts +5 -8
- package/modules/permission/src/guards/permission.guard.d.ts +2 -1
- package/modules/permission/src/services/permission.service.d.ts +6 -9
- package/package.json +107 -79
- package/public-api.d.ts +0 -1
- package/sd-angular-core-19.0.0-beta.81.tgz +0 -0
- package/services/api/src/api.model.d.ts +6 -1
- package/services/confirm/src/lib/confirm.service.d.ts +5 -0
- package/services/docx/index.d.ts +1 -0
- package/services/docx/src/lib/docx.model.d.ts +9 -0
- package/services/docx/src/lib/docx.service.d.ts +13 -0
- package/services/docx/src/public-api.d.ts +2 -0
- package/services/index.d.ts +1 -0
- package/services/notify/index.d.ts +1 -0
- package/services/notify/src/notify.model.d.ts +1 -1
- package/services/notify/src/notify.service.d.ts +5 -5
- package/utilities/extensions/src/string.extension.d.ts +3 -0
- package/utilities/extensions/src/utility.extension.d.ts +1 -0
- package/utilities/models/index.d.ts +3 -0
- package/utilities/models/src/filter.model.d.ts +17 -4
- package/utilities/models/src/icon.model.d.ts +2 -0
- package/utilities/models/src/nested-key-of.model.d.ts +5 -0
- package/utilities/models/src/order.model.d.ts +2 -1
- package/utilities/models/src/paging.model.d.ts +2 -1
- package/utilities/models/src/pattern.model.d.ts +1 -1
- package/utilities/models/src/unwrap-signal.model.d.ts +6 -0
- package/components/document-builder/src/plugins/comment/comment.plugin.d.ts +0 -4
- package/components/document-builder/src/plugins/table-fit/table-fit.plugin.d.ts +0 -4
- package/components/modal/src/modal/modal.component.d.ts +0 -31
- package/components/table/src/components/desktop-cell-view/desktop-cell-view.component.d.ts +0 -14
- package/fesm2022/sd-angular-core-guards-permission.mjs +0 -155
- package/fesm2022/sd-angular-core-guards-permission.mjs.map +0 -1
- package/fesm2022/sd-angular-core-guards.mjs +0 -6
- package/fesm2022/sd-angular-core-guards.mjs.map +0 -1
- package/fesm2022/sd-angular-core-modules-oidc.mjs +0 -127
- package/fesm2022/sd-angular-core-modules-oidc.mjs.map +0 -1
- package/guards/index.d.ts +0 -1
- package/guards/permission/index.d.ts +0 -4
- package/guards/permission/src/configurations/index.d.ts +0 -1
- package/guards/permission/src/configurations/permission.configuration.d.ts +0 -8
- package/guards/permission/src/directives/index.d.ts +0 -1
- package/guards/permission/src/directives/permission.directive.d.ts +0 -12
- package/guards/permission/src/guards/index.d.ts +0 -1
- package/guards/permission/src/guards/permission.guard.d.ts +0 -13
- package/guards/permission/src/services/index.d.ts +0 -1
- package/guards/permission/src/services/permission.service.d.ts +0 -15
- package/modules/oidc/dynamic-sts.loader.d.ts +0 -11
- package/modules/oidc/index.d.ts +0 -2
- package/modules/oidc/oidc.configuration.d.ts +0 -11
- package/modules/oidc/oidc.module.d.ts +0 -14
- package/sd-angular-core-19.0.0-beta.8.tgz +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sd-angular-core-components-import-excel.mjs","sources":["../../../projects/sd-angular/components/import-excel/src/import-excel.model.ts","../../../projects/sd-angular/components/import-excel/src/pipes/columm-hidden.pipe.ts","../../../projects/sd-angular/components/import-excel/src/pipes/column-transform.pipe.ts","../../../projects/sd-angular/components/import-excel/src/import-excel.component.ts","../../../projects/sd-angular/components/import-excel/src/import-excel.component.html","../../../projects/sd-angular/components/import-excel/sd-angular-core-components-import-excel.ts"],"sourcesContent":["export interface SdImportExcelValidation {\r\n idx: number;\r\n errorMessage?: string;\r\n warningMessage?: string;\r\n}\r\nexport interface SdImportExcelSheet<T = any> {\r\n name: string; // Tên của sheet\r\n items: T[] | (() => Promise<T[]>);\r\n headers: {\r\n value: Extract<keyof T, string>; // Trường muốn hiển thị\r\n display: string; // Label hiển thị\r\n }[];\r\n}\r\n\r\nexport interface SdImportExcelOption<T = any> {\r\n columns: SdUploadExcelColumn<T>[];\r\n accept: (items: T[], args: { file: File }) => SdImportExcelValidation[] | Promise<SdImportExcelValidation[]>;\r\n title?: string;\r\n fileName?: string;\r\n limit?: number;\r\n sheets?: SdImportExcelSheet[];\r\n transform?: (items: SdImportExcelItem<T>[]) => SdImportExcelItem<T>[] | Promise<SdImportExcelItem<T>[]>;\r\n validateItem?: (item: T, idx: number, items: T[]) => SdImportExcelValidation | Promise<SdImportExcelValidation>;\r\n validateItems?: (items: T[]) => SdImportExcelValidation[] | Promise<SdImportExcelValidation[]>;\r\n}\r\n\r\nexport type SdUploadExcelColumn<T = any> =\r\n | SdUploadExcelColumnString<T>\r\n | SdUploadExcelColumnNumber<T>\r\n | SdUploadExcelColumnBool<T>\r\n | SdUploadExcelColumnDate<T>\r\n | SdUploadExcelColumnTime<T>\r\n | SdUploadExcelColumnDateTime<T>\r\n | SdUploadExcelColumnValues<T>\r\n | SdUploadExcelColumnStringArray<T>;\r\n\r\nexport interface SdUploadExcelBaseColumn<T = any> {\r\n field: string;\r\n title: string;\r\n required?: boolean;\r\n width?: string;\r\n description?: string;\r\n hidden?: boolean | (() => boolean);\r\n fontColor?: string;\r\n fill?: string;\r\n transform?: (value: any, rowData: T) => string | Promise<string>;\r\n}\r\n\r\nexport interface SdUploadExcelColumnString<T = any> extends SdUploadExcelBaseColumn<T> {\r\n type: 'string';\r\n defaultValue?: string;\r\n pattern?: string;\r\n minlength?: number;\r\n maxlength?: number;\r\n}\r\n\r\nexport interface SdUploadExcelColumnNumber<T = any> extends SdUploadExcelBaseColumn<T> {\r\n type: 'number';\r\n defaultValue?: number;\r\n min?: number;\r\n max?: number;\r\n}\r\n\r\nexport interface SdUploadExcelColumnBool<T = any> extends SdUploadExcelBaseColumn<T> {\r\n type: 'bool';\r\n defaultValue?: boolean;\r\n parseToBool?: boolean;\r\n}\r\n\r\nexport interface SdUploadExcelColumnDate<T = any> extends SdUploadExcelBaseColumn<T> {\r\n type: 'date';\r\n format?: 'dd/MM/yyyy';\r\n defaultValue?: Date;\r\n minDate?: Date;\r\n maxDate?: Date;\r\n}\r\n\r\nexport interface SdUploadExcelColumnTime<T = any> extends SdUploadExcelBaseColumn<T> {\r\n type: 'time';\r\n format?: 'HH:mm' | 'HH:mm:ss';\r\n defaultValue?: Date;\r\n minDate?: Date;\r\n maxDate?: Date;\r\n}\r\n\r\nexport interface SdUploadExcelColumnDateTime<T = any> extends SdUploadExcelBaseColumn<T> {\r\n type: 'datetime';\r\n format?: 'dd/MM/yyyy HH:mm' | 'dd/MM/yyyy';\r\n defaultValue?: Date;\r\n minDate?: Date;\r\n maxDate?: Date;\r\n}\r\n\r\nexport interface SdUploadExcelColumnValues<T = any> extends SdUploadExcelBaseColumn<T> {\r\n type: 'values' | 'radio';\r\n defaultValue?: string | number;\r\n values: (string | number)[];\r\n checkValueInArray?: boolean;\r\n}\r\n\r\nexport interface SdUploadExcelColumnStringArray<T = any> extends SdUploadExcelBaseColumn<T> {\r\n type: 'array';\r\n divideString: string | ';';\r\n unitString: string | 'items';\r\n defaultValue?: string;\r\n minlength?: number;\r\n maxlength?: number;\r\n}\r\n\r\nexport type SdImportExcelItem<T = any> = {\r\n data: T;\r\n meta: {\r\n excelIndex: number;\r\n origin: T;\r\n error: Record<string, string>;\r\n errorMessages: string[];\r\n warning: Record<string, string>;\r\n warningMessages: string[];\r\n };\r\n};\r\n\r\n// export type ExcelItem<T> = {\r\n// origin?: T;\r\n// excelIndex?: number;\r\n// validation: SdUploadExcelValidation;\r\n// } & T;\r\n","import { Injectable, Pipe, PipeTransform } from '@angular/core';\r\nimport { SdUploadExcelColumn } from '../import-excel.model';\r\n@Pipe({\r\n name: 'columnHidden'\r\n})\r\n@Injectable()\r\nexport class ColumnHiddenPipe implements PipeTransform {\r\n constructor() { }\r\n transform(column: SdUploadExcelColumn): boolean {\r\n if (column.hidden === undefined) {\r\n return true;\r\n }\r\n if (typeof (column.hidden) === 'boolean') {\r\n return !column.hidden;\r\n }\r\n if (typeof (column.hidden) === 'function') {\r\n return !column.hidden();\r\n }\r\n return false;\r\n }\r\n}\r\n","import { Pipe, PipeTransform } from '@angular/core';\r\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\r\nimport { DateUtilities, NumberUtilities } from '@sd-angular/core/utilities';\r\nimport { SdImportExcelItem, SdUploadExcelColumn } from '../import-excel.model';\r\n\r\n@Pipe({\r\n name: 'columnTransform',\r\n standalone: true,\r\n})\r\nexport class ColumnTransformPipe implements PipeTransform {\r\n constructor(private sanitizer: DomSanitizer) {}\r\n\r\n // Chuyển thành async để hỗ trợ Promise từ bên ngoài\r\n async transform(item: SdImportExcelItem, column: SdUploadExcelColumn): Promise<string | SafeHtml> {\r\n const { type, transform, field } = column;\r\n const value = item.data[field];\r\n\r\n // 1. Ưu tiên hiển thị dữ liệu gốc nếu có lỗi\r\n if (item.meta.error[field]) {\r\n return item.meta.origin[field] ?? value ?? '';\r\n }\r\n\r\n // 2. Custom Transform (Hỗ trợ cả Sync và Async)\r\n if (transform) {\r\n // await sẽ hoạt động đúng dù transform trả về value thường hay Promise\r\n const result = await transform(item.data, value);\r\n return result ?? '';\r\n }\r\n\r\n // 3. Xử lý logic hiển thị\r\n switch (type) {\r\n case 'number':\r\n return NumberUtilities.toVN(value) ?? '';\r\n\r\n case 'bool':\r\n if (typeof value === 'boolean') {\r\n const html = `<div class=\"text-center\"><input type=\"checkbox\" ${value ? 'checked' : ''} disabled></div>`;\r\n // Bắt buộc bypass security để hiển thị được input checkbox\r\n return this.sanitizer.bypassSecurityTrustHtml(html);\r\n }\r\n return '';\r\n\r\n case 'date':\r\n return DateUtilities.toFormat(value, column.format || 'dd/MM/yyyy') ?? '';\r\n\r\n case 'datetime':\r\n return DateUtilities.toFormat(value, column.format || 'dd/MM/yyyy HH:mm') ?? '';\r\n\r\n default:\r\n return value ?? '';\r\n }\r\n }\r\n}","import { ChangeDetectorRef, Component, EventEmitter, Input, OnDestroy, OnInit, Output, ViewChild } from '@angular/core';\r\nimport * as uuid from 'uuid';\r\n\r\nimport { MatPaginator, MatPaginatorModule } from '@angular/material/paginator';\r\nimport { Subscription } from 'rxjs';\r\nimport { ColumnHiddenPipe } from './pipes/columm-hidden.pipe';\r\nimport { SdImportExcelItem, SdImportExcelOption, SdImportExcelSheet, SdImportExcelValidation } from './import-excel.model';\r\nimport { MatSlideToggleModule } from '@angular/material/slide-toggle';\r\nimport { MatTooltipModule } from '@angular/material/tooltip';\r\nimport { CommonModule } from '@angular/common';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { SdButton } from '@sd-angular/core/components/button';\r\nimport { MatIconModule } from '@angular/material/icon';\r\nimport { MatMenuModule } from '@angular/material/menu';\r\nimport { SdModal } from '@sd-angular/core/components/modal';\r\nimport { SdInput } from '@sd-angular/core/forms/input';\r\nimport { SdExcelService, SdExcelSheet, SdExcelTemplate, SdExcelTemplateColumn } from '@sd-angular/core/services/excel';\r\nimport { SdNotifyService } from '@sd-angular/core/services/notify';\r\nimport { DateUtilities, NumberUtilities } from '@sd-angular/core/utilities';\r\nimport { SdLoadingService } from '@sd-angular/core/services/loading';\r\nimport { ColumnTransformPipe } from './pipes/column-transform.pipe';\r\nimport { MatProgressSpinner } from '@angular/material/progress-spinner';\r\nimport { SdBadge } from \"@sd-angular/core/components/badge\";\r\n\r\n@Component({\r\n selector: 'sd-import-excel',\r\n templateUrl: './import-excel.component.html',\r\n styleUrls: ['./import-excel.component.scss'],\r\n imports: [\r\n CommonModule,\r\n FormsModule,\r\n MatSlideToggleModule,\r\n MatTooltipModule,\r\n MatPaginatorModule,\r\n MatSlideToggleModule,\r\n SdButton,\r\n SdModal,\r\n ColumnTransformPipe,\r\n ColumnHiddenPipe,\r\n MatIconModule,\r\n MatMenuModule,\r\n MatProgressSpinner,\r\n SdBadge\r\n],\r\n providers: [\r\n ColumnHiddenPipe\r\n ]\r\n})\r\nexport class SdImportExcel implements OnInit, OnDestroy {\r\n @Input({ required: true }) option!: SdImportExcelOption;\r\n @ViewChild(SdModal) modal!: SdModal;\r\n excelItems: SdImportExcelItem[] = [];\r\n // originItems: SdExcelItem[] = [];\r\n hasDescription = false;\r\n\r\n showing: 'ALL' | 'SUCCESS' | 'WARNING' | 'ERROR' = 'ALL';\r\n filteredItems: SdImportExcelItem[] = [];\r\n viewItems: SdImportExcelItem[] = [];\r\n numberOfSuccess = 0;\r\n numberOfError = 0;\r\n numberOfWarning = 0;\r\n file?: File;\r\n #paginator!: MatPaginator;\r\n #paginatorSub?: Subscription;\r\n @ViewChild(MatPaginator) set paginator(paginator: MatPaginator) {\r\n if (paginator && this.#paginator !== paginator) {\r\n this.#paginator = paginator;\r\n this.#paginatorSub?.unsubscribe(); // Clear cũ\r\n this.#paginatorSub = paginator.page.subscribe(this.#reload);\r\n this.#subscription.add(this.#paginatorSub);\r\n }\r\n }\r\n #subscription = new Subscription();\r\n uploading = false;\r\n isUploaded = false;\r\n isDownloadTemplate = false;\r\n @Output() sdClosed = new EventEmitter();\r\n constructor(\r\n private ref: ChangeDetectorRef,\r\n private excelService: SdExcelService,\r\n private notifyService: SdNotifyService,\r\n private columnHiddenPipe: ColumnHiddenPipe,\r\n private loadingService: SdLoadingService\r\n ) {}\r\n\r\n ngOnInit() {\r\n this.isUploaded = false;\r\n }\r\n\r\n ngOnDestroy() {\r\n this.#subscription.unsubscribe();\r\n }\r\n\r\n open = () => {\r\n this.#reset();\r\n this.modal.open();\r\n };\r\n\r\n close = () => {\r\n this.modal.close();\r\n };\r\n\r\n #reset = () => {\r\n this.excelItems = [];\r\n this.filteredItems = [];\r\n this.viewItems = [];\r\n this.numberOfSuccess = 0;\r\n this.numberOfError = 0;\r\n this.numberOfWarning = 0;\r\n this.showing = 'ALL';\r\n };\r\n\r\n #reload = () => {\r\n const pageIndex = this.#paginator.pageIndex;\r\n const pageSize = this.#paginator.pageSize;\r\n this.filteredItems = this.excelItems.filter(item => {\r\n const { errorMessages, warningMessages } = item.meta;\r\n if (this.showing === 'SUCCESS') {\r\n return !errorMessages.length && !warningMessages.length;\r\n } else if (this.showing === 'WARNING') {\r\n return !!warningMessages.length && !errorMessages.length;\r\n } else if (this.showing === 'ERROR') {\r\n return !!errorMessages.length;\r\n }\r\n return true;\r\n });\r\n this.viewItems = this.filteredItems.filter((item, index) => index >= pageIndex * pageSize && index < (pageIndex + 1) * pageSize);\r\n\r\n this.numberOfSuccess = this.excelItems.filter(this.#filterSuccess).length;\r\n this.numberOfError = this.excelItems.filter(this.#filterError).length;\r\n this.numberOfWarning = this.excelItems.filter(this.#filterWarning).length;\r\n };\r\n\r\n #filterError = (item: SdImportExcelItem) => !!item.meta.errorMessages.length;\r\n #filterWarning = (item: SdImportExcelItem) => item.meta.warningMessages.length && !item.meta.errorMessages.length;\r\n #filterSuccess = (item: SdImportExcelItem) => !item.meta.errorMessages.length && !item.meta.warningMessages.length;\r\n\r\n upload = async () => {\r\n try {\r\n const { transform, validateItem, validateItems } = this.option;\r\n const { items, file } = await this.excelService.upload();\r\n this.hasDescription = this.option.columns.some(e => !!e.description);\r\n const offset = this.hasDescription ? 2 : 1;\r\n items.splice(0, offset);\r\n if (items.length === 0) {\r\n this.notifyService.warning(`Tệp tin không có dữ liệu`);\r\n return;\r\n }\r\n const limit = this.option.limit || 1000;\r\n if (items.length > limit) {\r\n this.notifyService.warning(`Giới hạn tải lên ${limit} dòng`);\r\n return;\r\n }\r\n this.#reset();\r\n this.excelItems = items.map<SdImportExcelItem>((data, idx) => ({\r\n data,\r\n meta: {\r\n excelIndex: idx + (this.hasDescription ? 4 : 3),\r\n origin: { ...data },\r\n error: {},\r\n warning: {},\r\n errorMessages: [],\r\n warningMessages: [],\r\n },\r\n }));\r\n\r\n if (transform) {\r\n const mappedItems = transform(this.excelItems);\r\n if (mappedItems instanceof Promise) {\r\n this.uploading = true;\r\n this.excelItems = await mappedItems.finally(() => (this.uploading = false));\r\n } else {\r\n this.excelItems = mappedItems || this.excelItems;\r\n }\r\n }\r\n this.file = file!;\r\n this.loadingService.start();\r\n const validatePromises = this.excelItems.map((item, idx) => this.#validate(item, idx));\r\n await Promise.all(validatePromises);\r\n\r\n // Nếu không có error thì tiếp tục validate từ option validate truyền vào\r\n\r\n if (!this.excelItems.some(this.#filterError) && validateItems) {\r\n const results = await validateItems(this.excelItems.map(e => e.data));\r\n results\r\n .filter(result => result.idx >= 0)\r\n .forEach(result => {\r\n if (result?.errorMessage) {\r\n this.excelItems[result.idx].meta.errorMessages.push(result.errorMessage);\r\n }\r\n if (result?.warningMessage) {\r\n this.excelItems[result.idx].meta.warningMessages.push(result.warningMessage);\r\n }\r\n });\r\n }\r\n\r\n this.#paginator.pageIndex = 0;\r\n this.#reload();\r\n this.ref.detectChanges();\r\n\r\n this.isUploaded = false;\r\n } catch (err: any) {\r\n this.notifyService.error(err);\r\n } finally {\r\n this.loadingService.stop();\r\n }\r\n };\r\n\r\n #validate = async (excelItem: SdImportExcelItem, idx: number) => {\r\n const {\r\n data: item,\r\n meta: { error, errorMessages },\r\n } = excelItem;\r\n const { validateItem } = this.option;\r\n for (const column of this.option.columns) {\r\n if (!this.columnHiddenPipe.transform(column)) {\r\n continue;\r\n }\r\n try {\r\n if (column.defaultValue !== undefined) {\r\n item[column.field] = item[column.field] ?? column.defaultValue;\r\n } else if (column.required && !item[column.field] && item[column.field] !== 0) {\r\n error[column.field] = `Dữ liệu bắt buộc`;\r\n errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);\r\n continue;\r\n }\r\n if (column.type === 'string') {\r\n const value = (item[column.field] || '').toString();\r\n if (column.minlength !== undefined && value.length < column.minlength) {\r\n error[column.field] = `Độ dài chuỗi tối thiểu: ${column.minlength}`;\r\n errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);\r\n continue;\r\n }\r\n if (column.maxlength !== undefined && value.length > column.maxlength) {\r\n error[column.field] = `Độ dài chuỗi tối đa: ${column.maxlength}`;\r\n errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);\r\n continue;\r\n }\r\n item[column.field] = value;\r\n } else if (column.type === 'number') {\r\n if (item[column.field]) {\r\n const value = +item[column.field];\r\n if (!NumberUtilities.isNumber(item[column.field])) {\r\n error[column.field] = `${item[column.field]} không phải số hợp lệ`;\r\n errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);\r\n continue;\r\n }\r\n item[column.field] = value;\r\n }\r\n if (!item[column.field] && item[column.field] !== 0) {\r\n item[column.field] = undefined;\r\n }\r\n if (column.min !== undefined && item[column.field] < column.min) {\r\n error[column.field] = `${item[column.field]} không thỏa giá trị tối thiểu: ${column.min}`;\r\n errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);\r\n continue;\r\n }\r\n if (column.max !== undefined && item[column.field] > column.max) {\r\n error[column.field] = `${item[column.field]} không thỏa giá trị tối đa: ${column.max}`;\r\n errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);\r\n continue;\r\n }\r\n } else if (column.type === 'bool') {\r\n if (\r\n item[column.field] === 0 ||\r\n item[column.field] === '0' ||\r\n item[column.field] === false ||\r\n item[column.field]?.toString()?.toLowerCase()?.trim() === 'false'\r\n ) {\r\n item[column.field] = false;\r\n } else if (\r\n item[column.field] === 1 ||\r\n item[column.field] === '1' ||\r\n item[column.field] === true ||\r\n item[column.field]?.toString()?.toLowerCase()?.trim() === 'true'\r\n ) {\r\n item[column.field] = true;\r\n } else if (item[column.field] === '') item[column.field] = undefined;\r\n\r\n if (typeof item[column.field] !== 'boolean' && item[column.field] !== undefined && item[column.field] !== null) {\r\n error[column.field] = `Vui lòng nhập giá trị hợp lệ true, false, 1, 0`;\r\n errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);\r\n }\r\n } else if (column.type === 'values') {\r\n if (item[column.field] && typeof item[column.field] !== 'number' && typeof item[column.field] !== 'string') {\r\n error[column.field] = `Giá trị ${item[column.field]} không hợp lệ`;\r\n errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);\r\n continue;\r\n }\r\n if (column.checkValueInArray && item[column.field] && !column.values.some(e => e.toString() === item[column.field].toString())) {\r\n error[column.field] = `Giá trị ${item[column.field]} không thuộc danh sách cho phép [${column.values.join()}]`;\r\n errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);\r\n continue;\r\n }\r\n } else if (column.type === 'date' || column.type === 'datetime' || column.type === 'time') {\r\n const { type, format } = column;\r\n const val = item[column.field];\r\n if (val instanceof Date) {\r\n item[column.field] = val.toISOString();\r\n continue;\r\n }\r\n if (format && item[column.field]) {\r\n if (typeof val !== 'string') {\r\n error[column.field] = `Ngày ${val} không đúng định dạng ${column.format}`;\r\n errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);\r\n continue;\r\n }\r\n if (type === 'date' && !this.#isValidDate(format, val)) {\r\n error[column.field] = `Ngày ${val} không đúng định dạng ${column.format}`;\r\n errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);\r\n continue;\r\n }\r\n if (type === 'time' && !this.#isValidTime(format, val)) {\r\n error[column.field] = `Ngày ${val} không đúng định dạng ${column.format}`;\r\n errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);\r\n continue;\r\n }\r\n if (type === 'datetime' && !this.#isValidDateTime(format, val)) {\r\n error[column.field] = `Ngày ${val} không đúng định dạng ${column.format}`;\r\n errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);\r\n continue;\r\n }\r\n item[column.field] = DateUtilities.parseFrom(val, format);\r\n }\r\n if (item[column.field] && !DateUtilities.isDate(item[column.field])) {\r\n error[column.field] = `Ngày ${val} không đúng định dạng ${column.format}`;\r\n errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);\r\n continue;\r\n }\r\n }\r\n\r\n // Nếu pass validation từng column, kiểm tra validation theo hàm validateItem\r\n if (!errorMessages.length && validateItem) {\r\n const validation = await validateItem(\r\n item,\r\n idx,\r\n this.excelItems.map(e => e.data)\r\n );\r\n if (validation.errorMessage) excelItem.meta.errorMessages.push(validation.errorMessage);\r\n if (validation.warningMessage) excelItem.meta.warningMessages.push(validation.warningMessage);\r\n }\r\n } catch (ex: any) {\r\n error[column.field] = `${ex?.message || ex?.error || ex || 'Có lỗi xảy ra'}`;\r\n errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);\r\n }\r\n }\r\n };\r\n\r\n #mapItem = (item: SdImportExcelItem) => {\r\n const { data } = item;\r\n return data;\r\n };\r\n\r\n accept = () => {\r\n this.option!.accept(\r\n this.excelItems.map(e => e.data),\r\n { file: this.file! }\r\n );\r\n this.isUploaded = true;\r\n };\r\n\r\n setValidation = (validations: SdImportExcelValidation[]) => {\r\n this.excelItems.forEach(e => {\r\n e.meta.errorMessages = [];\r\n e.meta.warningMessages = [];\r\n });\r\n if (Array.isArray(validations)) {\r\n validations.forEach(validation => {\r\n if (validation.errorMessage) {\r\n this.excelItems[validation.idx].meta.errorMessages = [validation.errorMessage];\r\n }\r\n if (validation.warningMessage) {\r\n this.excelItems[validation.idx].meta.warningMessages = [validation.warningMessage];\r\n }\r\n });\r\n }\r\n this.#reload();\r\n this.ref.detectChanges();\r\n };\r\n\r\n view = (showing: 'ALL' | 'SUCCESS' | 'WARNING' | 'ERROR' = 'ALL') => {\r\n this.showing = showing;\r\n this.#paginator.pageIndex = 0;\r\n this.#reload();\r\n };\r\n\r\n downloadTemplate = async () => {\r\n const sheets: SdExcelSheet[] = [];\r\n if (Array.isArray(this.option?.sheets)) {\r\n for (const sheet of this.option.sheets) {\r\n if (sheet.name && sheet.items && sheet.headers) {\r\n if (Array.isArray(sheet.items)) {\r\n sheets.push({\r\n name: sheet.name,\r\n items: sheet.items,\r\n headers: sheet.headers,\r\n });\r\n } else {\r\n sheets.push({\r\n name: sheet.name,\r\n items: await sheet.items(),\r\n headers: sheet.headers,\r\n });\r\n }\r\n }\r\n }\r\n }\r\n const columnNotHiddens = this.option.columns.filter(column => this.columnHiddenPipe.transform(column));\r\n const excelTemplate: SdExcelTemplate = {\r\n fileName: this.option.fileName || 'Template',\r\n columns: columnNotHiddens.map(column => {\r\n return {\r\n field: column.field,\r\n title: column.title,\r\n width: column.width,\r\n required: column.required,\r\n description: column.description,\r\n fontColor: column.fontColor,\r\n fill: column.fill,\r\n };\r\n }),\r\n sheets,\r\n };\r\n this.isDownloadTemplate = true;\r\n await this.excelService.generateTemplate(excelTemplate).finally(() => {\r\n this.isDownloadTemplate = false;\r\n });\r\n };\r\n\r\n export = async () => {\r\n this.loadingService.start();\r\n const columns: SdExcelTemplateColumn[] = [\r\n {\r\n field: 'sdMessage',\r\n title: 'Thông báo',\r\n width: '250px',\r\n required: false,\r\n },\r\n ...this.option.columns.filter(column => this.columnHiddenPipe.transform(column)),\r\n ];\r\n await this.excelService\r\n .export({\r\n columns,\r\n items: this.filteredItems.map(e => {\r\n let result = {};\r\n for (const column of columns) {\r\n result = {\r\n ...result,\r\n [column.field]: e.meta.origin?.[column.field],\r\n };\r\n }\r\n return {\r\n ...result,\r\n sdMessage: (e.meta.errorMessages.join(', ') || e.meta.warningMessages.join(', ') || 'Thành công')\r\n ?.replace(/<strong>/g, '')\r\n .replace(/<\\/strong>/g, '')\r\n .replace(/<br>/g, '\\n'),\r\n };\r\n }),\r\n })\r\n .finally(this.loadingService.stop);\r\n };\r\n\r\n #isValidDate = (format: string, value: string) => {\r\n if (value?.length !== format?.length) {\r\n return false;\r\n }\r\n const regex =\r\n /^(?:(?:31(\\/|-|\\.)(?:0?[13578]|1[02]))\\1|(?:(?:29|30)(\\/|-|\\.)(?:0?[13-9]|1[0-2])\\2))(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$|^(?:29(\\/|-|\\.)0?2\\3(?:(?:(?:1[6-9]|[2-9]\\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\\d|2[0-8])(\\/|-|\\.)(?:(?:0?[1-9])|(?:1[0-2]))\\4(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$/;\r\n return regex.test(value);\r\n };\r\n\r\n #isValidTime = (format: string, value: string) => {\r\n if (value?.length !== format?.length) {\r\n return false;\r\n }\r\n return true;\r\n };\r\n\r\n #isValidDateTime = (format: string, value: string) => {\r\n if (value?.length !== format?.length) {\r\n return false;\r\n }\r\n const dates = value?.split(' ');\r\n if (dates.length !== 2) {\r\n return false;\r\n }\r\n const date = dates[0];\r\n if (!this.#isValidDate('dd/MM/yyyy', date)) {\r\n return false;\r\n }\r\n const time = dates[1];\r\n const regex = /^(0[0-9]|1[0-9]|2[0-3])(\\:)(0[0-9]|[0-5][0-9])$/;\r\n return regex.test(time);\r\n };\r\n onClosed = () => {\r\n this.sdClosed.emit();\r\n };\r\n}\r\n","@if (option) {\r\n <sd-modal [title]=\"option.title || 'Nhập dữ liệu 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ất cả\" 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ố dòng dữ liệu hợp lệ\"\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ố dòng dữ liệu có lỗi\"\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ố dòng dữ liệu có cảnh báo\"\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ạng thái</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ữ liệu hợp lệ</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ấn để tải tệp mẫu về máy\"\r\n aria-hidden=\"true\">\r\n <mat-icon class=\"empty-icon\">cloud_download</mat-icon>\r\n\r\n <h4>Chưa có dữ liệu tải lên</h4>\r\n <span class=\"text-small text-link\"> Nhấn vào đây để tải tệp mẫu </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ải lên\" 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ải về\" size=\"sm\" color=\"success\" type=\"outline\">\r\n </sd-button>\r\n }\r\n <sd-button\r\n (click)=\"accept()\"\r\n title=\"Xác nhận & Lưu\"\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","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1","i3.ColumnHiddenPipe"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sd-angular-core-components-import-excel.mjs","sources":["../../../projects/sd-angular/components/import-excel/src/import-excel.model.ts","../../../projects/sd-angular/components/import-excel/src/pipes/columm-hidden.pipe.ts","../../../projects/sd-angular/components/import-excel/src/pipes/column-transform.pipe.ts","../../../projects/sd-angular/components/import-excel/src/import-excel.component.ts","../../../projects/sd-angular/components/import-excel/src/import-excel.component.html","../../../projects/sd-angular/components/import-excel/sd-angular-core-components-import-excel.ts"],"sourcesContent":["export interface SdImportExcelValidation {\r\n idx: number;\r\n errorMessage?: string;\r\n warningMessage?: string;\r\n}\r\nexport interface SdImportExcelSheet<T = any> {\r\n name: string; // Tên của sheet\r\n items: T[] | (() => Promise<T[]>);\r\n headers: {\r\n value: Extract<keyof T, string>; // Trường muốn hiển thị\r\n display: string; // Label hiển thị\r\n }[];\r\n}\r\n\r\nexport interface SdImportExcelOption<T = any> {\r\n columns: SdUploadExcelColumn<T>[];\r\n accept: (items: T[], args: { file: File }) => SdImportExcelValidation[] | Promise<SdImportExcelValidation[]>;\r\n title?: string;\r\n fileName?: string;\r\n limit?: number;\r\n sheets?: SdImportExcelSheet[];\r\n transform?: (items: SdImportExcelItem<T>[]) => SdImportExcelItem<T>[] | Promise<SdImportExcelItem<T>[]>;\r\n validateItem?: (item: T, idx: number, items: T[]) => SdImportExcelValidation | Promise<SdImportExcelValidation>;\r\n validateItems?: (items: T[]) => SdImportExcelValidation[] | Promise<SdImportExcelValidation[]>;\r\n}\r\n\r\nexport type SdUploadExcelColumn<T = any> =\r\n | SdUploadExcelColumnString<T>\r\n | SdUploadExcelColumnNumber<T>\r\n | SdUploadExcelColumnBool<T>\r\n | SdUploadExcelColumnDate<T>\r\n | SdUploadExcelColumnTime<T>\r\n | SdUploadExcelColumnDateTime<T>\r\n | SdUploadExcelColumnValues<T>\r\n | SdUploadExcelColumnStringArray<T>;\r\n\r\nexport interface SdUploadExcelBaseColumn<T = any> {\r\n field: string;\r\n title: string;\r\n required?: boolean;\r\n width?: string;\r\n description?: string;\r\n hidden?: boolean | (() => boolean);\r\n fontColor?: string;\r\n fill?: string;\r\n transform?: (value: any, rowData: T) => string | Promise<string>;\r\n}\r\n\r\nexport interface SdUploadExcelColumnString<T = any> extends SdUploadExcelBaseColumn<T> {\r\n type: 'string';\r\n defaultValue?: string;\r\n pattern?: string;\r\n minlength?: number;\r\n maxlength?: number;\r\n}\r\n\r\nexport interface SdUploadExcelColumnNumber<T = any> extends SdUploadExcelBaseColumn<T> {\r\n type: 'number';\r\n defaultValue?: number;\r\n min?: number;\r\n max?: number;\r\n}\r\n\r\nexport interface SdUploadExcelColumnBool<T = any> extends SdUploadExcelBaseColumn<T> {\r\n type: 'bool';\r\n defaultValue?: boolean;\r\n parseToBool?: boolean;\r\n}\r\n\r\nexport interface SdUploadExcelColumnDate<T = any> extends SdUploadExcelBaseColumn<T> {\r\n type: 'date';\r\n format?: 'dd/MM/yyyy';\r\n defaultValue?: Date;\r\n minDate?: Date;\r\n maxDate?: Date;\r\n}\r\n\r\nexport interface SdUploadExcelColumnTime<T = any> extends SdUploadExcelBaseColumn<T> {\r\n type: 'time';\r\n format?: 'HH:mm' | 'HH:mm:ss';\r\n defaultValue?: Date;\r\n minDate?: Date;\r\n maxDate?: Date;\r\n}\r\n\r\nexport interface SdUploadExcelColumnDateTime<T = any> extends SdUploadExcelBaseColumn<T> {\r\n type: 'datetime';\r\n format?: 'dd/MM/yyyy HH:mm' | 'dd/MM/yyyy';\r\n defaultValue?: Date;\r\n minDate?: Date;\r\n maxDate?: Date;\r\n}\r\n\r\nexport interface SdUploadExcelColumnValues<T = any> extends SdUploadExcelBaseColumn<T> {\r\n type: 'values' | 'radio';\r\n defaultValue?: string | number;\r\n values: (string | number)[];\r\n checkValueInArray?: boolean;\r\n}\r\n\r\nexport interface SdUploadExcelColumnStringArray<T = any> extends SdUploadExcelBaseColumn<T> {\r\n type: 'array';\r\n divideString: string | ';';\r\n unitString: string | 'items';\r\n defaultValue?: string;\r\n minlength?: number;\r\n maxlength?: number;\r\n}\r\n\r\nexport type SdImportExcelItem<T = any> = {\r\n data: T;\r\n meta: {\r\n excelIndex: number;\r\n origin: T;\r\n error: Record<string, string>;\r\n errorMessages: string[];\r\n warning: Record<string, string>;\r\n warningMessages: string[];\r\n };\r\n};\r\n\r\n// export type ExcelItem<T> = {\r\n// origin?: T;\r\n// excelIndex?: number;\r\n// validation: SdUploadExcelValidation;\r\n// } & T;\r\n","import { Injectable, Pipe, PipeTransform } from '@angular/core';\r\nimport { SdUploadExcelColumn } from '../import-excel.model';\r\n@Pipe({\r\n name: 'columnHidden'\r\n})\r\n@Injectable()\r\nexport class ColumnHiddenPipe implements PipeTransform {\r\n constructor() { }\r\n transform(column: SdUploadExcelColumn): boolean {\r\n if (column.hidden === undefined) {\r\n return true;\r\n }\r\n if (typeof (column.hidden) === 'boolean') {\r\n return !column.hidden;\r\n }\r\n if (typeof (column.hidden) === 'function') {\r\n return !column.hidden();\r\n }\r\n return false;\r\n }\r\n}\r\n","import { Pipe, PipeTransform } from '@angular/core';\r\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\r\nimport { DateUtilities, NumberUtilities } from '@sd-angular/core/utilities';\r\nimport { SdImportExcelItem, SdUploadExcelColumn } from '../import-excel.model';\r\n\r\n@Pipe({\r\n name: 'columnTransform',\r\n standalone: true,\r\n})\r\nexport class ColumnTransformPipe implements PipeTransform {\r\n constructor(private sanitizer: DomSanitizer) {}\r\n\r\n // Chuyển thành async để hỗ trợ Promise từ bên ngoài\r\n async transform(item: SdImportExcelItem, column: SdUploadExcelColumn): Promise<string | SafeHtml> {\r\n const { type, transform, field } = column;\r\n const value = item.data[field];\r\n\r\n // 1. Ưu tiên hiển thị dữ liệu gốc nếu có lỗi\r\n if (item.meta.error[field]) {\r\n return item.meta.origin[field] ?? value ?? '';\r\n }\r\n\r\n // 2. Custom Transform (Hỗ trợ cả Sync và Async)\r\n if (transform) {\r\n // await sẽ hoạt động đúng dù transform trả về value thường hay Promise\r\n const result = await transform(item.data, value);\r\n return result ?? '';\r\n }\r\n\r\n // 3. Xử lý logic hiển thị\r\n switch (type) {\r\n case 'number':\r\n return NumberUtilities.toVN(value) ?? '';\r\n\r\n case 'bool':\r\n if (typeof value === 'boolean') {\r\n const html = `<div class=\"text-center\"><input type=\"checkbox\" ${value ? 'checked' : ''} disabled></div>`;\r\n // Bắt buộc bypass security để hiển thị được input checkbox\r\n return this.sanitizer.bypassSecurityTrustHtml(html);\r\n }\r\n return '';\r\n\r\n case 'date':\r\n return DateUtilities.toFormat(value, column.format || 'dd/MM/yyyy') ?? '';\r\n\r\n case 'datetime':\r\n return DateUtilities.toFormat(value, column.format || 'dd/MM/yyyy HH:mm') ?? '';\r\n\r\n default:\r\n return value ?? '';\r\n }\r\n }\r\n}","import { ChangeDetectorRef, Component, EventEmitter, Input, OnDestroy, OnInit, Output, ViewChild } from '@angular/core';\r\nimport * as uuid from 'uuid';\r\n\r\nimport { MatPaginator, MatPaginatorModule } from '@angular/material/paginator';\r\nimport { Subscription } from 'rxjs';\r\nimport { ColumnHiddenPipe } from './pipes/columm-hidden.pipe';\r\nimport { SdImportExcelItem, SdImportExcelOption, SdImportExcelSheet, SdImportExcelValidation } from './import-excel.model';\r\nimport { MatSlideToggleModule } from '@angular/material/slide-toggle';\r\nimport { MatTooltipModule } from '@angular/material/tooltip';\r\nimport { CommonModule } from '@angular/common';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { SdButton } from '@sd-angular/core/components/button';\r\nimport { MatIconModule } from '@angular/material/icon';\r\nimport { MatMenuModule } from '@angular/material/menu';\r\nimport { SdModal } from '@sd-angular/core/components/modal';\r\nimport { SdInput } from '@sd-angular/core/forms/input';\r\nimport { SdExcelService, SdExcelSheet, SdExcelTemplate, SdExcelTemplateColumn } from '@sd-angular/core/services/excel';\r\nimport { SdNotifyService } from '@sd-angular/core/services/notify';\r\nimport { DateUtilities, NumberUtilities } from '@sd-angular/core/utilities';\r\nimport { SdLoadingService } from '@sd-angular/core/services/loading';\r\nimport { ColumnTransformPipe } from './pipes/column-transform.pipe';\r\nimport { MatProgressSpinner } from '@angular/material/progress-spinner';\r\nimport { SdBadge } from \"@sd-angular/core/components/badge\";\r\n\r\n@Component({\r\n selector: 'sd-import-excel',\r\n templateUrl: './import-excel.component.html',\r\n styleUrls: ['./import-excel.component.scss'],\r\n imports: [\r\n CommonModule,\r\n FormsModule,\r\n MatSlideToggleModule,\r\n MatTooltipModule,\r\n MatPaginatorModule,\r\n MatSlideToggleModule,\r\n SdButton,\r\n SdModal,\r\n ColumnTransformPipe,\r\n ColumnHiddenPipe,\r\n MatIconModule,\r\n MatMenuModule,\r\n MatProgressSpinner,\r\n SdBadge\r\n],\r\n providers: [\r\n ColumnHiddenPipe\r\n ]\r\n})\r\nexport class SdImportExcel implements OnInit, OnDestroy {\r\n @Input({ required: true }) option!: SdImportExcelOption;\r\n @ViewChild(SdModal) modal!: SdModal;\r\n excelItems: SdImportExcelItem[] = [];\r\n // originItems: SdExcelItem[] = [];\r\n hasDescription = false;\r\n\r\n showing: 'ALL' | 'SUCCESS' | 'WARNING' | 'ERROR' = 'ALL';\r\n filteredItems: SdImportExcelItem[] = [];\r\n viewItems: SdImportExcelItem[] = [];\r\n numberOfSuccess = 0;\r\n numberOfError = 0;\r\n numberOfWarning = 0;\r\n file?: File;\r\n #paginator!: MatPaginator;\r\n #paginatorSub?: Subscription;\r\n @ViewChild(MatPaginator) set paginator(paginator: MatPaginator) {\r\n if (paginator && this.#paginator !== paginator) {\r\n this.#paginator = paginator;\r\n this.#paginatorSub?.unsubscribe(); // Clear cũ\r\n this.#paginatorSub = paginator.page.subscribe(this.#reload);\r\n this.#subscription.add(this.#paginatorSub);\r\n }\r\n }\r\n #subscription = new Subscription();\r\n uploading = false;\r\n isUploaded = false;\r\n isDownloadTemplate = false;\r\n @Output() sdClosed = new EventEmitter();\r\n constructor(\r\n private ref: ChangeDetectorRef,\r\n private excelService: SdExcelService,\r\n private notifyService: SdNotifyService,\r\n private columnHiddenPipe: ColumnHiddenPipe,\r\n private loadingService: SdLoadingService\r\n ) {}\r\n\r\n ngOnInit() {\r\n this.isUploaded = false;\r\n }\r\n\r\n ngOnDestroy() {\r\n this.#subscription.unsubscribe();\r\n }\r\n\r\n open = () => {\r\n this.#reset();\r\n this.modal.open();\r\n };\r\n\r\n close = () => {\r\n this.modal.close();\r\n };\r\n\r\n #reset = () => {\r\n this.excelItems = [];\r\n this.filteredItems = [];\r\n this.viewItems = [];\r\n this.numberOfSuccess = 0;\r\n this.numberOfError = 0;\r\n this.numberOfWarning = 0;\r\n this.showing = 'ALL';\r\n };\r\n\r\n #reload = () => {\r\n const pageIndex = this.#paginator.pageIndex;\r\n const pageSize = this.#paginator.pageSize;\r\n this.filteredItems = this.excelItems.filter(item => {\r\n const { errorMessages, warningMessages } = item.meta;\r\n if (this.showing === 'SUCCESS') {\r\n return !errorMessages.length && !warningMessages.length;\r\n } else if (this.showing === 'WARNING') {\r\n return !!warningMessages.length && !errorMessages.length;\r\n } else if (this.showing === 'ERROR') {\r\n return !!errorMessages.length;\r\n }\r\n return true;\r\n });\r\n this.viewItems = this.filteredItems.filter((item, index) => index >= pageIndex * pageSize && index < (pageIndex + 1) * pageSize);\r\n\r\n this.numberOfSuccess = this.excelItems.filter(this.#filterSuccess).length;\r\n this.numberOfError = this.excelItems.filter(this.#filterError).length;\r\n this.numberOfWarning = this.excelItems.filter(this.#filterWarning).length;\r\n };\r\n\r\n #filterError = (item: SdImportExcelItem) => !!item.meta.errorMessages.length;\r\n #filterWarning = (item: SdImportExcelItem) => item.meta.warningMessages.length && !item.meta.errorMessages.length;\r\n #filterSuccess = (item: SdImportExcelItem) => !item.meta.errorMessages.length && !item.meta.warningMessages.length;\r\n\r\n upload = async () => {\r\n try {\r\n const { transform, validateItem, validateItems } = this.option;\r\n const { items, file } = await this.excelService.upload();\r\n this.hasDescription = this.option.columns.some(e => !!e.description);\r\n const offset = this.hasDescription ? 2 : 1;\r\n items.splice(0, offset);\r\n if (items.length === 0) {\r\n this.notifyService.warning(`Tệp tin không có dữ liệu`);\r\n return;\r\n }\r\n const limit = this.option.limit || 1000;\r\n if (items.length > limit) {\r\n this.notifyService.warning(`Giới hạn tải lên ${limit} dòng`);\r\n return;\r\n }\r\n this.#reset();\r\n this.excelItems = items.map<SdImportExcelItem>((data, idx) => ({\r\n data,\r\n meta: {\r\n excelIndex: idx + (this.hasDescription ? 4 : 3),\r\n origin: { ...data },\r\n error: {},\r\n warning: {},\r\n errorMessages: [],\r\n warningMessages: [],\r\n },\r\n }));\r\n\r\n if (transform) {\r\n const mappedItems = transform(this.excelItems);\r\n if (mappedItems instanceof Promise) {\r\n this.uploading = true;\r\n this.excelItems = await mappedItems.finally(() => (this.uploading = false));\r\n } else {\r\n this.excelItems = mappedItems || this.excelItems;\r\n }\r\n }\r\n this.file = file!;\r\n this.loadingService.start();\r\n const validatePromises = this.excelItems.map((item, idx) => this.#validate(item, idx));\r\n await Promise.all(validatePromises);\r\n\r\n // Nếu không có error thì tiếp tục validate từ option validate truyền vào\r\n\r\n if (!this.excelItems.some(this.#filterError) && validateItems) {\r\n const results = await validateItems(this.excelItems.map(e => e.data));\r\n results\r\n .filter(result => result.idx >= 0)\r\n .forEach(result => {\r\n if (result?.errorMessage) {\r\n this.excelItems[result.idx].meta.errorMessages.push(result.errorMessage);\r\n }\r\n if (result?.warningMessage) {\r\n this.excelItems[result.idx].meta.warningMessages.push(result.warningMessage);\r\n }\r\n });\r\n }\r\n\r\n this.#paginator.pageIndex = 0;\r\n this.#reload();\r\n this.ref.detectChanges();\r\n\r\n this.isUploaded = false;\r\n } catch (err: any) {\r\n this.notifyService.error(err);\r\n } finally {\r\n this.loadingService.stop();\r\n }\r\n };\r\n\r\n #validate = async (excelItem: SdImportExcelItem, idx: number) => {\r\n const {\r\n data: item,\r\n meta: { error, errorMessages },\r\n } = excelItem;\r\n const { validateItem } = this.option;\r\n for (const column of this.option.columns) {\r\n if (!this.columnHiddenPipe.transform(column)) {\r\n continue;\r\n }\r\n try {\r\n if (column.defaultValue !== undefined) {\r\n item[column.field] = item[column.field] ?? column.defaultValue;\r\n } else if (column.required && !item[column.field] && item[column.field] !== 0) {\r\n error[column.field] = `Dữ liệu bắt buộc`;\r\n errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);\r\n continue;\r\n }\r\n if (column.type === 'string') {\r\n const value = (item[column.field] || '').toString();\r\n if (column.minlength !== undefined && value.length < column.minlength) {\r\n error[column.field] = `Độ dài chuỗi tối thiểu: ${column.minlength}`;\r\n errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);\r\n continue;\r\n }\r\n if (column.maxlength !== undefined && value.length > column.maxlength) {\r\n error[column.field] = `Độ dài chuỗi tối đa: ${column.maxlength}`;\r\n errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);\r\n continue;\r\n }\r\n item[column.field] = value;\r\n } else if (column.type === 'number') {\r\n if (item[column.field]) {\r\n const value = +item[column.field];\r\n if (!NumberUtilities.isNumber(item[column.field])) {\r\n error[column.field] = `${item[column.field]} không phải số hợp lệ`;\r\n errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);\r\n continue;\r\n }\r\n item[column.field] = value;\r\n }\r\n if (!item[column.field] && item[column.field] !== 0) {\r\n item[column.field] = undefined;\r\n }\r\n if (column.min !== undefined && item[column.field] < column.min) {\r\n error[column.field] = `${item[column.field]} không thỏa giá trị tối thiểu: ${column.min}`;\r\n errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);\r\n continue;\r\n }\r\n if (column.max !== undefined && item[column.field] > column.max) {\r\n error[column.field] = `${item[column.field]} không thỏa giá trị tối đa: ${column.max}`;\r\n errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);\r\n continue;\r\n }\r\n } else if (column.type === 'bool') {\r\n if (\r\n item[column.field] === 0 ||\r\n item[column.field] === '0' ||\r\n item[column.field] === false ||\r\n item[column.field]?.toString()?.toLowerCase()?.trim() === 'false'\r\n ) {\r\n item[column.field] = false;\r\n } else if (\r\n item[column.field] === 1 ||\r\n item[column.field] === '1' ||\r\n item[column.field] === true ||\r\n item[column.field]?.toString()?.toLowerCase()?.trim() === 'true'\r\n ) {\r\n item[column.field] = true;\r\n } else if (item[column.field] === '') item[column.field] = undefined;\r\n\r\n if (typeof item[column.field] !== 'boolean' && item[column.field] !== undefined && item[column.field] !== null) {\r\n error[column.field] = `Vui lòng nhập giá trị hợp lệ true, false, 1, 0`;\r\n errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);\r\n }\r\n } else if (column.type === 'values') {\r\n if (item[column.field] && typeof item[column.field] !== 'number' && typeof item[column.field] !== 'string') {\r\n error[column.field] = `Giá trị ${item[column.field]} không hợp lệ`;\r\n errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);\r\n continue;\r\n }\r\n if (column.checkValueInArray && item[column.field] && !column.values.some(e => e.toString() === item[column.field].toString())) {\r\n error[column.field] = `Giá trị ${item[column.field]} không thuộc danh sách cho phép [${column.values.join()}]`;\r\n errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);\r\n continue;\r\n }\r\n } else if (column.type === 'date' || column.type === 'datetime' || column.type === 'time') {\r\n const { type, format } = column;\r\n const val = item[column.field];\r\n if (val instanceof Date) {\r\n item[column.field] = val.toISOString();\r\n continue;\r\n }\r\n if (format && item[column.field]) {\r\n if (typeof val !== 'string') {\r\n error[column.field] = `Ngày ${val} không đúng định dạng ${column.format}`;\r\n errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);\r\n continue;\r\n }\r\n if (type === 'date' && !this.#isValidDate(format, val)) {\r\n error[column.field] = `Ngày ${val} không đúng định dạng ${column.format}`;\r\n errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);\r\n continue;\r\n }\r\n if (type === 'time' && !this.#isValidTime(format, val)) {\r\n error[column.field] = `Ngày ${val} không đúng định dạng ${column.format}`;\r\n errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);\r\n continue;\r\n }\r\n if (type === 'datetime' && !this.#isValidDateTime(format, val)) {\r\n error[column.field] = `Ngày ${val} không đúng định dạng ${column.format}`;\r\n errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);\r\n continue;\r\n }\r\n item[column.field] = DateUtilities.parseFrom(val, format);\r\n }\r\n if (item[column.field] && !DateUtilities.isDate(item[column.field])) {\r\n error[column.field] = `Ngày ${val} không đúng định dạng ${column.format}`;\r\n errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);\r\n continue;\r\n }\r\n }\r\n\r\n // Nếu pass validation từng column, kiểm tra validation theo hàm validateItem\r\n if (!errorMessages.length && validateItem) {\r\n const validation = await validateItem(\r\n item,\r\n idx,\r\n this.excelItems.map(e => e.data)\r\n );\r\n if (validation.errorMessage) excelItem.meta.errorMessages.push(validation.errorMessage);\r\n if (validation.warningMessage) excelItem.meta.warningMessages.push(validation.warningMessage);\r\n }\r\n } catch (ex: any) {\r\n error[column.field] = `${ex?.message || ex?.error || ex || 'Có lỗi xảy ra'}`;\r\n errorMessages.push(`<strong>[${column.title || column.field}]</strong> ${error[column.field]}`);\r\n }\r\n }\r\n };\r\n\r\n #mapItem = (item: SdImportExcelItem) => {\r\n const { data } = item;\r\n return data;\r\n };\r\n\r\n accept = () => {\r\n this.option!.accept(\r\n this.excelItems.map(e => e.data),\r\n { file: this.file! }\r\n );\r\n this.isUploaded = true;\r\n };\r\n\r\n setValidation = (validations: SdImportExcelValidation[]) => {\r\n this.excelItems.forEach(e => {\r\n e.meta.errorMessages = [];\r\n e.meta.warningMessages = [];\r\n });\r\n if (Array.isArray(validations)) {\r\n validations.forEach(validation => {\r\n if (validation.errorMessage) {\r\n this.excelItems[validation.idx].meta.errorMessages = [validation.errorMessage];\r\n }\r\n if (validation.warningMessage) {\r\n this.excelItems[validation.idx].meta.warningMessages = [validation.warningMessage];\r\n }\r\n });\r\n }\r\n this.#reload();\r\n this.ref.detectChanges();\r\n };\r\n\r\n view = (showing: 'ALL' | 'SUCCESS' | 'WARNING' | 'ERROR' = 'ALL') => {\r\n this.showing = showing;\r\n this.#paginator.pageIndex = 0;\r\n this.#reload();\r\n };\r\n\r\n downloadTemplate = async () => {\r\n const sheets: SdExcelSheet[] = [];\r\n if (Array.isArray(this.option?.sheets)) {\r\n for (const sheet of this.option.sheets) {\r\n if (sheet.name && sheet.items && sheet.headers) {\r\n if (Array.isArray(sheet.items)) {\r\n sheets.push({\r\n name: sheet.name,\r\n items: sheet.items,\r\n headers: sheet.headers,\r\n });\r\n } else {\r\n sheets.push({\r\n name: sheet.name,\r\n items: await sheet.items(),\r\n headers: sheet.headers,\r\n });\r\n }\r\n }\r\n }\r\n }\r\n const columnNotHiddens = this.option.columns.filter(column => this.columnHiddenPipe.transform(column));\r\n const excelTemplate: SdExcelTemplate = {\r\n fileName: this.option.fileName || 'Template',\r\n columns: columnNotHiddens.map(column => {\r\n return {\r\n field: column.field,\r\n title: column.title,\r\n width: column.width,\r\n required: column.required,\r\n description: column.description,\r\n fontColor: column.fontColor,\r\n fill: column.fill,\r\n };\r\n }),\r\n sheets,\r\n };\r\n this.isDownloadTemplate = true;\r\n await this.excelService.generateTemplate(excelTemplate).finally(() => {\r\n this.isDownloadTemplate = false;\r\n });\r\n };\r\n\r\n export = async () => {\r\n this.loadingService.start();\r\n const columns: SdExcelTemplateColumn[] = [\r\n {\r\n field: 'sdMessage',\r\n title: 'Thông báo',\r\n width: '250px',\r\n required: false,\r\n },\r\n ...this.option.columns.filter(column => this.columnHiddenPipe.transform(column)),\r\n ];\r\n await this.excelService\r\n .export({\r\n columns,\r\n items: this.filteredItems.map(e => {\r\n let result = {};\r\n for (const column of columns) {\r\n result = {\r\n ...result,\r\n [column.field]: e.meta.origin?.[column.field],\r\n };\r\n }\r\n return {\r\n ...result,\r\n sdMessage: (e.meta.errorMessages.join(', ') || e.meta.warningMessages.join(', ') || 'Thành công')\r\n ?.replace(/<strong>/g, '')\r\n .replace(/<\\/strong>/g, '')\r\n .replace(/<br>/g, '\\n'),\r\n };\r\n }),\r\n })\r\n .finally(this.loadingService.stop);\r\n };\r\n\r\n #isValidDate = (format: string, value: string) => {\r\n if (value?.length !== format?.length) {\r\n return false;\r\n }\r\n const regex =\r\n /^(?:(?:31(\\/|-|\\.)(?:0?[13578]|1[02]))\\1|(?:(?:29|30)(\\/|-|\\.)(?:0?[13-9]|1[0-2])\\2))(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$|^(?:29(\\/|-|\\.)0?2\\3(?:(?:(?:1[6-9]|[2-9]\\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\\d|2[0-8])(\\/|-|\\.)(?:(?:0?[1-9])|(?:1[0-2]))\\4(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$/;\r\n return regex.test(value);\r\n };\r\n\r\n #isValidTime = (format: string, value: string) => {\r\n if (value?.length !== format?.length) {\r\n return false;\r\n }\r\n return true;\r\n };\r\n\r\n #isValidDateTime = (format: string, value: string) => {\r\n if (value?.length !== format?.length) {\r\n return false;\r\n }\r\n const dates = value?.split(' ');\r\n if (dates.length !== 2) {\r\n return false;\r\n }\r\n const date = dates[0];\r\n if (!this.#isValidDate('dd/MM/yyyy', date)) {\r\n return false;\r\n }\r\n const time = dates[1];\r\n const regex = /^(0[0-9]|1[0-9]|2[0-3])(\\:)(0[0-9]|[0-5][0-9])$/;\r\n return regex.test(time);\r\n };\r\n onClosed = () => {\r\n this.sdClosed.emit();\r\n };\r\n}\r\n","@if (option) {\r\n <sd-modal [title]=\"option.title || 'Nhập dữ liệu 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ất cả\" 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ố dòng dữ liệu hợp lệ\"\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ố dòng dữ liệu có lỗi\"\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ố dòng dữ liệu có cảnh báo\"\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ạng thái</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ữ liệu hợp lệ</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ấn để tải tệp mẫu về máy\"\r\n aria-hidden=\"true\">\r\n <mat-icon class=\"empty-icon\">cloud_download</mat-icon>\r\n\r\n <h4>Chưa có dữ liệu tải lên</h4>\r\n <span class=\"text-small text-link\"> Nhấn vào đây để tải tệp mẫu </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ải lên\" 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ải về\" size=\"sm\" color=\"success\" type=\"outline\">\r\n </sd-button>\r\n }\r\n <sd-button\r\n (click)=\"accept()\"\r\n title=\"Xác nhận & Lưu\"\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","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1","i3.ColumnHiddenPipe"],"mappings":"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"}
|
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
import { CommonModule } from '@angular/common';
|
|
2
|
+
import * as i0 from '@angular/core';
|
|
3
|
+
import { EventEmitter, forwardRef, Input, Output, HostBinding, Component } from '@angular/core';
|
|
4
|
+
import * as i1 from '@ckeditor/ckeditor5-angular';
|
|
5
|
+
import { CKEditorModule } from '@ckeditor/ckeditor5-angular';
|
|
6
|
+
import { ClassicEditor, Essentials, FontColor, Paragraph, Bold, Italic, Underline, Link, List, Undo, Widget, Markdown, Mention } from 'ckeditor5';
|
|
7
|
+
import { Subscription, Subject } from 'rxjs';
|
|
8
|
+
import { throttleTime } from 'rxjs/operators';
|
|
9
|
+
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Component sd-mini-editor - Editor đơn giản cho comment input
|
|
13
|
+
* Sử dụng CKEditor với chế độ đơn giản (bold, italic, link)
|
|
14
|
+
* Hỗ trợ mention và output format (html/markdown)
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```html
|
|
18
|
+
* <sd-mini-editor
|
|
19
|
+
* [option]="editorOption"
|
|
20
|
+
* [(ngModel)]="content"
|
|
21
|
+
* (contentChange)="onContentChange($event)"
|
|
22
|
+
* >
|
|
23
|
+
* </sd-mini-editor>
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
class SdMiniEditor {
|
|
27
|
+
/** Cấu hình option cho editor */
|
|
28
|
+
option;
|
|
29
|
+
get maxEditorHeight() {
|
|
30
|
+
return this.option?.maxHeight;
|
|
31
|
+
}
|
|
32
|
+
/** NgModel binding - nội dung HTML/Markdown */
|
|
33
|
+
value = '';
|
|
34
|
+
valueChange = new EventEmitter();
|
|
35
|
+
/** Event emitter khi content thay đổi */
|
|
36
|
+
contentChange = new EventEmitter();
|
|
37
|
+
/** Event emitter khi blur */
|
|
38
|
+
blur = new EventEmitter();
|
|
39
|
+
/** Event emitter khi focus */
|
|
40
|
+
focus = new EventEmitter();
|
|
41
|
+
/** Disabled state */
|
|
42
|
+
disabled = false;
|
|
43
|
+
Editor = ClassicEditor;
|
|
44
|
+
#editor;
|
|
45
|
+
#subscription = new Subscription();
|
|
46
|
+
#contentChangeSubject = new Subject();
|
|
47
|
+
// Build editor config dynamically
|
|
48
|
+
get editorConfig() {
|
|
49
|
+
const enableMention = this.option?.enableMention ?? false;
|
|
50
|
+
const useMarkdown = this.option?.outputFormat === 'markdown';
|
|
51
|
+
const plugins = [Essentials, FontColor, Paragraph, Bold, Italic, Underline, Link, List, Undo, Widget];
|
|
52
|
+
// Add Markdown plugin if outputFormat is markdown
|
|
53
|
+
if (useMarkdown) {
|
|
54
|
+
plugins.push(Markdown);
|
|
55
|
+
}
|
|
56
|
+
// Add Mention plugin if enabled
|
|
57
|
+
if (enableMention) {
|
|
58
|
+
plugins.push(Mention);
|
|
59
|
+
}
|
|
60
|
+
// Build base config
|
|
61
|
+
const config = {
|
|
62
|
+
licenseKey: 'GPL',
|
|
63
|
+
getOption: () => this.option,
|
|
64
|
+
plugins,
|
|
65
|
+
toolbar: {
|
|
66
|
+
items: ['bold', 'italic', 'underline', '|', 'fontColor', '|', 'bulletedList', 'numberedList', '|', 'link'],
|
|
67
|
+
shouldNotGroupWhenFull: true,
|
|
68
|
+
},
|
|
69
|
+
placeholder: this.option?.placeholder,
|
|
70
|
+
link: {
|
|
71
|
+
addTargetToExternalLinks: true,
|
|
72
|
+
defaultProtocol: 'https://',
|
|
73
|
+
},
|
|
74
|
+
fontColor: {
|
|
75
|
+
columns: 5,
|
|
76
|
+
documentColors: 10,
|
|
77
|
+
colorPicker: { format: 'hex' },
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
// Add mention configuration if enabled
|
|
81
|
+
if (enableMention && this.option?.mentionConfig?.feeds) {
|
|
82
|
+
config.mention = {
|
|
83
|
+
feeds: this.option.mentionConfig.feeds,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
return config;
|
|
87
|
+
}
|
|
88
|
+
constructor() {
|
|
89
|
+
// Setup debounce cho content change
|
|
90
|
+
this.#subscription.add(this.#contentChangeSubject.pipe(throttleTime(500, undefined, { leading: true, trailing: true })).subscribe(content => {
|
|
91
|
+
const output = this.#convertOutput(content);
|
|
92
|
+
this.value = output;
|
|
93
|
+
this.#onChange(output);
|
|
94
|
+
this.valueChange.emit(output);
|
|
95
|
+
this.contentChange.emit(output);
|
|
96
|
+
this.option?.onChange?.(output);
|
|
97
|
+
}));
|
|
98
|
+
}
|
|
99
|
+
ngOnDestroy() {
|
|
100
|
+
this.#subscription.unsubscribe();
|
|
101
|
+
this.#editor?.destroy?.();
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Kiểm tra có nên enable mention plugin không
|
|
105
|
+
*/
|
|
106
|
+
#shouldEnableMention() {
|
|
107
|
+
return this.option?.enableMention ?? false;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Xử lý khi editor ready
|
|
111
|
+
*/
|
|
112
|
+
onReady(editor) {
|
|
113
|
+
this.#editor = editor;
|
|
114
|
+
// Set initial content
|
|
115
|
+
if (this.value) {
|
|
116
|
+
this.setContent(this.value);
|
|
117
|
+
}
|
|
118
|
+
// Lắng nghe sự kiện thay đổi nội dung
|
|
119
|
+
editor.model.document.on('change:data', () => {
|
|
120
|
+
const content = editor.getData();
|
|
121
|
+
this.#contentChangeSubject.next(content);
|
|
122
|
+
});
|
|
123
|
+
// Lắng nghe focus/blur events
|
|
124
|
+
editor.editing.view.document.on('focus', evt => {
|
|
125
|
+
const domEvent = evt.domEvent;
|
|
126
|
+
this.focus.emit(domEvent);
|
|
127
|
+
this.option?.onFocus?.(domEvent);
|
|
128
|
+
});
|
|
129
|
+
editor.editing.view.document.on('blur', evt => {
|
|
130
|
+
const domEvent = evt.domEvent;
|
|
131
|
+
this.blur.emit(domEvent);
|
|
132
|
+
this.option?.onBlur?.(domEvent);
|
|
133
|
+
});
|
|
134
|
+
// Lắng nghe sự kiện mention được chọn
|
|
135
|
+
if (this.#shouldEnableMention()) {
|
|
136
|
+
editor.commands.get('mention')?.on('execute', (_evt, data) => {
|
|
137
|
+
const mentionData = data[0];
|
|
138
|
+
this.option?.onMentionSelect?.(mentionData.mention);
|
|
139
|
+
// Trigger content change sau khi insert mention
|
|
140
|
+
const content = editor.getData();
|
|
141
|
+
this.#contentChangeSubject.next(content);
|
|
142
|
+
});
|
|
143
|
+
// Custom downcast converter để thay đổi cấu trúc mention HTML
|
|
144
|
+
editor.conversion.for('downcast').attributeToElement({
|
|
145
|
+
model: 'mention',
|
|
146
|
+
view: (mentionData, { writer }) => {
|
|
147
|
+
const data = mentionData;
|
|
148
|
+
const rawId = data?.id || '';
|
|
149
|
+
const marker = rawId[0];
|
|
150
|
+
const cleanId = rawId.slice(1);
|
|
151
|
+
return writer.createAttributeElement('span', {
|
|
152
|
+
class: 'ck-custom-mention',
|
|
153
|
+
'data-id': cleanId,
|
|
154
|
+
'data-marker': marker,
|
|
155
|
+
contenteditable: 'false',
|
|
156
|
+
});
|
|
157
|
+
},
|
|
158
|
+
converterPriority: 'highest',
|
|
159
|
+
});
|
|
160
|
+
// Xử lý keyboard để xóa mention 1 lần
|
|
161
|
+
editor.editing.view.document.on('keydown', (evt, data) => {
|
|
162
|
+
const keyEvent = data;
|
|
163
|
+
// Delete (46) hoặc Backspace (8)
|
|
164
|
+
if (keyEvent.keyCode === 46 || keyEvent.keyCode === 8) {
|
|
165
|
+
const model = editor.model;
|
|
166
|
+
const selection = model.document.selection;
|
|
167
|
+
const position = selection.getFirstPosition();
|
|
168
|
+
if (!position)
|
|
169
|
+
return;
|
|
170
|
+
// Tìm text node có mention attribute
|
|
171
|
+
const node = position.textNode || position.nodeBefore || position.nodeAfter;
|
|
172
|
+
if (node && node.is('$text')) {
|
|
173
|
+
const mentionAttr = node.getAttribute('mention');
|
|
174
|
+
if (mentionAttr) {
|
|
175
|
+
// Xóa toàn bộ text node chứa mention
|
|
176
|
+
model.change(writer => {
|
|
177
|
+
writer.remove(node);
|
|
178
|
+
});
|
|
179
|
+
evt.stop();
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Convert output theo format (html hoặc markdown)
|
|
188
|
+
* Khi sử dụng CKEditor Markdown plugin, getData() tự động trả về Markdown
|
|
189
|
+
*/
|
|
190
|
+
#convertOutput(content) {
|
|
191
|
+
// CKEditor Markdown plugin tự động xử lý conversion
|
|
192
|
+
// Không cần manual conversion nữa
|
|
193
|
+
return content;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Set nội dung cho editor
|
|
197
|
+
*/
|
|
198
|
+
setContent(content) {
|
|
199
|
+
this.#editor?.setData?.(content);
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Get nội dung từ editor
|
|
203
|
+
*/
|
|
204
|
+
getContent() {
|
|
205
|
+
if (this.#editor) {
|
|
206
|
+
const html = this.#editor.getData();
|
|
207
|
+
return this.#convertOutput(html);
|
|
208
|
+
}
|
|
209
|
+
return '';
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Get nội dung HTML gốc (không convert)
|
|
213
|
+
*/
|
|
214
|
+
getHtmlContent() {
|
|
215
|
+
return this.#editor?.getData?.() || '';
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Focus vào editor
|
|
219
|
+
*/
|
|
220
|
+
focusEditor() {
|
|
221
|
+
this.#editor?.editing?.view?.focus?.();
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Insert mention vào vị trí con trỏ hiện tại
|
|
225
|
+
*/
|
|
226
|
+
insertMention(item) {
|
|
227
|
+
if (!this.#editor)
|
|
228
|
+
return;
|
|
229
|
+
const firstFeed = this.option?.mentionConfig?.feeds?.[0];
|
|
230
|
+
const marker = item.marker || firstFeed?.marker || '@';
|
|
231
|
+
// Sử dụng CKEditor mention command
|
|
232
|
+
this.#editor.execute('mention', {
|
|
233
|
+
marker,
|
|
234
|
+
mention: {
|
|
235
|
+
id: item.id,
|
|
236
|
+
text: `${marker}${item.name}`,
|
|
237
|
+
},
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Get danh sách mentions trong nội dung
|
|
242
|
+
*/
|
|
243
|
+
getMentions() {
|
|
244
|
+
if (!this.#editor)
|
|
245
|
+
return [];
|
|
246
|
+
const mentions = [];
|
|
247
|
+
const root = this.#editor.model.document.getRoot();
|
|
248
|
+
if (!root)
|
|
249
|
+
return mentions;
|
|
250
|
+
const range = this.#editor.model.createRangeIn(root);
|
|
251
|
+
for (const item of range.getItems()) {
|
|
252
|
+
if (item.is('$text')) {
|
|
253
|
+
const mentionAttr = item.getAttribute('mention');
|
|
254
|
+
if (mentionAttr) {
|
|
255
|
+
const text = item.data;
|
|
256
|
+
const marker = text.charAt(0);
|
|
257
|
+
const name = text.substring(1);
|
|
258
|
+
const id = item.getAttribute('data-user-id');
|
|
259
|
+
mentions.push({ id, name, marker });
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return mentions;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* ControlValueAccessor: Write value
|
|
267
|
+
*/
|
|
268
|
+
writeValue(value) {
|
|
269
|
+
this.value = value || '';
|
|
270
|
+
if (this.#editor) {
|
|
271
|
+
this.setContent(this.value);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* ControlValueAccessor: Register change callback
|
|
276
|
+
*/
|
|
277
|
+
registerOnChange(fn) {
|
|
278
|
+
this.#onChange = fn;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* ControlValueAccessor: Register touched callback
|
|
282
|
+
*/
|
|
283
|
+
registerOnTouched(fn) {
|
|
284
|
+
this.#onTouched = fn;
|
|
285
|
+
}
|
|
286
|
+
/** ControlValueAccessor callbacks */
|
|
287
|
+
#onChange = () => { };
|
|
288
|
+
#onTouched = () => { };
|
|
289
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdMiniEditor, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
290
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.17", type: SdMiniEditor, isStandalone: true, selector: "sd-mini-editor", inputs: { option: "option", value: "value", disabled: "disabled" }, outputs: { valueChange: "valueChange", contentChange: "contentChange", blur: "blur", focus: "focus" }, host: { properties: { "style.--sd-mini-editor-max-height": "this.maxEditorHeight" } }, providers: [
|
|
291
|
+
{
|
|
292
|
+
provide: NG_VALUE_ACCESSOR,
|
|
293
|
+
useExisting: forwardRef(() => SdMiniEditor),
|
|
294
|
+
multi: true,
|
|
295
|
+
},
|
|
296
|
+
], ngImport: i0, template: "<ckeditor class=\"sd-mini-editor\" [editor]=\"Editor\" [config]=\"editorConfig\" [disabled]=\"disabled\" (ready)=\"onReady($event)\"> </ckeditor>\r\n", styles: [".sd-mini-editor{display:block}::ng-deep .ck-powered-by-balloon{display:none!important}::ng-deep .ck-mentions .ck-button.ck-on{background:var(--sd-primary)!important;color:#fff!important}::ng-deep .ck-mentions .ck-button.ck-on *{color:#fff!important}:host ::ng-deep .ck-editor{--ck-content-font-size: 14px;--ck-content-line-height: 1.5}:host ::ng-deep .ck-editor__editable_inline{border:var(--ck-focus-ring);border-top-left-radius:0!important;border-top-right-radius:0!important;max-height:var(--sd-mini-editor-max-height);overflow:auto}:host ::ng-deep .ck-toolbar{border-radius:0;border:0!important}:host ::ng-deep .ck-content img{max-width:100%!important;height:auto!important;object-fit:contain}:host ::ng-deep .ck-content p{margin-bottom:var(--ck-spacing-large);text-indent:0}:host ::ng-deep .ck-content ul,:host ::ng-deep .ck-content ol{padding-left:20px!important;margin-left:0!important}:host ::ng-deep .ck-custom-mention{font-weight:600;padding:0 2px;display:inline-block;pointer-events:none;-webkit-user-select:none;user-select:none;color:#2962ff}:host ::ng-deep .ck-custom-mention:before{content:attr(data-marker)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: CKEditorModule }, { kind: "component", type: i1.CKEditorComponent, selector: "ckeditor", inputs: ["editor", "config", "data", "tagName", "watchdog", "editorWatchdogConfig", "disableWatchdog", "disableTwoWayDataBinding", "disabled"], outputs: ["ready", "change", "blur", "focus", "error"] }] });
|
|
297
|
+
}
|
|
298
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdMiniEditor, decorators: [{
|
|
299
|
+
type: Component,
|
|
300
|
+
args: [{ selector: 'sd-mini-editor', standalone: true, imports: [CommonModule, CKEditorModule], providers: [
|
|
301
|
+
{
|
|
302
|
+
provide: NG_VALUE_ACCESSOR,
|
|
303
|
+
useExisting: forwardRef(() => SdMiniEditor),
|
|
304
|
+
multi: true,
|
|
305
|
+
},
|
|
306
|
+
], template: "<ckeditor class=\"sd-mini-editor\" [editor]=\"Editor\" [config]=\"editorConfig\" [disabled]=\"disabled\" (ready)=\"onReady($event)\"> </ckeditor>\r\n", styles: [".sd-mini-editor{display:block}::ng-deep .ck-powered-by-balloon{display:none!important}::ng-deep .ck-mentions .ck-button.ck-on{background:var(--sd-primary)!important;color:#fff!important}::ng-deep .ck-mentions .ck-button.ck-on *{color:#fff!important}:host ::ng-deep .ck-editor{--ck-content-font-size: 14px;--ck-content-line-height: 1.5}:host ::ng-deep .ck-editor__editable_inline{border:var(--ck-focus-ring);border-top-left-radius:0!important;border-top-right-radius:0!important;max-height:var(--sd-mini-editor-max-height);overflow:auto}:host ::ng-deep .ck-toolbar{border-radius:0;border:0!important}:host ::ng-deep .ck-content img{max-width:100%!important;height:auto!important;object-fit:contain}:host ::ng-deep .ck-content p{margin-bottom:var(--ck-spacing-large);text-indent:0}:host ::ng-deep .ck-content ul,:host ::ng-deep .ck-content ol{padding-left:20px!important;margin-left:0!important}:host ::ng-deep .ck-custom-mention{font-weight:600;padding:0 2px;display:inline-block;pointer-events:none;-webkit-user-select:none;user-select:none;color:#2962ff}:host ::ng-deep .ck-custom-mention:before{content:attr(data-marker)}\n"] }]
|
|
307
|
+
}], ctorParameters: () => [], propDecorators: { option: [{
|
|
308
|
+
type: Input,
|
|
309
|
+
args: [{ required: true }]
|
|
310
|
+
}], maxEditorHeight: [{
|
|
311
|
+
type: HostBinding,
|
|
312
|
+
args: ['style.--sd-mini-editor-max-height']
|
|
313
|
+
}], value: [{
|
|
314
|
+
type: Input
|
|
315
|
+
}], valueChange: [{
|
|
316
|
+
type: Output
|
|
317
|
+
}], contentChange: [{
|
|
318
|
+
type: Output
|
|
319
|
+
}], blur: [{
|
|
320
|
+
type: Output
|
|
321
|
+
}], focus: [{
|
|
322
|
+
type: Output
|
|
323
|
+
}], disabled: [{
|
|
324
|
+
type: Input
|
|
325
|
+
}] } });
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Generated bundle index. Do not edit.
|
|
329
|
+
*/
|
|
330
|
+
|
|
331
|
+
export { SdMiniEditor };
|
|
332
|
+
//# sourceMappingURL=sd-angular-core-components-mini-editor.mjs.map
|