@masterteam/components 0.0.108 → 0.0.110
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/assets/common.css +1 -1
- package/assets/i18n/ar.json +38 -28
- package/assets/i18n/en.json +10 -0
- package/fesm2022/masterteam-components-business-fields.mjs +260 -3
- package/fesm2022/masterteam-components-business-fields.mjs.map +1 -1
- package/fesm2022/masterteam-components-entities.mjs +2 -2
- package/fesm2022/masterteam-components-entities.mjs.map +1 -1
- package/fesm2022/masterteam-components-slider-field.mjs +2 -2
- package/fesm2022/masterteam-components-slider-field.mjs.map +1 -1
- package/fesm2022/masterteam-components.mjs +10 -1
- package/fesm2022/masterteam-components.mjs.map +1 -1
- package/package.json +1 -1
- package/types/masterteam-components-business-fields.d.ts +73 -1
- package/types/masterteam-components.d.ts +16 -3
- package/.codex-tmp-pack/extract/package/README.md +0 -63
- package/.codex-tmp-pack/extract/package/assets/cairo.css +0 -70
- package/.codex-tmp-pack/extract/package/assets/common.css +0 -2
- package/.codex-tmp-pack/extract/package/assets/fonts/Cairo-Black.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/Cairo-Bold.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/Cairo-ExtraBold.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/Cairo-ExtraLight.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/Cairo-Light.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/Cairo-Medium.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/Cairo-Regular.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/Cairo-SemiBold.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/Cairo-VariableFont_slnt,wght.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/Inter-Black.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/Inter-BlackItalic.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/Inter-Bold.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/Inter-BoldItalic.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/Inter-ExtraBold.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/Inter-ExtraBoldItalic.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/Inter-ExtraLight.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/Inter-ExtraLightItalic.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/Inter-Italic.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/Inter-Light.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/Inter-LightItalic.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/Inter-Medium.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/Inter-MediumItalic.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/Inter-Regular.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/Inter-SemiBold.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/Inter-SemiBoldItalic.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/Inter-Thin.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/Inter-ThinItalic.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/InterDisplay-Black.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/InterDisplay-BlackItalic.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/InterDisplay-Bold.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/InterDisplay-BoldItalic.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/InterDisplay-ExtraBold.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/InterDisplay-ExtraBoldItalic.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/InterDisplay-ExtraLight.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/InterDisplay-ExtraLightItalic.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/InterDisplay-Italic.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/InterDisplay-Light.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/InterDisplay-LightItalic.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/InterDisplay-Medium.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/InterDisplay-MediumItalic.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/InterDisplay-Regular.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/InterDisplay-SemiBold.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/InterDisplay-SemiBoldItalic.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/InterDisplay-Thin.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/InterDisplay-ThinItalic.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/InterVariable-Italic.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/fonts/InterVariable.woff2 +0 -0
- package/.codex-tmp-pack/extract/package/assets/i18n/ar.json +0 -44
- package/.codex-tmp-pack/extract/package/assets/i18n/en.json +0 -44
- package/.codex-tmp-pack/extract/package/assets/inter.css +0 -418
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-avatar-text.mjs +0 -46
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-avatar-text.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-avatar.mjs +0 -45
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-avatar.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-breadcrumb.mjs +0 -27
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-breadcrumb.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-business-fields.mjs +0 -222
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-business-fields.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-button-group.mjs +0 -20
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-button-group.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-button.mjs +0 -52
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-button.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-card.mjs +0 -28
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-card.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-checkbox-field.mjs +0 -88
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-checkbox-field.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-chip.mjs +0 -35
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-chip.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-client-page-menu.mjs +0 -92
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-client-page-menu.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-client-page.mjs +0 -93
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-client-page.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-color-picker-field.mjs +0 -94
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-color-picker-field.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-confirmation.mjs +0 -93
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-confirmation.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-date-field.mjs +0 -94
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-date-field.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-dialog.mjs +0 -33
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-dialog.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-drawer.mjs +0 -69
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-drawer.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-dynamic-drawer.mjs +0 -321
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-dynamic-drawer.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-editor-field.mjs +0 -96
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-editor-field.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-entities.mjs +0 -572
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-entities.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-field-validation.mjs +0 -103
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-field-validation.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-formula.mjs +0 -3102
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-formula.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-icon-field.mjs +0 -63
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-icon-field.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-list.mjs +0 -31
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-list.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-menu.mjs +0 -136
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-menu.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-modal.mjs +0 -50
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-modal.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-module-summary-card.mjs +0 -32
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-module-summary-card.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-multi-select-field.mjs +0 -197
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-multi-select-field.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-number-field.mjs +0 -95
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-number-field.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-page-header.mjs +0 -42
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-page-header.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-page.mjs +0 -35
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-page.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-paginator.mjs +0 -44
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-paginator.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-pick-list-field.mjs +0 -204
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-pick-list-field.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-progress.mjs +0 -41
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-progress.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-property-filter-builder.mjs +0 -383
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-property-filter-builder.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-radio-button-field.mjs +0 -85
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-radio-button-field.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-radio-cards-field.mjs +0 -68
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-radio-cards-field.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-radio-cards.mjs +0 -74
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-radio-cards.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-select-field.mjs +0 -258
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-select-field.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-sidebar.mjs +0 -36
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-sidebar.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-slider-field.mjs +0 -104
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-slider-field.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-statistic-card.mjs +0 -21
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-statistic-card.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-table.mjs +0 -583
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-table.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-tabs.mjs +0 -44
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-tabs.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-text-field.mjs +0 -159
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-text-field.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-textarea-field.mjs +0 -92
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-textarea-field.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-toast.mjs +0 -75
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-toast.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-toggle-field.mjs +0 -104
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-toggle-field.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-tooltip.mjs +0 -45
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-tooltip.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-topbar.mjs +0 -28
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-topbar.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-tree.mjs +0 -219
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-tree.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-upload-field.mjs +0 -480
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-upload-field.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-user-search-field.mjs +0 -153
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components-user-search-field.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components.mjs +0 -1338
- package/.codex-tmp-pack/extract/package/fesm2022/masterteam-components.mjs.map +0 -1
- package/.codex-tmp-pack/extract/package/types/masterteam-components-avatar-text.d.ts +0 -23
- package/.codex-tmp-pack/extract/package/types/masterteam-components-avatar.d.ts +0 -21
- package/.codex-tmp-pack/extract/package/types/masterteam-components-breadcrumb.d.ts +0 -18
- package/.codex-tmp-pack/extract/package/types/masterteam-components-business-fields.d.ts +0 -114
- package/.codex-tmp-pack/extract/package/types/masterteam-components-button-group.d.ts +0 -8
- package/.codex-tmp-pack/extract/package/types/masterteam-components-button.d.ts +0 -36
- package/.codex-tmp-pack/extract/package/types/masterteam-components-card.d.ts +0 -14
- package/.codex-tmp-pack/extract/package/types/masterteam-components-checkbox-field.d.ts +0 -34
- package/.codex-tmp-pack/extract/package/types/masterteam-components-chip.d.ts +0 -19
- package/.codex-tmp-pack/extract/package/types/masterteam-components-client-page-menu.d.ts +0 -35
- package/.codex-tmp-pack/extract/package/types/masterteam-components-client-page.d.ts +0 -42
- package/.codex-tmp-pack/extract/package/types/masterteam-components-color-picker-field.d.ts +0 -35
- package/.codex-tmp-pack/extract/package/types/masterteam-components-confirmation.d.ts +0 -41
- package/.codex-tmp-pack/extract/package/types/masterteam-components-date-field.d.ts +0 -41
- package/.codex-tmp-pack/extract/package/types/masterteam-components-dialog.d.ts +0 -12
- package/.codex-tmp-pack/extract/package/types/masterteam-components-drawer.d.ts +0 -30
- package/.codex-tmp-pack/extract/package/types/masterteam-components-dynamic-drawer.d.ts +0 -93
- package/.codex-tmp-pack/extract/package/types/masterteam-components-editor-field.d.ts +0 -34
- package/.codex-tmp-pack/extract/package/types/masterteam-components-entities.d.ts +0 -326
- package/.codex-tmp-pack/extract/package/types/masterteam-components-field-validation.d.ts +0 -13
- package/.codex-tmp-pack/extract/package/types/masterteam-components-formula.d.ts +0 -651
- package/.codex-tmp-pack/extract/package/types/masterteam-components-icon-field.d.ts +0 -27
- package/.codex-tmp-pack/extract/package/types/masterteam-components-list.d.ts +0 -18
- package/.codex-tmp-pack/extract/package/types/masterteam-components-menu.d.ts +0 -55
- package/.codex-tmp-pack/extract/package/types/masterteam-components-modal.d.ts +0 -18
- package/.codex-tmp-pack/extract/package/types/masterteam-components-module-summary-card.d.ts +0 -17
- package/.codex-tmp-pack/extract/package/types/masterteam-components-multi-select-field.d.ts +0 -74
- package/.codex-tmp-pack/extract/package/types/masterteam-components-number-field.d.ts +0 -42
- package/.codex-tmp-pack/extract/package/types/masterteam-components-page-header.d.ts +0 -30
- package/.codex-tmp-pack/extract/package/types/masterteam-components-page.d.ts +0 -26
- package/.codex-tmp-pack/extract/package/types/masterteam-components-paginator.d.ts +0 -20
- package/.codex-tmp-pack/extract/package/types/masterteam-components-pick-list-field.d.ts +0 -60
- package/.codex-tmp-pack/extract/package/types/masterteam-components-progress.d.ts +0 -20
- package/.codex-tmp-pack/extract/package/types/masterteam-components-property-filter-builder.d.ts +0 -90
- package/.codex-tmp-pack/extract/package/types/masterteam-components-radio-button-field.d.ts +0 -41
- package/.codex-tmp-pack/extract/package/types/masterteam-components-radio-cards-field.d.ts +0 -30
- package/.codex-tmp-pack/extract/package/types/masterteam-components-radio-cards.d.ts +0 -33
- package/.codex-tmp-pack/extract/package/types/masterteam-components-select-field.d.ts +0 -84
- package/.codex-tmp-pack/extract/package/types/masterteam-components-sidebar.d.ts +0 -28
- package/.codex-tmp-pack/extract/package/types/masterteam-components-slider-field.d.ts +0 -45
- package/.codex-tmp-pack/extract/package/types/masterteam-components-statistic-card.d.ts +0 -17
- package/.codex-tmp-pack/extract/package/types/masterteam-components-table.d.ts +0 -207
- package/.codex-tmp-pack/extract/package/types/masterteam-components-tabs.d.ts +0 -23
- package/.codex-tmp-pack/extract/package/types/masterteam-components-text-field.d.ts +0 -44
- package/.codex-tmp-pack/extract/package/types/masterteam-components-textarea-field.d.ts +0 -38
- package/.codex-tmp-pack/extract/package/types/masterteam-components-toast.d.ts +0 -26
- package/.codex-tmp-pack/extract/package/types/masterteam-components-toggle-field.d.ts +0 -41
- package/.codex-tmp-pack/extract/package/types/masterteam-components-tooltip.d.ts +0 -9
- package/.codex-tmp-pack/extract/package/types/masterteam-components-topbar.d.ts +0 -17
- package/.codex-tmp-pack/extract/package/types/masterteam-components-tree.d.ts +0 -98
- package/.codex-tmp-pack/extract/package/types/masterteam-components-upload-field.d.ts +0 -77
- package/.codex-tmp-pack/extract/package/types/masterteam-components-user-search-field.d.ts +0 -61
- package/.codex-tmp-pack/extract/package/types/masterteam-components.d.ts +0 -780
- package/.codex-tmp-pack/masterteam-components-0.0.108.tgz +0 -0
|
@@ -1,1338 +0,0 @@
|
|
|
1
|
-
import { providePrimeNG } from 'primeng/config';
|
|
2
|
-
import Aura from '@primeuix/themes/aura';
|
|
3
|
-
import { updatePreset, definePreset } from '@primeuix/themes';
|
|
4
|
-
import { MessageService, ConfirmationService } from 'primeng/api';
|
|
5
|
-
import { computed } from '@angular/core';
|
|
6
|
-
import { tap, catchError, finalize } from 'rxjs/operators';
|
|
7
|
-
import { HttpContextToken } from '@angular/common/http';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Converts a hex color string to an HSL tuple.
|
|
11
|
-
* @param hex - The hex color string (e.g., "#RRGGBB" or "#RGB").
|
|
12
|
-
* @returns An HSL tuple [hue, saturation, lightness] where hue is in degrees (0-360),
|
|
13
|
-
* and saturation/lightness are percentages (0-100).
|
|
14
|
-
*/
|
|
15
|
-
function hexToHsl(hex) {
|
|
16
|
-
let r = 0, g = 0, b = 0;
|
|
17
|
-
// Handle shorthand hex codes
|
|
18
|
-
if (hex.length === 4) {
|
|
19
|
-
r = parseInt(hex[1] + hex[1], 16);
|
|
20
|
-
g = parseInt(hex[2] + hex[2], 16);
|
|
21
|
-
b = parseInt(hex[3] + hex[3], 16);
|
|
22
|
-
}
|
|
23
|
-
else if (hex.length === 7) {
|
|
24
|
-
r = parseInt(hex.substring(1, 3), 16);
|
|
25
|
-
g = parseInt(hex.substring(3, 5), 16);
|
|
26
|
-
b = parseInt(hex.substring(5, 7), 16);
|
|
27
|
-
}
|
|
28
|
-
else {
|
|
29
|
-
throw new Error('Invalid hex color format. Expected #RGB or #RRGGBB.');
|
|
30
|
-
}
|
|
31
|
-
r /= 255;
|
|
32
|
-
g /= 255;
|
|
33
|
-
b /= 255;
|
|
34
|
-
const max = Math.max(r, g, b);
|
|
35
|
-
const min = Math.min(r, g, b);
|
|
36
|
-
let h = 0, s;
|
|
37
|
-
const l = (max + min) / 2;
|
|
38
|
-
if (max === min) {
|
|
39
|
-
h = s = 0; // achromatic
|
|
40
|
-
}
|
|
41
|
-
else {
|
|
42
|
-
const d = max - min;
|
|
43
|
-
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
|
44
|
-
switch (max) {
|
|
45
|
-
case r:
|
|
46
|
-
h = (g - b) / d + (g < b ? 6 : 0);
|
|
47
|
-
break;
|
|
48
|
-
case g:
|
|
49
|
-
h = (b - r) / d + 2;
|
|
50
|
-
break;
|
|
51
|
-
case b:
|
|
52
|
-
h = (r - g) / d + 4;
|
|
53
|
-
break;
|
|
54
|
-
}
|
|
55
|
-
h /= 6;
|
|
56
|
-
}
|
|
57
|
-
return [h * 360, s * 100, l * 100]; // HSL in degrees, percentage, percentage
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Converts HSL values to a hex color string.
|
|
61
|
-
* @param h - Hue (0-360).
|
|
62
|
-
* @param s - Saturation (0-100).
|
|
63
|
-
* @param l - Lightness (0-100).
|
|
64
|
-
* @returns The hex color string (e.g., "#RRGGBB").
|
|
65
|
-
*/
|
|
66
|
-
function hslToHex(h, s, l) {
|
|
67
|
-
l /= 100;
|
|
68
|
-
const a = (s * Math.min(l, 1 - l)) / 100;
|
|
69
|
-
const f = (n) => {
|
|
70
|
-
const k = (n + h / 30) % 12;
|
|
71
|
-
const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
|
|
72
|
-
return Math.round(255 * color)
|
|
73
|
-
.toString(16)
|
|
74
|
-
.padStart(2, '0');
|
|
75
|
-
};
|
|
76
|
-
return `#${f(0)}${f(8)}${f(4)}`;
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Defines the "ideal" lightness and saturation adjustment for each shade.
|
|
80
|
-
* Lightness for 500 is set to 50 as a balanced default.
|
|
81
|
-
*/
|
|
82
|
-
const PALETTE_PROFILE = {
|
|
83
|
-
'0': { l: 98, s_adjust: -50 },
|
|
84
|
-
'50': { l: 95, s_adjust: -40 },
|
|
85
|
-
'100': { l: 90, s_adjust: -30 },
|
|
86
|
-
'200': { l: 80, s_adjust: -20 },
|
|
87
|
-
'300': { l: 70, s_adjust: -10 },
|
|
88
|
-
'400': { l: 60, s_adjust: -5 },
|
|
89
|
-
'500': { l: 50, s_adjust: 0 },
|
|
90
|
-
'600': { l: 45, s_adjust: 5 },
|
|
91
|
-
'700': { l: 35, s_adjust: 10 },
|
|
92
|
-
'800': { l: 25, s_adjust: 15 },
|
|
93
|
-
'900': { l: 15, s_adjust: 20 },
|
|
94
|
-
'950': { l: 8, s_adjust: 25 },
|
|
95
|
-
};
|
|
96
|
-
// Helper to ensure palette is always in the correct 50-950 order
|
|
97
|
-
const ALL_SHADES = [
|
|
98
|
-
'0',
|
|
99
|
-
'50',
|
|
100
|
-
'100',
|
|
101
|
-
'200',
|
|
102
|
-
'300',
|
|
103
|
-
'400',
|
|
104
|
-
'500',
|
|
105
|
-
'600',
|
|
106
|
-
'700',
|
|
107
|
-
'800',
|
|
108
|
-
'900',
|
|
109
|
-
'950',
|
|
110
|
-
];
|
|
111
|
-
/**
|
|
112
|
-
* Clamps a number between a min and max value.
|
|
113
|
-
*/
|
|
114
|
-
function clamp(value, min, max) {
|
|
115
|
-
return Math.max(min, Math.min(max, value));
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Generates a Tailwind-like color palette (50-950) from any given base color.
|
|
119
|
-
*
|
|
120
|
-
* @param baseColorHex - The hex string of the base color (e.g., "#0284c7").
|
|
121
|
-
* @param baseColorShade - The shade of the base color (e.g., "500", "700").
|
|
122
|
-
* @returns An object representing the full color palette.
|
|
123
|
-
*/
|
|
124
|
-
function generateTailwindPalette(baseColorHex, baseColorShade = '500') {
|
|
125
|
-
// 1. Get HSL of the input color
|
|
126
|
-
const [h_base, s_base, l_base] = hexToHsl(baseColorHex);
|
|
127
|
-
// 2. Find the anchors
|
|
128
|
-
const baseProfile = PALETTE_PROFILE[baseColorShade];
|
|
129
|
-
/** The Hue is constant across the entire palette. */
|
|
130
|
-
const h = h_base;
|
|
131
|
-
/**
|
|
132
|
-
* Calculate the 500-shade's saturation by "reversing" the adjustment
|
|
133
|
-
* from the base color.
|
|
134
|
-
* e.g., if base is 700 (s_adjust: +10) and s_base is 80,
|
|
135
|
-
* s_500 will be 70.
|
|
136
|
-
*/
|
|
137
|
-
const s_500 = clamp(s_base - baseProfile.s_adjust, 0, 100);
|
|
138
|
-
/**
|
|
139
|
-
* Calculate the lightness "offset". This is the difference between
|
|
140
|
-
* the base color's actual lightness and its "ideal" lightness
|
|
141
|
-
* from the profile.
|
|
142
|
-
* e.g., if base is 700 (ideal L: 35) and l_base is 38,
|
|
143
|
-
* the offset is +3. This offset will be applied to all shades.
|
|
144
|
-
*/
|
|
145
|
-
const l_offset = l_base - baseProfile.l;
|
|
146
|
-
// 3. Generate the full palette
|
|
147
|
-
const palette = {};
|
|
148
|
-
for (const shade of ALL_SHADES) {
|
|
149
|
-
const profile = PALETTE_PROFILE[shade];
|
|
150
|
-
// Calculate the new saturation and lightness for this shade
|
|
151
|
-
const newS = clamp(s_500 + profile.s_adjust, 0, 100);
|
|
152
|
-
const newL = clamp(profile.l + l_offset, 0, 100);
|
|
153
|
-
palette[shade] = hslToHex(h, newS, newL);
|
|
154
|
-
}
|
|
155
|
-
// 4. Ensure the originally provided color is used exactly
|
|
156
|
-
// (to avoid rounding errors from HSL conversion)
|
|
157
|
-
palette[baseColorShade] = baseColorHex;
|
|
158
|
-
return palette;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
const toastStyle = {
|
|
162
|
-
// borderColor: '{surface.300}',
|
|
163
|
-
background: '{content.background}',
|
|
164
|
-
// color: '{surface.600}',
|
|
165
|
-
// closeButton: {
|
|
166
|
-
// hoverBackground: '{surface.100}',
|
|
167
|
-
// focusRing: {
|
|
168
|
-
// color: '{surface.600}',
|
|
169
|
-
// },
|
|
170
|
-
// },
|
|
171
|
-
};
|
|
172
|
-
function changePrimaryColor(color) {
|
|
173
|
-
updatePreset({
|
|
174
|
-
semantic: {
|
|
175
|
-
primary: generateTailwindPalette(color || '#2AAEC0'),
|
|
176
|
-
},
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
function changeBackgroundColor(color) {
|
|
180
|
-
if (color) {
|
|
181
|
-
const palette = generateTailwindPalette(color, '100');
|
|
182
|
-
document.documentElement.style.setProperty('--app-background-light', palette['100']);
|
|
183
|
-
document.documentElement.style.setProperty('--app-background-dark', palette['950']);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
function changeTextColor(color) {
|
|
187
|
-
const palette = generateTailwindPalette(color ?? '#334155', '700');
|
|
188
|
-
updatePreset({
|
|
189
|
-
semantic: {
|
|
190
|
-
colorScheme: {
|
|
191
|
-
light: {
|
|
192
|
-
text: {
|
|
193
|
-
color: palette['700'],
|
|
194
|
-
hoverColor: palette['800'],
|
|
195
|
-
hoverMutedColor: palette['600'],
|
|
196
|
-
mutedColor: palette['500'],
|
|
197
|
-
},
|
|
198
|
-
},
|
|
199
|
-
dark: {
|
|
200
|
-
text: {
|
|
201
|
-
color: palette['0'],
|
|
202
|
-
hoverColor: palette['0'],
|
|
203
|
-
hoverMutedColor: palette['300'],
|
|
204
|
-
mutedColor: palette['400'],
|
|
205
|
-
},
|
|
206
|
-
},
|
|
207
|
-
},
|
|
208
|
-
},
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
|
-
const MTPreset = (themeOptions) => {
|
|
212
|
-
const textPalette = generateTailwindPalette(themeOptions?.textColor ?? '#334155', '700');
|
|
213
|
-
const configs = {
|
|
214
|
-
options: {
|
|
215
|
-
prefix: 'mt',
|
|
216
|
-
cssLayer: {
|
|
217
|
-
name: 'primeng',
|
|
218
|
-
order: 'theme, base, primeng',
|
|
219
|
-
},
|
|
220
|
-
},
|
|
221
|
-
semantic: {
|
|
222
|
-
colorScheme: {
|
|
223
|
-
light: {
|
|
224
|
-
text: {
|
|
225
|
-
color: textPalette['700'],
|
|
226
|
-
hoverColor: textPalette['800'],
|
|
227
|
-
hoverMutedColor: textPalette['600'],
|
|
228
|
-
mutedColor: textPalette['500'],
|
|
229
|
-
},
|
|
230
|
-
},
|
|
231
|
-
dark: {
|
|
232
|
-
text: {
|
|
233
|
-
color: textPalette['0'],
|
|
234
|
-
hoverColor: textPalette['0'],
|
|
235
|
-
hoverMutedColor: textPalette['300'],
|
|
236
|
-
mutedColor: textPalette['400'],
|
|
237
|
-
},
|
|
238
|
-
},
|
|
239
|
-
},
|
|
240
|
-
primary: generateTailwindPalette(themeOptions?.primaryColor || '#2AAEC0'),
|
|
241
|
-
content: {
|
|
242
|
-
borderRadius: '{border.radius.lg}',
|
|
243
|
-
},
|
|
244
|
-
formField: {
|
|
245
|
-
borderRadius: '{border.radius.lg}',
|
|
246
|
-
},
|
|
247
|
-
},
|
|
248
|
-
components: {
|
|
249
|
-
dialog: {
|
|
250
|
-
header: {
|
|
251
|
-
padding: '0',
|
|
252
|
-
},
|
|
253
|
-
content: {
|
|
254
|
-
padding: '0',
|
|
255
|
-
},
|
|
256
|
-
footer: {
|
|
257
|
-
padding: '0',
|
|
258
|
-
},
|
|
259
|
-
},
|
|
260
|
-
toast: {
|
|
261
|
-
root: {
|
|
262
|
-
borderRadius: '{border.radius.xl}',
|
|
263
|
-
},
|
|
264
|
-
colorScheme: {
|
|
265
|
-
light: {
|
|
266
|
-
success: toastStyle,
|
|
267
|
-
info: toastStyle,
|
|
268
|
-
warn: toastStyle,
|
|
269
|
-
error: toastStyle,
|
|
270
|
-
secondary: toastStyle,
|
|
271
|
-
},
|
|
272
|
-
dark: {
|
|
273
|
-
success: toastStyle,
|
|
274
|
-
info: toastStyle,
|
|
275
|
-
warn: toastStyle,
|
|
276
|
-
error: toastStyle,
|
|
277
|
-
secondary: toastStyle,
|
|
278
|
-
},
|
|
279
|
-
},
|
|
280
|
-
},
|
|
281
|
-
togglebutton: {
|
|
282
|
-
root: {
|
|
283
|
-
padding: '1px',
|
|
284
|
-
},
|
|
285
|
-
colorScheme: {
|
|
286
|
-
light: {
|
|
287
|
-
root: {
|
|
288
|
-
checkedColor: '{primary.500}',
|
|
289
|
-
},
|
|
290
|
-
},
|
|
291
|
-
dark: {
|
|
292
|
-
root: {
|
|
293
|
-
checkedColor: '{primary.400}',
|
|
294
|
-
},
|
|
295
|
-
},
|
|
296
|
-
},
|
|
297
|
-
},
|
|
298
|
-
selectbutton: {
|
|
299
|
-
root: {
|
|
300
|
-
borderRadius: '{border.radius.lg}',
|
|
301
|
-
},
|
|
302
|
-
},
|
|
303
|
-
paginator: {
|
|
304
|
-
root: {
|
|
305
|
-
borderRadius: '{border.radius.lg}',
|
|
306
|
-
padding: '0 .5rem',
|
|
307
|
-
},
|
|
308
|
-
navButton: {
|
|
309
|
-
borderRadius: '0',
|
|
310
|
-
},
|
|
311
|
-
colorScheme: {
|
|
312
|
-
light: {
|
|
313
|
-
navButton: {
|
|
314
|
-
color: '{surface.600}',
|
|
315
|
-
hoverBackground: '#fff',
|
|
316
|
-
selectedBackground: '{surface.200}',
|
|
317
|
-
selectedColor: '{surface.600}',
|
|
318
|
-
focusRing: {
|
|
319
|
-
color: '{surface.200}',
|
|
320
|
-
},
|
|
321
|
-
},
|
|
322
|
-
},
|
|
323
|
-
dark: {
|
|
324
|
-
navButton: {
|
|
325
|
-
color: '{surface.200}',
|
|
326
|
-
hoverBackground: 'transparent',
|
|
327
|
-
selectedBackground: 'transparent',
|
|
328
|
-
selectedColor: '#fff',
|
|
329
|
-
focusRing: {
|
|
330
|
-
color: '#fff',
|
|
331
|
-
},
|
|
332
|
-
},
|
|
333
|
-
},
|
|
334
|
-
},
|
|
335
|
-
css: () => `
|
|
336
|
-
.p-paginator {
|
|
337
|
-
--p-paginator-gap: 0;
|
|
338
|
-
--p-paginator-nav-button-width: 2.2rem;
|
|
339
|
-
--p-paginator-nav-button-height: 2.2rem;
|
|
340
|
-
width: fit-content;
|
|
341
|
-
border: 1px solid var(--p-surface-200);
|
|
342
|
-
overflow: hidden;
|
|
343
|
-
font-size: .95rem;
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
.p-paginator-pages button,
|
|
347
|
-
.p-paginator-prev,
|
|
348
|
-
.p-paginator-next {
|
|
349
|
-
border-color: var(--p-surface-200);
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
.p-paginator-pages button {
|
|
353
|
-
border-style: solid;
|
|
354
|
-
border-width: 0 0 0 1px;
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
.p-paginator-pages button:first-child {
|
|
358
|
-
border-left: none;
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
.p-paginator-prev {
|
|
362
|
-
border-right: 1px solid var(--p-surface-200);
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
.p-paginator-next {
|
|
366
|
-
border-left: 1px solid var(--p-surface-200);
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
.p-paginator .p-select {
|
|
370
|
-
border: 0;
|
|
371
|
-
background: transparent;
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
.p-paginator .p-select .p-select-label {
|
|
375
|
-
padding: 0;
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
/* Dark Mode Styles */
|
|
379
|
-
.dark .p-paginator {
|
|
380
|
-
border-color: var(--p-surface-500);
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
.dark .p-paginator-pages button,
|
|
384
|
-
.dark .p-paginator-prev,
|
|
385
|
-
.dark .p-paginator-next {
|
|
386
|
-
border-color: var(--p-surface-500);
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
.dark .p-paginator-prev {
|
|
390
|
-
border-right-color: var(--p-surface-500);
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
.dark .p-paginator-next {
|
|
394
|
-
border-left-color: var(--p-surface-500);
|
|
395
|
-
}
|
|
396
|
-
`,
|
|
397
|
-
},
|
|
398
|
-
toggleswitch: {
|
|
399
|
-
root: {
|
|
400
|
-
width: '2.5rem',
|
|
401
|
-
height: '1.4rem',
|
|
402
|
-
},
|
|
403
|
-
},
|
|
404
|
-
select: {
|
|
405
|
-
optionGroup: {
|
|
406
|
-
fontWeight: 'bold',
|
|
407
|
-
padding: '6px 8px',
|
|
408
|
-
background: '{surface.50}',
|
|
409
|
-
color: '{primary.700}',
|
|
410
|
-
},
|
|
411
|
-
},
|
|
412
|
-
// steps: {
|
|
413
|
-
// item: {
|
|
414
|
-
// link: {
|
|
415
|
-
// gap: 'calc(50% + 0.25rem)',
|
|
416
|
-
// },
|
|
417
|
-
// number: {
|
|
418
|
-
// font: {
|
|
419
|
-
// size: '0.9rem',
|
|
420
|
-
// },
|
|
421
|
-
// active: {
|
|
422
|
-
// color: 'white',
|
|
423
|
-
// background: '{primary.500}',
|
|
424
|
-
// border: {
|
|
425
|
-
// color: '{primary.500}',
|
|
426
|
-
// },
|
|
427
|
-
// },
|
|
428
|
-
// },
|
|
429
|
-
// },
|
|
430
|
-
// },
|
|
431
|
-
},
|
|
432
|
-
};
|
|
433
|
-
return definePreset(Aura, configs);
|
|
434
|
-
};
|
|
435
|
-
function provideMTComponents(themeOptions) {
|
|
436
|
-
changeBackgroundColor(themeOptions?.backgroundColor);
|
|
437
|
-
return providePrimeNG({
|
|
438
|
-
zIndex: {
|
|
439
|
-
modal: 1900,
|
|
440
|
-
overlay: 1500,
|
|
441
|
-
menu: 1500,
|
|
442
|
-
tooltip: 1600,
|
|
443
|
-
},
|
|
444
|
-
theme: {
|
|
445
|
-
preset: MTPreset(themeOptions),
|
|
446
|
-
options: {
|
|
447
|
-
darkModeSelector: '.dark',
|
|
448
|
-
},
|
|
449
|
-
},
|
|
450
|
-
});
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
function provideMTMessages() {
|
|
454
|
-
return MessageService;
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
function provideMTConfirmation() {
|
|
458
|
-
return ConfirmationService;
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
class ValidatorConfig {
|
|
462
|
-
type;
|
|
463
|
-
value;
|
|
464
|
-
message;
|
|
465
|
-
customValidator;
|
|
466
|
-
constructor(config) {
|
|
467
|
-
this.type = config.type;
|
|
468
|
-
this.value = config.value;
|
|
469
|
-
this.message = config.message;
|
|
470
|
-
this.customValidator = config.customValidator;
|
|
471
|
-
}
|
|
472
|
-
// Factory methods for common validators
|
|
473
|
-
static required(message = 'This field is required') {
|
|
474
|
-
return new ValidatorConfig({ type: 'required', message });
|
|
475
|
-
}
|
|
476
|
-
static email(message = 'Please enter a valid email') {
|
|
477
|
-
return new ValidatorConfig({ type: 'email', message });
|
|
478
|
-
}
|
|
479
|
-
static minLength(length, message) {
|
|
480
|
-
return new ValidatorConfig({
|
|
481
|
-
type: 'minLength',
|
|
482
|
-
value: length,
|
|
483
|
-
message: message || `Minimum length is ${length} characters`,
|
|
484
|
-
});
|
|
485
|
-
}
|
|
486
|
-
static maxLength(length, message) {
|
|
487
|
-
return new ValidatorConfig({
|
|
488
|
-
type: 'maxLength',
|
|
489
|
-
value: length,
|
|
490
|
-
message: message || `Maximum length is ${length} characters`,
|
|
491
|
-
});
|
|
492
|
-
}
|
|
493
|
-
static min(value, message) {
|
|
494
|
-
return new ValidatorConfig({
|
|
495
|
-
type: 'min',
|
|
496
|
-
value,
|
|
497
|
-
message: message || `Minimum value is ${value}`,
|
|
498
|
-
});
|
|
499
|
-
}
|
|
500
|
-
static max(value, message) {
|
|
501
|
-
return new ValidatorConfig({
|
|
502
|
-
type: 'max',
|
|
503
|
-
value,
|
|
504
|
-
message: message || `Maximum value is ${value}`,
|
|
505
|
-
});
|
|
506
|
-
}
|
|
507
|
-
static pattern(pattern, message = 'Invalid format') {
|
|
508
|
-
return new ValidatorConfig({ type: 'pattern', value: pattern, message });
|
|
509
|
-
}
|
|
510
|
-
static custom(validator, message = 'Invalid value') {
|
|
511
|
-
return new ValidatorConfig({
|
|
512
|
-
type: 'custom',
|
|
513
|
-
customValidator: validator,
|
|
514
|
-
message,
|
|
515
|
-
});
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
|
-
class BaseFieldConfig {
|
|
519
|
-
key;
|
|
520
|
-
label;
|
|
521
|
-
type;
|
|
522
|
-
required;
|
|
523
|
-
disabled;
|
|
524
|
-
readonly;
|
|
525
|
-
hidden;
|
|
526
|
-
placeholder;
|
|
527
|
-
hint;
|
|
528
|
-
cssClass;
|
|
529
|
-
validators;
|
|
530
|
-
order;
|
|
531
|
-
colSpan;
|
|
532
|
-
defaultValue;
|
|
533
|
-
customTemplate;
|
|
534
|
-
relations;
|
|
535
|
-
formulaCondition;
|
|
536
|
-
constructor(config) {
|
|
537
|
-
this.key = config.key || 'Key';
|
|
538
|
-
this.label = config.label || '';
|
|
539
|
-
this.type = config.type;
|
|
540
|
-
this.required = config.required || false;
|
|
541
|
-
this.disabled = config.disabled || false;
|
|
542
|
-
this.readonly = config.readonly || false;
|
|
543
|
-
this.hidden = config.hidden || false;
|
|
544
|
-
this.placeholder = config.placeholder || '';
|
|
545
|
-
this.hint = config.hint || '';
|
|
546
|
-
this.cssClass = config.cssClass || '';
|
|
547
|
-
this.validators = config.validators || [];
|
|
548
|
-
this.order = config.order || 0;
|
|
549
|
-
this.relations = config.relations || [];
|
|
550
|
-
this.formulaCondition = config.formulaCondition;
|
|
551
|
-
this.colSpan = config.colSpan || 12;
|
|
552
|
-
}
|
|
553
|
-
}
|
|
554
|
-
// Specific configurations for different field types
|
|
555
|
-
class TextFieldConfig extends BaseFieldConfig {
|
|
556
|
-
inputType;
|
|
557
|
-
constructor(config) {
|
|
558
|
-
super({ ...config, type: 'text' });
|
|
559
|
-
this.inputType = config.inputType || 'text';
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
class TextareaFieldConfig extends BaseFieldConfig {
|
|
563
|
-
rows;
|
|
564
|
-
autoResize;
|
|
565
|
-
constructor(config) {
|
|
566
|
-
super({ ...config, type: 'textarea' });
|
|
567
|
-
this.rows = config.rows || 3;
|
|
568
|
-
this.autoResize = config.autoResize || false;
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
class SelectFieldConfig extends BaseFieldConfig {
|
|
572
|
-
options;
|
|
573
|
-
optionLabel;
|
|
574
|
-
optionValue;
|
|
575
|
-
group;
|
|
576
|
-
optionGroupLabel;
|
|
577
|
-
optionGroupChildren;
|
|
578
|
-
multiple;
|
|
579
|
-
filter;
|
|
580
|
-
filterBy;
|
|
581
|
-
filterPlaceholder;
|
|
582
|
-
showClear;
|
|
583
|
-
emptyMessage;
|
|
584
|
-
size;
|
|
585
|
-
hasPlaceholderPrefix;
|
|
586
|
-
constructor(config) {
|
|
587
|
-
super({ ...config, type: 'select' });
|
|
588
|
-
this.options = config.options;
|
|
589
|
-
this.optionLabel = config.optionLabel || 'label';
|
|
590
|
-
this.optionValue = config.optionValue || 'value';
|
|
591
|
-
this.group = config.group || false;
|
|
592
|
-
this.optionGroupLabel = config.optionGroupLabel || 'label';
|
|
593
|
-
this.optionGroupChildren = config.optionGroupChildren || 'items';
|
|
594
|
-
this.multiple = config.multiple || false;
|
|
595
|
-
this.filter = config.filter || false;
|
|
596
|
-
this.filterBy = config.filterBy || '';
|
|
597
|
-
this.filterPlaceholder = config.filterPlaceholder || 'Search...';
|
|
598
|
-
this.showClear = config.showClear || false;
|
|
599
|
-
this.emptyMessage = config.emptyMessage || 'No options available';
|
|
600
|
-
this.size = config.size || '';
|
|
601
|
-
this.hasPlaceholderPrefix =
|
|
602
|
-
config.hasPlaceholderPrefix === undefined
|
|
603
|
-
? true
|
|
604
|
-
: config.hasPlaceholderPrefix;
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
class RadioButtonFieldConfig extends BaseFieldConfig {
|
|
608
|
-
options;
|
|
609
|
-
optionLabel;
|
|
610
|
-
optionValue;
|
|
611
|
-
orientation;
|
|
612
|
-
constructor(config) {
|
|
613
|
-
super({ ...config, type: 'radio-button' });
|
|
614
|
-
this.options = config.options;
|
|
615
|
-
this.optionLabel = config.optionLabel || 'label';
|
|
616
|
-
this.optionValue = config.optionValue || 'value';
|
|
617
|
-
this.orientation = config.orientation || 'vertical';
|
|
618
|
-
}
|
|
619
|
-
}
|
|
620
|
-
class RadioCardsFieldConfig extends BaseFieldConfig {
|
|
621
|
-
options;
|
|
622
|
-
optionLabel;
|
|
623
|
-
optionValue;
|
|
624
|
-
size;
|
|
625
|
-
constructor(config) {
|
|
626
|
-
super({ ...config, type: 'radio-cards' });
|
|
627
|
-
this.options = config.options;
|
|
628
|
-
this.optionLabel = config.optionLabel || 'label';
|
|
629
|
-
this.optionValue = config.optionValue || 'value';
|
|
630
|
-
this.size = config.size || 'small';
|
|
631
|
-
}
|
|
632
|
-
}
|
|
633
|
-
class UserSearchFieldConfig extends BaseFieldConfig {
|
|
634
|
-
optionLabel;
|
|
635
|
-
optionValue;
|
|
636
|
-
size;
|
|
637
|
-
apiUrl;
|
|
638
|
-
context;
|
|
639
|
-
constructor(config) {
|
|
640
|
-
super({ ...config, type: 'user-search' });
|
|
641
|
-
this.optionLabel = config.optionLabel || 'label';
|
|
642
|
-
this.optionValue = config.optionValue || 'value';
|
|
643
|
-
this.size = config.size || '';
|
|
644
|
-
this.hint = config.hint || '';
|
|
645
|
-
this.context = config.context || undefined;
|
|
646
|
-
this.apiUrl = config.apiUrl || '';
|
|
647
|
-
this.placeholder = config.placeholder || 'Search';
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
class UploadFileFieldConfig extends BaseFieldConfig {
|
|
651
|
-
size;
|
|
652
|
-
endPoint;
|
|
653
|
-
userImgClass;
|
|
654
|
-
shape;
|
|
655
|
-
multiple;
|
|
656
|
-
accept;
|
|
657
|
-
fileSizeLimit;
|
|
658
|
-
context;
|
|
659
|
-
title;
|
|
660
|
-
description;
|
|
661
|
-
constructor(config) {
|
|
662
|
-
super({ ...config, type: 'upload-file' });
|
|
663
|
-
this.size = config.size || 'normal';
|
|
664
|
-
this.endPoint = config.endPoint || 'uploader';
|
|
665
|
-
this.userImgClass =
|
|
666
|
-
config.userImgClass || 'w-25! h-25! text-4xl! text-gray-400!';
|
|
667
|
-
this.shape = config.shape || 'field';
|
|
668
|
-
this.multiple = config.multiple ?? false;
|
|
669
|
-
this.accept = config.accept || '.pdf,.doc,.docx,.xlsx,image/*';
|
|
670
|
-
this.fileSizeLimit = config.fileSizeLimit || undefined;
|
|
671
|
-
this.context = config.context || undefined;
|
|
672
|
-
this.title = config.title || 'Upload File';
|
|
673
|
-
this.description = config.description || 'Click or drop a file to upload';
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
class DateFieldConfig extends BaseFieldConfig {
|
|
677
|
-
dateFormat;
|
|
678
|
-
showTime;
|
|
679
|
-
showSeconds;
|
|
680
|
-
hourFormat;
|
|
681
|
-
minDate;
|
|
682
|
-
maxDate;
|
|
683
|
-
disabledDates;
|
|
684
|
-
disabledDays;
|
|
685
|
-
yearRange;
|
|
686
|
-
showIcon;
|
|
687
|
-
icon;
|
|
688
|
-
showButtonBar;
|
|
689
|
-
showClear;
|
|
690
|
-
inline;
|
|
691
|
-
constructor(config) {
|
|
692
|
-
super({ ...config, type: 'date' });
|
|
693
|
-
this.dateFormat = config.dateFormat || 'yyyy-mm-dd';
|
|
694
|
-
this.showTime = config.showTime || false;
|
|
695
|
-
this.showSeconds = config.showSeconds || false;
|
|
696
|
-
this.hourFormat = config.hourFormat || '24';
|
|
697
|
-
this.minDate = config.minDate;
|
|
698
|
-
this.maxDate = config.maxDate;
|
|
699
|
-
this.disabledDates = config.disabledDates || [];
|
|
700
|
-
this.disabledDays = config.disabledDays || [];
|
|
701
|
-
this.yearRange = config.yearRange || '1900:2030';
|
|
702
|
-
this.showIcon = config.showIcon || true;
|
|
703
|
-
this.icon = config.icon || 'pi pi-calendar';
|
|
704
|
-
this.showButtonBar = config.showButtonBar || false;
|
|
705
|
-
this.showClear = config.showClear || true;
|
|
706
|
-
this.inline = config.inline || false;
|
|
707
|
-
}
|
|
708
|
-
}
|
|
709
|
-
class NumberFieldConfig extends BaseFieldConfig {
|
|
710
|
-
min;
|
|
711
|
-
max;
|
|
712
|
-
step;
|
|
713
|
-
prefix;
|
|
714
|
-
suffix;
|
|
715
|
-
currency;
|
|
716
|
-
locale;
|
|
717
|
-
minFractionDigits;
|
|
718
|
-
maxFractionDigits;
|
|
719
|
-
useGrouping;
|
|
720
|
-
showButtons;
|
|
721
|
-
buttonLayout;
|
|
722
|
-
incrementButtonClass;
|
|
723
|
-
decrementButtonClass;
|
|
724
|
-
incrementButtonIcon;
|
|
725
|
-
decrementButtonIcon;
|
|
726
|
-
constructor(config) {
|
|
727
|
-
super({ ...config, type: 'number' });
|
|
728
|
-
this.min = config.min;
|
|
729
|
-
this.max = config.max;
|
|
730
|
-
this.step = config.step || 1;
|
|
731
|
-
this.prefix = config.prefix;
|
|
732
|
-
this.suffix = config.suffix;
|
|
733
|
-
this.currency = config.currency;
|
|
734
|
-
this.locale = config.locale;
|
|
735
|
-
this.minFractionDigits = config.minFractionDigits;
|
|
736
|
-
this.maxFractionDigits = config.maxFractionDigits;
|
|
737
|
-
this.useGrouping = config.useGrouping || false;
|
|
738
|
-
this.showButtons = config.showButtons || false;
|
|
739
|
-
this.buttonLayout = config.buttonLayout || 'stacked';
|
|
740
|
-
this.incrementButtonClass = config.incrementButtonClass;
|
|
741
|
-
this.decrementButtonClass = config.decrementButtonClass;
|
|
742
|
-
this.incrementButtonIcon = config.incrementButtonIcon;
|
|
743
|
-
this.decrementButtonIcon = config.decrementButtonIcon;
|
|
744
|
-
}
|
|
745
|
-
}
|
|
746
|
-
class SliderFieldConfig extends BaseFieldConfig {
|
|
747
|
-
min;
|
|
748
|
-
max;
|
|
749
|
-
step;
|
|
750
|
-
orientation;
|
|
751
|
-
range;
|
|
752
|
-
animate;
|
|
753
|
-
unit;
|
|
754
|
-
constructor(config) {
|
|
755
|
-
super({ ...config, type: 'slider' });
|
|
756
|
-
this.min = config.min || 0;
|
|
757
|
-
this.max = config.max || 100;
|
|
758
|
-
this.step = config.step || 1;
|
|
759
|
-
this.orientation = config.orientation || 'horizontal';
|
|
760
|
-
this.range = config.range || false;
|
|
761
|
-
this.animate = config.animate || false;
|
|
762
|
-
this.unit = config.unit || '';
|
|
763
|
-
}
|
|
764
|
-
}
|
|
765
|
-
class MultiSelectFieldConfig extends BaseFieldConfig {
|
|
766
|
-
options;
|
|
767
|
-
optionLabel;
|
|
768
|
-
optionValue;
|
|
769
|
-
filter;
|
|
770
|
-
filterBy;
|
|
771
|
-
filterPlaceholder;
|
|
772
|
-
showClear;
|
|
773
|
-
emptyMessage;
|
|
774
|
-
display;
|
|
775
|
-
maxSelectedLabels;
|
|
776
|
-
selectedItemsLabel;
|
|
777
|
-
showToggleAll;
|
|
778
|
-
resetFilterOnHide;
|
|
779
|
-
constructor(config) {
|
|
780
|
-
super({ ...config, type: 'multi-select' });
|
|
781
|
-
this.options = config.options;
|
|
782
|
-
this.optionLabel = config.optionLabel || 'label';
|
|
783
|
-
this.optionValue = config.optionValue || 'value';
|
|
784
|
-
this.filter = config.filter || false;
|
|
785
|
-
this.filterBy = config.filterBy || '';
|
|
786
|
-
this.filterPlaceholder = config.filterPlaceholder || 'Search...';
|
|
787
|
-
this.showClear = config.showClear || false;
|
|
788
|
-
this.emptyMessage = config.emptyMessage || 'No options available';
|
|
789
|
-
this.display = config.display || 'comma';
|
|
790
|
-
this.maxSelectedLabels = config.maxSelectedLabels || 3;
|
|
791
|
-
this.selectedItemsLabel = config.selectedItemsLabel || '{0} items selected';
|
|
792
|
-
this.showToggleAll = config.showToggleAll || true;
|
|
793
|
-
this.resetFilterOnHide = config.resetFilterOnHide || false;
|
|
794
|
-
}
|
|
795
|
-
}
|
|
796
|
-
class PickListFieldConfig extends BaseFieldConfig {
|
|
797
|
-
options;
|
|
798
|
-
optionLabel;
|
|
799
|
-
optionValue;
|
|
800
|
-
sourceHeader;
|
|
801
|
-
targetHeader;
|
|
802
|
-
showSourceControls;
|
|
803
|
-
showTargetControls;
|
|
804
|
-
showSourceFilter;
|
|
805
|
-
showTargetFilter;
|
|
806
|
-
filterBy;
|
|
807
|
-
dataKey;
|
|
808
|
-
dragdrop;
|
|
809
|
-
responsive;
|
|
810
|
-
breakpoint;
|
|
811
|
-
constructor(config) {
|
|
812
|
-
super({ ...config, type: 'pick-list' });
|
|
813
|
-
this.options = config.options;
|
|
814
|
-
this.optionLabel = config.optionLabel || 'label';
|
|
815
|
-
this.optionValue = config.optionValue || 'value';
|
|
816
|
-
this.sourceHeader = config.sourceHeader || 'Available';
|
|
817
|
-
this.targetHeader = config.targetHeader || 'Selected';
|
|
818
|
-
this.showSourceControls =
|
|
819
|
-
config.showSourceControls !== undefined
|
|
820
|
-
? config.showSourceControls
|
|
821
|
-
: true;
|
|
822
|
-
this.showTargetControls =
|
|
823
|
-
config.showTargetControls !== undefined
|
|
824
|
-
? config.showTargetControls
|
|
825
|
-
: true;
|
|
826
|
-
this.showSourceFilter =
|
|
827
|
-
config.showSourceFilter !== undefined ? config.showSourceFilter : false;
|
|
828
|
-
this.showTargetFilter =
|
|
829
|
-
config.showTargetFilter !== undefined ? config.showTargetFilter : false;
|
|
830
|
-
this.filterBy = config.filterBy || this.optionLabel;
|
|
831
|
-
this.dataKey = config.dataKey || this.optionValue;
|
|
832
|
-
this.dragdrop = config.dragdrop ?? false;
|
|
833
|
-
this.responsive = config.responsive ?? true;
|
|
834
|
-
}
|
|
835
|
-
}
|
|
836
|
-
class CheckboxFieldConfig extends BaseFieldConfig {
|
|
837
|
-
binary;
|
|
838
|
-
trueValue;
|
|
839
|
-
falseValue;
|
|
840
|
-
checkboxIcon;
|
|
841
|
-
constructor(config) {
|
|
842
|
-
super({ ...config, type: 'checkbox' });
|
|
843
|
-
this.binary = config.binary !== false; // Default to true
|
|
844
|
-
this.trueValue = config.trueValue !== undefined ? config.trueValue : true;
|
|
845
|
-
this.falseValue =
|
|
846
|
-
config.falseValue !== undefined ? config.falseValue : false;
|
|
847
|
-
this.checkboxIcon = config.checkboxIcon;
|
|
848
|
-
}
|
|
849
|
-
}
|
|
850
|
-
class ToggleFieldConfig extends BaseFieldConfig {
|
|
851
|
-
toggleShape;
|
|
852
|
-
icon;
|
|
853
|
-
descriptionCard;
|
|
854
|
-
constructor(config) {
|
|
855
|
-
super({ ...config, type: 'toggle' });
|
|
856
|
-
this.toggleShape = config.toggleShape ?? 'toggle';
|
|
857
|
-
this.icon = config.icon;
|
|
858
|
-
this.descriptionCard = config.descriptionCard;
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
|
-
class EditorFieldConfig extends BaseFieldConfig {
|
|
862
|
-
constructor(config) {
|
|
863
|
-
super({ ...config, type: 'editor-field' });
|
|
864
|
-
}
|
|
865
|
-
}
|
|
866
|
-
class ColorPickerFieldConfig extends BaseFieldConfig {
|
|
867
|
-
format;
|
|
868
|
-
inline;
|
|
869
|
-
appendTo;
|
|
870
|
-
variant;
|
|
871
|
-
constructor(config) {
|
|
872
|
-
super({ ...config, type: 'color-picker' });
|
|
873
|
-
this.format = config.format || 'hex';
|
|
874
|
-
this.inline = config.inline || false;
|
|
875
|
-
this.appendTo = config.appendTo || 'body';
|
|
876
|
-
this.variant = config.variant || 'outlined';
|
|
877
|
-
}
|
|
878
|
-
}
|
|
879
|
-
class IconFieldConfig extends BaseFieldConfig {
|
|
880
|
-
constructor(config) {
|
|
881
|
-
super({ ...config, type: 'icon-field' });
|
|
882
|
-
}
|
|
883
|
-
}
|
|
884
|
-
class SpacerFieldConfig extends BaseFieldConfig {
|
|
885
|
-
constructor(config) {
|
|
886
|
-
super({
|
|
887
|
-
...config,
|
|
888
|
-
type: 'spacer',
|
|
889
|
-
key: config.key || `spacer_${Date.now()}`,
|
|
890
|
-
label: config.label || '',
|
|
891
|
-
});
|
|
892
|
-
}
|
|
893
|
-
}
|
|
894
|
-
class SchemaConnectionFieldConfig extends BaseFieldConfig {
|
|
895
|
-
configuration;
|
|
896
|
-
context;
|
|
897
|
-
filter;
|
|
898
|
-
constructor(config) {
|
|
899
|
-
super({ ...config, type: 'schema-connection' });
|
|
900
|
-
this.configuration = config.configuration;
|
|
901
|
-
this.context = config.context || undefined;
|
|
902
|
-
this.filter = config.filter ?? true;
|
|
903
|
-
}
|
|
904
|
-
}
|
|
905
|
-
function createCustomValidator(customValidator, message) {
|
|
906
|
-
return (control) => {
|
|
907
|
-
const result = customValidator(control.value);
|
|
908
|
-
if (result instanceof Promise) {
|
|
909
|
-
// Handle async validation
|
|
910
|
-
result.then((isValid) => {
|
|
911
|
-
if (!isValid) {
|
|
912
|
-
control.setErrors({
|
|
913
|
-
custom: { message: message || 'Invalid value' },
|
|
914
|
-
});
|
|
915
|
-
}
|
|
916
|
-
});
|
|
917
|
-
return null; // For async, return null initially
|
|
918
|
-
}
|
|
919
|
-
else {
|
|
920
|
-
// Handle sync validation
|
|
921
|
-
return result
|
|
922
|
-
? null
|
|
923
|
-
: { custom: { message: message || 'Invalid value' } };
|
|
924
|
-
}
|
|
925
|
-
};
|
|
926
|
-
}
|
|
927
|
-
function wrapValidatorWithMessage(validator, errorKey, message) {
|
|
928
|
-
return (control) => {
|
|
929
|
-
const result = validator(control);
|
|
930
|
-
if (result) {
|
|
931
|
-
// Replace the default error with custom message
|
|
932
|
-
return { [errorKey]: { ...result[Object.keys(result)[0]], message } };
|
|
933
|
-
}
|
|
934
|
-
return null;
|
|
935
|
-
};
|
|
936
|
-
}
|
|
937
|
-
// DynamicFieldConfig = input.required<any>({
|
|
938
|
-
// transform: (value: any) => this.transformToDateFieldConfig(value)
|
|
939
|
-
// });
|
|
940
|
-
// transformToDateFieldConfig(value: any){
|
|
941
|
-
// return new TextFieldConfig()
|
|
942
|
-
// }
|
|
943
|
-
|
|
944
|
-
/**
|
|
945
|
-
* @deprecated Use direct `select()` + `computed()` pattern instead for better performance.
|
|
946
|
-
*
|
|
947
|
-
* **Problem with BaseFacade:**
|
|
948
|
-
* - All computed signals depend on the full state, causing unnecessary recomputations
|
|
949
|
-
* - Bypasses NGXS selector memoization
|
|
950
|
-
* - Uses `as any` casting, losing type safety
|
|
951
|
-
*
|
|
952
|
-
* **New Pattern - Use slice-based selectors:**
|
|
953
|
-
*
|
|
954
|
-
* ```typescript
|
|
955
|
-
* // In your State class - add slice selectors:
|
|
956
|
-
* @Selector()
|
|
957
|
-
* static getLoadingActive(state: MyStateModel): string[] {
|
|
958
|
-
* return state.loadingActive;
|
|
959
|
-
* }
|
|
960
|
-
*
|
|
961
|
-
* @Selector()
|
|
962
|
-
* static getErrors(state: MyStateModel): Record<string, string | null> {
|
|
963
|
-
* return state.errors;
|
|
964
|
-
* }
|
|
965
|
-
*
|
|
966
|
-
* // In your Facade - don't extend BaseFacade:
|
|
967
|
-
* @Injectable({ providedIn: 'root' })
|
|
968
|
-
* export class MyFacade {
|
|
969
|
-
* private readonly store = inject(Store);
|
|
970
|
-
*
|
|
971
|
-
* // Data selectors - memoized by NGXS
|
|
972
|
-
* readonly items = select(MyState.getItems);
|
|
973
|
-
*
|
|
974
|
-
* // Loading/Error slices - memoized by NGXS
|
|
975
|
-
* private readonly loadingActive = select(MyState.getLoadingActive);
|
|
976
|
-
* private readonly errors = select(MyState.getErrors);
|
|
977
|
-
*
|
|
978
|
-
* // Loading signals - computed from slice (minimal reactivity)
|
|
979
|
-
* readonly isLoadingItems = computed(() =>
|
|
980
|
-
* this.loadingActive().includes(MyActionKey.GetItems)
|
|
981
|
-
* );
|
|
982
|
-
*
|
|
983
|
-
* // Error signals - computed from slice (minimal reactivity)
|
|
984
|
-
* readonly itemsError = computed(() =>
|
|
985
|
-
* this.errors()[MyActionKey.GetItems] ?? null
|
|
986
|
-
* );
|
|
987
|
-
*
|
|
988
|
-
* // Dispatchers
|
|
989
|
-
* loadItems() {
|
|
990
|
-
* return this.store.dispatch(new GetItems());
|
|
991
|
-
* }
|
|
992
|
-
* }
|
|
993
|
-
* ```
|
|
994
|
-
*
|
|
995
|
-
* **Template Usage:**
|
|
996
|
-
* ```html
|
|
997
|
-
* @if (facade.isLoadingItems()) {
|
|
998
|
-
* <loading-spinner />
|
|
999
|
-
* } @else if (facade.itemsError(); as error) {
|
|
1000
|
-
* <error-alert>{{ error }}</error-alert>
|
|
1001
|
-
* } @else {
|
|
1002
|
-
* @for (item of facade.items(); track item.id) {
|
|
1003
|
-
* <item-card [item]="item" />
|
|
1004
|
-
* }
|
|
1005
|
-
* }
|
|
1006
|
-
* ```
|
|
1007
|
-
*/
|
|
1008
|
-
class BaseFacade {
|
|
1009
|
-
/**
|
|
1010
|
-
* Creates a query object with separate signals for data, loading, and error states
|
|
1011
|
-
* Each property is its own signal for granular reactivity
|
|
1012
|
-
*
|
|
1013
|
-
* @example
|
|
1014
|
-
* readonly modulesQuery = this.query(
|
|
1015
|
-
* 'getModulesLoading',
|
|
1016
|
-
* (state) => state.allModules
|
|
1017
|
-
* );
|
|
1018
|
-
*
|
|
1019
|
-
* // In template - each is a separate signal:
|
|
1020
|
-
* @if (modulesQuery.isPending()) { Loading... }
|
|
1021
|
-
* @if (modulesQuery.error(); as error) { Error: {{ error }} }
|
|
1022
|
-
* @if (modulesQuery.data(); as modules) {
|
|
1023
|
-
* <div *ngFor="let m of modules">{{ m.title }}</div>
|
|
1024
|
-
* }
|
|
1025
|
-
*/
|
|
1026
|
-
query(loadingKey, dataSelector) {
|
|
1027
|
-
const stateSignal = this.state();
|
|
1028
|
-
const isPending = computed(() => {
|
|
1029
|
-
const currentState = stateSignal();
|
|
1030
|
-
return currentState.loadingActive?.includes(loadingKey) ?? false;
|
|
1031
|
-
}, ...(ngDevMode ? [{ debugName: "isPending" }] : []));
|
|
1032
|
-
const error = computed(() => {
|
|
1033
|
-
const currentState = stateSignal();
|
|
1034
|
-
return currentState.errors?.[loadingKey] ?? null;
|
|
1035
|
-
}, ...(ngDevMode ? [{ debugName: "error" }] : []));
|
|
1036
|
-
const data = computed(() => {
|
|
1037
|
-
const currentState = stateSignal();
|
|
1038
|
-
const hasError = currentState.errors?.[loadingKey];
|
|
1039
|
-
return hasError ? null : dataSelector(currentState);
|
|
1040
|
-
}, ...(ngDevMode ? [{ debugName: "data" }] : []));
|
|
1041
|
-
const isSuccess = computed(() => !isPending() && !error() && data() !== null, ...(ngDevMode ? [{ debugName: "isSuccess" }] : []));
|
|
1042
|
-
const isError = computed(() => !!error(), ...(ngDevMode ? [{ debugName: "isError" }] : []));
|
|
1043
|
-
return {
|
|
1044
|
-
data,
|
|
1045
|
-
isPending,
|
|
1046
|
-
isSuccess,
|
|
1047
|
-
isError,
|
|
1048
|
-
error,
|
|
1049
|
-
};
|
|
1050
|
-
}
|
|
1051
|
-
/**
|
|
1052
|
-
* Creates a loading signal for a specific operation
|
|
1053
|
-
*/
|
|
1054
|
-
loading(loadingKey) {
|
|
1055
|
-
const stateSignal = this.state();
|
|
1056
|
-
return computed(() => {
|
|
1057
|
-
const currentState = stateSignal();
|
|
1058
|
-
return currentState.loadingActive?.includes(loadingKey) ?? false;
|
|
1059
|
-
});
|
|
1060
|
-
}
|
|
1061
|
-
/**
|
|
1062
|
-
* Creates an error signal for a specific operation
|
|
1063
|
-
*/
|
|
1064
|
-
errorSignal(loadingKey) {
|
|
1065
|
-
const stateSignal = this.state();
|
|
1066
|
-
return computed(() => {
|
|
1067
|
-
const currentState = stateSignal();
|
|
1068
|
-
return currentState.errors?.[loadingKey] ?? null;
|
|
1069
|
-
});
|
|
1070
|
-
}
|
|
1071
|
-
}
|
|
1072
|
-
|
|
1073
|
-
function createEntityAdapter() {
|
|
1074
|
-
return {
|
|
1075
|
-
addOne: (state, entity) => [...state, entity],
|
|
1076
|
-
upsertOne: (state, entity, uniqueKey = 'id') => {
|
|
1077
|
-
const key = entity[uniqueKey];
|
|
1078
|
-
if (key == null)
|
|
1079
|
-
return state;
|
|
1080
|
-
const index = state.findIndex((e) => e[uniqueKey] === key);
|
|
1081
|
-
if (index === -1) {
|
|
1082
|
-
return [...state, entity];
|
|
1083
|
-
}
|
|
1084
|
-
const clone = [...state];
|
|
1085
|
-
clone[index] = entity;
|
|
1086
|
-
return clone;
|
|
1087
|
-
},
|
|
1088
|
-
updateOne: (state, id, changes, uniqueKey = 'id') => state.map((e) => (e[uniqueKey] === id ? { ...e, ...changes } : e)),
|
|
1089
|
-
removeOne: (state, id, uniqueKey = 'id') => state.filter((e) => e[uniqueKey] !== id),
|
|
1090
|
-
setAll: (_state, entities) => [...entities],
|
|
1091
|
-
};
|
|
1092
|
-
}
|
|
1093
|
-
|
|
1094
|
-
function startLoading(ctx, loadingName) {
|
|
1095
|
-
const { loadingActive, errors } = ctx.getState();
|
|
1096
|
-
if (!loadingActive.includes(loadingName)) {
|
|
1097
|
-
ctx.patchState({
|
|
1098
|
-
loadingActive: [...loadingActive, loadingName],
|
|
1099
|
-
});
|
|
1100
|
-
}
|
|
1101
|
-
if (errors && errors[loadingName]) {
|
|
1102
|
-
const { [loadingName]: _removed, ...rest } = errors;
|
|
1103
|
-
ctx.patchState({ errors: rest });
|
|
1104
|
-
}
|
|
1105
|
-
}
|
|
1106
|
-
function endLoading(ctx, loadingName) {
|
|
1107
|
-
const { loadingActive } = ctx.getState();
|
|
1108
|
-
ctx.patchState({
|
|
1109
|
-
loadingActive: loadingActive.filter((name) => name !== loadingName),
|
|
1110
|
-
});
|
|
1111
|
-
}
|
|
1112
|
-
function setLoadingError(ctx, loadingName, message) {
|
|
1113
|
-
const { errors } = ctx.getState();
|
|
1114
|
-
ctx.patchState({
|
|
1115
|
-
errors: { ...errors, [loadingName]: message },
|
|
1116
|
-
});
|
|
1117
|
-
}
|
|
1118
|
-
|
|
1119
|
-
function handleApiRequest(config) {
|
|
1120
|
-
const { ctx, key, request$, onSuccess, onError, errorMessage } = config;
|
|
1121
|
-
startLoading(ctx, key);
|
|
1122
|
-
return request$.pipe(tap((response) => {
|
|
1123
|
-
const state = ctx.getState();
|
|
1124
|
-
const patch = onSuccess(response, state);
|
|
1125
|
-
if (patch) {
|
|
1126
|
-
ctx.patchState(patch);
|
|
1127
|
-
}
|
|
1128
|
-
}), catchError((error) => {
|
|
1129
|
-
const state = ctx.getState();
|
|
1130
|
-
const message = error?.error?.message ?? error?.message ?? errorMessage;
|
|
1131
|
-
setLoadingError(ctx, key, message);
|
|
1132
|
-
// Call onError callback if provided
|
|
1133
|
-
if (onError) {
|
|
1134
|
-
const patch = onError(error, state);
|
|
1135
|
-
if (patch) {
|
|
1136
|
-
ctx.patchState(patch);
|
|
1137
|
-
}
|
|
1138
|
-
}
|
|
1139
|
-
throw error;
|
|
1140
|
-
}), finalize(() => endLoading(ctx, key)));
|
|
1141
|
-
}
|
|
1142
|
-
|
|
1143
|
-
/**
|
|
1144
|
-
* T = entity type (Module, User, ...)
|
|
1145
|
-
* TState = full state model (must include LoadingStateShape)
|
|
1146
|
-
* TLoad = union type of loading keys for this feature
|
|
1147
|
-
*/
|
|
1148
|
-
class CrudStateBase {
|
|
1149
|
-
adapter = createEntityAdapter();
|
|
1150
|
-
/**
|
|
1151
|
-
* Helper to create default updateState function
|
|
1152
|
-
*/
|
|
1153
|
-
getDefaultUpdateState(stateProperty) {
|
|
1154
|
-
// Try to extract the property name from the stateProperty function
|
|
1155
|
-
const funcStr = stateProperty.toString();
|
|
1156
|
-
const match = funcStr.match(/\.([a-zA-Z_$][a-zA-Z0-9_$]*)/); // Match .propertyName
|
|
1157
|
-
const key = match ? match[1] : 'items';
|
|
1158
|
-
return (state, items) => ({ [key]: items });
|
|
1159
|
-
}
|
|
1160
|
-
/**
|
|
1161
|
-
* @deprecated Use `handleApiRequest` directly with `onSuccess` callback.
|
|
1162
|
-
* The `load()` method provides no significant benefit over `handleApiRequest`.
|
|
1163
|
-
*
|
|
1164
|
-
* @example
|
|
1165
|
-
* // Instead of this.load(), use:
|
|
1166
|
-
* return handleApiRequest({
|
|
1167
|
-
* ctx,
|
|
1168
|
-
* key: ActionKey.GetItems,
|
|
1169
|
-
* request$: req$,
|
|
1170
|
-
* onSuccess: (response) => ({
|
|
1171
|
-
* items: response.data ?? [],
|
|
1172
|
-
* }),
|
|
1173
|
-
* });
|
|
1174
|
-
*/
|
|
1175
|
-
load(ctx, config) {
|
|
1176
|
-
return handleApiRequest({
|
|
1177
|
-
ctx,
|
|
1178
|
-
key: config.key,
|
|
1179
|
-
request$: config.request$,
|
|
1180
|
-
onSuccess: (response, state) => {
|
|
1181
|
-
const data = config.transform
|
|
1182
|
-
? config.transform(response.data)
|
|
1183
|
-
: response.data;
|
|
1184
|
-
// If stateProperty provided, use adapter for array operations
|
|
1185
|
-
if (config.stateProperty) {
|
|
1186
|
-
const items = this.adapter.setAll(config.stateProperty(state), data);
|
|
1187
|
-
const updateState = config.updateState ??
|
|
1188
|
-
this.getDefaultUpdateState(config.stateProperty);
|
|
1189
|
-
return updateState(state, items);
|
|
1190
|
-
}
|
|
1191
|
-
// Otherwise, use custom updateState directly
|
|
1192
|
-
if (config.updateState) {
|
|
1193
|
-
return config.updateState(state, data);
|
|
1194
|
-
}
|
|
1195
|
-
throw new Error('Either stateProperty or updateState must be provided');
|
|
1196
|
-
},
|
|
1197
|
-
onError: config.onError,
|
|
1198
|
-
errorMessage: config.errorMessage ?? 'Failed to load data',
|
|
1199
|
-
});
|
|
1200
|
-
}
|
|
1201
|
-
/**
|
|
1202
|
-
* Create one entity with config object
|
|
1203
|
-
*/
|
|
1204
|
-
create(ctx, config) {
|
|
1205
|
-
const updateState = config.updateState ?? this.getDefaultUpdateState(config.stateProperty);
|
|
1206
|
-
return handleApiRequest({
|
|
1207
|
-
ctx,
|
|
1208
|
-
key: config.key,
|
|
1209
|
-
request$: config.request$,
|
|
1210
|
-
onSuccess: (response, state) => {
|
|
1211
|
-
const entity = config.transform
|
|
1212
|
-
? config.transform(response.data)
|
|
1213
|
-
: response.data;
|
|
1214
|
-
const items = this.adapter.addOne(config.stateProperty(state), entity);
|
|
1215
|
-
return updateState(state, items);
|
|
1216
|
-
},
|
|
1217
|
-
onError: config.onError,
|
|
1218
|
-
errorMessage: config.errorMessage ?? 'Failed to create item',
|
|
1219
|
-
});
|
|
1220
|
-
}
|
|
1221
|
-
/**
|
|
1222
|
-
* Update one entity with config object
|
|
1223
|
-
*/
|
|
1224
|
-
update(ctx, config) {
|
|
1225
|
-
const updateState = config.updateState ?? this.getDefaultUpdateState(config.stateProperty);
|
|
1226
|
-
return handleApiRequest({
|
|
1227
|
-
ctx,
|
|
1228
|
-
key: config.key,
|
|
1229
|
-
request$: config.request$,
|
|
1230
|
-
onSuccess: (response, state) => {
|
|
1231
|
-
const entity = config.transform
|
|
1232
|
-
? config.transform(response.data)
|
|
1233
|
-
: response.data;
|
|
1234
|
-
const items = this.adapter.upsertOne(config.stateProperty(state), entity, config.uniqueKey);
|
|
1235
|
-
return updateState(state, items);
|
|
1236
|
-
},
|
|
1237
|
-
onError: config.onError,
|
|
1238
|
-
errorMessage: config.errorMessage ?? 'Failed to update item',
|
|
1239
|
-
});
|
|
1240
|
-
}
|
|
1241
|
-
/**
|
|
1242
|
-
* Delete one entity with config object
|
|
1243
|
-
*/
|
|
1244
|
-
delete(ctx, config) {
|
|
1245
|
-
const updateState = config.updateState ?? this.getDefaultUpdateState(config.stateProperty);
|
|
1246
|
-
return handleApiRequest({
|
|
1247
|
-
ctx,
|
|
1248
|
-
key: config.key,
|
|
1249
|
-
request$: config.request$,
|
|
1250
|
-
onSuccess: (_response, state) => {
|
|
1251
|
-
const items = this.adapter.removeOne(config.stateProperty(state), config.id, config.uniqueKey);
|
|
1252
|
-
return updateState(state, items);
|
|
1253
|
-
},
|
|
1254
|
-
onError: config.onError,
|
|
1255
|
-
errorMessage: config.errorMessage ?? 'Failed to delete item',
|
|
1256
|
-
});
|
|
1257
|
-
}
|
|
1258
|
-
}
|
|
1259
|
-
|
|
1260
|
-
function isInvalid(control) {
|
|
1261
|
-
if (!control)
|
|
1262
|
-
return false;
|
|
1263
|
-
return control && control?.invalid && control?.touched;
|
|
1264
|
-
}
|
|
1265
|
-
|
|
1266
|
-
/**
|
|
1267
|
-
* Shared HTTP context token for request configuration.
|
|
1268
|
-
* Used by interceptors to determine base URL routing.
|
|
1269
|
-
*
|
|
1270
|
-
* @example
|
|
1271
|
-
* ```typescript
|
|
1272
|
-
* import { REQUEST_CONTEXT } from '@masterteam/components';
|
|
1273
|
-
*
|
|
1274
|
-
* // In a service
|
|
1275
|
-
* private context = new HttpContext().set(REQUEST_CONTEXT, { useBaseUrl: true });
|
|
1276
|
-
*
|
|
1277
|
-
* getMetadata(): Observable<any> {
|
|
1278
|
-
* return this.http.get('metadata', { context: this.context });
|
|
1279
|
-
* }
|
|
1280
|
-
*
|
|
1281
|
-
* // In interceptor
|
|
1282
|
-
* const config = req.context.get(REQUEST_CONTEXT);
|
|
1283
|
-
* if (config?.useBaseUrl) {
|
|
1284
|
-
* // Use base URL
|
|
1285
|
-
* }
|
|
1286
|
-
* ```
|
|
1287
|
-
*/
|
|
1288
|
-
const REQUEST_CONTEXT = new HttpContextToken(() => ({ useBaseUrl: false }));
|
|
1289
|
-
|
|
1290
|
-
/**
|
|
1291
|
-
* Color utility functions for brand display.
|
|
1292
|
-
*/
|
|
1293
|
-
/**
|
|
1294
|
-
* Converts a hex color to a light shade (equivalent to primary-100 in Tailwind).
|
|
1295
|
-
* This creates a color with ~10% opacity or a very light tint by mixing with white.
|
|
1296
|
-
*/
|
|
1297
|
-
function getLightColor(hexColor) {
|
|
1298
|
-
const hex = hexColor.replace('#', '');
|
|
1299
|
-
const r = parseInt(hex.substring(0, 2), 16);
|
|
1300
|
-
const g = parseInt(hex.substring(2, 4), 16);
|
|
1301
|
-
const b = parseInt(hex.substring(4, 6), 16);
|
|
1302
|
-
const lightR = Math.round(r * 0.1 + 255 * 0.9);
|
|
1303
|
-
const lightG = Math.round(g * 0.1 + 255 * 0.9);
|
|
1304
|
-
const lightB = Math.round(b * 0.1 + 255 * 0.9);
|
|
1305
|
-
return `#${lightR.toString(16).padStart(2, '0')}${lightG
|
|
1306
|
-
.toString(16)
|
|
1307
|
-
.padStart(2, '0')}${lightB.toString(16).padStart(2, '0')}`;
|
|
1308
|
-
}
|
|
1309
|
-
function getContrastColor(bgColor) {
|
|
1310
|
-
let r = 0, g = 0, b = 0;
|
|
1311
|
-
if (bgColor.startsWith('#')) {
|
|
1312
|
-
const hex = bgColor.slice(1);
|
|
1313
|
-
if (hex.length === 3) {
|
|
1314
|
-
r = parseInt(hex[0] + hex[0], 16);
|
|
1315
|
-
g = parseInt(hex[1] + hex[1], 16);
|
|
1316
|
-
b = parseInt(hex[2] + hex[2], 16);
|
|
1317
|
-
}
|
|
1318
|
-
else if (hex.length === 6) {
|
|
1319
|
-
r = parseInt(hex.slice(0, 2), 16);
|
|
1320
|
-
g = parseInt(hex.slice(2, 4), 16);
|
|
1321
|
-
b = parseInt(hex.slice(4, 6), 16);
|
|
1322
|
-
}
|
|
1323
|
-
}
|
|
1324
|
-
const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
|
|
1325
|
-
return luminance > 0.5 ? '' : '#ffffff';
|
|
1326
|
-
}
|
|
1327
|
-
|
|
1328
|
-
/*
|
|
1329
|
-
* Public API Surface of components
|
|
1330
|
-
*/
|
|
1331
|
-
// Config
|
|
1332
|
-
|
|
1333
|
-
/**
|
|
1334
|
-
* Generated bundle index. Do not edit.
|
|
1335
|
-
*/
|
|
1336
|
-
|
|
1337
|
-
export { BaseFacade, BaseFieldConfig, CheckboxFieldConfig, ColorPickerFieldConfig, CrudStateBase, DateFieldConfig, EditorFieldConfig, IconFieldConfig, MultiSelectFieldConfig, NumberFieldConfig, PickListFieldConfig, REQUEST_CONTEXT, RadioButtonFieldConfig, RadioCardsFieldConfig, SchemaConnectionFieldConfig, SelectFieldConfig, SliderFieldConfig, SpacerFieldConfig, TextFieldConfig, TextareaFieldConfig, ToggleFieldConfig, UploadFileFieldConfig, UserSearchFieldConfig, ValidatorConfig, changeBackgroundColor, changePrimaryColor, changeTextColor, createCustomValidator, createEntityAdapter, endLoading, generateTailwindPalette, getContrastColor, getLightColor, handleApiRequest, isInvalid, provideMTComponents, provideMTConfirmation, provideMTMessages, setLoadingError, startLoading, wrapValidatorWithMessage };
|
|
1338
|
-
//# sourceMappingURL=masterteam-components.mjs.map
|