@sdcorejs/angular 19.1.3 → 19.1.4
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 +17 -14
- package/components/audit-diff/index.d.ts +2 -0
- package/components/audit-diff/src/audit-diff.component.d.ts +30 -0
- package/components/audit-diff/src/audit-diff.engine.d.ts +40 -0
- package/components/badge/src/badge.component.d.ts +1 -1
- package/components/breadcrumb/index.d.ts +1 -0
- package/components/breadcrumb/src/breadcrumb.component.d.ts +50 -0
- package/components/data-state/index.d.ts +1 -0
- package/components/data-state/src/data-state.component.d.ts +40 -0
- package/components/document-builder/src/components/header-footer-builder/header-footer-builder.component.d.ts +1 -2
- package/components/document-builder/src/document-builder.component.d.ts +4 -4
- package/components/form-generic/src/components/form-builder/components/attribute-expression/attribute-expression.component.d.ts +7 -8
- package/components/form-generic/src/components/form-builder/components/attribute-input/attribute-input.component.d.ts +4 -5
- package/components/form-generic/src/components/form-builder/components/attribute-input-number/attribute-input-number.component.d.ts +1 -2
- package/components/form-generic/src/components/form-builder/components/attribute-parameter/attribute-parameter.component.d.ts +6 -5
- package/components/form-generic/src/components/form-builder/components/attribute-select/attribute-select.component.d.ts +4 -5
- package/components/form-generic/src/components/form-builder/components/attribute-selection/attribute-selection.component.d.ts +9 -9
- package/components/form-generic/src/components/form-builder/components/attribute-selection/components/build-queries/build-queries.component.d.ts +8 -7
- package/components/form-generic/src/components/form-builder/components/attribute-selection/components/build-variables/build-variables.component.d.ts +8 -7
- package/components/form-generic/src/components/form-builder/components/attribute-switch/attribute-switch.component.d.ts +3 -4
- package/components/form-generic/src/components/form-builder/components/attribute-table/attribute-table.component.d.ts +5 -6
- package/components/form-generic/src/components/form-builder/components/attribute-template/attribute-template.component.d.ts +1 -2
- package/components/form-generic/src/components/form-builder/components/attribute-textarea/attribute-textarea.component.d.ts +4 -5
- package/components/form-generic/src/components/form-builder/components/checkbox/attribute/checkbox-attribute.component.d.ts +6 -6
- package/components/form-generic/src/components/form-builder/components/chip-calendar/attribute/chip-calendar-attribute.component.d.ts +6 -6
- package/components/form-generic/src/components/form-builder/components/chip-calendar/control/chip-calendar-control.component.d.ts +3 -3
- package/components/form-generic/src/components/form-builder/components/chip-string/attribute/chip-string-attribute.component.d.ts +6 -6
- package/components/form-generic/src/components/form-builder/components/chip-string/control/chip-string-control.component.d.ts +3 -3
- package/components/form-generic/src/components/form-builder/components/configure-validation/configure-validation.component.d.ts +2 -2
- package/components/form-generic/src/components/form-builder/components/datetime/attribute/datetime-attribute.component.d.ts +6 -6
- package/components/form-generic/src/components/form-builder/components/datetime/control/datetime-control.component.d.ts +3 -3
- package/components/form-generic/src/components/form-builder/components/expression-builder/expression-builder.component.d.ts +6 -5
- package/components/form-generic/src/components/form-builder/components/html/attribute/components/build-queries/build-queries.component.d.ts +7 -6
- package/components/form-generic/src/components/form-builder/components/html/attribute/html-attribute.component.d.ts +7 -8
- package/components/form-generic/src/components/form-builder/components/html/control/html-control.component.d.ts +3 -4
- package/components/form-generic/src/components/form-builder/components/number/attribute/number-attribute.component.d.ts +6 -6
- package/components/form-generic/src/components/form-builder/components/number/control/number-control.component.d.ts +3 -3
- package/components/form-generic/src/components/form-builder/components/radio/attribute/radio-attribute.component.d.ts +6 -6
- package/components/form-generic/src/components/form-builder/components/radio/control/radio-control.component.d.ts +3 -3
- package/components/form-generic/src/components/form-builder/components/select/attribute/select-attribute.component.d.ts +6 -6
- package/components/form-generic/src/components/form-builder/components/select/control/select-control.component.d.ts +3 -3
- package/components/form-generic/src/components/form-builder/components/table/attribute/table-attribute.component.d.ts +6 -6
- package/components/form-generic/src/components/form-builder/components/table/control/table-control.component.d.ts +3 -3
- package/components/form-generic/src/components/form-builder/components/textarea/attribute/textarea-attribute.component.d.ts +6 -6
- package/components/form-generic/src/components/form-builder/components/textarea/control/textarea-control.component.d.ts +3 -3
- package/components/form-generic/src/components/form-builder/components/textfield/attribute/textfield-attribute.component.d.ts +6 -6
- package/components/form-generic/src/components/form-builder/components/textfield/control/textfield-control.component.d.ts +3 -3
- package/components/form-generic/src/components/form-builder/components/upload/attribute/upload-attribute.component.d.ts +6 -6
- package/components/form-generic/src/components/form-builder/components/upload/control/upload-control.component.d.ts +3 -3
- package/components/form-generic/src/components/form-render/components/item/components/chip-calendar/chip-calendar.component.d.ts +7 -6
- package/components/form-generic/src/components/form-render/components/item/components/chip-string/chip-string.component.d.ts +7 -6
- package/components/form-generic/src/components/form-render/components/item/components/datetime/datetime.component.d.ts +7 -7
- package/components/form-generic/src/components/form-render/components/item/components/html/html.component.d.ts +6 -6
- package/components/form-generic/src/components/form-render/components/item/components/number/number.component.d.ts +7 -6
- package/components/form-generic/src/components/form-render/components/item/components/radio/radio.component.d.ts +6 -7
- package/components/form-generic/src/components/form-render/components/item/components/select/select.component.d.ts +6 -7
- package/components/form-generic/src/components/form-render/components/item/components/table/table.component.d.ts +8 -8
- package/components/form-generic/src/components/form-render/components/item/components/textarea/textarea.component.d.ts +7 -6
- package/components/form-generic/src/components/form-render/components/item/components/textfield/textfield.component.d.ts +7 -6
- package/components/form-generic/src/components/form-render/components/item/components/upload/upload.component.d.ts +7 -6
- package/components/form-generic/src/components/form-render/components/item/item.component.d.ts +4 -4
- package/components/form-generic/src/components/sd-feel-expression/sd-feel-expression.component.d.ts +8 -9
- package/components/form-generic/src/pipes/component-viewed.pipe.d.ts +2 -3
- package/components/form-generic/src/pipes/html.pipe.d.ts +2 -2
- package/components/form-generic/src/services/form-render.service.d.ts +2 -2
- package/components/import-excel/src/import-excel.component.d.ts +4 -7
- package/components/import-excel/src/pipes/column-transform.pipe.d.ts +3 -2
- package/components/index.d.ts +4 -0
- package/components/job-progress/index.d.ts +1 -0
- package/components/job-progress/src/job-progress.component.d.ts +34 -0
- package/components/mini-editor/src/mini-editor.component.d.ts +7 -7
- package/components/modal/src/modal.component.d.ts +6 -1
- package/components/preview/index.d.ts +3 -0
- package/components/preview/src/preview-pdf/preview-pdf.browser.d.ts +28 -0
- package/components/preview/src/preview-pdf/preview-pdf.component.d.ts +61 -23
- package/components/preview/src/preview-pdf/preview-pdf.pdfjs.d.ts +77 -0
- package/components/preview/src/preview-pdf/preview-pdf.print.d.ts +10 -0
- package/components/preview/src/preview-pdf/preview-pdf.types.d.ts +11 -9
- package/components/side-drawer/src/side-drawer.component.d.ts +6 -1
- package/components/tab/src/tab-group.component.d.ts +1 -0
- package/components/tab/src/tab.component.d.ts +7 -1
- package/components/tab-router/src/components/tab-router-item/tab-router-item.component.d.ts +3 -4
- package/components/tab-router/src/pipes/tab-info.pipe.d.ts +2 -2
- package/components/tab-router/src/services/tab-decorator.service.d.ts +2 -1
- package/components/table/src/components/filter/column-filter/column-filter.component.d.ts +1 -1
- package/components/table/src/components/popup-export/popup-export.component.d.ts +6 -6
- package/components/table/src/models/table-column.model.d.ts +1 -1
- package/components/table/src/services/config.service.d.ts +3 -2
- package/components/table/src/services/table-filter/table-filter.model.d.ts +1 -1
- package/components/table/src/services/table-filter/table-filter.service.d.ts +2 -2
- package/components/tree/src/tree.component.d.ts +13 -2
- package/components/tree/src/tree.model.d.ts +11 -0
- package/components/upload-file/src/components/preview/preview.component.d.ts +4 -4
- package/directives/src/sd-hover-copy.directive.d.ts +6 -5
- package/directives/src/sd-href.directive.d.ts +2 -2
- package/directives/src/sd-scroll.directive.d.ts +3 -2
- package/fesm2022/sdcorejs-angular-components-anchor.mjs +14 -14
- package/fesm2022/sdcorejs-angular-components-anchor.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-audit-diff.mjs +332 -0
- package/fesm2022/sdcorejs-angular-components-audit-diff.mjs.map +1 -0
- package/fesm2022/sdcorejs-angular-components-badge.mjs +1 -0
- package/fesm2022/sdcorejs-angular-components-badge.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-breadcrumb.mjs +121 -0
- package/fesm2022/sdcorejs-angular-components-breadcrumb.mjs.map +1 -0
- package/fesm2022/sdcorejs-angular-components-data-state.mjs +68 -0
- package/fesm2022/sdcorejs-angular-components-data-state.mjs.map +1 -0
- package/fesm2022/sdcorejs-angular-components-document-builder.mjs +16 -21
- package/fesm2022/sdcorejs-angular-components-document-builder.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-editor.mjs +6 -4
- package/fesm2022/sdcorejs-angular-components-editor.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-form-generic.mjs +463 -806
- package/fesm2022/sdcorejs-angular-components-form-generic.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-import-excel.mjs +23 -33
- package/fesm2022/sdcorejs-angular-components-import-excel.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-job-progress.mjs +97 -0
- package/fesm2022/sdcorejs-angular-components-job-progress.mjs.map +1 -0
- package/fesm2022/sdcorejs-angular-components-mini-editor.mjs +9 -19
- package/fesm2022/sdcorejs-angular-components-mini-editor.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-modal.mjs +60 -3
- package/fesm2022/sdcorejs-angular-components-modal.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-preview.mjs +1437 -217
- package/fesm2022/sdcorejs-angular-components-preview.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-query-bar.mjs +4 -4
- package/fesm2022/sdcorejs-angular-components-query-bar.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-query-builder.mjs +1 -1
- package/fesm2022/sdcorejs-angular-components-query-builder.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-side-drawer.mjs +38 -1
- package/fesm2022/sdcorejs-angular-components-side-drawer.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-tab-router.mjs +16 -22
- package/fesm2022/sdcorejs-angular-components-tab-router.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-tab.mjs +47 -3
- package/fesm2022/sdcorejs-angular-components-tab.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-table.mjs +94 -61
- package/fesm2022/sdcorejs-angular-components-table.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-tree.mjs +185 -16
- package/fesm2022/sdcorejs-angular-components-tree.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-upload-file.mjs +14 -21
- package/fesm2022/sdcorejs-angular-components-upload-file.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components.mjs +4 -0
- package/fesm2022/sdcorejs-angular-components.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-directives.mjs +29 -41
- package/fesm2022/sdcorejs-angular-directives.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs +7 -7
- package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-checkbox.mjs +20 -73
- package/fesm2022/sdcorejs-angular-forms-checkbox.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs +6 -3
- package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-chip.mjs +6 -3
- package/fesm2022/sdcorejs-angular-forms-chip.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-date-range.mjs +16 -13
- package/fesm2022/sdcorejs-angular-forms-date-range.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-date.mjs +42 -65
- package/fesm2022/sdcorejs-angular-forms-date.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-datetime.mjs +51 -66
- package/fesm2022/sdcorejs-angular-forms-datetime.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-entity-picker.mjs +384 -0
- package/fesm2022/sdcorejs-angular-forms-entity-picker.mjs.map +1 -0
- package/fesm2022/sdcorejs-angular-forms-input-color.mjs +1 -1
- package/fesm2022/sdcorejs-angular-forms-input-color.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-input-number.mjs +7 -5
- package/fesm2022/sdcorejs-angular-forms-input-number.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-input.mjs +289 -55
- package/fesm2022/sdcorejs-angular-forms-input.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-models.mjs +155 -2
- package/fesm2022/sdcorejs-angular-forms-models.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-radio.mjs +44 -68
- package/fesm2022/sdcorejs-angular-forms-radio.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-select.mjs +6 -20
- package/fesm2022/sdcorejs-angular-forms-select.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-switch.mjs +19 -66
- package/fesm2022/sdcorejs-angular-forms-switch.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-textarea.mjs +6 -5
- package/fesm2022/sdcorejs-angular-forms-textarea.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-time-range.mjs +279 -0
- package/fesm2022/sdcorejs-angular-forms-time-range.mjs.map +1 -0
- package/fesm2022/sdcorejs-angular-forms-time.mjs +309 -0
- package/fesm2022/sdcorejs-angular-forms-time.mjs.map +1 -0
- package/fesm2022/sdcorejs-angular-forms-tree-select.mjs +210 -0
- package/fesm2022/sdcorejs-angular-forms-tree-select.mjs.map +1 -0
- package/fesm2022/sdcorejs-angular-forms.mjs +73 -4
- package/fesm2022/sdcorejs-angular-forms.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-i18n.mjs +355 -10
- package/fesm2022/sdcorejs-angular-i18n.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-interceptors.mjs +12 -17
- package/fesm2022/sdcorejs-angular-interceptors.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-modules-layout.mjs +859 -78
- package/fesm2022/sdcorejs-angular-modules-layout.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-pipes.mjs +5 -7
- package/fesm2022/sdcorejs-angular-pipes.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-api.mjs +407 -137
- package/fesm2022/sdcorejs-angular-services-api.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-cache.mjs +515 -105
- package/fesm2022/sdcorejs-angular-services-cache.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-confirm.mjs +5 -7
- package/fesm2022/sdcorejs-angular-services-confirm.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-docx.mjs +7 -10
- package/fesm2022/sdcorejs-angular-services-docx.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-loading.mjs +339 -74
- package/fesm2022/sdcorejs-angular-services-loading.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-notify.mjs +7 -10
- package/fesm2022/sdcorejs-angular-services-notify.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-persistence.mjs +899 -0
- package/fesm2022/sdcorejs-angular-services-persistence.mjs.map +1 -0
- package/fesm2022/sdcorejs-angular-services-storage.mjs +324 -122
- package/fesm2022/sdcorejs-angular-services-storage.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-task.mjs +389 -0
- package/fesm2022/sdcorejs-angular-services-task.mjs.map +1 -0
- package/fesm2022/sdcorejs-angular-services-unsaved-changes.mjs +255 -0
- package/fesm2022/sdcorejs-angular-services-unsaved-changes.mjs.map +1 -0
- package/fesm2022/sdcorejs-angular-services-viewport.mjs +76 -0
- package/fesm2022/sdcorejs-angular-services-viewport.mjs.map +1 -0
- package/fesm2022/sdcorejs-angular-services.mjs +4 -0
- package/fesm2022/sdcorejs-angular-services.mjs.map +1 -1
- package/forms/autocomplete/src/autocomplete.component.d.ts +3 -4
- package/forms/checkbox/src/checkbox.component.d.ts +4 -8
- package/forms/date/src/date.component.d.ts +3 -2
- package/forms/date-range/src/date-range.component.d.ts +5 -8
- package/forms/datetime/src/datetime.component.d.ts +3 -2
- package/forms/entity-picker/index.d.ts +1 -0
- package/forms/entity-picker/src/entity-picker.component.d.ts +123 -0
- package/forms/index.d.ts +6 -0
- package/forms/input/index.d.ts +1 -0
- package/forms/input/src/input-mask.d.ts +43 -0
- package/forms/input/src/input.component.d.ts +26 -9
- package/forms/input-number/src/input-number.component.d.ts +1 -1
- package/forms/models/index.d.ts +1 -0
- package/forms/models/src/sd-form-control-connector.d.ts +86 -0
- package/forms/radio/src/radio.component.d.ts +12 -8
- package/forms/src/forms.module.d.ts +9 -5
- package/forms/switch/src/switch.component.d.ts +4 -7
- package/forms/time/index.d.ts +3 -0
- package/forms/time/src/time-picker.adapter.d.ts +13 -0
- package/forms/time/src/time-value.d.ts +19 -0
- package/forms/time/src/time.component.d.ts +78 -0
- package/forms/time-range/index.d.ts +2 -0
- package/forms/time-range/src/time-range-value.d.ts +14 -0
- package/forms/time-range/src/time-range.component.d.ts +80 -0
- package/forms/tree-select/index.d.ts +1 -0
- package/forms/tree-select/src/tree-select.component.d.ts +71 -0
- package/i18n/src/en.d.ts +68 -2
- package/interceptors/no-internet/no-internet.interceptor.d.ts +2 -3
- package/interceptors/unauthorized/unauthorized.interceptor.d.ts +2 -2
- package/modules/layout/components/index.d.ts +6 -0
- package/modules/layout/components/layout-main/layout-main.component.d.ts +7 -2
- package/modules/layout/components/shared/menu-tree/menu-tree.component.d.ts +28 -0
- package/modules/layout/components/shared/user-menu/user-menu.component.d.ts +25 -0
- package/modules/layout/components/sidebar-mobile-v2/main.component.d.ts +27 -0
- package/modules/layout/components/sidebar-mobile-v3/main.component.d.ts +28 -0
- package/modules/layout/components/sidebar-v1/components/sidebar/sidebar.component.d.ts +3 -4
- package/modules/layout/components/sidebar-v1/main.component.d.ts +2 -2
- package/modules/layout/components/sidebar-v2/main.component.d.ts +36 -0
- package/modules/layout/components/sidebar-v3/main.component.d.ts +29 -0
- package/modules/layout/configurations/layout.configuration.d.ts +36 -2
- package/modules/layout/index.d.ts +1 -0
- package/modules/layout/pipes/menu.pipe.d.ts +2 -2
- package/modules/layout/services/index.d.ts +3 -0
- package/modules/layout/services/layout.service.d.ts +2 -2
- package/modules/layout/services/menu/menu.utils.d.ts +6 -0
- package/modules/layout/services/navigation-state/navigation-state.service.d.ts +18 -0
- package/modules/layout/services/responsive/responsive.service.d.ts +12 -0
- package/modules/layout/services/storage/storage.service.d.ts +21 -8
- package/package.json +49 -1
- package/pipes/src/safe-html.pipe.d.ts +2 -2
- package/services/api/src/api.model.d.ts +54 -15
- package/services/api/src/api.service.d.ts +13 -8
- package/services/api/src/interceptors/api.interceptor.d.ts +1 -1
- package/services/cache/src/cache.model.d.ts +46 -13
- package/services/cache/src/cache.service.d.ts +5 -2
- package/services/confirm/src/lib/confirm.service.d.ts +2 -2
- package/services/docx/src/lib/docx.service.d.ts +2 -3
- package/services/index.d.ts +4 -0
- package/services/loading/src/loading.service.d.ts +15 -8
- package/services/notify/src/components/toast/toast.component.d.ts +2 -3
- package/services/persistence/index.d.ts +5 -0
- package/services/persistence/src/graph-serializer.d.ts +16 -0
- package/services/persistence/src/persistence-envelope.d.ts +28 -0
- package/services/persistence/src/persistence-key.d.ts +17 -0
- package/services/persistence/src/persistence.model.d.ts +63 -0
- package/services/persistence/src/storage-adapter.d.ts +29 -0
- package/services/storage/src/storage.model.d.ts +20 -5
- package/services/storage/src/storage.service.d.ts +6 -3
- package/services/task/index.d.ts +3 -0
- package/services/task/src/task.model.d.ts +75 -0
- package/services/task/src/task.service.d.ts +14 -0
- package/services/task/src/task.tokens.d.ts +12 -0
- package/services/unsaved-changes/index.d.ts +4 -0
- package/services/unsaved-changes/src/unsaved-changes.adapters.d.ts +15 -0
- package/services/unsaved-changes/src/unsaved-changes.model.d.ts +41 -0
- package/services/unsaved-changes/src/unsaved-changes.service.d.ts +16 -0
- package/services/unsaved-changes/src/unsaved-changes.tokens.d.ts +9 -0
- package/services/viewport/index.d.ts +3 -0
- package/services/viewport/src/viewport.model.d.ts +12 -0
- package/services/viewport/src/viewport.service.d.ts +18 -0
- package/services/viewport/src/viewport.tokens.d.ts +6 -0
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
import { NgTemplateOutlet } from '@angular/common';
|
|
2
|
+
import * as i0 from '@angular/core';
|
|
3
|
+
import { inject, TemplateRef, Directive, input, computed, contentChild, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
4
|
+
import { I18nService } from '@sdcorejs/angular/i18n';
|
|
5
|
+
|
|
6
|
+
const DEFAULT_REDACTED_VALUE = '••••••';
|
|
7
|
+
function sdBuildAuditDiff(before, after, options = {}) {
|
|
8
|
+
const context = {
|
|
9
|
+
options,
|
|
10
|
+
fields: options.fields ?? [],
|
|
11
|
+
rows: [],
|
|
12
|
+
activeBefore: new WeakSet(),
|
|
13
|
+
activeAfter: new WeakSet(),
|
|
14
|
+
};
|
|
15
|
+
walkValue(context, before, after, true, true, '$', '$');
|
|
16
|
+
return context.rows.sort((left, right) => compareRows(left, right, context.fields));
|
|
17
|
+
}
|
|
18
|
+
function walkValue(context, before, after, beforePresent, afterPresent, path, configPath) {
|
|
19
|
+
if (isConfigured(context.fields, configPath, 'hidden'))
|
|
20
|
+
return;
|
|
21
|
+
if (isConfigured(context.fields, configPath, 'redacted')) {
|
|
22
|
+
addAtomicRow(context, before, after, beforePresent, afterPresent, path, configPath, true);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const field = findExactField(context.fields, configPath);
|
|
26
|
+
if (field?.format || field?.enumMap) {
|
|
27
|
+
addAtomicRow(context, before, after, beforePresent, afterPresent, path, configPath, false);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const beforeArray = Array.isArray(before);
|
|
31
|
+
const afterArray = Array.isArray(after);
|
|
32
|
+
if (beforeArray || afterArray) {
|
|
33
|
+
if ((!beforePresent && afterArray) || (beforeArray && !afterPresent) || (beforeArray && afterArray)) {
|
|
34
|
+
const arrayKey = field?.arrayKey;
|
|
35
|
+
if (arrayKey && walkStableArray(context, beforeArray ? before : [], afterArray ? after : [], path, configPath, arrayKey))
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
addAtomicRow(context, before, after, beforePresent, afterPresent, path, configPath, false);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const beforeObject = isPlainObject(before);
|
|
42
|
+
const afterObject = isPlainObject(after);
|
|
43
|
+
const canRecurse = (beforeObject && afterObject) || (beforeObject && !afterPresent) || (afterObject && !beforePresent);
|
|
44
|
+
if (canRecurse) {
|
|
45
|
+
if ((beforeObject && context.activeBefore.has(before)) || (afterObject && context.activeAfter.has(after)))
|
|
46
|
+
return;
|
|
47
|
+
if (beforeObject)
|
|
48
|
+
context.activeBefore.add(before);
|
|
49
|
+
if (afterObject)
|
|
50
|
+
context.activeAfter.add(after);
|
|
51
|
+
const beforeRecord = beforeObject ? before : {};
|
|
52
|
+
const afterRecord = afterObject ? after : {};
|
|
53
|
+
const keys = [...new Set([...Object.keys(beforeRecord), ...Object.keys(afterRecord)])].sort(compareText);
|
|
54
|
+
if (keys.length === 0) {
|
|
55
|
+
addAtomicRow(context, before, after, beforePresent, afterPresent, path, configPath, false);
|
|
56
|
+
if (beforeObject)
|
|
57
|
+
context.activeBefore.delete(before);
|
|
58
|
+
if (afterObject)
|
|
59
|
+
context.activeAfter.delete(after);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
for (const key of keys) {
|
|
63
|
+
const childBeforePresent = beforeObject && hasOwn(beforeRecord, key);
|
|
64
|
+
const childAfterPresent = afterObject && hasOwn(afterRecord, key);
|
|
65
|
+
walkValue(context, childBeforePresent ? beforeRecord[key] : undefined, childAfterPresent ? afterRecord[key] : undefined, childBeforePresent, childAfterPresent, path === '$' ? key : `${path}.${key}`, configPath === '$' ? key : `${configPath}.${key}`);
|
|
66
|
+
}
|
|
67
|
+
if (beforeObject)
|
|
68
|
+
context.activeBefore.delete(before);
|
|
69
|
+
if (afterObject)
|
|
70
|
+
context.activeAfter.delete(after);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
addAtomicRow(context, before, after, beforePresent, afterPresent, path, configPath, false);
|
|
74
|
+
}
|
|
75
|
+
function walkStableArray(context, before, after, path, configPath, keySelector) {
|
|
76
|
+
const beforeItems = indexStableArray(before, keySelector);
|
|
77
|
+
const afterItems = indexStableArray(after, keySelector);
|
|
78
|
+
if (!beforeItems || !afterItems)
|
|
79
|
+
return false;
|
|
80
|
+
const keys = [...new Set([...beforeItems.keys(), ...afterItems.keys()])].sort(compareText);
|
|
81
|
+
const keyName = typeof keySelector === 'string' ? keySelector : 'key';
|
|
82
|
+
for (const key of keys) {
|
|
83
|
+
const beforeItem = beforeItems.get(key);
|
|
84
|
+
const afterItem = afterItems.get(key);
|
|
85
|
+
const itemPath = `${path}[${keyName}=${encodeURIComponent(key)}]`;
|
|
86
|
+
const itemConfigPath = `${configPath}[]`;
|
|
87
|
+
if (!beforeItem || !afterItem) {
|
|
88
|
+
walkValue(context, beforeItem?.value, afterItem?.value, Boolean(beforeItem), Boolean(afterItem), itemPath, itemConfigPath);
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
walkValue(context, beforeItem.value, afterItem.value, true, true, itemPath, itemConfigPath);
|
|
92
|
+
}
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
function indexStableArray(items, keySelector) {
|
|
96
|
+
const result = new Map();
|
|
97
|
+
for (const item of items) {
|
|
98
|
+
let key;
|
|
99
|
+
try {
|
|
100
|
+
key = typeof keySelector === 'function' ? keySelector(item) : isObject(item) ? item[keySelector] : undefined;
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
const serialized = serializeStableKey(key);
|
|
106
|
+
if (serialized === null || result.has(serialized))
|
|
107
|
+
return null;
|
|
108
|
+
result.set(serialized, { key, value: item });
|
|
109
|
+
}
|
|
110
|
+
return result;
|
|
111
|
+
}
|
|
112
|
+
function serializeStableKey(key) {
|
|
113
|
+
if (key === null)
|
|
114
|
+
return 'null:null';
|
|
115
|
+
switch (typeof key) {
|
|
116
|
+
case 'string':
|
|
117
|
+
case 'number':
|
|
118
|
+
case 'bigint':
|
|
119
|
+
case 'boolean':
|
|
120
|
+
return `${typeof key}:${String(key)}`;
|
|
121
|
+
default:
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
function addAtomicRow(context, before, after, beforePresent, afterPresent, path, configPath, redacted) {
|
|
126
|
+
const kind = classifyChange(before, after, beforePresent, afterPresent);
|
|
127
|
+
if (kind === 'unchanged' && !context.options.includeUnchanged)
|
|
128
|
+
return;
|
|
129
|
+
const field = findExactField(context.fields, configPath);
|
|
130
|
+
const redactedValue = context.options.redactedValue ?? DEFAULT_REDACTED_VALUE;
|
|
131
|
+
const normalizedBefore = redacted
|
|
132
|
+
? beforePresent
|
|
133
|
+
? redactedValue
|
|
134
|
+
: undefined
|
|
135
|
+
: normalizeValue(before, beforePresent, 'before', kind, path, configPath, field, after);
|
|
136
|
+
const normalizedAfter = redacted
|
|
137
|
+
? afterPresent
|
|
138
|
+
? redactedValue
|
|
139
|
+
: undefined
|
|
140
|
+
: normalizeValue(after, afterPresent, 'after', kind, path, configPath, field, before);
|
|
141
|
+
context.rows.push({
|
|
142
|
+
id: path,
|
|
143
|
+
path,
|
|
144
|
+
configPath,
|
|
145
|
+
label: field?.label ?? (path === '$' ? (context.options.rootLabel ?? 'Value') : path),
|
|
146
|
+
kind,
|
|
147
|
+
before: normalizedBefore,
|
|
148
|
+
after: normalizedAfter,
|
|
149
|
+
beforePresent,
|
|
150
|
+
afterPresent,
|
|
151
|
+
redacted,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
function normalizeValue(value, present, side, kind, path, configPath, field, otherValue) {
|
|
155
|
+
if (!present)
|
|
156
|
+
return undefined;
|
|
157
|
+
const mapped = field?.enumMap && hasOwn(field.enumMap, String(value)) ? field.enumMap[String(value)] : value;
|
|
158
|
+
if (!field?.format)
|
|
159
|
+
return mapped;
|
|
160
|
+
try {
|
|
161
|
+
return field.format(mapped, {
|
|
162
|
+
path,
|
|
163
|
+
configPath,
|
|
164
|
+
side,
|
|
165
|
+
kind,
|
|
166
|
+
before: side === 'before' ? value : otherValue,
|
|
167
|
+
after: side === 'after' ? value : otherValue,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
return mapped;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
function classifyChange(before, after, beforePresent, afterPresent) {
|
|
175
|
+
if (!beforePresent && afterPresent)
|
|
176
|
+
return 'added';
|
|
177
|
+
if (beforePresent && !afterPresent)
|
|
178
|
+
return 'removed';
|
|
179
|
+
return deepEqual(before, after) ? 'unchanged' : 'changed';
|
|
180
|
+
}
|
|
181
|
+
function deepEqual(left, right, seen = new WeakMap()) {
|
|
182
|
+
if (Object.is(left, right))
|
|
183
|
+
return true;
|
|
184
|
+
if (left instanceof Date && right instanceof Date)
|
|
185
|
+
return left.getTime() === right.getTime();
|
|
186
|
+
if (!isObject(left) || !isObject(right))
|
|
187
|
+
return false;
|
|
188
|
+
let rightSet = seen.get(left);
|
|
189
|
+
if (rightSet?.has(right))
|
|
190
|
+
return true;
|
|
191
|
+
if (!rightSet) {
|
|
192
|
+
rightSet = new WeakSet();
|
|
193
|
+
seen.set(left, rightSet);
|
|
194
|
+
}
|
|
195
|
+
rightSet.add(right);
|
|
196
|
+
if (Array.isArray(left) && Array.isArray(right)) {
|
|
197
|
+
if (left.length !== right.length)
|
|
198
|
+
return false;
|
|
199
|
+
return left.every((value, index) => deepEqual(value, right[index], seen));
|
|
200
|
+
}
|
|
201
|
+
if (!isPlainObject(left) || !isPlainObject(right))
|
|
202
|
+
return false;
|
|
203
|
+
const leftKeys = Object.keys(left).sort(compareText);
|
|
204
|
+
const rightKeys = Object.keys(right).sort(compareText);
|
|
205
|
+
if (leftKeys.length !== rightKeys.length || leftKeys.some((key, index) => key !== rightKeys[index]))
|
|
206
|
+
return false;
|
|
207
|
+
return leftKeys.every(key => deepEqual(left[key], right[key], seen));
|
|
208
|
+
}
|
|
209
|
+
function compareRows(left, right, fields) {
|
|
210
|
+
const leftOrder = explicitOrder(left.configPath, fields);
|
|
211
|
+
const rightOrder = explicitOrder(right.configPath, fields);
|
|
212
|
+
if (leftOrder !== rightOrder)
|
|
213
|
+
return leftOrder - rightOrder;
|
|
214
|
+
return compareText(left.path, right.path);
|
|
215
|
+
}
|
|
216
|
+
function explicitOrder(path, fields) {
|
|
217
|
+
const field = fields
|
|
218
|
+
.filter(candidate => Number.isFinite(candidate.order) && isPathOrDescendant(path, candidate.path))
|
|
219
|
+
.sort((left, right) => right.path.length - left.path.length)[0];
|
|
220
|
+
return field?.order ?? Number.POSITIVE_INFINITY;
|
|
221
|
+
}
|
|
222
|
+
function findExactField(fields, path) {
|
|
223
|
+
return fields.find(field => field.path === path);
|
|
224
|
+
}
|
|
225
|
+
function isConfigured(fields, path, property) {
|
|
226
|
+
return fields.some(field => Boolean(field[property]) && isPathOrDescendant(path, field.path));
|
|
227
|
+
}
|
|
228
|
+
function isPathOrDescendant(path, ancestor) {
|
|
229
|
+
return path === ancestor || path.startsWith(`${ancestor}.`) || path.startsWith(`${ancestor}[]`);
|
|
230
|
+
}
|
|
231
|
+
function isObject(value) {
|
|
232
|
+
return typeof value === 'object' && value !== null;
|
|
233
|
+
}
|
|
234
|
+
function isPlainObject(value) {
|
|
235
|
+
if (!isObject(value))
|
|
236
|
+
return false;
|
|
237
|
+
const prototype = Object.getPrototypeOf(value);
|
|
238
|
+
return prototype === Object.prototype || prototype === null;
|
|
239
|
+
}
|
|
240
|
+
function hasOwn(object, key) {
|
|
241
|
+
return Object.prototype.hasOwnProperty.call(object, key);
|
|
242
|
+
}
|
|
243
|
+
function compareText(left, right) {
|
|
244
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
class SdAuditDiffValueTemplateDirective {
|
|
248
|
+
template = inject(TemplateRef);
|
|
249
|
+
static ngTemplateContextGuard(_directive, _context) {
|
|
250
|
+
return true;
|
|
251
|
+
}
|
|
252
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdAuditDiffValueTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
253
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.21", type: SdAuditDiffValueTemplateDirective, isStandalone: true, selector: "ng-template[sdAuditDiffValue]", ngImport: i0 });
|
|
254
|
+
}
|
|
255
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdAuditDiffValueTemplateDirective, decorators: [{
|
|
256
|
+
type: Directive,
|
|
257
|
+
args: [{
|
|
258
|
+
selector: 'ng-template[sdAuditDiffValue]',
|
|
259
|
+
standalone: true,
|
|
260
|
+
}]
|
|
261
|
+
}] });
|
|
262
|
+
class SdAuditDiff {
|
|
263
|
+
before = input(undefined);
|
|
264
|
+
after = input(undefined);
|
|
265
|
+
options = input({});
|
|
266
|
+
mode = input('table');
|
|
267
|
+
ariaLabel = input(undefined);
|
|
268
|
+
#i18n = inject(I18nService);
|
|
269
|
+
rows = computed(() => {
|
|
270
|
+
const options = this.options();
|
|
271
|
+
return sdBuildAuditDiff(this.before(), this.after(), {
|
|
272
|
+
...options,
|
|
273
|
+
rootLabel: options.rootLabel ?? this.text('value.label'),
|
|
274
|
+
});
|
|
275
|
+
});
|
|
276
|
+
valueTemplate = contentChild(SdAuditDiffValueTemplateDirective);
|
|
277
|
+
text(key) {
|
|
278
|
+
return this.#i18n.t(`core.component.audit-diff.${key}`);
|
|
279
|
+
}
|
|
280
|
+
valueContext(row, side) {
|
|
281
|
+
return { $implicit: row[side], row, side };
|
|
282
|
+
}
|
|
283
|
+
displayValue(row, side) {
|
|
284
|
+
const present = side === 'before' ? row.beforePresent : row.afterPresent;
|
|
285
|
+
if (!present)
|
|
286
|
+
return this.text('value.not-set');
|
|
287
|
+
const value = row[side];
|
|
288
|
+
if (value === undefined)
|
|
289
|
+
return this.text('value.undefined');
|
|
290
|
+
if (value === null)
|
|
291
|
+
return this.text('value.null');
|
|
292
|
+
if (value instanceof Date)
|
|
293
|
+
return value.toISOString();
|
|
294
|
+
if (typeof value === 'boolean')
|
|
295
|
+
return this.text(`value.${value ? 'true' : 'false'}`);
|
|
296
|
+
if (typeof value === 'string')
|
|
297
|
+
return value;
|
|
298
|
+
if (typeof value === 'number' || typeof value === 'bigint')
|
|
299
|
+
return String(value);
|
|
300
|
+
return safeStringify(value);
|
|
301
|
+
}
|
|
302
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdAuditDiff, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
303
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: SdAuditDiff, isStandalone: true, selector: "sd-audit-diff", inputs: { before: { classPropertyName: "before", publicName: "before", isSignal: true, isRequired: false, transformFunction: null }, after: { classPropertyName: "after", publicName: "after", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "valueTemplate", first: true, predicate: SdAuditDiffValueTemplateDirective, descendants: true, isSignal: true }], ngImport: i0, template: "@let currentRows = rows();\n@let customValue = valueTemplate();\n\n@if (currentRows.length === 0) {\n <p class=\"sd-audit-diff__empty\" data-audit-empty role=\"status\">{{ text('empty') }}</p>\n} @else if (mode() === 'table') {\n <div class=\"sd-audit-diff__table-scroll\">\n <table class=\"sd-audit-diff__table\" [attr.aria-label]=\"ariaLabel() || text('label')\">\n <thead>\n <tr>\n <th scope=\"col\">{{ text('field') }}</th>\n <th scope=\"col\">{{ text('before') }}</th>\n <th scope=\"col\">{{ text('after') }}</th>\n </tr>\n </thead>\n <tbody>\n @for (row of currentRows; track row.id) {\n <tr data-audit-row [attr.data-change-kind]=\"row.kind\">\n <th scope=\"row\">\n <span class=\"sd-audit-diff__field\">{{ row.label }}</span>\n <span class=\"sd-audit-diff__kind\">{{ text('kind.' + row.kind) }}</span>\n </th>\n <td data-audit-before>\n @if (customValue) {\n <ng-container\n [ngTemplateOutlet]=\"customValue.template\"\n [ngTemplateOutletContext]=\"valueContext(row, 'before')\"></ng-container>\n } @else {\n {{ displayValue(row, 'before') }}\n }\n </td>\n <td data-audit-after>\n @if (customValue) {\n <ng-container\n [ngTemplateOutlet]=\"customValue.template\"\n [ngTemplateOutletContext]=\"valueContext(row, 'after')\"></ng-container>\n } @else {\n {{ displayValue(row, 'after') }}\n }\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n} @else {\n <dl class=\"sd-audit-diff__details\" [attr.aria-label]=\"ariaLabel() || text('label')\">\n @for (row of currentRows; track row.id) {\n <div class=\"sd-audit-diff__detail\" data-audit-row [attr.data-change-kind]=\"row.kind\">\n <dt>\n <span class=\"sd-audit-diff__field\">{{ row.label }}</span>\n <span class=\"sd-audit-diff__kind\">{{ text('kind.' + row.kind) }}</span>\n </dt>\n <dd data-audit-before>\n <span class=\"sd-audit-diff__side-label\">{{ text('before') }}</span>\n @if (customValue) {\n <ng-container [ngTemplateOutlet]=\"customValue.template\" [ngTemplateOutletContext]=\"valueContext(row, 'before')\"></ng-container>\n } @else {\n <span>{{ displayValue(row, 'before') }}</span>\n }\n </dd>\n <dd data-audit-after>\n <span class=\"sd-audit-diff__side-label\">{{ text('after') }}</span>\n @if (customValue) {\n <ng-container [ngTemplateOutlet]=\"customValue.template\" [ngTemplateOutletContext]=\"valueContext(row, 'after')\"></ng-container>\n } @else {\n <span>{{ displayValue(row, 'after') }}</span>\n }\n </dd>\n </div>\n }\n </dl>\n}\n", styles: [":host{display:block}.sd-audit-diff__table-scroll{overflow-x:auto;border:1px solid var(--sd-border-color, #dfe3e8);border-radius:8px}.sd-audit-diff__table{width:100%;border-collapse:collapse;background:var(--sd-surface, #fff)}.sd-audit-diff__table th,.sd-audit-diff__table td{min-width:160px;padding:10px 12px;border-bottom:1px solid var(--sd-border-color, #dfe3e8);text-align:left;vertical-align:top;overflow-wrap:anywhere}.sd-audit-diff__table th:first-child{min-width:180px}.sd-audit-diff__table tbody tr:last-child>*{border-bottom:0}.sd-audit-diff__field,.sd-audit-diff__kind,.sd-audit-diff__side-label{display:block}.sd-audit-diff__kind,.sd-audit-diff__side-label{margin-top:2px;color:var(--sd-text-muted, #5f6772);font-size:.75rem;font-weight:400}.sd-audit-diff__details{display:grid;gap:12px;margin:0}.sd-audit-diff__detail{display:grid;grid-template-columns:minmax(140px,.8fr) repeat(2,minmax(0,1fr));gap:12px;padding:12px;border:1px solid var(--sd-border-color, #dfe3e8);border-radius:8px;background:var(--sd-surface, #fff)}.sd-audit-diff__detail dt,.sd-audit-diff__detail dd{min-width:0;margin:0;overflow-wrap:anywhere}.sd-audit-diff__empty{margin:0;padding:16px;border:1px dashed var(--sd-border-color, #dfe3e8);border-radius:8px;color:var(--sd-text-muted, #5f6772);text-align:center}@media(max-width:640px){.sd-audit-diff__detail{grid-template-columns:1fr}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
304
|
+
}
|
|
305
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdAuditDiff, decorators: [{
|
|
306
|
+
type: Component,
|
|
307
|
+
args: [{ selector: 'sd-audit-diff', standalone: true, imports: [NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, template: "@let currentRows = rows();\n@let customValue = valueTemplate();\n\n@if (currentRows.length === 0) {\n <p class=\"sd-audit-diff__empty\" data-audit-empty role=\"status\">{{ text('empty') }}</p>\n} @else if (mode() === 'table') {\n <div class=\"sd-audit-diff__table-scroll\">\n <table class=\"sd-audit-diff__table\" [attr.aria-label]=\"ariaLabel() || text('label')\">\n <thead>\n <tr>\n <th scope=\"col\">{{ text('field') }}</th>\n <th scope=\"col\">{{ text('before') }}</th>\n <th scope=\"col\">{{ text('after') }}</th>\n </tr>\n </thead>\n <tbody>\n @for (row of currentRows; track row.id) {\n <tr data-audit-row [attr.data-change-kind]=\"row.kind\">\n <th scope=\"row\">\n <span class=\"sd-audit-diff__field\">{{ row.label }}</span>\n <span class=\"sd-audit-diff__kind\">{{ text('kind.' + row.kind) }}</span>\n </th>\n <td data-audit-before>\n @if (customValue) {\n <ng-container\n [ngTemplateOutlet]=\"customValue.template\"\n [ngTemplateOutletContext]=\"valueContext(row, 'before')\"></ng-container>\n } @else {\n {{ displayValue(row, 'before') }}\n }\n </td>\n <td data-audit-after>\n @if (customValue) {\n <ng-container\n [ngTemplateOutlet]=\"customValue.template\"\n [ngTemplateOutletContext]=\"valueContext(row, 'after')\"></ng-container>\n } @else {\n {{ displayValue(row, 'after') }}\n }\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n} @else {\n <dl class=\"sd-audit-diff__details\" [attr.aria-label]=\"ariaLabel() || text('label')\">\n @for (row of currentRows; track row.id) {\n <div class=\"sd-audit-diff__detail\" data-audit-row [attr.data-change-kind]=\"row.kind\">\n <dt>\n <span class=\"sd-audit-diff__field\">{{ row.label }}</span>\n <span class=\"sd-audit-diff__kind\">{{ text('kind.' + row.kind) }}</span>\n </dt>\n <dd data-audit-before>\n <span class=\"sd-audit-diff__side-label\">{{ text('before') }}</span>\n @if (customValue) {\n <ng-container [ngTemplateOutlet]=\"customValue.template\" [ngTemplateOutletContext]=\"valueContext(row, 'before')\"></ng-container>\n } @else {\n <span>{{ displayValue(row, 'before') }}</span>\n }\n </dd>\n <dd data-audit-after>\n <span class=\"sd-audit-diff__side-label\">{{ text('after') }}</span>\n @if (customValue) {\n <ng-container [ngTemplateOutlet]=\"customValue.template\" [ngTemplateOutletContext]=\"valueContext(row, 'after')\"></ng-container>\n } @else {\n <span>{{ displayValue(row, 'after') }}</span>\n }\n </dd>\n </div>\n }\n </dl>\n}\n", styles: [":host{display:block}.sd-audit-diff__table-scroll{overflow-x:auto;border:1px solid var(--sd-border-color, #dfe3e8);border-radius:8px}.sd-audit-diff__table{width:100%;border-collapse:collapse;background:var(--sd-surface, #fff)}.sd-audit-diff__table th,.sd-audit-diff__table td{min-width:160px;padding:10px 12px;border-bottom:1px solid var(--sd-border-color, #dfe3e8);text-align:left;vertical-align:top;overflow-wrap:anywhere}.sd-audit-diff__table th:first-child{min-width:180px}.sd-audit-diff__table tbody tr:last-child>*{border-bottom:0}.sd-audit-diff__field,.sd-audit-diff__kind,.sd-audit-diff__side-label{display:block}.sd-audit-diff__kind,.sd-audit-diff__side-label{margin-top:2px;color:var(--sd-text-muted, #5f6772);font-size:.75rem;font-weight:400}.sd-audit-diff__details{display:grid;gap:12px;margin:0}.sd-audit-diff__detail{display:grid;grid-template-columns:minmax(140px,.8fr) repeat(2,minmax(0,1fr));gap:12px;padding:12px;border:1px solid var(--sd-border-color, #dfe3e8);border-radius:8px;background:var(--sd-surface, #fff)}.sd-audit-diff__detail dt,.sd-audit-diff__detail dd{min-width:0;margin:0;overflow-wrap:anywhere}.sd-audit-diff__empty{margin:0;padding:16px;border:1px dashed var(--sd-border-color, #dfe3e8);border-radius:8px;color:var(--sd-text-muted, #5f6772);text-align:center}@media(max-width:640px){.sd-audit-diff__detail{grid-template-columns:1fr}}\n"] }]
|
|
308
|
+
}] });
|
|
309
|
+
function safeStringify(value) {
|
|
310
|
+
const seen = new WeakSet();
|
|
311
|
+
try {
|
|
312
|
+
const result = JSON.stringify(value, (_key, current) => {
|
|
313
|
+
if (typeof current !== 'object' || current === null)
|
|
314
|
+
return current;
|
|
315
|
+
if (seen.has(current))
|
|
316
|
+
return '[Circular]';
|
|
317
|
+
seen.add(current);
|
|
318
|
+
return current;
|
|
319
|
+
});
|
|
320
|
+
return result ?? String(value);
|
|
321
|
+
}
|
|
322
|
+
catch {
|
|
323
|
+
return String(value);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Generated bundle index. Do not edit.
|
|
329
|
+
*/
|
|
330
|
+
|
|
331
|
+
export { SdAuditDiff, SdAuditDiffValueTemplateDirective, sdBuildAuditDiff };
|
|
332
|
+
//# sourceMappingURL=sdcorejs-angular-components-audit-diff.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdcorejs-angular-components-audit-diff.mjs","sources":["../../../projects/sdcorejs-angular/components/audit-diff/src/audit-diff.engine.ts","../../../projects/sdcorejs-angular/components/audit-diff/src/audit-diff.component.ts","../../../projects/sdcorejs-angular/components/audit-diff/src/audit-diff.component.html","../../../projects/sdcorejs-angular/components/audit-diff/sdcorejs-angular-components-audit-diff.ts"],"sourcesContent":["export type SdAuditDiffKind = 'added' | 'removed' | 'changed' | 'unchanged';\nexport type SdAuditDiffSide = 'before' | 'after';\nexport type SdAuditDiffArrayKey = string | ((item: unknown) => unknown);\n\nexport interface SdAuditDiffFormatContext {\n readonly path: string;\n readonly configPath: string;\n readonly side: SdAuditDiffSide;\n readonly kind: SdAuditDiffKind;\n readonly before: unknown;\n readonly after: unknown;\n}\n\nexport interface SdAuditDiffField {\n readonly path: string;\n readonly label?: string;\n readonly order?: number;\n readonly hidden?: boolean;\n readonly redacted?: boolean;\n readonly arrayKey?: SdAuditDiffArrayKey;\n readonly enumMap?: Readonly<Record<string, unknown>>;\n readonly format?: (value: unknown, context: SdAuditDiffFormatContext) => unknown;\n}\n\nexport interface SdAuditDiffOptions {\n readonly fields?: readonly SdAuditDiffField[];\n readonly includeUnchanged?: boolean;\n readonly redactedValue?: unknown;\n readonly rootLabel?: string;\n}\n\nexport interface SdAuditDiffRow {\n readonly id: string;\n readonly path: string;\n readonly configPath: string;\n readonly label: string;\n readonly kind: SdAuditDiffKind;\n readonly before: unknown;\n readonly after: unknown;\n readonly beforePresent: boolean;\n readonly afterPresent: boolean;\n readonly redacted: boolean;\n}\n\ninterface WalkContext {\n readonly options: SdAuditDiffOptions;\n readonly fields: readonly SdAuditDiffField[];\n readonly rows: SdAuditDiffRow[];\n readonly activeBefore: WeakSet<object>;\n readonly activeAfter: WeakSet<object>;\n}\n\ninterface StableArrayItem {\n readonly key: unknown;\n readonly value: unknown;\n}\n\nconst DEFAULT_REDACTED_VALUE = '••••••';\n\nexport function sdBuildAuditDiff(before: unknown, after: unknown, options: SdAuditDiffOptions = {}): SdAuditDiffRow[] {\n const context: WalkContext = {\n options,\n fields: options.fields ?? [],\n rows: [],\n activeBefore: new WeakSet<object>(),\n activeAfter: new WeakSet<object>(),\n };\n walkValue(context, before, after, true, true, '$', '$');\n return context.rows.sort((left, right) => compareRows(left, right, context.fields));\n}\n\nfunction walkValue(\n context: WalkContext,\n before: unknown,\n after: unknown,\n beforePresent: boolean,\n afterPresent: boolean,\n path: string,\n configPath: string\n): void {\n if (isConfigured(context.fields, configPath, 'hidden')) return;\n if (isConfigured(context.fields, configPath, 'redacted')) {\n addAtomicRow(context, before, after, beforePresent, afterPresent, path, configPath, true);\n return;\n }\n\n const field = findExactField(context.fields, configPath);\n if (field?.format || field?.enumMap) {\n addAtomicRow(context, before, after, beforePresent, afterPresent, path, configPath, false);\n return;\n }\n\n const beforeArray = Array.isArray(before);\n const afterArray = Array.isArray(after);\n if (beforeArray || afterArray) {\n if ((!beforePresent && afterArray) || (beforeArray && !afterPresent) || (beforeArray && afterArray)) {\n const arrayKey = field?.arrayKey;\n if (arrayKey && walkStableArray(context, beforeArray ? before : [], afterArray ? after : [], path, configPath, arrayKey)) return;\n }\n addAtomicRow(context, before, after, beforePresent, afterPresent, path, configPath, false);\n return;\n }\n\n const beforeObject = isPlainObject(before);\n const afterObject = isPlainObject(after);\n const canRecurse = (beforeObject && afterObject) || (beforeObject && !afterPresent) || (afterObject && !beforePresent);\n if (canRecurse) {\n if ((beforeObject && context.activeBefore.has(before)) || (afterObject && context.activeAfter.has(after))) return;\n if (beforeObject) context.activeBefore.add(before);\n if (afterObject) context.activeAfter.add(after);\n const beforeRecord = beforeObject ? before : {};\n const afterRecord = afterObject ? after : {};\n const keys = [...new Set([...Object.keys(beforeRecord), ...Object.keys(afterRecord)])].sort(compareText);\n if (keys.length === 0) {\n addAtomicRow(context, before, after, beforePresent, afterPresent, path, configPath, false);\n if (beforeObject) context.activeBefore.delete(before);\n if (afterObject) context.activeAfter.delete(after);\n return;\n }\n for (const key of keys) {\n const childBeforePresent = beforeObject && hasOwn(beforeRecord, key);\n const childAfterPresent = afterObject && hasOwn(afterRecord, key);\n walkValue(\n context,\n childBeforePresent ? beforeRecord[key] : undefined,\n childAfterPresent ? afterRecord[key] : undefined,\n childBeforePresent,\n childAfterPresent,\n path === '$' ? key : `${path}.${key}`,\n configPath === '$' ? key : `${configPath}.${key}`\n );\n }\n if (beforeObject) context.activeBefore.delete(before);\n if (afterObject) context.activeAfter.delete(after);\n return;\n }\n\n addAtomicRow(context, before, after, beforePresent, afterPresent, path, configPath, false);\n}\n\nfunction walkStableArray(\n context: WalkContext,\n before: readonly unknown[],\n after: readonly unknown[],\n path: string,\n configPath: string,\n keySelector: SdAuditDiffArrayKey\n): boolean {\n const beforeItems = indexStableArray(before, keySelector);\n const afterItems = indexStableArray(after, keySelector);\n if (!beforeItems || !afterItems) return false;\n\n const keys = [...new Set([...beforeItems.keys(), ...afterItems.keys()])].sort(compareText);\n const keyName = typeof keySelector === 'string' ? keySelector : 'key';\n for (const key of keys) {\n const beforeItem = beforeItems.get(key);\n const afterItem = afterItems.get(key);\n const itemPath = `${path}[${keyName}=${encodeURIComponent(key)}]`;\n const itemConfigPath = `${configPath}[]`;\n if (!beforeItem || !afterItem) {\n walkValue(context, beforeItem?.value, afterItem?.value, Boolean(beforeItem), Boolean(afterItem), itemPath, itemConfigPath);\n continue;\n }\n walkValue(context, beforeItem.value, afterItem.value, true, true, itemPath, itemConfigPath);\n }\n return true;\n}\n\nfunction indexStableArray(items: readonly unknown[], keySelector: SdAuditDiffArrayKey): Map<string, StableArrayItem> | null {\n const result = new Map<string, StableArrayItem>();\n for (const item of items) {\n let key: unknown;\n try {\n key = typeof keySelector === 'function' ? keySelector(item) : isObject(item) ? item[keySelector] : undefined;\n } catch {\n return null;\n }\n const serialized = serializeStableKey(key);\n if (serialized === null || result.has(serialized)) return null;\n result.set(serialized, { key, value: item });\n }\n return result;\n}\n\nfunction serializeStableKey(key: unknown): string | null {\n if (key === null) return 'null:null';\n switch (typeof key) {\n case 'string':\n case 'number':\n case 'bigint':\n case 'boolean':\n return `${typeof key}:${String(key)}`;\n default:\n return null;\n }\n}\n\nfunction addAtomicRow(\n context: WalkContext,\n before: unknown,\n after: unknown,\n beforePresent: boolean,\n afterPresent: boolean,\n path: string,\n configPath: string,\n redacted: boolean\n): void {\n const kind = classifyChange(before, after, beforePresent, afterPresent);\n if (kind === 'unchanged' && !context.options.includeUnchanged) return;\n\n const field = findExactField(context.fields, configPath);\n const redactedValue = context.options.redactedValue ?? DEFAULT_REDACTED_VALUE;\n const normalizedBefore = redacted\n ? beforePresent\n ? redactedValue\n : undefined\n : normalizeValue(before, beforePresent, 'before', kind, path, configPath, field, after);\n const normalizedAfter = redacted\n ? afterPresent\n ? redactedValue\n : undefined\n : normalizeValue(after, afterPresent, 'after', kind, path, configPath, field, before);\n\n context.rows.push({\n id: path,\n path,\n configPath,\n label: field?.label ?? (path === '$' ? (context.options.rootLabel ?? 'Value') : path),\n kind,\n before: normalizedBefore,\n after: normalizedAfter,\n beforePresent,\n afterPresent,\n redacted,\n });\n}\n\nfunction normalizeValue(\n value: unknown,\n present: boolean,\n side: SdAuditDiffSide,\n kind: SdAuditDiffKind,\n path: string,\n configPath: string,\n field: SdAuditDiffField | undefined,\n otherValue: unknown\n): unknown {\n if (!present) return undefined;\n const mapped = field?.enumMap && hasOwn(field.enumMap, String(value)) ? field.enumMap[String(value)] : value;\n if (!field?.format) return mapped;\n try {\n return field.format(mapped, {\n path,\n configPath,\n side,\n kind,\n before: side === 'before' ? value : otherValue,\n after: side === 'after' ? value : otherValue,\n });\n } catch {\n return mapped;\n }\n}\n\nfunction classifyChange(before: unknown, after: unknown, beforePresent: boolean, afterPresent: boolean): SdAuditDiffKind {\n if (!beforePresent && afterPresent) return 'added';\n if (beforePresent && !afterPresent) return 'removed';\n return deepEqual(before, after) ? 'unchanged' : 'changed';\n}\n\nfunction deepEqual(left: unknown, right: unknown, seen = new WeakMap<object, WeakSet<object>>()): boolean {\n if (Object.is(left, right)) return true;\n if (left instanceof Date && right instanceof Date) return left.getTime() === right.getTime();\n if (!isObject(left) || !isObject(right)) return false;\n let rightSet = seen.get(left);\n if (rightSet?.has(right)) return true;\n if (!rightSet) {\n rightSet = new WeakSet<object>();\n seen.set(left, rightSet);\n }\n rightSet.add(right);\n if (Array.isArray(left) && Array.isArray(right)) {\n if (left.length !== right.length) return false;\n return left.every((value, index) => deepEqual(value, right[index], seen));\n }\n if (!isPlainObject(left) || !isPlainObject(right)) return false;\n const leftKeys = Object.keys(left).sort(compareText);\n const rightKeys = Object.keys(right).sort(compareText);\n if (leftKeys.length !== rightKeys.length || leftKeys.some((key, index) => key !== rightKeys[index])) return false;\n return leftKeys.every(key => deepEqual(left[key], right[key], seen));\n}\n\nfunction compareRows(left: SdAuditDiffRow, right: SdAuditDiffRow, fields: readonly SdAuditDiffField[]): number {\n const leftOrder = explicitOrder(left.configPath, fields);\n const rightOrder = explicitOrder(right.configPath, fields);\n if (leftOrder !== rightOrder) return leftOrder - rightOrder;\n return compareText(left.path, right.path);\n}\n\nfunction explicitOrder(path: string, fields: readonly SdAuditDiffField[]): number {\n const field = fields\n .filter(candidate => Number.isFinite(candidate.order) && isPathOrDescendant(path, candidate.path))\n .sort((left, right) => right.path.length - left.path.length)[0];\n return field?.order ?? Number.POSITIVE_INFINITY;\n}\n\nfunction findExactField(fields: readonly SdAuditDiffField[], path: string): SdAuditDiffField | undefined {\n return fields.find(field => field.path === path);\n}\n\nfunction isConfigured(fields: readonly SdAuditDiffField[], path: string, property: 'hidden' | 'redacted'): boolean {\n return fields.some(field => Boolean(field[property]) && isPathOrDescendant(path, field.path));\n}\n\nfunction isPathOrDescendant(path: string, ancestor: string): boolean {\n return path === ancestor || path.startsWith(`${ancestor}.`) || path.startsWith(`${ancestor}[]`);\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (!isObject(value)) return false;\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n\nfunction hasOwn(object: object, key: PropertyKey): boolean {\n return Object.prototype.hasOwnProperty.call(object, key);\n}\n\nfunction compareText(left: string, right: string): number {\n return left < right ? -1 : left > right ? 1 : 0;\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, Directive, TemplateRef, computed, contentChild, inject, input } from '@angular/core';\nimport { I18nService } from '@sdcorejs/angular/i18n';\nimport { SdAuditDiffOptions, SdAuditDiffRow, SdAuditDiffSide, sdBuildAuditDiff } from './audit-diff.engine';\n\nexport type SdAuditDiffMode = 'table' | 'detail-list';\n\nexport interface SdAuditDiffValueTemplateContext {\n readonly $implicit: unknown;\n readonly row: SdAuditDiffRow;\n readonly side: SdAuditDiffSide;\n}\n\n@Directive({\n selector: 'ng-template[sdAuditDiffValue]',\n standalone: true,\n})\nexport class SdAuditDiffValueTemplateDirective {\n readonly template = inject<TemplateRef<SdAuditDiffValueTemplateContext>>(TemplateRef);\n\n static ngTemplateContextGuard(\n _directive: SdAuditDiffValueTemplateDirective,\n _context: unknown\n ): _context is SdAuditDiffValueTemplateContext {\n return true;\n }\n}\n\n@Component({\n selector: 'sd-audit-diff',\n standalone: true,\n imports: [NgTemplateOutlet],\n templateUrl: './audit-diff.component.html',\n styleUrl: './audit-diff.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class SdAuditDiff {\n readonly before = input<unknown>(undefined);\n readonly after = input<unknown>(undefined);\n readonly options = input<SdAuditDiffOptions>({});\n readonly mode = input<SdAuditDiffMode>('table');\n readonly ariaLabel = input<string | undefined>(undefined);\n\n readonly #i18n = inject(I18nService);\n readonly rows = computed(() => {\n const options = this.options();\n return sdBuildAuditDiff(this.before(), this.after(), {\n ...options,\n rootLabel: options.rootLabel ?? this.text('value.label'),\n });\n });\n protected readonly valueTemplate = contentChild(SdAuditDiffValueTemplateDirective);\n\n protected text(key: string): string {\n return this.#i18n.t(`core.component.audit-diff.${key}`);\n }\n\n protected valueContext(row: SdAuditDiffRow, side: SdAuditDiffSide): SdAuditDiffValueTemplateContext {\n return { $implicit: row[side], row, side };\n }\n\n protected displayValue(row: SdAuditDiffRow, side: SdAuditDiffSide): string {\n const present = side === 'before' ? row.beforePresent : row.afterPresent;\n if (!present) return this.text('value.not-set');\n const value = row[side];\n if (value === undefined) return this.text('value.undefined');\n if (value === null) return this.text('value.null');\n if (value instanceof Date) return value.toISOString();\n if (typeof value === 'boolean') return this.text(`value.${value ? 'true' : 'false'}`);\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'bigint') return String(value);\n return safeStringify(value);\n }\n}\n\nfunction safeStringify(value: unknown): string {\n const seen = new WeakSet<object>();\n try {\n const result = JSON.stringify(value, (_key, current: unknown) => {\n if (typeof current !== 'object' || current === null) return current;\n if (seen.has(current)) return '[Circular]';\n seen.add(current);\n return current;\n });\n return result ?? String(value);\n } catch {\n return String(value);\n }\n}\n","@let currentRows = rows();\n@let customValue = valueTemplate();\n\n@if (currentRows.length === 0) {\n <p class=\"sd-audit-diff__empty\" data-audit-empty role=\"status\">{{ text('empty') }}</p>\n} @else if (mode() === 'table') {\n <div class=\"sd-audit-diff__table-scroll\">\n <table class=\"sd-audit-diff__table\" [attr.aria-label]=\"ariaLabel() || text('label')\">\n <thead>\n <tr>\n <th scope=\"col\">{{ text('field') }}</th>\n <th scope=\"col\">{{ text('before') }}</th>\n <th scope=\"col\">{{ text('after') }}</th>\n </tr>\n </thead>\n <tbody>\n @for (row of currentRows; track row.id) {\n <tr data-audit-row [attr.data-change-kind]=\"row.kind\">\n <th scope=\"row\">\n <span class=\"sd-audit-diff__field\">{{ row.label }}</span>\n <span class=\"sd-audit-diff__kind\">{{ text('kind.' + row.kind) }}</span>\n </th>\n <td data-audit-before>\n @if (customValue) {\n <ng-container\n [ngTemplateOutlet]=\"customValue.template\"\n [ngTemplateOutletContext]=\"valueContext(row, 'before')\"></ng-container>\n } @else {\n {{ displayValue(row, 'before') }}\n }\n </td>\n <td data-audit-after>\n @if (customValue) {\n <ng-container\n [ngTemplateOutlet]=\"customValue.template\"\n [ngTemplateOutletContext]=\"valueContext(row, 'after')\"></ng-container>\n } @else {\n {{ displayValue(row, 'after') }}\n }\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n} @else {\n <dl class=\"sd-audit-diff__details\" [attr.aria-label]=\"ariaLabel() || text('label')\">\n @for (row of currentRows; track row.id) {\n <div class=\"sd-audit-diff__detail\" data-audit-row [attr.data-change-kind]=\"row.kind\">\n <dt>\n <span class=\"sd-audit-diff__field\">{{ row.label }}</span>\n <span class=\"sd-audit-diff__kind\">{{ text('kind.' + row.kind) }}</span>\n </dt>\n <dd data-audit-before>\n <span class=\"sd-audit-diff__side-label\">{{ text('before') }}</span>\n @if (customValue) {\n <ng-container [ngTemplateOutlet]=\"customValue.template\" [ngTemplateOutletContext]=\"valueContext(row, 'before')\"></ng-container>\n } @else {\n <span>{{ displayValue(row, 'before') }}</span>\n }\n </dd>\n <dd data-audit-after>\n <span class=\"sd-audit-diff__side-label\">{{ text('after') }}</span>\n @if (customValue) {\n <ng-container [ngTemplateOutlet]=\"customValue.template\" [ngTemplateOutletContext]=\"valueContext(row, 'after')\"></ng-container>\n } @else {\n <span>{{ displayValue(row, 'after') }}</span>\n }\n </dd>\n </div>\n }\n </dl>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -36,6 +36,7 @@ class SdBadge {
|
|
|
36
36
|
// ==========================================
|
|
37
37
|
// 2. OUTPUT
|
|
38
38
|
// ==========================================
|
|
39
|
+
// why: the template reads EventEmitter.observed to expose pointer styling only when a click listener exists.
|
|
39
40
|
click = new EventEmitter();
|
|
40
41
|
onClick = (event) => {
|
|
41
42
|
event.stopPropagation();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdcorejs-angular-components-badge.mjs","sources":["../../../projects/sdcorejs-angular/components/badge/src/badge.component.ts","../../../projects/sdcorejs-angular/components/badge/src/badge.component.html","../../../projects/sdcorejs-angular/components/badge/sdcorejs-angular-components-badge.ts"],"sourcesContent":["import { CommonModule } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, EventEmitter, Output, booleanAttribute, computed, input } from '@angular/core';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport { SdIcon, type SdIconSet } from '@sdcorejs/angular/modules/icon';\nimport { Color, Size } from '@sdcorejs/utils/models';\n\n// Export các Type để dùng chung\nexport type SdBadgeType = 'tag' | 'round' | 'icon';\n\n@Component({\n selector: 'sd-badge',\n templateUrl: './badge.component.html',\n styleUrl: './badge.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [CommonModule, SdIcon, MatTooltipModule],\n})\nexport class SdBadge {\n defaultIcon = 'fiber_manual_record';\n\n // ==========================================\n // 1. SIGNAL INPUTS\n // ==========================================\n type = input<SdBadgeType, SdBadgeType | undefined | null>('icon', {\n transform: value => value || 'icon',\n });\n\n color = input<Color, Color | undefined | null>('secondary', {\n transform: value => value || 'secondary',\n });\n\n primary = input(false, { transform: booleanAttribute });\n secondary = input(false, { transform: booleanAttribute });\n success = input(false, { transform: booleanAttribute });\n info = input(false, { transform: booleanAttribute });\n warning = input(false, { transform: booleanAttribute });\n error = input(false, { transform: booleanAttribute });\n\n fontSet = input<SdIconSet | undefined, SdIconSet | undefined | null>(undefined, {\n transform: value => value ?? undefined,\n });\n\n title = input<string | number | undefined | null>();\n description = input<string | undefined | null>();\n tooltip = input<string | undefined | null>();\n icon = input<string | undefined | null>();\n\n size = input<Size, Size | undefined | null>('sm', {\n transform: value => value || 'sm',\n });\n\n // ==========================================\n // 2. OUTPUT\n // ==========================================\n @Output() click = new EventEmitter<Event>();\n\n onClick = (event: Event) => {\n event.stopPropagation();\n this.click.emit(event);\n };\n\n // ==========================================\n // 3. COMPUTED STATE\n // ==========================================\n\n effectiveColor = computed(() => {\n if (this.primary()) return 'primary';\n if (this.secondary()) return 'secondary';\n if (this.success()) return 'success';\n if (this.info()) return 'info';\n if (this.warning()) return 'warning';\n if (this.error()) return 'error';\n return this.color();\n });\n\n baseColorClasses = computed(() => {\n const c = this.effectiveColor();\n return {\n 'c-primary': c === 'primary',\n 'c-secondary': c === 'secondary',\n 'c-info': c === 'info',\n 'c-success': c === 'success',\n 'c-warning': c === 'warning',\n 'c-error': c === 'error',\n };\n });\n\n iconColorClasses = computed(() => {\n const c = this.effectiveColor();\n return {\n 'c-primary': c === 'primary',\n 'c-secondary': c === 'secondary',\n 'c-info': c === 'info',\n 'c-success': c === 'success',\n 'c-warning': c === 'warning',\n 'c-error': c === 'error',\n };\n });\n\n iconSizeAndFontClasses = computed(() => {\n const s = this.size();\n return {\n 'c-sm': s === 'sm',\n 'c-md': s === 'md',\n 'c-lg': s === 'lg',\n };\n });\n\n iconCssSize = computed(() => {\n const s = this.size();\n if (s === 'md') return '18px';\n if (s === 'lg') return '24px';\n return '16px';\n });\n\n // why: keep container size classes separate from icon element size classes.\n containerSizeClasses = computed(() => {\n const s = this.size();\n return {\n 'c-badge--sm': s === 'sm',\n 'c-badge--md': s === 'md',\n 'c-badge--lg': s === 'lg',\n };\n });\n\n // GỘP CLASS CHO BADGE TYPE = 'TAG' (cũng dùng lại cho 'ROUND' khi có icon)\n tagIconCombinedClasses = computed(() => ({\n ...this.iconSizeAndFontClasses(),\n ...this.baseColorClasses(),\n }));\n\n // GỘP CLASS CHO CONTAINER round/tag (color tint + size modifier)\n containerCombinedClasses = computed(() => ({\n ...this.baseColorClasses(),\n ...this.containerSizeClasses(),\n }));\n\n // GỘP CLASS CHO BADGE TYPE = 'ICON'\n iconCombinedClasses = computed(() => ({\n ...this.iconSizeAndFontClasses(),\n ...this.iconColorClasses(),\n }));\n}\n","@let _type = type();\n@let _tooltip = tooltip();\n@let _title = title();\n@let _description = description();\n@let _fontSet = fontSet();\n@let _iconCssSize = iconCssSize();\n@let iconName = icon() || defaultIcon;\n@let isPointer = click.observed;\n\n@if (_type === 'round') {\n <div\n class=\"c-badge\"\n matTooltipPosition=\"above\"\n [matTooltip]=\"_tooltip || ''\"\n matTooltipClass=\"sd-multiline-tooltip\"\n [ngClass]=\"containerCombinedClasses()\"\n [class.c-badge--has-icon]=\"!!icon()\"\n [class.pointer]=\"isPointer\"\n (click)=\"onClick($event)\"\n aria-hidden=\"true\">\n @if (icon()) {\n <sd-icon\n class=\"c-material-icon\"\n [name]=\"iconName\"\n [fontSet]=\"_fontSet\"\n [size]=\"_iconCssSize\"\n [ngClass]=\"tagIconCombinedClasses()\"></sd-icon>\n }\n <span class=\"c-badge-title\">{{ _title }}</span>\n </div>\n} @else if (_type === 'tag') {\n <div\n class=\"c-badge c-badge--tag\"\n matTooltipPosition=\"above\"\n [matTooltip]=\"_tooltip || ''\"\n matTooltipClass=\"sd-multiline-tooltip\"\n [ngClass]=\"containerCombinedClasses()\"\n [class.pointer]=\"isPointer\"\n (click)=\"onClick($event)\"\n aria-hidden=\"true\">\n <div class=\"c-icon d-flex align-items-center\">\n @if (icon()) {\n <sd-icon\n class=\"c-material-icon mr-4\"\n [name]=\"iconName\"\n [fontSet]=\"_fontSet\"\n [size]=\"_iconCssSize\"\n [ngClass]=\"tagIconCombinedClasses()\"></sd-icon>\n }\n <div class=\"d-flex flex-column align-items-start\">\n <span class=\"T14R c-badge-title\">{{ _title }}</span>\n @if (_description) {\n <span class=\"T12R c-badge-description\">{{ _description }}</span>\n }\n </div>\n </div>\n </div>\n} @else {\n <div\n class=\"d-flex\"\n matTooltipPosition=\"above\"\n [matTooltip]=\"_tooltip || ''\"\n matTooltipClass=\"sd-multiline-tooltip\"\n [class.c-badge-icon]=\"_type === 'icon'\"\n [class.pointer]=\"isPointer\"\n (click)=\"onClick($event)\"\n aria-hidden=\"true\">\n <div class=\"c-icon d-flex align-items-center\">\n <sd-icon\n class=\"c-material-icon mr-4\"\n [name]=\"iconName\"\n [fontSet]=\"_fontSet\"\n [size]=\"_iconCssSize\"\n [ngClass]=\"iconCombinedClasses()\"></sd-icon>\n <div class=\"d-flex flex-column\">\n <span class=\"T14R c-badge-title\">{{ _title }}</span>\n @if (_description) {\n <span class=\"T10R c-badge-description\">{{ _description }}</span>\n }\n </div>\n </div>\n </div>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sdcorejs-angular-components-badge.mjs","sources":["../../../projects/sdcorejs-angular/components/badge/src/badge.component.ts","../../../projects/sdcorejs-angular/components/badge/src/badge.component.html","../../../projects/sdcorejs-angular/components/badge/sdcorejs-angular-components-badge.ts"],"sourcesContent":["import { CommonModule } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, EventEmitter, Output, booleanAttribute, computed, input } from '@angular/core';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport { SdIcon, type SdIconSet } from '@sdcorejs/angular/modules/icon';\nimport { Color, Size } from '@sdcorejs/utils/models';\n\n// Export các Type để dùng chung\nexport type SdBadgeType = 'tag' | 'round' | 'icon';\n\n@Component({\n selector: 'sd-badge',\n templateUrl: './badge.component.html',\n styleUrl: './badge.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [CommonModule, SdIcon, MatTooltipModule],\n})\nexport class SdBadge {\n defaultIcon = 'fiber_manual_record';\n\n // ==========================================\n // 1. SIGNAL INPUTS\n // ==========================================\n type = input<SdBadgeType, SdBadgeType | undefined | null>('icon', {\n transform: value => value || 'icon',\n });\n\n color = input<Color, Color | undefined | null>('secondary', {\n transform: value => value || 'secondary',\n });\n\n primary = input(false, { transform: booleanAttribute });\n secondary = input(false, { transform: booleanAttribute });\n success = input(false, { transform: booleanAttribute });\n info = input(false, { transform: booleanAttribute });\n warning = input(false, { transform: booleanAttribute });\n error = input(false, { transform: booleanAttribute });\n\n fontSet = input<SdIconSet | undefined, SdIconSet | undefined | null>(undefined, {\n transform: value => value ?? undefined,\n });\n\n title = input<string | number | undefined | null>();\n description = input<string | undefined | null>();\n tooltip = input<string | undefined | null>();\n icon = input<string | undefined | null>();\n\n size = input<Size, Size | undefined | null>('sm', {\n transform: value => value || 'sm',\n });\n\n // ==========================================\n // 2. OUTPUT\n // ==========================================\n // why: the template reads EventEmitter.observed to expose pointer styling only when a click listener exists.\n @Output() readonly click = new EventEmitter<Event>();\n\n onClick = (event: Event) => {\n event.stopPropagation();\n this.click.emit(event);\n };\n\n // ==========================================\n // 3. COMPUTED STATE\n // ==========================================\n\n effectiveColor = computed(() => {\n if (this.primary()) return 'primary';\n if (this.secondary()) return 'secondary';\n if (this.success()) return 'success';\n if (this.info()) return 'info';\n if (this.warning()) return 'warning';\n if (this.error()) return 'error';\n return this.color();\n });\n\n baseColorClasses = computed(() => {\n const c = this.effectiveColor();\n return {\n 'c-primary': c === 'primary',\n 'c-secondary': c === 'secondary',\n 'c-info': c === 'info',\n 'c-success': c === 'success',\n 'c-warning': c === 'warning',\n 'c-error': c === 'error',\n };\n });\n\n iconColorClasses = computed(() => {\n const c = this.effectiveColor();\n return {\n 'c-primary': c === 'primary',\n 'c-secondary': c === 'secondary',\n 'c-info': c === 'info',\n 'c-success': c === 'success',\n 'c-warning': c === 'warning',\n 'c-error': c === 'error',\n };\n });\n\n iconSizeAndFontClasses = computed(() => {\n const s = this.size();\n return {\n 'c-sm': s === 'sm',\n 'c-md': s === 'md',\n 'c-lg': s === 'lg',\n };\n });\n\n iconCssSize = computed(() => {\n const s = this.size();\n if (s === 'md') return '18px';\n if (s === 'lg') return '24px';\n return '16px';\n });\n\n // why: keep container size classes separate from icon element size classes.\n containerSizeClasses = computed(() => {\n const s = this.size();\n return {\n 'c-badge--sm': s === 'sm',\n 'c-badge--md': s === 'md',\n 'c-badge--lg': s === 'lg',\n };\n });\n\n // GỘP CLASS CHO BADGE TYPE = 'TAG' (cũng dùng lại cho 'ROUND' khi có icon)\n tagIconCombinedClasses = computed(() => ({\n ...this.iconSizeAndFontClasses(),\n ...this.baseColorClasses(),\n }));\n\n // GỘP CLASS CHO CONTAINER round/tag (color tint + size modifier)\n containerCombinedClasses = computed(() => ({\n ...this.baseColorClasses(),\n ...this.containerSizeClasses(),\n }));\n\n // GỘP CLASS CHO BADGE TYPE = 'ICON'\n iconCombinedClasses = computed(() => ({\n ...this.iconSizeAndFontClasses(),\n ...this.iconColorClasses(),\n }));\n}\n","@let _type = type();\n@let _tooltip = tooltip();\n@let _title = title();\n@let _description = description();\n@let _fontSet = fontSet();\n@let _iconCssSize = iconCssSize();\n@let iconName = icon() || defaultIcon;\n@let isPointer = click.observed;\n\n@if (_type === 'round') {\n <div\n class=\"c-badge\"\n matTooltipPosition=\"above\"\n [matTooltip]=\"_tooltip || ''\"\n matTooltipClass=\"sd-multiline-tooltip\"\n [ngClass]=\"containerCombinedClasses()\"\n [class.c-badge--has-icon]=\"!!icon()\"\n [class.pointer]=\"isPointer\"\n (click)=\"onClick($event)\"\n aria-hidden=\"true\">\n @if (icon()) {\n <sd-icon\n class=\"c-material-icon\"\n [name]=\"iconName\"\n [fontSet]=\"_fontSet\"\n [size]=\"_iconCssSize\"\n [ngClass]=\"tagIconCombinedClasses()\"></sd-icon>\n }\n <span class=\"c-badge-title\">{{ _title }}</span>\n </div>\n} @else if (_type === 'tag') {\n <div\n class=\"c-badge c-badge--tag\"\n matTooltipPosition=\"above\"\n [matTooltip]=\"_tooltip || ''\"\n matTooltipClass=\"sd-multiline-tooltip\"\n [ngClass]=\"containerCombinedClasses()\"\n [class.pointer]=\"isPointer\"\n (click)=\"onClick($event)\"\n aria-hidden=\"true\">\n <div class=\"c-icon d-flex align-items-center\">\n @if (icon()) {\n <sd-icon\n class=\"c-material-icon mr-4\"\n [name]=\"iconName\"\n [fontSet]=\"_fontSet\"\n [size]=\"_iconCssSize\"\n [ngClass]=\"tagIconCombinedClasses()\"></sd-icon>\n }\n <div class=\"d-flex flex-column align-items-start\">\n <span class=\"T14R c-badge-title\">{{ _title }}</span>\n @if (_description) {\n <span class=\"T12R c-badge-description\">{{ _description }}</span>\n }\n </div>\n </div>\n </div>\n} @else {\n <div\n class=\"d-flex\"\n matTooltipPosition=\"above\"\n [matTooltip]=\"_tooltip || ''\"\n matTooltipClass=\"sd-multiline-tooltip\"\n [class.c-badge-icon]=\"_type === 'icon'\"\n [class.pointer]=\"isPointer\"\n (click)=\"onClick($event)\"\n aria-hidden=\"true\">\n <div class=\"c-icon d-flex align-items-center\">\n <sd-icon\n class=\"c-material-icon mr-4\"\n [name]=\"iconName\"\n [fontSet]=\"_fontSet\"\n [size]=\"_iconCssSize\"\n [ngClass]=\"iconCombinedClasses()\"></sd-icon>\n <div class=\"d-flex flex-column\">\n <span class=\"T14R c-badge-title\">{{ _title }}</span>\n @if (_description) {\n <span class=\"T10R c-badge-description\">{{ _description }}</span>\n }\n </div>\n </div>\n </div>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|