cmat 0.0.87 → 0.0.89

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (228) hide show
  1. package/fesm2022/cmat-components-adapter.mjs +9 -9
  2. package/fesm2022/cmat-components-adapter.mjs.map +1 -1
  3. package/fesm2022/cmat-components-breadcrumb.mjs +98 -80
  4. package/fesm2022/cmat-components-breadcrumb.mjs.map +1 -1
  5. package/fesm2022/cmat-components-card.mjs +26 -34
  6. package/fesm2022/cmat-components-card.mjs.map +1 -1
  7. package/fesm2022/cmat-components-carousel.mjs +467 -556
  8. package/fesm2022/cmat-components-carousel.mjs.map +1 -1
  9. package/fesm2022/cmat-components-cascade.mjs +272 -259
  10. package/fesm2022/cmat-components-cascade.mjs.map +1 -1
  11. package/fesm2022/cmat-components-chip-input.mjs +200 -116
  12. package/fesm2022/cmat-components-chip-input.mjs.map +1 -1
  13. package/fesm2022/cmat-components-code-editor.mjs +85 -38
  14. package/fesm2022/cmat-components-code-editor.mjs.map +1 -1
  15. package/fesm2022/cmat-components-color-picker.mjs +841 -0
  16. package/fesm2022/cmat-components-color-picker.mjs.map +1 -0
  17. package/fesm2022/cmat-components-custom-formly.mjs +1396 -838
  18. package/fesm2022/cmat-components-custom-formly.mjs.map +1 -1
  19. package/fesm2022/cmat-components-data-picker.mjs +999 -0
  20. package/fesm2022/cmat-components-data-picker.mjs.map +1 -0
  21. package/fesm2022/cmat-components-date-range.mjs +310 -264
  22. package/fesm2022/cmat-components-date-range.mjs.map +1 -1
  23. package/fesm2022/cmat-components-date-time-display.mjs +16 -20
  24. package/fesm2022/cmat-components-date-time-display.mjs.map +1 -1
  25. package/fesm2022/cmat-components-drawer.mjs +120 -137
  26. package/fesm2022/cmat-components-drawer.mjs.map +1 -1
  27. package/fesm2022/cmat-components-empty-state.mjs +17 -24
  28. package/fesm2022/cmat-components-empty-state.mjs.map +1 -1
  29. package/fesm2022/cmat-components-file-preview.mjs +18 -24
  30. package/fesm2022/cmat-components-file-preview.mjs.map +1 -1
  31. package/fesm2022/cmat-components-filter-toolbar.mjs +30 -39
  32. package/fesm2022/cmat-components-filter-toolbar.mjs.map +1 -1
  33. package/fesm2022/cmat-components-form-actions.mjs +12 -12
  34. package/fesm2022/cmat-components-form-actions.mjs.map +1 -1
  35. package/fesm2022/cmat-components-fullscreen.mjs +10 -10
  36. package/fesm2022/cmat-components-fullscreen.mjs.map +1 -1
  37. package/fesm2022/cmat-components-highlight.mjs +49 -41
  38. package/fesm2022/cmat-components-highlight.mjs.map +1 -1
  39. package/fesm2022/cmat-components-image-viewer.mjs +104 -107
  40. package/fesm2022/cmat-components-image-viewer.mjs.map +1 -1
  41. package/fesm2022/cmat-components-inline-loading.mjs +12 -15
  42. package/fesm2022/cmat-components-inline-loading.mjs.map +1 -1
  43. package/fesm2022/cmat-components-json-editor.mjs +118 -75
  44. package/fesm2022/cmat-components-json-editor.mjs.map +1 -1
  45. package/fesm2022/cmat-components-knob-input.mjs +196 -178
  46. package/fesm2022/cmat-components-knob-input.mjs.map +1 -1
  47. package/fesm2022/cmat-components-masonry.mjs +26 -41
  48. package/fesm2022/cmat-components-masonry.mjs.map +1 -1
  49. package/fesm2022/cmat-components-material-color-picker.mjs +81 -80
  50. package/fesm2022/cmat-components-material-color-picker.mjs.map +1 -1
  51. package/fesm2022/cmat-components-material-datetimepicker.mjs +1213 -1287
  52. package/fesm2022/cmat-components-material-datetimepicker.mjs.map +1 -1
  53. package/fesm2022/cmat-components-navigation.mjs +467 -450
  54. package/fesm2022/cmat-components-navigation.mjs.map +1 -1
  55. package/fesm2022/cmat-components-opt-input.mjs +143 -132
  56. package/fesm2022/cmat-components-opt-input.mjs.map +1 -1
  57. package/fesm2022/cmat-components-org-chart.mjs +68 -83
  58. package/fesm2022/cmat-components-org-chart.mjs.map +1 -1
  59. package/fesm2022/cmat-components-page-header.mjs +18 -24
  60. package/fesm2022/cmat-components-page-header.mjs.map +1 -1
  61. package/fesm2022/cmat-components-pagination.mjs +220 -136
  62. package/fesm2022/cmat-components-pagination.mjs.map +1 -1
  63. package/fesm2022/cmat-components-password-strength.mjs +262 -215
  64. package/fesm2022/cmat-components-password-strength.mjs.map +1 -1
  65. package/fesm2022/cmat-components-popover.mjs +227 -195
  66. package/fesm2022/cmat-components-popover.mjs.map +1 -1
  67. package/fesm2022/cmat-components-progress-bar.mjs +15 -34
  68. package/fesm2022/cmat-components-progress-bar.mjs.map +1 -1
  69. package/fesm2022/cmat-components-qrcode.mjs +96 -88
  70. package/fesm2022/cmat-components-qrcode.mjs.map +1 -1
  71. package/fesm2022/cmat-components-rating.mjs +70 -67
  72. package/fesm2022/cmat-components-rating.mjs.map +1 -1
  73. package/fesm2022/cmat-components-rich-text-editor.mjs +23 -26
  74. package/fesm2022/cmat-components-rich-text-editor.mjs.map +1 -1
  75. package/fesm2022/cmat-components-select-search.mjs +192 -160
  76. package/fesm2022/cmat-components-select-search.mjs.map +1 -1
  77. package/fesm2022/cmat-components-select-table.mjs +276 -213
  78. package/fesm2022/cmat-components-select-table.mjs.map +1 -1
  79. package/fesm2022/cmat-components-select-tree.mjs +178 -128
  80. package/fesm2022/cmat-components-select-tree.mjs.map +1 -1
  81. package/fesm2022/cmat-components-skeleton.mjs +44 -28
  82. package/fesm2022/cmat-components-skeleton.mjs.map +1 -1
  83. package/fesm2022/cmat-components-speed-dial.mjs +108 -163
  84. package/fesm2022/cmat-components-speed-dial.mjs.map +1 -1
  85. package/fesm2022/cmat-components-status-tag.mjs +29 -36
  86. package/fesm2022/cmat-components-status-tag.mjs.map +1 -1
  87. package/fesm2022/cmat-components-table-toolbar.mjs +14 -18
  88. package/fesm2022/cmat-components-table-toolbar.mjs.map +1 -1
  89. package/fesm2022/cmat-components-timeline.mjs +111 -118
  90. package/fesm2022/cmat-components-timeline.mjs.map +1 -1
  91. package/fesm2022/cmat-components-toast.mjs +65 -66
  92. package/fesm2022/cmat-components-toast.mjs.map +1 -1
  93. package/fesm2022/cmat-components-transfer-picker.mjs +131 -160
  94. package/fesm2022/cmat-components-transfer-picker.mjs.map +1 -1
  95. package/fesm2022/cmat-components-treetable.mjs +32 -39
  96. package/fesm2022/cmat-components-treetable.mjs.map +1 -1
  97. package/fesm2022/cmat-components-upload.mjs +186 -176
  98. package/fesm2022/cmat-components-upload.mjs.map +1 -1
  99. package/fesm2022/cmat-directives-animate-on-scroll.mjs +25 -28
  100. package/fesm2022/cmat-directives-animate-on-scroll.mjs.map +1 -1
  101. package/fesm2022/cmat-directives-arrow-cursor.mjs +85 -92
  102. package/fesm2022/cmat-directives-arrow-cursor.mjs.map +1 -1
  103. package/fesm2022/cmat-directives-autofocus.mjs +3 -3
  104. package/fesm2022/cmat-directives-autofocus.mjs.map +1 -1
  105. package/fesm2022/cmat-directives-data-exporter.mjs +49 -50
  106. package/fesm2022/cmat-directives-data-exporter.mjs.map +1 -1
  107. package/fesm2022/cmat-directives-debounce.mjs +16 -19
  108. package/fesm2022/cmat-directives-debounce.mjs.map +1 -1
  109. package/fesm2022/cmat-directives-digit-only.mjs +60 -69
  110. package/fesm2022/cmat-directives-digit-only.mjs.map +1 -1
  111. package/fesm2022/cmat-directives-equal-validator.mjs +3 -3
  112. package/fesm2022/cmat-directives-equal-validator.mjs.map +1 -1
  113. package/fesm2022/cmat-directives-seamless-auto-scroll.mjs +32 -30
  114. package/fesm2022/cmat-directives-seamless-auto-scroll.mjs.map +1 -1
  115. package/fesm2022/cmat-lib-mock-api.mjs +6 -6
  116. package/fesm2022/cmat-lib-mock-api.mjs.map +1 -1
  117. package/fesm2022/cmat-pipes-bytes.mjs +3 -3
  118. package/fesm2022/cmat-pipes-bytes.mjs.map +1 -1
  119. package/fesm2022/cmat-pipes-date-format.mjs +3 -3
  120. package/fesm2022/cmat-pipes-date-format.mjs.map +1 -1
  121. package/fesm2022/cmat-pipes-find-by-key.mjs +3 -3
  122. package/fesm2022/cmat-pipes-find-by-key.mjs.map +1 -1
  123. package/fesm2022/cmat-pipes-group-by.mjs +3 -3
  124. package/fesm2022/cmat-pipes-group-by.mjs.map +1 -1
  125. package/fesm2022/cmat-pipes-keys.mjs +3 -3
  126. package/fesm2022/cmat-pipes-keys.mjs.map +1 -1
  127. package/fesm2022/cmat-pipes-secure.mjs +7 -13
  128. package/fesm2022/cmat-pipes-secure.mjs.map +1 -1
  129. package/fesm2022/cmat-pipes-uppercase.mjs +3 -3
  130. package/fesm2022/cmat-pipes-uppercase.mjs.map +1 -1
  131. package/fesm2022/cmat-services-alert.mjs +26 -27
  132. package/fesm2022/cmat-services-alert.mjs.map +1 -1
  133. package/fesm2022/cmat-services-config.mjs +14 -23
  134. package/fesm2022/cmat-services-config.mjs.map +1 -1
  135. package/fesm2022/cmat-services-confirmation.mjs +8 -8
  136. package/fesm2022/cmat-services-confirmation.mjs.map +1 -1
  137. package/fesm2022/cmat-services-data.mjs +6 -10
  138. package/fesm2022/cmat-services-data.mjs.map +1 -1
  139. package/fesm2022/cmat-services-export-as.mjs +3 -3
  140. package/fesm2022/cmat-services-export-as.mjs.map +1 -1
  141. package/fesm2022/cmat-services-loading.mjs +30 -47
  142. package/fesm2022/cmat-services-loading.mjs.map +1 -1
  143. package/fesm2022/cmat-services-local-storage.mjs +3 -3
  144. package/fesm2022/cmat-services-local-storage.mjs.map +1 -1
  145. package/fesm2022/cmat-services-media-watcher.mjs +43 -34
  146. package/fesm2022/cmat-services-media-watcher.mjs.map +1 -1
  147. package/fesm2022/cmat-services-platform.mjs +3 -3
  148. package/fesm2022/cmat-services-platform.mjs.map +1 -1
  149. package/fesm2022/cmat-services-splash-screen.mjs +3 -3
  150. package/fesm2022/cmat-services-splash-screen.mjs.map +1 -1
  151. package/fesm2022/cmat-services-title.mjs +3 -3
  152. package/fesm2022/cmat-services-title.mjs.map +1 -1
  153. package/fesm2022/cmat-services-translation.mjs +11 -11
  154. package/fesm2022/cmat-services-translation.mjs.map +1 -1
  155. package/fesm2022/cmat-services-utils.mjs +3 -3
  156. package/fesm2022/cmat-services-utils.mjs.map +1 -1
  157. package/fesm2022/cmat.mjs +9241 -7507
  158. package/fesm2022/cmat.mjs.map +1 -1
  159. package/icons/material-icons/heroicons-outline.svg +3 -0
  160. package/icons/material-icons/heroicons-solid.svg +3 -0
  161. package/package.json +10 -1
  162. package/styles/components/bundle.scss +21 -0
  163. package/styles/overrides/angular-material.scss +32 -10
  164. package/tailwind/plugins/theming.js +183 -183
  165. package/types/cmat-components-breadcrumb.d.ts +40 -37
  166. package/types/cmat-components-card.d.ts +11 -13
  167. package/types/cmat-components-carousel.d.ts +87 -113
  168. package/types/cmat-components-cascade.d.ts +84 -65
  169. package/types/cmat-components-chip-input.d.ts +29 -24
  170. package/types/cmat-components-code-editor.d.ts +28 -12
  171. package/types/cmat-components-color-picker.d.ts +236 -0
  172. package/types/cmat-components-custom-formly.d.ts +316 -184
  173. package/types/cmat-components-data-picker.d.ts +372 -0
  174. package/types/cmat-components-date-range.d.ts +31 -36
  175. package/types/cmat-components-date-time-display.d.ts +8 -8
  176. package/types/cmat-components-drawer.d.ts +30 -32
  177. package/types/cmat-components-empty-state.d.ts +9 -10
  178. package/types/cmat-components-file-preview.d.ts +9 -9
  179. package/types/cmat-components-filter-toolbar.d.ts +15 -15
  180. package/types/cmat-components-form-actions.d.ts +5 -5
  181. package/types/cmat-components-fullscreen.d.ts +5 -5
  182. package/types/cmat-components-highlight.d.ts +13 -14
  183. package/types/cmat-components-image-viewer.d.ts +29 -33
  184. package/types/cmat-components-inline-loading.d.ts +6 -6
  185. package/types/cmat-components-json-editor.d.ts +15 -17
  186. package/types/cmat-components-knob-input.d.ts +58 -55
  187. package/types/cmat-components-masonry.d.ts +9 -12
  188. package/types/cmat-components-material-color-picker.d.ts +16 -21
  189. package/types/cmat-components-material-datetimepicker.d.ts +174 -216
  190. package/types/cmat-components-navigation.d.ts +34 -39
  191. package/types/cmat-components-opt-input.d.ts +35 -33
  192. package/types/cmat-components-org-chart.d.ts +8 -9
  193. package/types/cmat-components-page-header.d.ts +9 -9
  194. package/types/cmat-components-pagination.d.ts +36 -40
  195. package/types/cmat-components-password-strength.d.ts +58 -64
  196. package/types/cmat-components-popover.d.ts +22 -32
  197. package/types/cmat-components-progress-bar.d.ts +7 -10
  198. package/types/cmat-components-qrcode.d.ts +22 -22
  199. package/types/cmat-components-rating.d.ts +17 -19
  200. package/types/cmat-components-rich-text-editor.d.ts +11 -12
  201. package/types/cmat-components-select-search.d.ts +48 -36
  202. package/types/cmat-components-select-table.d.ts +38 -34
  203. package/types/cmat-components-select-tree.d.ts +17 -15
  204. package/types/cmat-components-skeleton.d.ts +27 -10
  205. package/types/cmat-components-speed-dial.d.ts +24 -33
  206. package/types/cmat-components-status-tag.d.ts +19 -9
  207. package/types/cmat-components-table-toolbar.d.ts +7 -7
  208. package/types/cmat-components-timeline.d.ts +33 -34
  209. package/types/cmat-components-toast.d.ts +26 -30
  210. package/types/cmat-components-transfer-picker.d.ts +51 -56
  211. package/types/cmat-components-treetable.d.ts +12 -13
  212. package/types/cmat-components-upload.d.ts +33 -38
  213. package/types/cmat-components-x6-angular-shape.d.ts +1 -1
  214. package/types/cmat-directives-animate-on-scroll.d.ts +7 -7
  215. package/types/cmat-directives-arrow-cursor.d.ts +18 -20
  216. package/types/cmat-directives-data-exporter.d.ts +10 -10
  217. package/types/cmat-directives-debounce.d.ts +5 -5
  218. package/types/cmat-directives-digit-only.d.ts +13 -13
  219. package/types/cmat-directives-seamless-auto-scroll.d.ts +7 -7
  220. package/types/cmat-pipes-secure.d.ts +1 -3
  221. package/types/cmat-services-alert.d.ts +11 -12
  222. package/types/cmat-services-config.d.ts +2 -7
  223. package/types/cmat-services-confirmation.d.ts +2 -2
  224. package/types/cmat-services-data.d.ts +0 -1
  225. package/types/cmat-services-loading.d.ts +14 -22
  226. package/types/cmat-services-media-watcher.d.ts +5 -5
  227. package/types/cmat-services-translation.d.ts +4 -5
  228. package/types/cmat.d.ts +2167 -1746
@@ -1,6 +1,9 @@
1
- import { isNil, isString, isArray, isUndefined } from 'lodash-es';
1
+ import { HttpClient, HttpEventType } from '@angular/common/http';
2
2
  import * as i0 from '@angular/core';
3
- import { ViewChild, Component, ChangeDetectionStrategy, inject, Renderer2, ElementRef, ViewEncapsulation, signal, DestroyRef, ViewChildren, ViewContainerRef } from '@angular/core';
3
+ import { inject, Injectable, viewChild, Component, ChangeDetectionStrategy, Renderer2, ElementRef, ViewEncapsulation, signal, computed, DestroyRef, ViewContainerRef } from '@angular/core';
4
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
5
+ import { catchError, of } from 'rxjs';
6
+ import { isNil, isString, isEqual, isArray, isUndefined } from 'lodash-es';
4
7
  import * as i2 from '@angular/material/icon';
5
8
  import { MatIconModule } from '@angular/material/icon';
6
9
  import * as i1$3 from '@ngx-formly/core';
@@ -14,22 +17,21 @@ import { FocusMonitor } from '@angular/cdk/a11y';
14
17
  import * as i2$1 from '@angular/common';
15
18
  import { CommonModule, NgClass, AsyncPipe, NgStyle, NgTemplateOutlet } from '@angular/common';
16
19
  import * as i1$4 from '@angular/forms';
17
- import { ReactiveFormsModule, FormsModule, FormControl, FormGroup } from '@angular/forms';
20
+ import { ReactiveFormsModule, FormsModule, FormControl, FormGroup, UntypedFormGroup } from '@angular/forms';
18
21
  import * as i1$2 from '@angular/material/form-field';
19
- import { MatFormFieldModule, MatFormField } from '@angular/material/form-field';
22
+ import { MatFormField, MatFormFieldModule } from '@angular/material/form-field';
20
23
  import * as i3 from '@angular/material/button';
21
24
  import { MatButtonModule } from '@angular/material/button';
22
25
  import { FieldType } from '@ngx-formly/material/form-field';
23
- import { HttpClient, HttpEventType } from '@angular/common/http';
24
- import { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';
25
26
  import { CmatCascadeListComponent } from 'cmat/components/cascade';
26
27
  import { CmatMediaWatcherService } from 'cmat/services/media-watcher';
27
28
  import * as i1$5 from '@angular/material/checkbox';
28
- import { MatCheckboxModule, MatCheckbox } from '@angular/material/checkbox';
29
+ import { MatCheckboxModule } from '@angular/material/checkbox';
29
30
  import * as i3$1 from '@angular/material/core';
30
31
  import { MatRippleModule } from '@angular/material/core';
31
32
  import { CmatChipInputComponent } from 'cmat/components/chip-input';
32
- import { CmatMaterialColorPickerComponent } from 'cmat/components/material-color-picker';
33
+ import { CmatColorPickerButtonComponent } from 'cmat/components/color-picker';
34
+ import { CmatDataPickerComponent } from 'cmat/components/data-picker';
33
35
  import { CmatDateRangeComponent } from 'cmat/components/date-range';
34
36
  import * as i1$6 from '@angular/material/input';
35
37
  import { MatInputModule } from '@angular/material/input';
@@ -39,11 +41,10 @@ import { FormlySelectModule } from '@ngx-formly/core/select';
39
41
  import { CmatDigitOnlyDirective } from 'cmat/directives/digit-only';
40
42
  import { CmatRatingComponent } from 'cmat/components/rating';
41
43
  import * as i1$7 from '@angular/material/radio';
42
- import { MatRadioModule, MatRadioGroup } from '@angular/material/radio';
44
+ import { MatRadioGroup, MatRadioModule } from '@angular/material/radio';
43
45
  import * as i1$8 from '@angular/material/select';
44
46
  import { MatSelectModule } from '@angular/material/select';
45
47
  import { CmatSelectSearchComponent } from 'cmat/components/select-search';
46
- import { ReplaySubject, of, take } from 'rxjs';
47
48
  import { CmatSelectTreeComponent } from 'cmat/components/select-tree';
48
49
  import { CmatSelectTableComponent } from 'cmat/components/select-table';
49
50
  import * as i2$3 from '@angular/material/stepper';
@@ -64,7 +65,7 @@ import BlotFormatter from '@enzedonline/quill-blot-formatter2';
64
65
  import { CmatUrlStateConfigService } from 'cmat/services/config';
65
66
  import { CmatUtilsService } from 'cmat/services/utils';
66
67
  import dayjs from 'dayjs';
67
- import { Document, Packer, Paragraph, AlignmentType, TextRun, BorderStyle, HeadingLevel, ImageRun, HighlightColor } from 'docx';
68
+ import { Document, Packer, Paragraph, AlignmentType, TextRun, ImageRun, BorderStyle, HeadingLevel, HighlightColor } from 'docx';
68
69
  import * as FileSaver from 'file-saver-es';
69
70
  import * as i2$4 from 'ngx-quill';
70
71
  import { QuillModule } from 'ngx-quill';
@@ -74,6 +75,190 @@ import { CmatKnobInputComponent } from 'cmat/components/knob-input';
74
75
  import * as i1$a from '@angular/material/slider';
75
76
  import { MatSliderModule } from '@angular/material/slider';
76
77
 
78
+ /**
79
+ * Domain 数据加载服务
80
+ *
81
+ * 提供统一的远程数据加载能力,支持 GET/POST 请求、数据提取、转换和错误处理。
82
+ * 所有使用 domain 配置的 Formly 组件都应使用此服务,避免重复实现。
83
+ */
84
+ class DomainDataService {
85
+ constructor() {
86
+ this._http = inject(HttpClient);
87
+ }
88
+ /**
89
+ * 从 domain 配置加载数据
90
+ *
91
+ * @param domain - 数据域配置对象
92
+ * @param destroyRef - Angular 销毁引用,用于自动取消订阅
93
+ * @param options - 加载选项(转换函数、回调等)
94
+ *
95
+ * @example
96
+ * ```typescript
97
+ * // 简单用法
98
+ * this.domainDataService.load(this.props.domain, this._destroyRef, {
99
+ * onSuccess: (data) => this.urlData.set(data)
100
+ * });
101
+ *
102
+ * // 自定义转换
103
+ * this.domainDataService.load(this.props.domain, this._destroyRef, {
104
+ * transform: (raw) => raw.map(item => ({ label: item.name, value: item.id })),
105
+ * onSuccess: (data) => this.optionsData.set(data),
106
+ * componentName: 'MyComponent'
107
+ * });
108
+ * ```
109
+ */
110
+ load(domain, destroyRef, options = {}) {
111
+ const { transform, onSuccess, onError, componentName = 'Unknown' } = options;
112
+ // 验证 domain 配置
113
+ if (!domain?.url || !domain?.key || !domain?.code || !domain?.value) {
114
+ onSuccess?.([]);
115
+ return;
116
+ }
117
+ const method = domain.method ?? 'GET';
118
+ // eslint-disable-next-line @typescript-eslint/naming-convention
119
+ const headers = { 'Content-Type': 'application/json' };
120
+ let request$;
121
+ if (method === 'POST') {
122
+ // POST 请求处理
123
+ const requestBodyType = domain.requestBodyType ?? 'json';
124
+ let body;
125
+ if (requestBodyType === 'json') {
126
+ // JSON 格式
127
+ try {
128
+ body = domain.requestBody ? JSON.parse(domain.requestBody) : {};
129
+ }
130
+ catch (e) {
131
+ console.error(`[${componentName}] Invalid JSON request body:`, e);
132
+ onSuccess?.([]);
133
+ return;
134
+ }
135
+ }
136
+ else {
137
+ // FormData 格式(简单键值对)
138
+ const formData = new URLSearchParams();
139
+ if (domain.requestBody) {
140
+ domain.requestBody.split('\n').forEach((line) => {
141
+ const trimmed = line.trim();
142
+ if (trimmed?.includes('=')) {
143
+ const [key, ...valueParts] = trimmed.split('=');
144
+ formData.append(key.trim(), valueParts.join('=').trim());
145
+ }
146
+ });
147
+ }
148
+ body = formData.toString();
149
+ headers['Content-Type'] = 'application/x-www-form-urlencoded';
150
+ }
151
+ request$ = this._http.post(domain.url, body, { headers }).pipe(takeUntilDestroyed(destroyRef), catchError((error) => {
152
+ console.error(`[${componentName}] Failed to load data (POST):`, error);
153
+ onError?.(error);
154
+ onSuccess?.([]);
155
+ return of([]);
156
+ }));
157
+ }
158
+ else {
159
+ // GET 请求处理
160
+ request$ = this._http.get(domain.url).pipe(takeUntilDestroyed(destroyRef), catchError((error) => {
161
+ console.error(`[${componentName}] Failed to load data (GET):`, error);
162
+ onError?.(error);
163
+ onSuccess?.([]);
164
+ return of([]);
165
+ }));
166
+ }
167
+ request$.subscribe((data) => {
168
+ if (!Array.isArray(data) || data.length === 0) {
169
+ onSuccess?.([]);
170
+ return;
171
+ }
172
+ try {
173
+ const { key, code, value } = domain;
174
+ // 查找匹配的主对象
175
+ const matchedItem = data.find((item) => typeof item === 'object' && item !== null && item[key] === code);
176
+ if (matchedItem?.[value]) {
177
+ const extractedData = matchedItem[value];
178
+ // 确保提取的是数组
179
+ if (Array.isArray(extractedData)) {
180
+ // 如果提供了自定义转换函数,使用它;否则使用默认转换
181
+ const result = transform
182
+ ? transform(extractedData)
183
+ : this._defaultTransform(extractedData);
184
+ onSuccess?.(result);
185
+ }
186
+ else {
187
+ console.warn(`[${componentName}] Extracted data is not an array:`, extractedData);
188
+ onSuccess?.([]);
189
+ }
190
+ }
191
+ else {
192
+ console.warn(`[${componentName}] No matching item found for code:`, code);
193
+ onSuccess?.([]);
194
+ }
195
+ }
196
+ catch (e) {
197
+ console.error(`[${componentName}] Error processing data:`, e);
198
+ onError?.(e);
199
+ onSuccess?.([]);
200
+ }
201
+ });
202
+ }
203
+ /**
204
+ * 默认数据转换函数
205
+ *
206
+ * 将原始 API 数据转换为标准的 OptionData 格式。
207
+ * 智能映射常见字段名:
208
+ * - value: value / id / code
209
+ * - label: label / name / text
210
+ *
211
+ * @param rawData - 原始数据数组
212
+ * @returns 转换后的 OptionData 数组
213
+ */
214
+ _defaultTransform(rawData) {
215
+ return rawData.map((item) => {
216
+ // 处理非对象情况(如字符串数组、数字数组)
217
+ if (typeof item !== 'object' || item === null) {
218
+ return {
219
+ value: item,
220
+ label: String(item)
221
+ };
222
+ }
223
+ const obj = item;
224
+ // 智能映射 value 字段
225
+ const finalValue = obj.value ?? obj.id ?? obj.code;
226
+ // 智能映射 label 字段
227
+ let finalLabel;
228
+ if (obj.label) {
229
+ finalLabel = obj.label;
230
+ }
231
+ else if (obj.name) {
232
+ finalLabel = obj.name;
233
+ }
234
+ else if (obj.text) {
235
+ finalLabel = obj.text;
236
+ }
237
+ else if (finalValue != null) {
238
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
239
+ finalLabel = String(finalValue);
240
+ }
241
+ else {
242
+ finalLabel = '';
243
+ }
244
+ return {
245
+ value: finalValue,
246
+ label: finalLabel,
247
+ disabled: !!obj.disabled,
248
+ ...obj // 保留原始对象的其他属性
249
+ };
250
+ });
251
+ }
252
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: DomainDataService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
253
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: DomainDataService, providedIn: 'root' }); }
254
+ }
255
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: DomainDataService, decorators: [{
256
+ type: Injectable,
257
+ args: [{
258
+ providedIn: 'root'
259
+ }]
260
+ }] });
261
+
77
262
  function addonsExtension(field) {
78
263
  const props = field.props;
79
264
  if (!props || (field.wrappers?.includes('addons'))) {
@@ -88,16 +273,23 @@ function addonsExtension(field) {
88
273
  }
89
274
 
90
275
  class CmatAddonsWrapperComponent extends FieldWrapper {
276
+ constructor() {
277
+ super(...arguments);
278
+ this.matPrefix = viewChild('matPrefix', /* @ts-ignore */
279
+ ...(ngDevMode ? [{ debugName: "matPrefix" }] : /* istanbul ignore next */ []));
280
+ this.matSuffix = viewChild('matSuffix', /* @ts-ignore */
281
+ ...(ngDevMode ? [{ debugName: "matSuffix" }] : /* istanbul ignore next */ []));
282
+ }
91
283
  ngAfterViewInit() {
92
- if (this.matPrefix) {
93
- this.props.prefix = this.matPrefix;
284
+ if (this.matPrefix()) {
285
+ this.props.prefix = this.matPrefix();
94
286
  }
95
- if (this.matSuffix) {
96
- this.props.suffix = this.matSuffix;
287
+ if (this.matSuffix()) {
288
+ this.props.suffix = this.matSuffix();
97
289
  }
98
290
  }
99
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatAddonsWrapperComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
100
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: CmatAddonsWrapperComponent, isStandalone: true, selector: "cmat-addons-wrapper", viewQueries: [{ propertyName: "matPrefix", first: true, predicate: ["matPrefix"], descendants: true, static: true }, { propertyName: "matSuffix", first: true, predicate: ["matSuffix"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: `
291
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatAddonsWrapperComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
292
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: CmatAddonsWrapperComponent, isStandalone: true, selector: "cmat-addons-wrapper", viewQueries: [{ propertyName: "matPrefix", first: true, predicate: ["matPrefix"], descendants: true, isSignal: true }, { propertyName: "matSuffix", first: true, predicate: ["matSuffix"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: `
101
293
  <ng-template #matPrefix>
102
294
  @if(props.addonLeft){
103
295
  <span>
@@ -128,7 +320,7 @@ class CmatAddonsWrapperComponent extends FieldWrapper {
128
320
  </ng-template>
129
321
  `, isInline: true, dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: FormlyMaterialModule }] }); }
130
322
  }
131
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatAddonsWrapperComponent, decorators: [{
323
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatAddonsWrapperComponent, decorators: [{
132
324
  type: Component,
133
325
  args: [{
134
326
  selector: 'cmat-addons-wrapper',
@@ -164,50 +356,46 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
164
356
  `,
165
357
  imports: [MatIconModule, FormlyMaterialModule]
166
358
  }]
167
- }], propDecorators: { matPrefix: [{
168
- type: ViewChild,
169
- args: ['matPrefix', { static: true }]
170
- }], matSuffix: [{
171
- type: ViewChild,
172
- args: ['matSuffix', { static: true }]
173
- }] } });
359
+ }], propDecorators: { matPrefix: [{ type: i0.ViewChild, args: ['matPrefix', { isSignal: true }] }], matSuffix: [{ type: i0.ViewChild, args: ['matSuffix', { isSignal: true }] }] } });
174
360
 
175
361
  class CmatCardWrapperComponent extends FieldWrapper {
176
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatCardWrapperComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
177
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: CmatCardWrapperComponent, isStandalone: true, selector: "cmat-card-wrapper", usesInheritance: true, ngImport: i0, template: "<mat-card class=\"dark:bg-white/5\">\r\n @if(props.label){\r\n <mat-card-title class=\"p-4\">{{ props.label }}</mat-card-title>\r\n }\r\n \r\n <mat-card-content>\r\n <ng-container #fieldComponent></ng-container>\r\n </mat-card-content> \r\n</mat-card>", dependencies: [{ kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i1.MatCardContent, selector: "mat-card-content" }, { kind: "directive", type: i1.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
362
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatCardWrapperComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
363
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: CmatCardWrapperComponent, isStandalone: true, selector: "cmat-card-wrapper", usesInheritance: true, ngImport: i0, template: "<mat-card class=\"dark:bg-white/5\">\r\n @if(props.label){\r\n <mat-card-title class=\"p-4\">{{ props.label }}</mat-card-title>\r\n }\r\n \r\n <mat-card-content>\r\n <ng-container #fieldComponent></ng-container>\r\n </mat-card-content> \r\n</mat-card>", dependencies: [{ kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i1.MatCardContent, selector: "mat-card-content" }, { kind: "directive", type: i1.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
178
364
  }
179
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatCardWrapperComponent, decorators: [{
365
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatCardWrapperComponent, decorators: [{
180
366
  type: Component,
181
367
  args: [{ selector: 'cmat-card-wrapper', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatCardModule], template: "<mat-card class=\"dark:bg-white/5\">\r\n @if(props.label){\r\n <mat-card-title class=\"p-4\">{{ props.label }}</mat-card-title>\r\n }\r\n \r\n <mat-card-content>\r\n <ng-container #fieldComponent></ng-container>\r\n </mat-card-content> \r\n</mat-card>" }]
182
368
  }] });
183
369
 
184
370
  class CmatExpansionWrapperComponent extends FieldWrapper {
185
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatExpansionWrapperComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
186
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.11", type: CmatExpansionWrapperComponent, isStandalone: true, selector: "cmat-expansion-wrapper", usesInheritance: true, ngImport: i0, template: "<mat-expansion-panel [expanded]=\"true\">\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n {{ to.label }}\r\n </mat-panel-title>\r\n <mat-panel-description>\r\n {{ to.description }}\r\n </mat-panel-description>\r\n </mat-expansion-panel-header>\r\n <ng-template #fieldComponent matExpansionPanelContent></ng-template>\r\n</mat-expansion-panel>", dependencies: [{ kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i1$1.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i1$1.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i1$1.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i1$1.MatExpansionPanelDescription, selector: "mat-panel-description" }, { kind: "directive", type: i1$1.MatExpansionPanelContent, selector: "ng-template[matExpansionPanelContent]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
371
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatExpansionWrapperComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
372
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.6", type: CmatExpansionWrapperComponent, isStandalone: true, selector: "cmat-expansion-wrapper", usesInheritance: true, ngImport: i0, template: "<mat-expansion-panel [expanded]=\"true\">\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n {{ to.label }}\r\n </mat-panel-title>\r\n <mat-panel-description>\r\n {{ to.description }}\r\n </mat-panel-description>\r\n </mat-expansion-panel-header>\r\n <ng-template #fieldComponent matExpansionPanelContent></ng-template>\r\n</mat-expansion-panel>", dependencies: [{ kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i1$1.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i1$1.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i1$1.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i1$1.MatExpansionPanelDescription, selector: "mat-panel-description" }, { kind: "directive", type: i1$1.MatExpansionPanelContent, selector: "ng-template[matExpansionPanelContent]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
187
373
  }
188
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatExpansionWrapperComponent, decorators: [{
374
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatExpansionWrapperComponent, decorators: [{
189
375
  type: Component,
190
376
  args: [{ selector: 'cmat-expansion-wrapper', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatExpansionModule], template: "<mat-expansion-panel [expanded]=\"true\">\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n {{ to.label }}\r\n </mat-panel-title>\r\n <mat-panel-description>\r\n {{ to.description }}\r\n </mat-panel-description>\r\n </mat-expansion-panel-header>\r\n <ng-template #fieldComponent matExpansionPanelContent></ng-template>\r\n</mat-expansion-panel>" }]
191
377
  }] });
192
378
 
193
379
  class CmatPanelWrapperComponent extends FieldWrapper {
194
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatPanelWrapperComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
195
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.11", type: CmatPanelWrapperComponent, isStandalone: true, selector: "cmat-panel-wrapper", usesInheritance: true, ngImport: i0, template: "<h3 class=\"px-2\">{{ to.label }}</h3>\r\n<div>\r\n <ng-container #fieldComponent></ng-container>\r\n</div>", changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
380
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatPanelWrapperComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
381
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.6", type: CmatPanelWrapperComponent, isStandalone: true, selector: "cmat-panel-wrapper", usesInheritance: true, ngImport: i0, template: "<h3 class=\"px-2\">{{ props.label }}</h3>\r\n<div>\r\n <ng-container #fieldComponent></ng-container>\r\n</div>", changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
196
382
  }
197
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatPanelWrapperComponent, decorators: [{
383
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatPanelWrapperComponent, decorators: [{
198
384
  type: Component,
199
- args: [{ selector: 'cmat-panel-wrapper', changeDetection: ChangeDetectionStrategy.OnPush, imports: [], template: "<h3 class=\"px-2\">{{ to.label }}</h3>\r\n<div>\r\n <ng-container #fieldComponent></ng-container>\r\n</div>" }]
385
+ args: [{ selector: 'cmat-panel-wrapper', changeDetection: ChangeDetectionStrategy.OnPush, imports: [], template: "<h3 class=\"px-2\">{{ props.label }}</h3>\r\n<div>\r\n <ng-container #fieldComponent></ng-container>\r\n</div>" }]
200
386
  }] });
201
387
 
202
388
  class CmatFormFieldWrapperComponent extends FieldWrapper {
203
389
  constructor() {
204
390
  super();
391
+ this.formField = viewChild.required(MatFormField, /* @ts-ignore */
392
+ ...(ngDevMode ? [{ debugName: "formField" }] : /* istanbul ignore next */ []));
205
393
  this._renderer = inject(Renderer2);
206
394
  this._elementRef = inject(ElementRef);
207
395
  this._focusMonitor = inject(FocusMonitor);
208
396
  }
209
397
  ngOnInit() {
210
- _defineHiddenProp(this.field, '_formField', this.formField);
398
+ _defineHiddenProp(this.field, '_formField', this.formField());
211
399
  this._focusMonitor.monitor(this._elementRef, true).subscribe((origin) => {
212
400
  if (!origin && this.field.focus) {
213
401
  this.field.focus = false;
@@ -215,9 +403,8 @@ class CmatFormFieldWrapperComponent extends FieldWrapper {
215
403
  });
216
404
  }
217
405
  ngAfterViewInit() {
218
- if (this.formField.appearance !== 'outline' && this.props.hideFieldUnderline === true) {
219
- const formFieldElement = this._elementRef.nativeElement;
220
- const underlineElement = formFieldElement.querySelector('.mat-form-field-underline');
406
+ if (this.formField().appearance !== 'outline' && this.props.hideFieldUnderline === true) {
407
+ const underlineElement = this.formField()._elementRef.nativeElement.querySelector('.mat-form-field-underline');
221
408
  if (underlineElement?.parentNode) {
222
409
  this._renderer.removeChild(underlineElement.parentNode, underlineElement);
223
410
  }
@@ -227,16 +414,13 @@ class CmatFormFieldWrapperComponent extends FieldWrapper {
227
414
  delete this.field._formField;
228
415
  this._focusMonitor.stopMonitoring(this._elementRef);
229
416
  }
230
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatFormFieldWrapperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
231
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: CmatFormFieldWrapperComponent, isStandalone: true, selector: "cmat-form-field-wrapper", viewQueries: [{ propertyName: "formField", first: true, predicate: MatFormField, descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<mat-form-field [hideRequiredMarker]=\"true\" [floatLabel]=\"$any(props.floatLabel)\" [appearance]=\"$any(props.appearance)\"\r\n [subscriptSizing]=\"$any(props.subscriptSizing)\" [color]=\"props.color ?? 'primary'\">\r\n <ng-container #fieldComponent></ng-container>\r\n @if(props.label && props.hideLabel !== true){\r\n <mat-label>\r\n {{ props.label }}\r\n @if(props.required && props.hideRequiredMarker !== true){\r\n <span aria-hidden=\"true\" class=\"mat-form-field-required-marker mat-mdc-form-field-required-marker\">*</span>\r\n }\r\n </mat-label>\r\n }\r\n\r\n @if(props.textPrefix){\r\n <ng-container matTextPrefix>\r\n <ng-container [ngTemplateOutlet]=\"props.textPrefix\" [ngTemplateOutletContext]=\"{ field: field }\"></ng-container>\r\n </ng-container>\r\n }\r\n\r\n @if(props.prefix){\r\n <ng-container matPrefix>\r\n <ng-container [ngTemplateOutlet]=\"props.prefix\" [ngTemplateOutletContext]=\"{ field: field }\"></ng-container>\r\n </ng-container>\r\n }\r\n\r\n @if(props.textSuffix){\r\n <ng-container matTextSuffix>\r\n <ng-container [ngTemplateOutlet]=\"props.textSuffix\" [ngTemplateOutletContext]=\"{ field: field }\"></ng-container>\r\n </ng-container>\r\n }\r\n\r\n @if(props.suffix){\r\n <ng-container matSuffix>\r\n <ng-container [ngTemplateOutlet]=\"props.suffix\" [ngTemplateOutletContext]=\"{ field: field }\"></ng-container>\r\n </ng-container>\r\n }\r\n\r\n @if(props.showValidationMessage){\r\n <mat-error>\r\n <formly-validation-message [field]=\"field\"></formly-validation-message>\r\n </mat-error>\r\n }\r\n\r\n @if(props.description || props.hintStart){\r\n <mat-hint>\r\n <ng-container [ngTemplateOutlet]=\"stringOrTemplate\" [ngTemplateOutletContext]=\"{ content: props.description || props.hintStart }\">\r\n </ng-container>\r\n </mat-hint>\r\n }\r\n\r\n @if(props.hintEnd){\r\n <mat-hint align=\"end\">\r\n <ng-container [ngTemplateOutlet]=\"stringOrTemplate\" [ngTemplateOutletContext]=\"{ content: props.hintEnd }\">\r\n </ng-container>\r\n </mat-hint>\r\n }\r\n</mat-form-field>\r\n\r\n<ng-template #stringOrTemplate let-content=\"content\">\r\n @if(!content.createEmbeddedView){\r\n <ng-container>{{ content }}</ng-container>\r\n }@else {\r\n <ng-container [ngTemplateOutlet]=\"content\" [ngTemplateOutletContext]=\"{ field: field }\"></ng-container>\r\n }\r\n</ng-template>", styles: ["cmat-form-field-wrapper .mat-mdc-form-field,cmat-form-field-wrapper .mat-form-field{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i1$2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i1$2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i1$2.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i1$2.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i1$2.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i1$2.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormlyModule }, { kind: "component", type: i1$3.LegacyFormlyValidationMessage, selector: "formly-validation-message" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
417
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatFormFieldWrapperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
418
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: CmatFormFieldWrapperComponent, isStandalone: true, selector: "cmat-form-field-wrapper", viewQueries: [{ propertyName: "formField", first: true, predicate: MatFormField, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<mat-form-field [hideRequiredMarker]=\"true\" [floatLabel]=\"$any(props.floatLabel)\" [appearance]=\"$any(props.appearance)\"\r\n [subscriptSizing]=\"$any(props.subscriptSizing)\" [color]=\"props.color ?? 'primary'\">\r\n <ng-container #fieldComponent></ng-container>\r\n @if(props.label && props.hideLabel !== true){\r\n <mat-label>\r\n {{ props.label }}\r\n @if(props.required && props.hideRequiredMarker !== true){\r\n <span aria-hidden=\"true\" class=\"mat-form-field-required-marker mat-mdc-form-field-required-marker\">*</span>\r\n }\r\n </mat-label>\r\n }\r\n\r\n @if(props.textPrefix){\r\n <ng-container matTextPrefix>\r\n <ng-container [ngTemplateOutlet]=\"props.textPrefix\" [ngTemplateOutletContext]=\"{ field: field }\"></ng-container>\r\n </ng-container>\r\n }\r\n\r\n @if(props.prefix){\r\n <ng-container matPrefix>\r\n <ng-container [ngTemplateOutlet]=\"props.prefix\" [ngTemplateOutletContext]=\"{ field: field }\"></ng-container>\r\n </ng-container>\r\n }\r\n\r\n @if(props.textSuffix){\r\n <ng-container matTextSuffix>\r\n <ng-container [ngTemplateOutlet]=\"props.textSuffix\" [ngTemplateOutletContext]=\"{ field: field }\"></ng-container>\r\n </ng-container>\r\n }\r\n\r\n @if(props.suffix){\r\n <ng-container matSuffix>\r\n <ng-container [ngTemplateOutlet]=\"props.suffix\" [ngTemplateOutletContext]=\"{ field: field }\"></ng-container>\r\n </ng-container>\r\n }\r\n\r\n @if(props.showValidationMessage){\r\n <mat-error>\r\n <formly-validation-message [field]=\"field\"></formly-validation-message>\r\n </mat-error>\r\n }\r\n\r\n @if(props.description || props.hintStart){\r\n <mat-hint>\r\n <ng-container [ngTemplateOutlet]=\"stringOrTemplate\" [ngTemplateOutletContext]=\"{ content: props.description || props.hintStart }\">\r\n </ng-container>\r\n </mat-hint>\r\n }\r\n\r\n @if(props.hintEnd){\r\n <mat-hint align=\"end\">\r\n <ng-container [ngTemplateOutlet]=\"stringOrTemplate\" [ngTemplateOutletContext]=\"{ content: props.hintEnd }\">\r\n </ng-container>\r\n </mat-hint>\r\n }\r\n</mat-form-field>\r\n\r\n<ng-template #stringOrTemplate let-content=\"content\">\r\n @if(!content.createEmbeddedView){\r\n <ng-container>{{ content }}</ng-container>\r\n }@else {\r\n <ng-container [ngTemplateOutlet]=\"content\" [ngTemplateOutletContext]=\"{ field: field }\"></ng-container>\r\n }\r\n</ng-template>", styles: ["cmat-form-field-wrapper .mat-mdc-form-field,cmat-form-field-wrapper .mat-form-field{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i1$2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i1$2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i1$2.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i1$2.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i1$2.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i1$2.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormlyModule }, { kind: "component", type: i1$3.LegacyFormlyValidationMessage, selector: "formly-validation-message" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
232
419
  }
233
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatFormFieldWrapperComponent, decorators: [{
420
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatFormFieldWrapperComponent, decorators: [{
234
421
  type: Component,
235
422
  args: [{ selector: 'cmat-form-field-wrapper', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [MatFormFieldModule, ReactiveFormsModule, CommonModule, FormlyModule], template: "<mat-form-field [hideRequiredMarker]=\"true\" [floatLabel]=\"$any(props.floatLabel)\" [appearance]=\"$any(props.appearance)\"\r\n [subscriptSizing]=\"$any(props.subscriptSizing)\" [color]=\"props.color ?? 'primary'\">\r\n <ng-container #fieldComponent></ng-container>\r\n @if(props.label && props.hideLabel !== true){\r\n <mat-label>\r\n {{ props.label }}\r\n @if(props.required && props.hideRequiredMarker !== true){\r\n <span aria-hidden=\"true\" class=\"mat-form-field-required-marker mat-mdc-form-field-required-marker\">*</span>\r\n }\r\n </mat-label>\r\n }\r\n\r\n @if(props.textPrefix){\r\n <ng-container matTextPrefix>\r\n <ng-container [ngTemplateOutlet]=\"props.textPrefix\" [ngTemplateOutletContext]=\"{ field: field }\"></ng-container>\r\n </ng-container>\r\n }\r\n\r\n @if(props.prefix){\r\n <ng-container matPrefix>\r\n <ng-container [ngTemplateOutlet]=\"props.prefix\" [ngTemplateOutletContext]=\"{ field: field }\"></ng-container>\r\n </ng-container>\r\n }\r\n\r\n @if(props.textSuffix){\r\n <ng-container matTextSuffix>\r\n <ng-container [ngTemplateOutlet]=\"props.textSuffix\" [ngTemplateOutletContext]=\"{ field: field }\"></ng-container>\r\n </ng-container>\r\n }\r\n\r\n @if(props.suffix){\r\n <ng-container matSuffix>\r\n <ng-container [ngTemplateOutlet]=\"props.suffix\" [ngTemplateOutletContext]=\"{ field: field }\"></ng-container>\r\n </ng-container>\r\n }\r\n\r\n @if(props.showValidationMessage){\r\n <mat-error>\r\n <formly-validation-message [field]=\"field\"></formly-validation-message>\r\n </mat-error>\r\n }\r\n\r\n @if(props.description || props.hintStart){\r\n <mat-hint>\r\n <ng-container [ngTemplateOutlet]=\"stringOrTemplate\" [ngTemplateOutletContext]=\"{ content: props.description || props.hintStart }\">\r\n </ng-container>\r\n </mat-hint>\r\n }\r\n\r\n @if(props.hintEnd){\r\n <mat-hint align=\"end\">\r\n <ng-container [ngTemplateOutlet]=\"stringOrTemplate\" [ngTemplateOutletContext]=\"{ content: props.hintEnd }\">\r\n </ng-container>\r\n </mat-hint>\r\n }\r\n</mat-form-field>\r\n\r\n<ng-template #stringOrTemplate let-content=\"content\">\r\n @if(!content.createEmbeddedView){\r\n <ng-container>{{ content }}</ng-container>\r\n }@else {\r\n <ng-container [ngTemplateOutlet]=\"content\" [ngTemplateOutletContext]=\"{ field: field }\"></ng-container>\r\n }\r\n</ng-template>", styles: ["cmat-form-field-wrapper .mat-mdc-form-field,cmat-form-field-wrapper .mat-form-field{width:100%}\n"] }]
236
- }], ctorParameters: () => [], propDecorators: { formField: [{
237
- type: ViewChild,
238
- args: [MatFormField, { static: true }]
239
- }] } });
423
+ }], ctorParameters: () => [], propDecorators: { formField: [{ type: i0.ViewChild, args: [i0.forwardRef(() => MatFormField), { isSignal: true }] }] } });
240
424
 
241
425
  const DANGEROUS_PATTERNS = [
242
426
  /\bdocument\s*\./i,
@@ -254,7 +438,8 @@ class CmatButtonTypeComponent extends FieldType {
254
438
  super(...arguments);
255
439
  this.defaultOptions = {
256
440
  props: {
257
- color: 'primary'
441
+ color: 'primary',
442
+ type: 'button'
258
443
  }
259
444
  };
260
445
  }
@@ -286,10 +471,10 @@ class CmatButtonTypeComponent extends FieldType {
286
471
  console.error('Error executing function from string:', error);
287
472
  }
288
473
  }
289
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatButtonTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
290
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.11", type: CmatButtonTypeComponent, isStandalone: true, selector: "cmat-button-type", usesInheritance: true, ngImport: i0, template: "<button class=\"print:hidden\" matButton=\"filled\" [type]=\"props.type\" [color]=\"props.color\" [disabled]=\"disabled\" (click)=\"onClick($event)\">\r\n {{ props.label }}\r\n</button>", dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
474
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatButtonTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
475
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.6", type: CmatButtonTypeComponent, isStandalone: true, selector: "cmat-button-type", usesInheritance: true, ngImport: i0, template: "<button class=\"print:hidden\" matButton=\"filled\" [type]=\"props.type\" [color]=\"props.color\" [disabled]=\"disabled\" (click)=\"onClick($event)\">\r\n {{ props.label }}\r\n</button>", dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
291
476
  }
292
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatButtonTypeComponent, decorators: [{
477
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatButtonTypeComponent, decorators: [{
293
478
  type: Component,
294
479
  args: [{ selector: 'cmat-button-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatButtonModule], template: "<button class=\"print:hidden\" matButton=\"filled\" [type]=\"props.type\" [color]=\"props.color\" [disabled]=\"disabled\" (click)=\"onClick($event)\">\r\n {{ props.label }}\r\n</button>" }]
295
480
  }] });
@@ -304,269 +489,427 @@ class CmatCascadeTypeComponent extends FieldType {
304
489
  changeOnSelect: false
305
490
  },
306
491
  };
307
- this.urlData = [];
308
- this.isHandSet = signal(false, ...(ngDevMode ? [{ debugName: "isHandSet" }] : /* istanbul ignore next */ []));
309
- this.refreshVersion = signal(0, ...(ngDevMode ? [{ debugName: "refreshVersion" }] : /* istanbul ignore next */ []));
310
- this._http = inject(HttpClient);
492
+ this.urlData = signal([], /* @ts-ignore */
493
+ ...(ngDevMode ? [{ debugName: "urlData" }] : /* istanbul ignore next */ []));
311
494
  this._cmatMediaWatcherService = inject(CmatMediaWatcherService);
495
+ // eslint-disable-next-line @typescript-eslint/member-ordering
496
+ this.isHandSet = computed(() => {
497
+ return !this._cmatMediaWatcherService.mediaChange().matchingAliases.includes('lg');
498
+ }, /* @ts-ignore */
499
+ ...(ngDevMode ? [{ debugName: "isHandSet" }] : /* istanbul ignore next */ []));
500
+ this._lastDomain = undefined;
312
501
  this._destroyRef = inject(DestroyRef);
502
+ this._domainDataService = inject(DomainDataService);
313
503
  }
314
504
  ngOnInit() {
315
- const url = this.props?.domain?.url;
316
- if (url && this.props?.domain?.code && this.props?.domain?.key && this.props?.domain?.value) {
317
- this._http.get(url).pipe(takeUntilDestroyed(this._destroyRef)).subscribe((data) => {
318
- if (data) {
319
- const key = this.field.props?.domain?.key;
320
- const code = this.field.props?.domain?.code;
321
- const datas = data.filter((i) => {
322
- if (key)
323
- return i[key] === code;
324
- return false;
325
- });
326
- if (datas && this.field.props?.domain?.value) {
327
- this.urlData = datas[0][this.field.props?.domain?.value];
328
- }
329
- else {
330
- this.urlData = [];
331
- }
332
- }
333
- else {
334
- this.urlData = [];
335
- }
336
- this.refreshVersion.update(value => value + 1);
337
- });
338
- }
339
- else {
340
- this.urlData = [];
341
- this.refreshVersion.update(value => value + 1);
342
- }
343
- this._cmatMediaWatcherService.onMediaChange$
344
- .pipe(takeUntilDestroyed(this._destroyRef))
345
- .subscribe(({ matchingAliases }) => {
346
- this.isHandSet.set(!matchingAliases.includes('lg'));
347
- this.refreshVersion.update(value => value + 1);
505
+ this._lastDomain = this.props.domain;
506
+ this._refreshData();
507
+ }
508
+ ngDoCheck() {
509
+ const currentDomain = this.props.domain;
510
+ let shouldRefresh = false;
511
+ // 1. 检查 domain 变化
512
+ if (!isEqual(currentDomain, this._lastDomain)) {
513
+ this._lastDomain = currentDomain;
514
+ shouldRefresh = true;
515
+ }
516
+ if (shouldRefresh) {
517
+ this._refreshData();
518
+ }
519
+ }
520
+ _refreshData() {
521
+ const domain = this.props.domain;
522
+ // 使用 DomainDataService 加载远程数据
523
+ this._domainDataService.load(domain, this._destroyRef, {
524
+ onSuccess: data => this.urlData.set(data),
525
+ componentName: 'CmatCascadeTypeComponent'
348
526
  });
349
527
  }
350
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatCascadeTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
351
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.11", type: CmatCascadeTypeComponent, isStandalone: true, selector: "cmat-cascade-type", usesInheritance: true, ngImport: i0, template: "<cmat-cascade-list [formControl]=\"formControl\" [clearable]=\"props.clearable\" [fullLevels]=\"props.fullLevels\"\r\n [changeOnSelect]=\"props.changeOnSelect\" [placeholder]=\"placeholder\" [options]=\"urlData\" [tabIndex]=\"props.tabindex\"\r\n [required]=\"required\" [touchUi]=\"isHandSet()\" [attr.data-refresh]=\"refreshVersion()\"></cmat-cascade-list>\r\n", styles: [":host{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: CmatCascadeListComponent, selector: "cmat-cascade-list", inputs: ["id", "options", "clearable", "fullLevels", "changeOnSelect", "allowLabelValue", "touchUi", "placeholder", "value", "required", "disabled"], exportAs: ["cmatCascadeList"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
528
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatCascadeTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
529
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.6", type: CmatCascadeTypeComponent, isStandalone: true, selector: "cmat-cascade-type", usesInheritance: true, ngImport: i0, template: "<cmat-cascade-list [formControl]=\"formControl\" [clearable]=\"props.clearable\" [fullLevels]=\"props.fullLevels\"\r\n [changeOnSelect]=\"props.changeOnSelect\" [placeholder]=\"placeholder\" [options]=\"urlData()\" [tabIndex]=\"props.tabindex\"\r\n [required]=\"required\" [touchUi]=\"isHandSet()\"></cmat-cascade-list>\r\n", styles: [":host{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: CmatCascadeListComponent, selector: "cmat-cascade-list", inputs: ["options", "clearable", "fullLevels", "changeOnSelect", "allowLabelValue", "touchUi", "placeholder", "disabled", "required", "value"], exportAs: ["cmatCascadeList"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
352
530
  }
353
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatCascadeTypeComponent, decorators: [{
531
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatCascadeTypeComponent, decorators: [{
354
532
  type: Component,
355
- args: [{ selector: 'cmat-cascade-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [ReactiveFormsModule, CmatCascadeListComponent], template: "<cmat-cascade-list [formControl]=\"formControl\" [clearable]=\"props.clearable\" [fullLevels]=\"props.fullLevels\"\r\n [changeOnSelect]=\"props.changeOnSelect\" [placeholder]=\"placeholder\" [options]=\"urlData\" [tabIndex]=\"props.tabindex\"\r\n [required]=\"required\" [touchUi]=\"isHandSet()\" [attr.data-refresh]=\"refreshVersion()\"></cmat-cascade-list>\r\n", styles: [":host{width:100%}\n"] }]
533
+ args: [{ selector: 'cmat-cascade-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [ReactiveFormsModule, CmatCascadeListComponent], template: "<cmat-cascade-list [formControl]=\"formControl\" [clearable]=\"props.clearable\" [fullLevels]=\"props.fullLevels\"\r\n [changeOnSelect]=\"props.changeOnSelect\" [placeholder]=\"placeholder\" [options]=\"urlData()\" [tabIndex]=\"props.tabindex\"\r\n [required]=\"required\" [touchUi]=\"isHandSet()\"></cmat-cascade-list>\r\n", styles: [":host{width:100%}\n"] }]
356
534
  }], ctorParameters: () => [] });
357
535
 
358
536
  class CmatCheckListTypeComponent extends FieldType {
359
537
  constructor() {
360
538
  super();
361
- this.isIndeterminate = false;
362
- this.isChecked = false;
363
- this.urlData = [];
364
- this.optionsData = [];
365
- this.checklist = [];
366
- this.filteredData = [];
367
- this._http = inject(HttpClient);
539
+ this.isIndeterminate = signal(false, /* @ts-ignore */
540
+ ...(ngDevMode ? [{ debugName: "isIndeterminate" }] : /* istanbul ignore next */ []));
541
+ this.isChecked = signal(false, /* @ts-ignore */
542
+ ...(ngDevMode ? [{ debugName: "isChecked" }] : /* istanbul ignore next */ []));
543
+ this.urlData = signal([], /* @ts-ignore */
544
+ ...(ngDevMode ? [{ debugName: "urlData" }] : /* istanbul ignore next */ []));
545
+ this.optionsData = signal([], /* @ts-ignore */
546
+ ...(ngDevMode ? [{ debugName: "optionsData" }] : /* istanbul ignore next */ []));
547
+ this.checklist = signal([], /* @ts-ignore */
548
+ ...(ngDevMode ? [{ debugName: "checklist" }] : /* istanbul ignore next */ []));
549
+ this.filteredItems = signal(null, /* @ts-ignore */
550
+ ...(ngDevMode ? [{ debugName: "filteredItems" }] : /* istanbul ignore next */ []));
551
+ // 响应式数据源
552
+ this.datas = computed(() => {
553
+ if (this.urlData().length > 0) {
554
+ return this.urlData();
555
+ }
556
+ return this.optionsData() || [];
557
+ }, /* @ts-ignore */
558
+ ...(ngDevMode ? [{ debugName: "datas" }] : /* istanbul ignore next */ []));
559
+ // 响应式过滤数据
560
+ this.filteredData = computed(() => {
561
+ const currentDatas = this.datas();
562
+ const query = this._filterQuery();
563
+ if (!query) {
564
+ return currentDatas;
565
+ }
566
+ return currentDatas.filter((data) => this._toSearchText(data.value).toLowerCase().includes(query.toLowerCase()) ||
567
+ this._toSearchText(data.label).toLowerCase().includes(query.toLowerCase()));
568
+ }, /* @ts-ignore */
569
+ ...(ngDevMode ? [{ debugName: "filteredData" }] : /* istanbul ignore next */ []));
570
+ this._lastDomain = undefined;
571
+ this._lastOptions = undefined;
368
572
  this._destroyRef = inject(DestroyRef);
369
- this._filteredItems = signal(null, ...(ngDevMode ? [{ debugName: "_filteredItems" }] : /* istanbul ignore next */ []));
370
- this._filteredItems$ = toObservable(this._filteredItems);
371
- }
372
- get filteredItems$() {
373
- return this._filteredItems$;
374
- }
375
- get datas() {
376
- if (isArray(this.field.props?.options)) {
377
- return this.urlData?.length > 0 ? this.urlData : this.field.props?.options ?? [];
378
- }
379
- else {
380
- return this.urlData?.length > 0 ? this.urlData : this.optionsData || [];
381
- }
573
+ this._domainDataService = inject(DomainDataService);
574
+ this._filterQuery = signal('', /* @ts-ignore */
575
+ ...(ngDevMode ? [{ debugName: "_filterQuery" }] : /* istanbul ignore next */ []));
382
576
  }
383
577
  ngOnInit() {
384
- if (this.field.props?.options && !isArray(this.field.props?.options)) {
385
- this.field.props?.options.pipe(takeUntilDestroyed(this._destroyRef)).subscribe((data) => {
386
- this.optionsData = data;
387
- });
388
- }
389
- const url = this.field.props?.domain?.url;
390
- if (url && this.field.props?.domain?.code && this.field.props?.domain?.key && this.field.props?.domain?.value) {
391
- this._http.get(url).pipe(takeUntilDestroyed(this._destroyRef)).subscribe((data) => {
392
- if (data) {
393
- const key = this.field.props?.domain?.key;
394
- const code = this.field.props?.domain?.code;
395
- const datas = data.filter((i) => {
396
- if (key)
397
- return i[key] === code;
398
- return false;
399
- });
400
- if (datas && this.field.props?.domain?.value) {
401
- this.urlData = datas[0][this.field.props?.domain?.value] ?? [];
402
- }
403
- else {
404
- this.urlData = [];
405
- }
406
- }
407
- else {
408
- this.urlData = [];
409
- }
410
- this.filteredData = this.datas;
411
- this._filteredItems.set(this.filteredData);
412
- });
413
- }
414
- else {
415
- this.urlData = [];
416
- this.filteredData = this.datas;
417
- this._filteredItems.set(this.filteredData);
418
- }
578
+ this._lastDomain = this.props.domain;
579
+ this._lastOptions = this.field.props?.options;
580
+ this._refreshData();
581
+ this._refreshFilteredData();
419
582
  this.formControl.valueChanges.pipe(takeUntilDestroyed(this._destroyRef)).subscribe((value) => {
420
- this.checklist = (value ?? []);
583
+ const newVal = (value ?? []);
584
+ this.checklist.set(newVal);
421
585
  this._getAllCheckCountState();
422
586
  });
423
587
  }
588
+ ngDoCheck() {
589
+ const currentDomain = this.props.domain;
590
+ const currentOptions = this.field.props?.options;
591
+ let shouldRefresh = false;
592
+ // 1. 检查 domain 变化
593
+ if (!isEqual(currentDomain, this._lastDomain)) {
594
+ this._lastDomain = currentDomain;
595
+ shouldRefresh = true;
596
+ }
597
+ // 2. 检查 options 变化 (仅当 domain 未配置时,options 才生效,但为了稳妥,只要变了就更新)
598
+ // 注意:如果 domain 存在,urlData 优先级更高,但更新 optionsData 也无妨,因为 allOptions computed 会优先取 urlData
599
+ if (!isEqual(currentOptions, this._lastOptions)) {
600
+ this._lastOptions = currentOptions;
601
+ shouldRefresh = true;
602
+ }
603
+ if (shouldRefresh) {
604
+ this._refreshData();
605
+ }
606
+ }
424
607
  trackByFn(index, item) {
425
- return item.id ?? index;
608
+ return item.id ?? item.value ?? index;
426
609
  }
427
610
  filterByQuery(event) {
428
611
  const query = typeof event === 'string' ? event : event.target?.value ?? '';
429
- const normalizedQuery = query.toLowerCase();
430
- this.filteredData = this.datas.filter((data) => this._toSearchText(data.value).toLowerCase().includes(normalizedQuery) || this._toSearchText(data.label).toLowerCase().includes(normalizedQuery));
431
- this._filteredItems.set(this.filteredData);
612
+ this._filterQuery.set(query.toLowerCase());
432
613
  this._getAllCheckCountState();
433
614
  }
434
615
  toggleCheckList(data, event) {
435
616
  event.preventDefault();
436
617
  if (data.disabled || this.props.disabled)
437
618
  return;
438
- const index = this.checklist.findIndex(item => item.value === data.value);
439
- if (index > -1) {
440
- this.checklist.splice(index, 1);
441
- }
442
- else {
443
- this.checklist = [...this.checklist, data];
444
- }
445
- this.formControl.setValue(this.checklist);
619
+ this.checklist.update((currentList) => {
620
+ const index = currentList.findIndex(item => item.value === data.value);
621
+ let newList;
622
+ if (index > -1) {
623
+ newList = currentList.filter(item => item.value !== data.value);
624
+ }
625
+ else {
626
+ newList = [...currentList, data];
627
+ }
628
+ return newList;
629
+ });
630
+ // 同步表单值
631
+ this.formControl.setValue(this.checklist());
632
+ this._getAllCheckCountState();
446
633
  }
447
634
  allCheckChange(check) {
635
+ const itemsToAdd = this.filteredData().filter((t) => {
636
+ const index = this.checklist().findIndex(item => item.value === t.value);
637
+ return index < 0 && !t.disabled;
638
+ });
448
639
  if (check) {
449
- const itemsToAdd = this.filteredData.filter((t) => {
450
- const index = this.checklist.findIndex(item => item.value === t.value);
451
- return index < 0 && !t.disabled;
452
- });
453
- this.checklist = [...this.checklist, ...itemsToAdd];
640
+ this.checklist.set([...this.checklist(), ...itemsToAdd]);
454
641
  }
455
642
  else {
456
- this.checklist = this.checklist.filter((item) => {
457
- const existsInFiltered = this.filteredData.some(t => t.value === item.value);
458
- const shouldRemove = existsInFiltered && this.filteredData.find(t => t.value === item.value)?.disabled === false;
643
+ this.checklist.set(this.checklist().filter((item) => {
644
+ const existsInFiltered = this.filteredData().some(t => t.value === item.value);
645
+ const shouldRemove = existsInFiltered && this.filteredData().find(t => t.value === item.value)?.disabled === false;
459
646
  return !shouldRemove;
460
- });
647
+ }));
461
648
  }
462
- this.formControl.setValue(this.checklist);
649
+ this.formControl.setValue(this.checklist());
650
+ this._getAllCheckCountState();
463
651
  }
464
652
  isCheck(data) {
465
- const selected = (this.formControl.value ?? []);
466
- return selected.filter((i) => i.value === data.value).length > 0;
653
+ const selected = this.checklist();
654
+ return selected.some((i) => i.value === data.value);
655
+ }
656
+ _refreshFilteredData() {
657
+ this.filteredItems.set(this.filteredData());
658
+ this._getAllCheckCountState();
467
659
  }
468
660
  _getAllCheckCountState() {
469
- if (this.props.showAllCheck && !this.props.disabled) {
470
- let allCheckCount = 0;
471
- if (this.checklist?.length > 0) {
472
- this.filteredData.forEach((t) => {
473
- const index = this.checklist.findIndex(item => item.value === t.value && !t.disabled);
474
- if (index > -1) {
475
- allCheckCount += 1;
476
- }
477
- });
478
- if (this.filteredData.filter(i => !i.disabled).length === allCheckCount) {
479
- this.isChecked = true;
480
- this.isIndeterminate = false;
481
- }
482
- else if (allCheckCount === 0) {
483
- this.isChecked = false;
484
- this.isIndeterminate = false;
485
- }
486
- else {
487
- this.isChecked = false;
488
- this.isIndeterminate = true;
489
- }
490
- }
491
- else {
492
- this.checklist = [];
493
- this.isChecked = false;
494
- this.isIndeterminate = false;
495
- }
661
+ if (!this.props.showAllCheck || this.props.disabled)
662
+ return;
663
+ const currentChecklist = this.checklist();
664
+ const currentFiltered = this.filteredData();
665
+ const enabledFilteredItems = currentFiltered.filter(i => !i.disabled);
666
+ const totalEnabled = enabledFilteredItems.length;
667
+ if (totalEnabled === 0) {
668
+ this.isChecked.set(false);
669
+ this.isIndeterminate.set(false);
670
+ return;
671
+ }
672
+ const allCheckCount = enabledFilteredItems.filter(t => currentChecklist.some(item => item.value === t.value)).length;
673
+ if (allCheckCount === 0) {
674
+ this.isChecked.set(false);
675
+ this.isIndeterminate.set(false);
676
+ }
677
+ else if (allCheckCount === totalEnabled) {
678
+ this.isChecked.set(true);
679
+ this.isIndeterminate.set(false);
680
+ }
681
+ else {
682
+ this.isChecked.set(false);
683
+ this.isIndeterminate.set(true);
496
684
  }
497
685
  }
498
686
  _toSearchText(value) {
499
687
  return typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean' ? String(value) : '';
500
688
  }
501
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatCheckListTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
502
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: CmatCheckListTypeComponent, isStandalone: true, selector: "cmat-checklist-type", usesInheritance: true, ngImport: i0, template: "<div class=\"flex flex-col\">\r\n <div class=\"p-2\">\r\n @if(props.label){\r\n <legend class=\"text-lg\">\r\n {{ props.label }}\r\n @if(props.required){\r\n <span>*</span>\r\n }\r\n </legend>\r\n }\r\n @if(props.description){\r\n <p>{{ props.description }}</p>\r\n }\r\n </div>\r\n\r\n <div class=\"w-full h-full rounded-sm border shadow-sm bg-card\" [tabIndex]=\"props.tabindex\">\r\n <div class=\"flex items-center m-1 mr-2 min-h-12 print:hidden\">\r\n @if (props.showAllCheck&&!props.disabled) {\r\n <div>\r\n <mat-checkbox class=\"flex items-center h-10 min-h-10 m-1\" [color]=\"'primary'\" [checked]=\"isChecked\"\r\n [indeterminate]=\"isIndeterminate\" (change)=\"allCheckChange($event.checked)\">\r\n </mat-checkbox>\r\n </div>\r\n }\r\n <div class=\"flex items-center w-full\">\r\n <mat-icon class=\"icon-size-5\" [svgIcon]=\"'heroicons_solid:magnifying-glass'\"></mat-icon>\r\n <div class=\"ml-2\">\r\n <input #query class=\"w-full min-w-0 py-1 border-none\" type=\"text\"\r\n placeholder=\"\u8F93\u5165\u8FC7\u6EE4\u4FE1\u606F\" (input)=\"filterByQuery(query.value)\">\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"border-t overflow-y-auto scrollbar-custom\"\r\n [ngClass]=\"props.controlMaxHeight?'max-h-64 sm:max-h-128 lg:max-h-64':''\">\r\n @if ((filteredItems$ | async); as filteredItems) {\r\n @if(filteredItems.length>0){\r\n @for (data of filteredItems; track trackByFn($index, data)) {\r\n <div role=\"presentation\" class=\"flex items-center pl-2 pr-4 py-2 cursor-pointer hover:bg-hover\" matRipple\r\n (click)=\"toggleCheckList(data,$event)\">\r\n <mat-checkbox class=\"flex items-center h-10 min-h-10 pointer-events-none\" disableRipple [color]=\"'primary'\"\r\n [checked]=\"isCheck(data)\" [disabled]=\"data.disabled||props.disabled\">\r\n <div class=\"flex flex-col flex-auto\">\r\n <div class=\"font-medium leading-5 truncate\">{{data.label}}</div>\r\n </div>\r\n </mat-checkbox>\r\n </div>\r\n }\r\n } @else {\r\n <div\r\n class=\"flex flex-auto flex-col items-center justify-center bg-slate-100 dark:bg-transparent h-64 sm:h-128 lg:h-64\">\r\n <mat-icon class=\"icon-size-24\" [svgIcon]=\"'heroicons_outline:document-magnifying-glass'\"></mat-icon>\r\n <div class=\"mt-4 text-2xl font-bold tracking-tight text-secondary\">\u6CA1\u6709\u6570\u636E!</div>\r\n </div>\r\n }\r\n }\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [":host{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i1$5.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatRippleModule }, { kind: "directive", type: i3$1.MatRipple, selector: "[mat-ripple], [matRipple]", inputs: ["matRippleColor", "matRippleUnbounded", "matRippleCentered", "matRippleRadius", "matRippleAnimation", "matRippleDisabled", "matRippleTrigger"], exportAs: ["matRipple"] }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
689
+ _refreshData() {
690
+ const domain = this.props.domain;
691
+ // 使用 DomainDataService 加载远程数据
692
+ this._domainDataService.load(domain, this._destroyRef, {
693
+ onSuccess: (data) => {
694
+ this.urlData.set(data);
695
+ this._refreshFilteredData();
696
+ },
697
+ componentName: 'CmatCheckListTypeComponent'
698
+ });
699
+ // 处理静态 options
700
+ if (!domain?.url && this.field.props?.options && isArray(this.field.props?.options)) {
701
+ this.optionsData.set(this.field.props.options || []);
702
+ }
703
+ else if (!domain?.url) {
704
+ this.optionsData.set([]);
705
+ }
706
+ }
707
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatCheckListTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
708
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: CmatCheckListTypeComponent, isStandalone: true, selector: "cmat-checklist-type", usesInheritance: true, ngImport: i0, template: "<div class=\"flex flex-col\">\r\n <div class=\"p-2\">\r\n @if(props.label){\r\n <legend class=\"text-lg\">\r\n {{ props.label }}\r\n @if(props.required){\r\n <span>*</span>\r\n }\r\n </legend>\r\n }\r\n @if(props.description){\r\n <p>{{ props.description }}</p>\r\n }\r\n </div>\r\n\r\n <div class=\"w-full h-full rounded-sm border shadow-sm bg-card\" [tabIndex]=\"props.tabindex\">\r\n <div class=\"flex items-center m-1 mr-2 min-h-12 print:hidden\">\r\n @if (props.showAllCheck&&!props.disabled) {\r\n <div>\r\n <mat-checkbox class=\"flex items-center h-10 min-h-10 m-1\" [color]=\"'primary'\" [checked]=\"isChecked()\"\r\n [indeterminate]=\"isIndeterminate()\" (change)=\"allCheckChange($event.checked)\">\r\n </mat-checkbox>\r\n </div>\r\n }\r\n <div class=\"flex items-center w-full\">\r\n <mat-icon class=\"icon-size-5\" [svgIcon]=\"'heroicons_solid:magnifying-glass'\"></mat-icon>\r\n <div class=\"ml-2\">\r\n <input #query class=\"w-full min-w-0 py-1 border-none\" type=\"text\" placeholder=\"\u8F93\u5165\u8FC7\u6EE4\u4FE1\u606F\"\r\n [disabled]=\"props.disabled\"\r\n (input)=\"filterByQuery(query.value)\">\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"flex flex-col border-t overflow-y-auto scrollbar-custom\"\r\n [ngClass]=\"props.controlMaxHeight?'max-h-64 sm:max-h-128 lg:max-h-64':'flex-auto'\">\r\n @if (filteredItems()) {\r\n @if(filteredItems()!.length>0){\r\n @for (data of filteredItems(); track trackByFn($index, data)) {\r\n <div role=\"presentation\" class=\"flex items-center pl-2 pr-4 py-2 h-15 w-full\" matRipple [matRippleDisabled]=\"disabled\"\r\n [ngClass]=\"{'cursor-pointer hover:bg-hover': !disabled}\" (click)=\"toggleCheckList(data,$event)\">\r\n <mat-checkbox class=\"flex items-center h-10 min-h-10 pointer-events-none\" disableRipple [color]=\"'primary'\"\r\n [checked]=\"isCheck(data)\" [disabled]=\"data.disabled||props.disabled\">\r\n <div class=\"flex flex-col flex-auto\">\r\n <div class=\"font-medium leading-5 truncate\">{{data.label}}</div>\r\n </div>\r\n </mat-checkbox>\r\n </div>\r\n }\r\n } @else {\r\n <div\r\n class=\"flex flex-auto flex-col items-center justify-center bg-slate-100 dark:bg-transparent h-64 sm:h-128 lg:h-64\">\r\n <mat-icon class=\"icon-size-24\" [svgIcon]=\"'heroicons_outline:document-magnifying-glass'\"></mat-icon>\r\n <div class=\"mt-4 text-2xl font-bold tracking-tight text-secondary\">\u6CA1\u6709\u6570\u636E!</div>\r\n </div>\r\n }\r\n }\r\n </div>\r\n </div>\r\n</div>", styles: [":host{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i1$5.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatRippleModule }, { kind: "directive", type: i3$1.MatRipple, selector: "[mat-ripple], [matRipple]", inputs: ["matRippleColor", "matRippleUnbounded", "matRippleCentered", "matRippleRadius", "matRippleAnimation", "matRippleDisabled", "matRippleTrigger"], exportAs: ["matRipple"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
503
709
  }
504
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatCheckListTypeComponent, decorators: [{
710
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatCheckListTypeComponent, decorators: [{
505
711
  type: Component,
506
- args: [{ selector: 'cmat-checklist-type', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatCheckboxModule, MatIconModule, NgClass, MatRippleModule, AsyncPipe], template: "<div class=\"flex flex-col\">\r\n <div class=\"p-2\">\r\n @if(props.label){\r\n <legend class=\"text-lg\">\r\n {{ props.label }}\r\n @if(props.required){\r\n <span>*</span>\r\n }\r\n </legend>\r\n }\r\n @if(props.description){\r\n <p>{{ props.description }}</p>\r\n }\r\n </div>\r\n\r\n <div class=\"w-full h-full rounded-sm border shadow-sm bg-card\" [tabIndex]=\"props.tabindex\">\r\n <div class=\"flex items-center m-1 mr-2 min-h-12 print:hidden\">\r\n @if (props.showAllCheck&&!props.disabled) {\r\n <div>\r\n <mat-checkbox class=\"flex items-center h-10 min-h-10 m-1\" [color]=\"'primary'\" [checked]=\"isChecked\"\r\n [indeterminate]=\"isIndeterminate\" (change)=\"allCheckChange($event.checked)\">\r\n </mat-checkbox>\r\n </div>\r\n }\r\n <div class=\"flex items-center w-full\">\r\n <mat-icon class=\"icon-size-5\" [svgIcon]=\"'heroicons_solid:magnifying-glass'\"></mat-icon>\r\n <div class=\"ml-2\">\r\n <input #query class=\"w-full min-w-0 py-1 border-none\" type=\"text\"\r\n placeholder=\"\u8F93\u5165\u8FC7\u6EE4\u4FE1\u606F\" (input)=\"filterByQuery(query.value)\">\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"border-t overflow-y-auto scrollbar-custom\"\r\n [ngClass]=\"props.controlMaxHeight?'max-h-64 sm:max-h-128 lg:max-h-64':''\">\r\n @if ((filteredItems$ | async); as filteredItems) {\r\n @if(filteredItems.length>0){\r\n @for (data of filteredItems; track trackByFn($index, data)) {\r\n <div role=\"presentation\" class=\"flex items-center pl-2 pr-4 py-2 cursor-pointer hover:bg-hover\" matRipple\r\n (click)=\"toggleCheckList(data,$event)\">\r\n <mat-checkbox class=\"flex items-center h-10 min-h-10 pointer-events-none\" disableRipple [color]=\"'primary'\"\r\n [checked]=\"isCheck(data)\" [disabled]=\"data.disabled||props.disabled\">\r\n <div class=\"flex flex-col flex-auto\">\r\n <div class=\"font-medium leading-5 truncate\">{{data.label}}</div>\r\n </div>\r\n </mat-checkbox>\r\n </div>\r\n }\r\n } @else {\r\n <div\r\n class=\"flex flex-auto flex-col items-center justify-center bg-slate-100 dark:bg-transparent h-64 sm:h-128 lg:h-64\">\r\n <mat-icon class=\"icon-size-24\" [svgIcon]=\"'heroicons_outline:document-magnifying-glass'\"></mat-icon>\r\n <div class=\"mt-4 text-2xl font-bold tracking-tight text-secondary\">\u6CA1\u6709\u6570\u636E!</div>\r\n </div>\r\n }\r\n }\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [":host{width:100%}\n"] }]
712
+ args: [{ selector: 'cmat-checklist-type', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatCheckboxModule, MatIconModule, NgClass, MatRippleModule], template: "<div class=\"flex flex-col\">\r\n <div class=\"p-2\">\r\n @if(props.label){\r\n <legend class=\"text-lg\">\r\n {{ props.label }}\r\n @if(props.required){\r\n <span>*</span>\r\n }\r\n </legend>\r\n }\r\n @if(props.description){\r\n <p>{{ props.description }}</p>\r\n }\r\n </div>\r\n\r\n <div class=\"w-full h-full rounded-sm border shadow-sm bg-card\" [tabIndex]=\"props.tabindex\">\r\n <div class=\"flex items-center m-1 mr-2 min-h-12 print:hidden\">\r\n @if (props.showAllCheck&&!props.disabled) {\r\n <div>\r\n <mat-checkbox class=\"flex items-center h-10 min-h-10 m-1\" [color]=\"'primary'\" [checked]=\"isChecked()\"\r\n [indeterminate]=\"isIndeterminate()\" (change)=\"allCheckChange($event.checked)\">\r\n </mat-checkbox>\r\n </div>\r\n }\r\n <div class=\"flex items-center w-full\">\r\n <mat-icon class=\"icon-size-5\" [svgIcon]=\"'heroicons_solid:magnifying-glass'\"></mat-icon>\r\n <div class=\"ml-2\">\r\n <input #query class=\"w-full min-w-0 py-1 border-none\" type=\"text\" placeholder=\"\u8F93\u5165\u8FC7\u6EE4\u4FE1\u606F\"\r\n [disabled]=\"props.disabled\"\r\n (input)=\"filterByQuery(query.value)\">\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"flex flex-col border-t overflow-y-auto scrollbar-custom\"\r\n [ngClass]=\"props.controlMaxHeight?'max-h-64 sm:max-h-128 lg:max-h-64':'flex-auto'\">\r\n @if (filteredItems()) {\r\n @if(filteredItems()!.length>0){\r\n @for (data of filteredItems(); track trackByFn($index, data)) {\r\n <div role=\"presentation\" class=\"flex items-center pl-2 pr-4 py-2 h-15 w-full\" matRipple [matRippleDisabled]=\"disabled\"\r\n [ngClass]=\"{'cursor-pointer hover:bg-hover': !disabled}\" (click)=\"toggleCheckList(data,$event)\">\r\n <mat-checkbox class=\"flex items-center h-10 min-h-10 pointer-events-none\" disableRipple [color]=\"'primary'\"\r\n [checked]=\"isCheck(data)\" [disabled]=\"data.disabled||props.disabled\">\r\n <div class=\"flex flex-col flex-auto\">\r\n <div class=\"font-medium leading-5 truncate\">{{data.label}}</div>\r\n </div>\r\n </mat-checkbox>\r\n </div>\r\n }\r\n } @else {\r\n <div\r\n class=\"flex flex-auto flex-col items-center justify-center bg-slate-100 dark:bg-transparent h-64 sm:h-128 lg:h-64\">\r\n <mat-icon class=\"icon-size-24\" [svgIcon]=\"'heroicons_outline:document-magnifying-glass'\"></mat-icon>\r\n <div class=\"mt-4 text-2xl font-bold tracking-tight text-secondary\">\u6CA1\u6709\u6570\u636E!</div>\r\n </div>\r\n }\r\n }\r\n </div>\r\n </div>\r\n</div>", styles: [":host{width:100%}\n"] }]
507
713
  }], ctorParameters: () => [] });
508
714
 
509
715
  class CmatChipsInputTypeComponent extends FieldType {
510
716
  constructor() {
511
717
  super();
512
- this.autocompleteUrlData = [];
513
- this._http = inject(HttpClient);
718
+ this.urlData = signal([], /* @ts-ignore */
719
+ ...(ngDevMode ? [{ debugName: "urlData" }] : /* istanbul ignore next */ []));
720
+ this.autocompleteOptions = computed(() => {
721
+ const data = this.urlData();
722
+ if (data && data.length > 0) {
723
+ return data.filter((item) => typeof item === 'string');
724
+ }
725
+ const staticText = this.props?.autocompleteText;
726
+ if (staticText) {
727
+ return staticText.split(',').map(s => s.trim()).filter(s => s.length > 0);
728
+ }
729
+ return [];
730
+ }, /* @ts-ignore */
731
+ ...(ngDevMode ? [{ debugName: "autocompleteOptions" }] : /* istanbul ignore next */ []));
732
+ this._lastDomain = undefined;
514
733
  this._destroyRef = inject(DestroyRef);
515
- }
516
- get autocompleteText() {
517
- if (this.autocompleteUrlData?.length > 0) {
518
- // Ensure all elements are strings, filter out non-strings
519
- return this.autocompleteUrlData.filter((item) => typeof item === 'string');
520
- }
521
- return this.props?.autocompleteText?.split(',') ?? [];
734
+ this._domainDataService = inject(DomainDataService);
522
735
  }
523
736
  ngOnInit() {
524
- const url = this.props?.domain?.url;
525
- if (url && this.props?.domain?.code && this.props?.domain?.key && this.props?.domain?.value) {
526
- this._http.get(url).pipe(takeUntilDestroyed(this._destroyRef)).subscribe((data) => {
527
- if (data) {
528
- const key = this.field.props?.domain?.key;
529
- const code = this.field.props?.domain?.code;
530
- const datas = data
531
- .filter((i) => typeof i === 'object' && i !== null)
532
- .filter((i) => {
533
- if (key)
534
- return i[key] === code;
535
- return false;
737
+ this._lastDomain = this.props.domain;
738
+ this._refreshData();
739
+ }
740
+ ngDoCheck() {
741
+ const currentDomain = this.props.domain;
742
+ let shouldRefresh = false;
743
+ if (!isEqual(currentDomain, this._lastDomain)) {
744
+ this._lastDomain = currentDomain;
745
+ shouldRefresh = true;
746
+ }
747
+ if (shouldRefresh) {
748
+ this._refreshData();
749
+ }
750
+ }
751
+ _refreshData() {
752
+ const domain = this.props.domain;
753
+ // 使用 DomainDataService 加载远程数据
754
+ this._domainDataService.load(domain, this._destroyRef, {
755
+ transform: (rawData) => {
756
+ // Chips 特殊处理:支持字符串数组或逗号分隔的字符串
757
+ if (rawData.length > 0 && typeof rawData[0] === 'string') {
758
+ return rawData;
759
+ }
760
+ else if (rawData.length > 0 && typeof rawData[0] === 'object' && rawData[0] !== null) {
761
+ // 如果是对象数组,尝试提取 label/name/text 字段
762
+ return rawData.map((item) => {
763
+ const obj = item;
764
+ return (obj.label ?? obj.name ?? obj.text ?? obj.value ?? item);
536
765
  });
537
- if (datas && this.field.props?.domain?.value) {
538
- this.autocompleteUrlData = [datas[0][this.field.props?.domain?.value]];
539
- }
540
- else {
541
- this.autocompleteUrlData = [];
542
- }
766
+ }
767
+ return rawData;
768
+ },
769
+ onSuccess: (data) => {
770
+ // 如果提取的是字符串,转换为数组
771
+ if (data.length === 1 && typeof data[0] === 'string') {
772
+ this.urlData.set((data[0]).split(',').map(s => s.trim()));
543
773
  }
544
774
  else {
545
- this.autocompleteUrlData = [];
775
+ this.urlData.set(data);
546
776
  }
547
- });
548
- }
549
- else {
550
- this.autocompleteUrlData = [];
551
- }
777
+ },
778
+ componentName: 'CmatChipsInputTypeComponent'
779
+ });
552
780
  }
553
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatChipsInputTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
554
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.11", type: CmatChipsInputTypeComponent, isStandalone: true, selector: "cmat-chips-input-type", usesInheritance: true, ngImport: i0, template: "<cmat-chip-input [hasAutocomplete]=\"props.hasAutocomplete??false\" [formControl]=\"formControl\"\r\n [placeholder]=\"placeholder\" [selectableOptions]=\"autocompleteText\" [tabIndex]=\"props.tabindex\" [required]=\"required\"></cmat-chip-input>", styles: [":host{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: CmatChipInputComponent, selector: "cmat-chip-input", inputs: ["id", "selectableOptions", "hasAutocomplete", "outputIsString", "separatorKey", "placeholder", "value", "required", "disabled"], exportAs: ["cmatChipInput"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
781
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatChipsInputTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
782
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.6", type: CmatChipsInputTypeComponent, isStandalone: true, selector: "cmat-chips-input-type", usesInheritance: true, ngImport: i0, template: "<cmat-chip-input \r\n [hasAutocomplete]=\"props.hasAutocomplete ?? false\" \r\n [formControl]=\"formControl\"\r\n [selectableOptions]=\"autocompleteOptions()\" \r\n [tabIndex]=\"props.tabindex\" \r\n [required]=\"required\">\r\n</cmat-chip-input>", styles: [":host{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: CmatChipInputComponent, selector: "cmat-chip-input", inputs: ["selectableOptions", "hasAutocomplete", "outputIsString", "separatorKey", "placeholder", "value", "required", "disabled"], exportAs: ["cmatChipInput"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
555
783
  }
556
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatChipsInputTypeComponent, decorators: [{
784
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatChipsInputTypeComponent, decorators: [{
557
785
  type: Component,
558
- args: [{ selector: 'cmat-chips-input-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [ReactiveFormsModule, CmatChipInputComponent], template: "<cmat-chip-input [hasAutocomplete]=\"props.hasAutocomplete??false\" [formControl]=\"formControl\"\r\n [placeholder]=\"placeholder\" [selectableOptions]=\"autocompleteText\" [tabIndex]=\"props.tabindex\" [required]=\"required\"></cmat-chip-input>", styles: [":host{width:100%}\n"] }]
786
+ args: [{ selector: 'cmat-chips-input-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [ReactiveFormsModule, CmatChipInputComponent], template: "<cmat-chip-input \r\n [hasAutocomplete]=\"props.hasAutocomplete ?? false\" \r\n [formControl]=\"formControl\"\r\n [selectableOptions]=\"autocompleteOptions()\" \r\n [tabIndex]=\"props.tabindex\" \r\n [required]=\"required\">\r\n</cmat-chip-input>", styles: [":host{width:100%}\n"] }]
559
787
  }], ctorParameters: () => [] });
560
788
 
561
789
  class CmatColorPickerTypeComponent extends FieldType$1 {
562
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatColorPickerTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
563
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.11", type: CmatColorPickerTypeComponent, isStandalone: true, selector: "cmat-color-picker-type", usesInheritance: true, ngImport: i0, template: "<cmat-material-color-picker [title]=\"props.label??''\" [formControl]=\"formControl\" [readonly]=\"disabled\"\r\n [tabindex]=\"props.tabindex\"></cmat-material-color-picker>", styles: [":host{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: CmatMaterialColorPickerComponent, selector: "cmat-material-color-picker", inputs: ["color", "title", "readonly"], outputs: ["colorChanged"], exportAs: ["cmatMaterialColorPicker"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
790
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatColorPickerTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
791
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.6", type: CmatColorPickerTypeComponent, isStandalone: true, selector: "cmat-color-picker-type", usesInheritance: true, ngImport: i0, template: "<cmat-color-picker-button [value]=\"value\" [label]=\"props.label??''\" [placeholder]=\"props.placeholder??''\" [tabindex]=\"props.tabindex\" [disabled]=\"props.disabled??false\" (valueChanged)=\"value=$event\"></cmat-color-picker-button>", styles: [":host{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: CmatColorPickerButtonComponent, selector: "cmat-color-picker-button", inputs: ["format", "value", "hideAlpha", "disabled", "placeholder", "label"], outputs: ["formatChange", "valueChange", "disabledChange", "formatChanged", "valueChanged", "colorChanged"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
564
792
  }
565
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatColorPickerTypeComponent, decorators: [{
793
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatColorPickerTypeComponent, decorators: [{
566
794
  type: Component,
567
- args: [{ selector: 'cmat-color-picker-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [ReactiveFormsModule, CmatMaterialColorPickerComponent], template: "<cmat-material-color-picker [title]=\"props.label??''\" [formControl]=\"formControl\" [readonly]=\"disabled\"\r\n [tabindex]=\"props.tabindex\"></cmat-material-color-picker>", styles: [":host{width:100%}\n"] }]
795
+ args: [{ selector: 'cmat-color-picker-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [ReactiveFormsModule, CmatColorPickerButtonComponent], template: "<cmat-color-picker-button [value]=\"value\" [label]=\"props.label??''\" [placeholder]=\"props.placeholder??''\" [tabindex]=\"props.tabindex\" [disabled]=\"props.disabled??false\" (valueChanged)=\"value=$event\"></cmat-color-picker-button>", styles: [":host{width:100%}\n"] }]
568
796
  }] });
569
797
 
798
+ class CmatDataPickerTypeComponent extends FieldType {
799
+ constructor() {
800
+ super();
801
+ this.dataProviderSignal = signal(undefined, /* @ts-ignore */
802
+ ...(ngDevMode ? [{ debugName: "dataProviderSignal" }] : /* istanbul ignore next */ []));
803
+ this._http = inject(HttpClient);
804
+ this._destroyRef = inject(DestroyRef);
805
+ // 用于记录上一次的配置快照
806
+ this._lastDomain = undefined;
807
+ this._lastApiUrl = undefined;
808
+ }
809
+ ngOnInit() {
810
+ // 初始化快照
811
+ this._lastDomain = this.props.domain;
812
+ this._lastApiUrl = this.props.apiUrl;
813
+ // 执行初始创建逻辑
814
+ this._createDataProvider();
815
+ }
816
+ ngDoCheck() {
817
+ const currentDomain = this.props.domain;
818
+ const currentApiUrl = this.props.apiUrl;
819
+ let shouldRefresh = false;
820
+ // 检查 domain 变化
821
+ if (!isEqual(currentDomain, this._lastDomain)) {
822
+ this._lastDomain = currentDomain;
823
+ shouldRefresh = true;
824
+ }
825
+ // 检查 apiUrl 变化
826
+ if (currentApiUrl !== this._lastApiUrl) {
827
+ this._lastApiUrl = currentApiUrl;
828
+ shouldRefresh = true;
829
+ }
830
+ if (shouldRefresh) {
831
+ this._createDataProvider();
832
+ }
833
+ }
834
+ /**
835
+ * 统一创建 dataProvider 的方法
836
+ */
837
+ _createDataProvider() {
838
+ const domain = this.props.domain;
839
+ const apiUrl = this.props.apiUrl;
840
+ if (domain?.url && domain?.key && domain?.code && domain?.value) {
841
+ this._createDataProviderFromDomain(domain);
842
+ }
843
+ else if (apiUrl) {
844
+ // 如果提供了 apiUrl,创建简单的 HTTP provider
845
+ this._createDataProviderFromUrl(apiUrl);
846
+ }
847
+ else {
848
+ // 没有配置,清空 provider
849
+ this.dataProviderSignal.set(undefined);
850
+ }
851
+ }
852
+ /**
853
+ * 从 domain 配置创建 dataProvider
854
+ */
855
+ _createDataProviderFromDomain(domain) {
856
+ if (!domain.url || !domain.key || !domain.code || !domain.value)
857
+ return;
858
+ const provider = {
859
+ loadPage: (query) => {
860
+ const params = {
861
+ page: query.page,
862
+ size: query.size,
863
+ };
864
+ if (query.search) {
865
+ params[domain.key] = domain.code;
866
+ params['search'] = query.search;
867
+ }
868
+ if (query.orderBy) {
869
+ params['orderBy'] = query.orderBy;
870
+ params['desc'] = query.desc ?? false;
871
+ }
872
+ return this._http.post(domain.url, params).pipe(takeUntilDestroyed(this._destroyRef), catchError((error) => {
873
+ console.error('Failed to load data picker data:', error);
874
+ return of({ data: [], total: 0 });
875
+ }));
876
+ },
877
+ };
878
+ this.dataProviderSignal.set(provider);
879
+ }
880
+ /**
881
+ * 从 URL 创建简单的 dataProvider
882
+ */
883
+ _createDataProviderFromUrl(url) {
884
+ const provider = {
885
+ loadPage: (query) => {
886
+ const params = {
887
+ page: query.page,
888
+ size: query.size,
889
+ };
890
+ if (query.search) {
891
+ params['search'] = query.search;
892
+ }
893
+ if (query.orderBy) {
894
+ params['orderBy'] = query.orderBy;
895
+ params['desc'] = query.desc ?? false;
896
+ }
897
+ return this._http.post(url, params).pipe(takeUntilDestroyed(this._destroyRef), catchError((error) => {
898
+ console.error('Failed to load data picker data:', error);
899
+ return of({ data: [], total: 0 });
900
+ }));
901
+ },
902
+ };
903
+ this.dataProviderSignal.set(provider);
904
+ }
905
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatDataPickerTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
906
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.6", type: CmatDataPickerTypeComponent, isStandalone: true, selector: "cmat-data-picker-type", usesInheritance: true, ngImport: i0, template: "<cmat-data-picker\r\n [formControl]=\"formControl\"\r\n [dataProvider]=\"dataProviderSignal()\"\r\n [columns]=\"props.columns ?? []\"\r\n [keyField]=\"props.keyField ?? 'id'\"\r\n [labelField]=\"props.labelField ?? 'name'\"\r\n [multiple]=\"props.multiple ?? false\"\r\n [searchable]=\"props.searchable ?? true\"\r\n [pageSize]=\"props.pageSize ?? 20\"\r\n [uiMode]=\"props.uiMode ?? 'auto'\"\r\n [drawerPosition]=\"props.drawerPosition ?? 'end'\"\r\n [drawerWidth]=\"props.drawerWidth ?? '600px'\"\r\n [dialogWidth]=\"props.dialogWidth ?? '800px'\"\r\n [dialogMaxHeight]=\"props.dialogMaxHeight ?? '80vh'\"\r\n [displayTemplate]=\"props.displayTemplate\"\r\n [placeholder]=\"placeholder\"\r\n [required]=\"required\">\r\n</cmat-data-picker>\r\n", styles: [":host{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: CmatDataPickerComponent, selector: "cmat-data-picker", inputs: ["apiUrl", "dataSource", "dataProvider", "columns", "keyField", "labelField", "displayTemplate", "displayLabelFn", "multiple", "searchable", "debounceTime", "pageSize", "uiMode", "drawerPosition", "drawerWidth", "dialogWidth", "dialogMaxHeight", "placeholder", "value", "required", "disabled"], outputs: ["selectionChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
907
+ }
908
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatDataPickerTypeComponent, decorators: [{
909
+ type: Component,
910
+ args: [{ selector: 'cmat-data-picker-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [ReactiveFormsModule, CmatDataPickerComponent], template: "<cmat-data-picker\r\n [formControl]=\"formControl\"\r\n [dataProvider]=\"dataProviderSignal()\"\r\n [columns]=\"props.columns ?? []\"\r\n [keyField]=\"props.keyField ?? 'id'\"\r\n [labelField]=\"props.labelField ?? 'name'\"\r\n [multiple]=\"props.multiple ?? false\"\r\n [searchable]=\"props.searchable ?? true\"\r\n [pageSize]=\"props.pageSize ?? 20\"\r\n [uiMode]=\"props.uiMode ?? 'auto'\"\r\n [drawerPosition]=\"props.drawerPosition ?? 'end'\"\r\n [drawerWidth]=\"props.drawerWidth ?? '600px'\"\r\n [dialogWidth]=\"props.dialogWidth ?? '800px'\"\r\n [dialogMaxHeight]=\"props.dialogMaxHeight ?? '80vh'\"\r\n [displayTemplate]=\"props.displayTemplate\"\r\n [placeholder]=\"placeholder\"\r\n [required]=\"required\">\r\n</cmat-data-picker>\r\n", styles: [":host{width:100%}\n"] }]
911
+ }], ctorParameters: () => [] });
912
+
570
913
  class CmatDateRangeTypeComponent extends FieldType {
571
914
  constructor() {
572
915
  super(...arguments);
@@ -578,10 +921,10 @@ class CmatDateRangeTypeComponent extends FieldType {
578
921
  },
579
922
  };
580
923
  }
581
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatDateRangeTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
582
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.11", type: CmatDateRangeTypeComponent, isStandalone: true, selector: "cmat-date-range-type", usesInheritance: true, ngImport: i0, template: "<cmat-date-range [dateFormat]=\"props.dateFormat\" [timeFormat]=\"props.timeFormat\" [timeRange]=\"props.timeRange\" \r\n[formControl]=\"formControl\" [tabindex]=\"props.tabindex\" [readonly]=\"disabled\">\r\n</cmat-date-range>", styles: [":host{width:100%}\n"], dependencies: [{ kind: "component", type: CmatDateRangeComponent, selector: "cmat-date-range", inputs: ["controlClass", "initData", "readonly", "dateFormat", "timeFormat", "timeRange", "range"], outputs: ["rangeChanged"], exportAs: ["cmatDateRange"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
924
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatDateRangeTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
925
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.6", type: CmatDateRangeTypeComponent, isStandalone: true, selector: "cmat-date-range-type", usesInheritance: true, ngImport: i0, template: "<cmat-date-range [dateFormat]=\"props.dateFormat\" [timeFormat]=\"props.timeFormat\" [timeRange]=\"props.timeRange\" \r\n[formControl]=\"formControl\" [tabindex]=\"props.tabindex\" [readonly]=\"disabled\">\r\n</cmat-date-range>", styles: [":host{width:100%}\n"], dependencies: [{ kind: "component", type: CmatDateRangeComponent, selector: "cmat-date-range", inputs: ["controlClass", "dateFormat", "timeFormat", "readonly", "timeRange", "range"], outputs: ["rangeChanged"], exportAs: ["cmatDateRange"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
583
926
  }
584
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatDateRangeTypeComponent, decorators: [{
927
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatDateRangeTypeComponent, decorators: [{
585
928
  type: Component,
586
929
  args: [{ selector: 'cmat-date-range-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CmatDateRangeComponent, ReactiveFormsModule], template: "<cmat-date-range [dateFormat]=\"props.dateFormat\" [timeFormat]=\"props.timeFormat\" [timeRange]=\"props.timeRange\" \r\n[formControl]=\"formControl\" [tabindex]=\"props.tabindex\" [readonly]=\"disabled\">\r\n</cmat-date-range>", styles: [":host{width:100%}\n"] }]
587
930
  }] });
@@ -602,21 +945,17 @@ class CmatDatepickerTypeComponent extends FieldType {
602
945
  twelvehour: false
603
946
  }
604
947
  };
605
- this.isHandSet = signal(false, ...(ngDevMode ? [{ debugName: "isHandSet" }] : /* istanbul ignore next */ []));
606
948
  this._cmatMediaWatcherService = inject(CmatMediaWatcherService);
607
- this._destroyRef = inject(DestroyRef);
608
- }
609
- ngOnInit() {
610
- this._cmatMediaWatcherService.onMediaChange$
611
- .pipe(takeUntilDestroyed(this._destroyRef))
612
- .subscribe(({ matchingAliases }) => {
613
- this.isHandSet.set(!matchingAliases.includes('lg'));
614
- });
615
- }
616
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatDatepickerTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
617
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: CmatDatepickerTypeComponent, isStandalone: true, selector: "cmat-datepicker-type", usesInheritance: true, ngImport: i0, template: "@if(props.togglePosition==='left'){\r\n<cmat-datetimepicker-toggle matPrefix [for]=\"datetimePicker\" [disabled]=\"disabled\"></cmat-datetimepicker-toggle>\r\n}\r\n\r\n<cmat-datetimepicker #datetimePicker openOnFocus=\"true\" [startView]=\"props.startView\" [mode]=\"props.mode\"\r\n [timeInterval]=\"props.timeInterval\" [twelvehour]=\"props.twelvehour\" [type]=\"props.type\"\r\n [multiYearSelector]=\"props.multiYearSelector\" [timeInput]=\"props.timeInput\" [touchUi]=\"isHandSet()\"\r\n [disabled]=\"disabled\"></cmat-datetimepicker>\r\n\r\n<input autocomplete=\"false\" matInput [cmatDatetimepicker]=\"datetimePicker\" [required]=\"required\"\r\n [formControl]=\"formControl\" [placeholder]=\"placeholder\" />\r\n\r\n@if(props.togglePosition==='right'){\r\n<cmat-datetimepicker-toggle matSuffix [for]=\"datetimePicker\" [disabled]=\"disabled\"></cmat-datetimepicker-toggle>\r\n}", styles: [":host{width:100%;display:flex}\n"], dependencies: [{ kind: "component", type: CmatDatetimepickerToggleComponent, selector: "cmat-datetimepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disableRipple", "disabled"], exportAs: ["cmatDatetimepickerToggle"] }, { kind: "directive", type: CmatDatetimepickerInputDirective, selector: "input[cmatDatetimepicker]", inputs: ["cmatDatetimepicker", "cmatDatepickerFilter", "value", "min", "max", "disabled"], outputs: ["dateChange", "dateInput"], exportAs: ["cmatDatepickerInput"] }, { kind: "component", type: CmatDatetimepickerComponent, selector: "cmat-datetimepicker", inputs: ["startView", "mode", "timeInterval", "preventSameDateTimeSelection", "xPosition", "yPosition", "multiYearSelector", "twelvehour", "panelClass", "opened", "color", "startAt", "type", "timeInput", "touchUi", "disabled", "restoreFocus"], outputs: ["selectedChanged", "openedStream", "closedStream", "viewChanged"], exportAs: ["cmatDatetimepicker"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i1$6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "directive", type: i1$2.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i1$2.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
949
+ // eslint-disable-next-line @typescript-eslint/member-ordering
950
+ this.isHandSet = computed(() => {
951
+ return !this._cmatMediaWatcherService.mediaChange().matchingAliases.includes('lg');
952
+ }, /* @ts-ignore */
953
+ ...(ngDevMode ? [{ debugName: "isHandSet" }] : /* istanbul ignore next */ []));
954
+ }
955
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatDatepickerTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
956
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: CmatDatepickerTypeComponent, isStandalone: true, selector: "cmat-datepicker-type", usesInheritance: true, ngImport: i0, template: "@if(props.togglePosition==='left'){\r\n<cmat-datetimepicker-toggle matPrefix [for]=\"datetimePicker\" [disabled]=\"disabled\"></cmat-datetimepicker-toggle>\r\n}\r\n\r\n<cmat-datetimepicker #datetimePicker openOnFocus=\"true\" [startView]=\"props.startView\" [mode]=\"props.mode\"\r\n [timeInterval]=\"props.timeInterval\" [twelvehour]=\"props.twelvehour\" [type]=\"props.type\"\r\n [multiYearSelector]=\"props.multiYearSelector\" [timeInput]=\"props.timeInput\" [touchUi]=\"isHandSet()\"\r\n [disabled]=\"disabled\"></cmat-datetimepicker>\r\n\r\n<input autocomplete=\"false\" matInput [cmatDatetimepicker]=\"datetimePicker\" [required]=\"required\"\r\n [formControl]=\"formControl\" [placeholder]=\"placeholder\" />\r\n\r\n@if(props.togglePosition==='right'){\r\n<cmat-datetimepicker-toggle matSuffix [for]=\"datetimePicker\" [disabled]=\"disabled\"></cmat-datetimepicker-toggle>\r\n}", styles: [":host{width:100%;display:flex}\n"], dependencies: [{ kind: "component", type: CmatDatetimepickerToggleComponent, selector: "cmat-datetimepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disableRipple", "disabled"], exportAs: ["cmatDatetimepickerToggle"] }, { kind: "directive", type: CmatDatetimepickerInputDirective, selector: "input[cmatDatetimepicker]", inputs: ["cmatDatetimepicker", "cmatDatepickerFilter", "min", "max", "disabled", "value"], outputs: ["dateChange", "dateInput"], exportAs: ["cmatDatepickerInput"] }, { kind: "component", type: CmatDatetimepickerComponent, selector: "cmat-datetimepicker", inputs: ["startView", "mode", "timeInterval", "preventSameDateTimeSelection", "xPosition", "yPosition", "multiYearSelector", "twelvehour", "panelClass", "timeInput", "touchUi", "restoreFocus", "color", "type", "opened", "disabled", "startAt"], outputs: ["openedStream", "closedStream", "viewChanged"], exportAs: ["cmatDatetimepicker"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i1$6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "directive", type: i1$2.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i1$2.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$4.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
618
957
  }
619
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatDatepickerTypeComponent, decorators: [{
958
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatDatepickerTypeComponent, decorators: [{
620
959
  type: Component,
621
960
  args: [{ selector: 'cmat-datepicker-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CmatDatetimepickerToggleComponent, CmatDatetimepickerInputDirective, CmatDatetimepickerComponent, MatInputModule, FormsModule, ReactiveFormsModule], template: "@if(props.togglePosition==='left'){\r\n<cmat-datetimepicker-toggle matPrefix [for]=\"datetimePicker\" [disabled]=\"disabled\"></cmat-datetimepicker-toggle>\r\n}\r\n\r\n<cmat-datetimepicker #datetimePicker openOnFocus=\"true\" [startView]=\"props.startView\" [mode]=\"props.mode\"\r\n [timeInterval]=\"props.timeInterval\" [twelvehour]=\"props.twelvehour\" [type]=\"props.type\"\r\n [multiYearSelector]=\"props.multiYearSelector\" [timeInput]=\"props.timeInput\" [touchUi]=\"isHandSet()\"\r\n [disabled]=\"disabled\"></cmat-datetimepicker>\r\n\r\n<input autocomplete=\"false\" matInput [cmatDatetimepicker]=\"datetimePicker\" [required]=\"required\"\r\n [formControl]=\"formControl\" [placeholder]=\"placeholder\" />\r\n\r\n@if(props.togglePosition==='right'){\r\n<cmat-datetimepicker-toggle matSuffix [for]=\"datetimePicker\" [disabled]=\"disabled\"></cmat-datetimepicker-toggle>\r\n}", styles: [":host{width:100%;display:flex}\n"] }]
622
961
  }], ctorParameters: () => [] });
@@ -632,74 +971,113 @@ class CmatMultiCheckboxTypeComponent extends FieldType {
632
971
  labelPosition: 'after'
633
972
  },
634
973
  };
635
- this._http = inject(HttpClient);
974
+ this.urlData = [];
975
+ this._lastDomain = undefined;
976
+ this._lastOptions = undefined;
636
977
  this._destroyRef = inject(DestroyRef);
637
- this._urlData = signal([], ...(ngDevMode ? [{ debugName: "_urlData" }] : /* istanbul ignore next */ []));
638
- this._urlData$ = toObservable(this._urlData);
978
+ this._domainDataService = inject(DomainDataService);
979
+ }
980
+ ngOnInit() {
981
+ this._lastDomain = this.props.domain;
982
+ this._lastOptions = this.field.props?.options;
983
+ this._refreshData();
639
984
  }
640
- get urlData$() {
641
- return this._urlData$;
985
+ ngDoCheck() {
986
+ const currentDomain = this.props.domain;
987
+ const currentOptions = this.field.props?.options;
988
+ let shouldRefresh = false;
989
+ // 1. 检查 domain 变化
990
+ if (!isEqual(currentDomain, this._lastDomain)) {
991
+ this._lastDomain = currentDomain;
992
+ shouldRefresh = true;
993
+ }
994
+ // 2. 检查 options 变化
995
+ if (!isEqual(currentOptions, this._lastOptions)) {
996
+ this._lastOptions = currentOptions;
997
+ shouldRefresh = true;
998
+ }
999
+ if (shouldRefresh) {
1000
+ this._refreshData();
1001
+ }
642
1002
  }
643
1003
  onChange(optionValue, checked) {
644
- const value = optionValue ?? '';
1004
+ if (optionValue === undefined || optionValue === null)
1005
+ return;
645
1006
  this.formControl.markAsDirty();
646
1007
  if (this.props.type === 'array') {
647
1008
  const currentValue = (this.formControl.value ?? []);
648
1009
  this.formControl.patchValue(checked
649
- ? [...currentValue, value]
650
- : currentValue.filter(o => o !== value));
1010
+ ? [...currentValue, optionValue]
1011
+ : currentValue.filter(o => o !== optionValue));
651
1012
  }
652
1013
  else {
653
- this.formControl.patchValue({ ...(this.formControl.value ?? {}), [value]: checked });
1014
+ const currentObj = this.formControl.value ?? {};
1015
+ this.formControl.patchValue({
1016
+ ...currentObj,
1017
+ [optionValue]: checked
1018
+ });
654
1019
  }
655
1020
  this.formControl.markAsTouched();
656
1021
  }
657
- ngOnInit() {
658
- const url = this.field.props?.domain?.url;
659
- if (url && this.field.props?.domain?.code && this.field.props?.domain?.key && this.field.props?.domain?.value) {
660
- this._http.get(url).pipe(takeUntilDestroyed(this._destroyRef)).subscribe((data) => {
661
- if (data) {
662
- const key = this.field.props?.domain?.key;
663
- const code = this.field.props?.domain?.code;
664
- const datas = data.filter((i) => {
665
- if (key)
666
- return i[key] === code;
667
- return false;
668
- });
669
- if (datas && this.field.props?.domain?.value) {
670
- this._urlData.set(datas[0][this.field.props?.domain?.value] ?? []);
671
- }
672
- else {
673
- this._urlData.set([]);
674
- }
675
- }
676
- else {
677
- this._urlData.set([]);
678
- }
679
- });
1022
+ isChecked(option) {
1023
+ const formValue = this.formControl.value;
1024
+ let optionValue;
1025
+ if (option.value !== undefined) {
1026
+ optionValue = option.value;
1027
+ }
1028
+ else if (option.value !== undefined) {
1029
+ optionValue = option.value;
1030
+ }
1031
+ if (optionValue === undefined || optionValue === null) {
1032
+ return false;
1033
+ }
1034
+ if (!formValue) {
1035
+ return false;
1036
+ }
1037
+ const safeOptionValue = String(optionValue);
1038
+ if (this.props.type === 'array') {
1039
+ if (Array.isArray(formValue)) {
1040
+ return formValue.some(v => String(v) === safeOptionValue);
1041
+ }
1042
+ return false;
680
1043
  }
681
1044
  else {
682
- this._urlData.set([]);
1045
+ if (typeof formValue === 'object' && formValue !== null) {
1046
+ return !!formValue[safeOptionValue];
1047
+ }
1048
+ return false;
683
1049
  }
684
1050
  }
685
- isChecked(option) {
686
- const formValue = this.formControl.value;
687
- const optionValue = option.value ?? '';
688
- return !!formValue && (this.props.type === 'array' ? formValue.includes(optionValue) : !!formValue[optionValue]);
1051
+ trackByFn(index, option) {
1052
+ return option.value ?? index;
689
1053
  }
690
- trackByFn(index) {
691
- return index;
1054
+ getData() {
1055
+ return this.urlData;
692
1056
  }
693
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatMultiCheckboxTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
694
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: CmatMultiCheckboxTypeComponent, isStandalone: true, selector: "cmat-multicheckbox-type", viewQueries: [{ propertyName: "checkboxes", predicate: MatCheckbox, descendants: true }], usesInheritance: true, ngImport: i0, template: "@if ((urlData$ | async); as urlData) {\r\n@for (option of (urlData.length > 0 ? urlData : (props.options | formlySelectOptions : field | async)); track\r\ntrackByFn($index)) {\r\n<mat-checkbox [tabIndex]=\"props.tabindex\" [color]=\"props.color\" [labelPosition]=\"props.labelPosition\"\r\n [checked]=\"isChecked(option)\" [disabled]=\"formControl.disabled || option.disabled\"\r\n (change)=\"onChange(option.value?.toString(), $event.checked)\">\r\n {{ option.label }}\r\n</mat-checkbox>\r\n}\r\n}", styles: [":host{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i1$5.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: FormlySelectModule }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: i2$2.LegacyFormlySelectOptionsPipe, name: "formlySelectOptions" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1057
+ _refreshData() {
1058
+ const domain = this.props.domain;
1059
+ // 使用 DomainDataService 加载远程数据
1060
+ this._domainDataService.load(domain, this._destroyRef, {
1061
+ onSuccess: (data) => {
1062
+ this.urlData = data;
1063
+ },
1064
+ componentName: 'CmatMultiCheckboxTypeComponent'
1065
+ });
1066
+ // 处理静态 options(当没有 domain 时)
1067
+ if (!domain?.url && this.field.props?.options) {
1068
+ const options = this.field.props.options;
1069
+ if (Array.isArray(options)) {
1070
+ this.urlData = options;
1071
+ }
1072
+ }
1073
+ }
1074
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatMultiCheckboxTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1075
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: CmatMultiCheckboxTypeComponent, isStandalone: true, selector: "cmat-multicheckbox-type", usesInheritance: true, ngImport: i0, template: "@if (urlData) {\r\n\r\n @let options = props.domain ? getData() : (props.options | formlySelectOptions : field | async);\r\n \r\n @for (option of options; track trackByFn($index, option)) {\r\n <mat-checkbox \r\n [tabIndex]=\"props.tabindex\" \r\n [color]=\"props.color\" \r\n [labelPosition]=\"props.labelPosition\"\r\n [checked]=\"isChecked(option)\" \r\n [disabled]=\"formControl.disabled || option.disabled\"\r\n (change)=\"onChange(option.value, $event.checked)\">\r\n {{ option.label }}\r\n </mat-checkbox>\r\n }\r\n}", styles: [":host{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i1$5.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: FormlySelectModule }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: i2$2.LegacyFormlySelectOptionsPipe, name: "formlySelectOptions" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
695
1076
  }
696
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatMultiCheckboxTypeComponent, decorators: [{
1077
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatMultiCheckboxTypeComponent, decorators: [{
697
1078
  type: Component,
698
- args: [{ selector: 'cmat-multicheckbox-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatCheckboxModule, AsyncPipe, FormlySelectModule], template: "@if ((urlData$ | async); as urlData) {\r\n@for (option of (urlData.length > 0 ? urlData : (props.options | formlySelectOptions : field | async)); track\r\ntrackByFn($index)) {\r\n<mat-checkbox [tabIndex]=\"props.tabindex\" [color]=\"props.color\" [labelPosition]=\"props.labelPosition\"\r\n [checked]=\"isChecked(option)\" [disabled]=\"formControl.disabled || option.disabled\"\r\n (change)=\"onChange(option.value?.toString(), $event.checked)\">\r\n {{ option.label }}\r\n</mat-checkbox>\r\n}\r\n}", styles: [":host{width:100%}\n"] }]
699
- }], ctorParameters: () => [], propDecorators: { checkboxes: [{
700
- type: ViewChildren,
701
- args: [MatCheckbox]
702
- }] } });
1079
+ args: [{ selector: 'cmat-multicheckbox-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatCheckboxModule, AsyncPipe, FormlySelectModule], template: "@if (urlData) {\r\n\r\n @let options = props.domain ? getData() : (props.options | formlySelectOptions : field | async);\r\n \r\n @for (option of options; track trackByFn($index, option)) {\r\n <mat-checkbox \r\n [tabIndex]=\"props.tabindex\" \r\n [color]=\"props.color\" \r\n [labelPosition]=\"props.labelPosition\"\r\n [checked]=\"isChecked(option)\" \r\n [disabled]=\"formControl.disabled || option.disabled\"\r\n (change)=\"onChange(option.value, $event.checked)\">\r\n {{ option.label }}\r\n </mat-checkbox>\r\n }\r\n}", styles: [":host{width:100%}\n"] }]
1080
+ }], ctorParameters: () => [] });
703
1081
 
704
1082
  class CmatNumberTypeComponent extends FieldType {
705
1083
  constructor() {
@@ -712,10 +1090,10 @@ class CmatNumberTypeComponent extends FieldType {
712
1090
  },
713
1091
  };
714
1092
  }
715
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatNumberTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
716
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.11", type: CmatNumberTypeComponent, isStandalone: true, selector: "cmat-number-type", usesInheritance: true, ngImport: i0, template: "<input matInput cmatDigitOnly [formControl]=\"formControl\" [readonly]=\"props.readonly\" [placeholder]=\"placeholder\" [tabIndex]=\"props.tabindex\" [required]=\"required\" [decimal]=\"props.decimal\" [allowNegatives]=\"true\" [allowPaste]=\"true\"\r\n [min]=\"props.min\" [max]=\"props.max\" [errorStateMatcher]=\"errorStateMatcher\">\r\n\r\n", styles: [":host{width:100%}\n"], dependencies: [{ kind: "directive", type: CmatDigitOnlyDirective, selector: "[cmatDigitOnly]", inputs: ["decimal", "decimalSeparator", "allowNegatives", "allowPaste", "negativeSign", "min", "max", "pattern"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i1$6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1093
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatNumberTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1094
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.6", type: CmatNumberTypeComponent, isStandalone: true, selector: "cmat-number-type", usesInheritance: true, ngImport: i0, template: "<input matInput cmatDigitOnly [formControl]=\"formControl\" [readonly]=\"props.readonly\" [placeholder]=\"placeholder\" [tabIndex]=\"props.tabindex\" [required]=\"required\" [decimal]=\"props.decimal\" [allowNegatives]=\"true\" [allowPaste]=\"true\"\r\n [min]=\"props.min\" [max]=\"props.max\" [errorStateMatcher]=\"errorStateMatcher\">\r\n\r\n", styles: [":host{width:100%}\n"], dependencies: [{ kind: "directive", type: CmatDigitOnlyDirective, selector: "[cmatDigitOnly]", inputs: ["decimal", "decimalSeparator", "allowNegatives", "allowPaste", "negativeSign", "min", "max", "pattern"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i1$6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
717
1095
  }
718
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatNumberTypeComponent, decorators: [{
1096
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatNumberTypeComponent, decorators: [{
719
1097
  type: Component,
720
1098
  args: [{ selector: 'cmat-number-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CmatDigitOnlyDirective, MatInputModule, ReactiveFormsModule], template: "<input matInput cmatDigitOnly [formControl]=\"formControl\" [readonly]=\"props.readonly\" [placeholder]=\"placeholder\" [tabIndex]=\"props.tabindex\" [required]=\"required\" [decimal]=\"props.decimal\" [allowNegatives]=\"true\" [allowPaste]=\"true\"\r\n [min]=\"props.min\" [max]=\"props.max\" [errorStateMatcher]=\"errorStateMatcher\">\r\n\r\n", styles: [":host{width:100%}\n"] }]
721
1099
  }] });
@@ -728,14 +1106,15 @@ class CmatRatingTypeComponent extends FieldType {
728
1106
  stars: 5,
729
1107
  readonly: false,
730
1108
  hover: true,
731
- half: true
1109
+ half: true,
1110
+ showMode: 'horizontal'
732
1111
  },
733
1112
  };
734
1113
  }
735
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatRatingTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
736
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: CmatRatingTypeComponent, isStandalone: true, selector: "cmat-rating-type", usesInheritance: true, ngImport: i0, template: "@if(props.customColor&&props.customColor.indexOf('#')>-1){\r\n<div [ngStyle]=\"{'color': props.customColor}\">\r\n <cmat-rating [formControl]=\"formControl\" [tabIndex]=\"props.tabindex\" [stars]=\"props.stars\"\r\n [readonly]=\"props.readonly\" [hover]=\"props.hover\" [half]=\"props.half\" [showMode]=\"props.showMode\"></cmat-rating>\r\n</div>\r\n}@else{\r\n<cmat-rating [formControl]=\"formControl\" [tabIndex]=\"props.tabindex\" [stars]=\"props.stars\" [readonly]=\"props.readonly\"\r\n [hover]=\"props.hover\" [half]=\"props.half\" [color]=\"props.customColor\" [showMode]=\"props.showMode\"></cmat-rating>\r\n}", styles: [":host{width:100%}\n"], dependencies: [{ kind: "component", type: CmatRatingComponent, selector: "cmat-rating", inputs: ["id", "stars", "readonly", "hover", "half", "color", "showMode", "placeholder", "value", "required", "disabled"], outputs: ["valueChange"], exportAs: ["cmatRating"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1114
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatRatingTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1115
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: CmatRatingTypeComponent, isStandalone: true, selector: "cmat-rating-type", usesInheritance: true, ngImport: i0, template: "@if(props.customColor&&props.customColor.indexOf('#')>-1){\r\n<div [ngStyle]=\"{'color': props.customColor}\">\r\n <cmat-rating [formControl]=\"formControl\" [tabIndex]=\"props.tabindex\" [stars]=\"props.stars\"\r\n [readonly]=\"props.readonly\" [hover]=\"props.hover\" [half]=\"props.half\" [showMode]=\"props.showMode\"></cmat-rating>\r\n</div>\r\n}@else{\r\n<cmat-rating [formControl]=\"formControl\" [tabIndex]=\"props.tabindex\" [stars]=\"props.stars\" [readonly]=\"props.readonly\"\r\n [hover]=\"props.hover\" [half]=\"props.half\" [color]=\"props.customColor\" [showMode]=\"props.showMode\"></cmat-rating>\r\n}", styles: [":host{width:100%}\n"], dependencies: [{ kind: "component", type: CmatRatingComponent, selector: "cmat-rating", inputs: ["stars", "readonly", "hover", "half", "color", "showMode", "placeholder", "value", "required", "disabled"], outputs: ["valueChange"], exportAs: ["cmatRating"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
737
1116
  }
738
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatRatingTypeComponent, decorators: [{
1117
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatRatingTypeComponent, decorators: [{
739
1118
  type: Component,
740
1119
  args: [{ selector: 'cmat-rating-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CmatRatingComponent, ReactiveFormsModule, NgStyle], template: "@if(props.customColor&&props.customColor.indexOf('#')>-1){\r\n<div [ngStyle]=\"{'color': props.customColor}\">\r\n <cmat-rating [formControl]=\"formControl\" [tabIndex]=\"props.tabindex\" [stars]=\"props.stars\"\r\n [readonly]=\"props.readonly\" [hover]=\"props.hover\" [half]=\"props.half\" [showMode]=\"props.showMode\"></cmat-rating>\r\n</div>\r\n}@else{\r\n<cmat-rating [formControl]=\"formControl\" [tabIndex]=\"props.tabindex\" [stars]=\"props.stars\" [readonly]=\"props.readonly\"\r\n [hover]=\"props.hover\" [half]=\"props.half\" [color]=\"props.customColor\" [showMode]=\"props.showMode\"></cmat-rating>\r\n}", styles: [":host{width:100%}\n"] }]
741
1120
  }] });
@@ -751,49 +1130,39 @@ class CmatRadioTypeComponent extends FieldType {
751
1130
  labelPosition: 'after'
752
1131
  },
753
1132
  };
754
- this._http = inject(HttpClient);
755
- this._urlData = signal([], ...(ngDevMode ? [{ debugName: "_urlData" }] : /* istanbul ignore next */ []));
1133
+ this.urlData = signal([], /* @ts-ignore */
1134
+ ...(ngDevMode ? [{ debugName: "urlData" }] : /* istanbul ignore next */ []));
1135
+ this.radioGroup = viewChild(MatRadioGroup, /* @ts-ignore */
1136
+ ...(ngDevMode ? [{ debugName: "radioGroup" }] : /* istanbul ignore next */ []));
1137
+ this._lastDomain = undefined;
756
1138
  this._destroyRef = inject(DestroyRef);
757
- this._urlData$ = toObservable(this._urlData);
758
- }
759
- get urlData$() {
760
- return this._urlData$;
1139
+ this._domainDataService = inject(DomainDataService);
761
1140
  }
762
1141
  ngOnInit() {
763
- const url = this.field.props?.domain?.url;
764
- if (url && this.field.props?.domain?.code && this.field.props?.domain?.key && this.field.props?.domain?.value) {
765
- this._http.get(url).pipe(takeUntilDestroyed(this._destroyRef)).subscribe((data) => {
766
- if (data) {
767
- const key = this.field.props?.domain?.key;
768
- const code = this.field.props?.domain?.code;
769
- const datas = data.filter((i) => {
770
- if (key)
771
- return i[key] === code;
772
- return false;
773
- });
774
- if (datas && this.field.props?.domain?.value) {
775
- this._urlData.set(datas[0][this.field.props?.domain?.value] ?? []);
776
- }
777
- else {
778
- this._urlData.set([]);
779
- }
780
- }
781
- else {
782
- this._urlData.set([]);
783
- }
784
- });
1142
+ this._lastDomain = this.props.domain;
1143
+ this._refreshData();
1144
+ }
1145
+ ngDoCheck() {
1146
+ const currentDomain = this.props.domain;
1147
+ let shouldRefresh = false;
1148
+ // 1. 检查 domain 变化
1149
+ if (!isEqual(currentDomain, this._lastDomain)) {
1150
+ this._lastDomain = currentDomain;
1151
+ shouldRefresh = true;
785
1152
  }
786
- else {
787
- this._urlData.set([]);
1153
+ if (shouldRefresh) {
1154
+ this._refreshData();
788
1155
  }
789
1156
  }
790
1157
  ngAfterViewInit() {
791
1158
  this.focusObserver = _observe(this.field, ['focus'], ({ currentValue }) => {
792
- if (this.props.tabindex === -1 && currentValue && this.radioGroup._radios.length > 0) {
793
- setTimeout(() => {
794
- const radio = this.radioGroup.selected ?? this.radioGroup._radios.first;
795
- radio.focus();
796
- });
1159
+ if (this.radioGroup()) {
1160
+ if (this.props.tabindex === -1 && currentValue && this.radioGroup()._radios.length > 0) {
1161
+ setTimeout(() => {
1162
+ const radio = this.radioGroup().selected ?? this.radioGroup()._radios.first;
1163
+ radio?.focus();
1164
+ });
1165
+ }
797
1166
  }
798
1167
  });
799
1168
  }
@@ -801,19 +1170,24 @@ class CmatRadioTypeComponent extends FieldType {
801
1170
  super.ngOnDestroy();
802
1171
  this.focusObserver?.unsubscribe();
803
1172
  }
804
- trackByFn(index) {
805
- return index;
1173
+ trackByFn(index, option) {
1174
+ return option.value ?? index;
1175
+ }
1176
+ _refreshData() {
1177
+ const domain = this.props.domain;
1178
+ // 使用 DomainDataService 加载远程数据
1179
+ this._domainDataService.load(domain, this._destroyRef, {
1180
+ onSuccess: data => this.urlData.set(data),
1181
+ componentName: 'CmatRadioTypeComponent'
1182
+ });
806
1183
  }
807
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatRadioTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
808
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: CmatRadioTypeComponent, isStandalone: true, selector: "cmat-radio-type", viewQueries: [{ propertyName: "radioGroup", first: true, predicate: MatRadioGroup, descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<mat-radio-group [formControl]=\"formControl\" [required]=\"required\" [tabindex]=\"props.tabindex\">\r\n @if ((urlData$ | async); as urlData) {\r\n @for (option of (urlData.length > 0 ? urlData : (props.options | formlySelectOptions : field | async)); track\r\n trackByFn($index)) {\r\n <mat-radio-button [color]=\"props.color\" [labelPosition]=\"props.labelPosition\" [disabled]=\"option.disabled\"\r\n [value]=\"option.value\">\r\n {{ option.label }}\r\n </mat-radio-button>\r\n }\r\n }\r\n</mat-radio-group>", styles: [":host{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: MatRadioModule }, { kind: "directive", type: i1$7.MatRadioGroup, selector: "mat-radio-group", inputs: ["color", "name", "labelPosition", "value", "selected", "disabled", "required", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioGroup"] }, { kind: "component", type: i1$7.MatRadioButton, selector: "mat-radio-button", inputs: ["id", "name", "aria-label", "aria-labelledby", "aria-describedby", "disableRipple", "tabIndex", "checked", "value", "labelPosition", "disabled", "required", "color", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioButton"] }, { kind: "ngmodule", type: FormlySelectModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: i2$2.LegacyFormlySelectOptionsPipe, name: "formlySelectOptions" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1184
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatRadioTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1185
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: CmatRadioTypeComponent, isStandalone: true, selector: "cmat-radio-type", viewQueries: [{ propertyName: "radioGroup", first: true, predicate: MatRadioGroup, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<mat-radio-group [formControl]=\"formControl\" [required]=\"required\" [tabindex]=\"props.tabindex\">\r\n @if (urlData()) {\r\n @for (option of (urlData().length > 0 ? urlData() : (props.options | formlySelectOptions : field | async)); track\r\n trackByFn($index, option)) {\r\n <mat-radio-button [color]=\"props.color\" [labelPosition]=\"props.labelPosition\" [disabled]=\"option.disabled\"\r\n [value]=\"option.value\">\r\n {{ option.label }}\r\n </mat-radio-button>\r\n }\r\n }\r\n</mat-radio-group>", styles: [":host{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: MatRadioModule }, { kind: "directive", type: i1$7.MatRadioGroup, selector: "mat-radio-group", inputs: ["color", "name", "labelPosition", "value", "selected", "disabled", "required", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioGroup"] }, { kind: "component", type: i1$7.MatRadioButton, selector: "mat-radio-button", inputs: ["id", "name", "aria-label", "aria-labelledby", "aria-describedby", "disableRipple", "tabIndex", "checked", "value", "labelPosition", "disabled", "required", "color", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioButton"] }, { kind: "ngmodule", type: FormlySelectModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: i2$2.LegacyFormlySelectOptionsPipe, name: "formlySelectOptions" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
809
1186
  }
810
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatRadioTypeComponent, decorators: [{
1187
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatRadioTypeComponent, decorators: [{
811
1188
  type: Component,
812
- args: [{ selector: 'cmat-radio-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatRadioModule, AsyncPipe, FormlySelectModule, ReactiveFormsModule], template: "<mat-radio-group [formControl]=\"formControl\" [required]=\"required\" [tabindex]=\"props.tabindex\">\r\n @if ((urlData$ | async); as urlData) {\r\n @for (option of (urlData.length > 0 ? urlData : (props.options | formlySelectOptions : field | async)); track\r\n trackByFn($index)) {\r\n <mat-radio-button [color]=\"props.color\" [labelPosition]=\"props.labelPosition\" [disabled]=\"option.disabled\"\r\n [value]=\"option.value\">\r\n {{ option.label }}\r\n </mat-radio-button>\r\n }\r\n }\r\n</mat-radio-group>", styles: [":host{width:100%}\n"] }]
813
- }], ctorParameters: () => [], propDecorators: { radioGroup: [{
814
- type: ViewChild,
815
- args: [MatRadioGroup, { static: true }]
816
- }] } });
1189
+ args: [{ selector: 'cmat-radio-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatRadioModule, AsyncPipe, FormlySelectModule, ReactiveFormsModule], template: "<mat-radio-group [formControl]=\"formControl\" [required]=\"required\" [tabindex]=\"props.tabindex\">\r\n @if (urlData()) {\r\n @for (option of (urlData().length > 0 ? urlData() : (props.options | formlySelectOptions : field | async)); track\r\n trackByFn($index, option)) {\r\n <mat-radio-button [color]=\"props.color\" [labelPosition]=\"props.labelPosition\" [disabled]=\"option.disabled\"\r\n [value]=\"option.value\">\r\n {{ option.label }}\r\n </mat-radio-button>\r\n }\r\n }\r\n</mat-radio-group>", styles: [":host{width:100%}\n"] }]
1190
+ }], ctorParameters: () => [], propDecorators: { radioGroup: [{ type: i0.ViewChild, args: [i0.forwardRef(() => MatRadioGroup), { isSignal: true }] }] } });
817
1191
 
818
1192
  class CmatRepeatTypeComponent extends FieldArrayType {
819
1193
  constructor() {
@@ -824,10 +1198,10 @@ class CmatRepeatTypeComponent extends FieldArrayType {
824
1198
  },
825
1199
  };
826
1200
  }
827
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatRepeatTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
828
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: CmatRepeatTypeComponent, isStandalone: true, selector: "cmat-repeat-type", usesInheritance: true, ngImport: i0, template: "<div class=\"mb-2\" [tabIndex]=\"props.tabindex\">\r\n @if(props.label){\r\n <legend class=\"text-lg\">\r\n {{ props.label }}\r\n @if(props.required){\r\n <span>*</span>\r\n }\r\n </legend>\r\n }\r\n\r\n @if(props.description){\r\n <p>{{ props.description }}</p>\r\n }\r\n\r\n <div class=\"mb-2 h-1 border-solid border-b-2\"></div>\r\n <div class=\"flex flex-col repeat-body\">\r\n @for (field of field.fieldGroup; track $index) {\r\n <div class=\"flex flex-row repeat-item\">\r\n <formly-field class=\"repeat-field\" [field]=\"field\"></formly-field>\r\n @if(!props.disabled){\r\n <div class=\"flex items-center pl-2 print:hidden\">\r\n <button matIconButton color=\"warn\" matTooltip=\"\u5220\u9664\" (click)=\"remove($index)\">\r\n <mat-icon color=\"warn\" [svgIcon]=\"'heroicons_outline:trash'\"></mat-icon>\r\n </button>\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n @if(!props.disabled){\r\n <div class=\"mt-2 print:hidden\">\r\n <button matButton=\"filled\" color=\"primary\" (click)=\"add()\">{{ props.addText}}</button>\r\n </div>\r\n }\r\n\r\n</div>", styles: [":host{width:100%}::ng-deep .repeat-body .repeat-item:not(:first-child) .repeat-field .mat-mdc-form-field-infix .mat-mdc-floating-label{display:none!important}::ng-deep .repeat-body .repeat-item:not(:first-child) .repeat-field .mat-mdc-form-field-subscript-wrapper{display:none!important}::ng-deep .repeat-body .repeat-item:not(:first-child) .repeat-field .mat-mdc-text-field-wrapper{margin-top:8px}\n"], dependencies: [{ kind: "ngmodule", type: FormlyModule }, { kind: "component", type: i1$3.LegacyFormlyField, selector: "formly-field" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1201
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatRepeatTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1202
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: CmatRepeatTypeComponent, isStandalone: true, selector: "cmat-repeat-type", usesInheritance: true, ngImport: i0, template: "<div class=\"mb-2\" [tabIndex]=\"props.tabindex\">\r\n @if(props.label){\r\n <legend class=\"text-lg\">\r\n {{ props.label }}\r\n @if(props.required){\r\n <span>*</span>\r\n }\r\n </legend>\r\n }\r\n\r\n @if(props.description){\r\n <p>{{ props.description }}</p>\r\n }\r\n\r\n <div class=\"mb-2 h-1 border-solid border-b-2\"></div>\r\n <div class=\"flex flex-col repeat-body\">\r\n @for (field of field.fieldGroup; track $index) {\r\n <div class=\"flex flex-row repeat-item\">\r\n <formly-field class=\"repeat-field\" [field]=\"field\"></formly-field>\r\n @if(!props.disabled){\r\n <div class=\"flex items-center pl-2 print:hidden\">\r\n <button matIconButton color=\"warn\" matTooltip=\"\u5220\u9664\" (click)=\"remove($index)\">\r\n <mat-icon color=\"warn\" [svgIcon]=\"'heroicons_outline:trash'\"></mat-icon>\r\n </button>\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n @if(!props.disabled){\r\n <div class=\"mt-2 print:hidden\">\r\n <button matButton=\"filled\" color=\"primary\" (click)=\"add()\">{{ props.addText}}</button>\r\n </div>\r\n }\r\n\r\n</div>", styles: [":host{width:100%}::ng-deep .repeat-body .repeat-item:not(:first-child) .repeat-field .mat-mdc-form-field-infix .mat-mdc-floating-label{display:none!important}::ng-deep .repeat-body .repeat-item:not(:first-child) .repeat-field .mat-mdc-form-field-subscript-wrapper{display:none!important}::ng-deep .repeat-body .repeat-item:not(:first-child) .repeat-field .mat-mdc-text-field-wrapper{margin-top:8px}\n"], dependencies: [{ kind: "ngmodule", type: FormlyModule }, { kind: "component", type: i1$3.LegacyFormlyField, selector: "formly-field" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
829
1203
  }
830
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatRepeatTypeComponent, decorators: [{
1204
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatRepeatTypeComponent, decorators: [{
831
1205
  type: Component,
832
1206
  args: [{ selector: 'cmat-repeat-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [FormlyModule, MatIconModule, MatButtonModule], template: "<div class=\"mb-2\" [tabIndex]=\"props.tabindex\">\r\n @if(props.label){\r\n <legend class=\"text-lg\">\r\n {{ props.label }}\r\n @if(props.required){\r\n <span>*</span>\r\n }\r\n </legend>\r\n }\r\n\r\n @if(props.description){\r\n <p>{{ props.description }}</p>\r\n }\r\n\r\n <div class=\"mb-2 h-1 border-solid border-b-2\"></div>\r\n <div class=\"flex flex-col repeat-body\">\r\n @for (field of field.fieldGroup; track $index) {\r\n <div class=\"flex flex-row repeat-item\">\r\n <formly-field class=\"repeat-field\" [field]=\"field\"></formly-field>\r\n @if(!props.disabled){\r\n <div class=\"flex items-center pl-2 print:hidden\">\r\n <button matIconButton color=\"warn\" matTooltip=\"\u5220\u9664\" (click)=\"remove($index)\">\r\n <mat-icon color=\"warn\" [svgIcon]=\"'heroicons_outline:trash'\"></mat-icon>\r\n </button>\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n @if(!props.disabled){\r\n <div class=\"mt-2 print:hidden\">\r\n <button matButton=\"filled\" color=\"primary\" (click)=\"add()\">{{ props.addText}}</button>\r\n </div>\r\n }\r\n\r\n</div>", styles: [":host{width:100%}::ng-deep .repeat-body .repeat-item:not(:first-child) .repeat-field .mat-mdc-form-field-infix .mat-mdc-floating-label{display:none!important}::ng-deep .repeat-body .repeat-item:not(:first-child) .repeat-field .mat-mdc-form-field-subscript-wrapper{display:none!important}::ng-deep .repeat-body .repeat-item:not(:first-child) .repeat-field .mat-mdc-text-field-wrapper{margin-top:8px}\n"] }]
833
1207
  }] });
@@ -842,80 +1216,105 @@ class CmatSelectTypeComponent extends FieldType {
842
1216
  showToggleAllCheckbox: false
843
1217
  },
844
1218
  };
845
- this.optionsData = [];
846
- this.filteredCustomDetails = new ReplaySubject(1);
847
- this.filteredCache = [];
848
- this.isIndeterminate = false;
849
- this.isChecked = false;
850
- this.multiFilterCtrl = new FormControl('');
851
- this._http = inject(HttpClient);
1219
+ this.searchControl = new FormControl('');
1220
+ this.urlData = signal([], /* @ts-ignore */
1221
+ ...(ngDevMode ? [{ debugName: "urlData" }] : /* istanbul ignore next */ []));
1222
+ this.optionsData = signal([], /* @ts-ignore */
1223
+ ...(ngDevMode ? [{ debugName: "optionsData" }] : /* istanbul ignore next */ []));
1224
+ this.filteredOptions = computed(() => {
1225
+ const allData = this.allOptions();
1226
+ const search = this._searchText();
1227
+ if (!search) {
1228
+ return allData;
1229
+ }
1230
+ return allData.filter((item) => {
1231
+ const labelMatch = item.label?.toString().toLowerCase().includes(search);
1232
+ const valueMatch = item.value?.toString().toLowerCase().includes(search);
1233
+ return labelMatch ?? valueMatch;
1234
+ });
1235
+ }, /* @ts-ignore */
1236
+ ...(ngDevMode ? [{ debugName: "filteredOptions" }] : /* istanbul ignore next */ []));
1237
+ this.isIndeterminate = computed(() => {
1238
+ if (!this.props.multiple || !this.props.search)
1239
+ return false;
1240
+ const visibleOptions = this.filteredOptions().filter(o => !o.disabled);
1241
+ if (visibleOptions.length === 0)
1242
+ return false;
1243
+ const currentValue = this.formControl.value;
1244
+ if (!isArray(currentValue))
1245
+ return false;
1246
+ const selectedVisibleCount = visibleOptions.filter(opt => currentValue.some(sel => this._isSameSelectValue(sel, opt))).length;
1247
+ return selectedVisibleCount > 0 && selectedVisibleCount < visibleOptions.length;
1248
+ }, /* @ts-ignore */
1249
+ ...(ngDevMode ? [{ debugName: "isIndeterminate" }] : /* istanbul ignore next */ []));
1250
+ this.isChecked = computed(() => {
1251
+ if (!this.props.multiple || !this.props.search)
1252
+ return false;
1253
+ const visibleOptions = this.filteredOptions().filter(o => !o.disabled);
1254
+ if (visibleOptions.length === 0)
1255
+ return false;
1256
+ const currentValue = this.formControl.value;
1257
+ if (!isArray(currentValue))
1258
+ return false;
1259
+ const selectedVisibleCount = visibleOptions.filter(opt => currentValue.some(sel => this._isSameSelectValue(sel, opt))).length;
1260
+ return selectedVisibleCount > 0 && selectedVisibleCount === visibleOptions.length;
1261
+ }, /* @ts-ignore */
1262
+ ...(ngDevMode ? [{ debugName: "isChecked" }] : /* istanbul ignore next */ []));
1263
+ this.allOptions = computed(() => {
1264
+ if (this.urlData().length > 0) {
1265
+ return this.urlData();
1266
+ }
1267
+ return this.optionsData() || [];
1268
+ }, /* @ts-ignore */
1269
+ ...(ngDevMode ? [{ debugName: "allOptions" }] : /* istanbul ignore next */ []));
1270
+ this._searchText = signal('', /* @ts-ignore */
1271
+ ...(ngDevMode ? [{ debugName: "_searchText" }] : /* istanbul ignore next */ []));
1272
+ this._lastDomain = undefined;
1273
+ this._lastOptions = undefined;
1274
+ this._domainDataService = inject(DomainDataService);
852
1275
  this._destroyRef = inject(DestroyRef);
853
- this._urlData = [];
854
1276
  }
855
- get datas() {
856
- if (isArray(this.field.props?.options)) {
857
- return this._urlData?.length > 0 ? this._urlData : this.field.props?.options ?? [];
858
- }
859
- else {
860
- return this._urlData?.length > 0 ? this._urlData : this.optionsData || [];
1277
+ ngOnInit() {
1278
+ this._lastDomain = this.props.domain;
1279
+ this._lastOptions = this.field.props?.options;
1280
+ this._refreshData();
1281
+ if (!isUndefined(this.formControl.value) && !isArray(this.formControl.value) && this.props.multiple) {
1282
+ this.formControl.setValue([this.formControl.value]);
861
1283
  }
1284
+ this.searchControl.valueChanges
1285
+ .pipe(takeUntilDestroyed(this._destroyRef))
1286
+ .subscribe((value) => {
1287
+ this._searchText.set(value ?? '');
1288
+ });
862
1289
  }
863
- ngOnInit() {
864
- if (this.field.props?.options && !isArray(this.field.props?.options)) {
865
- this.field.props?.options.pipe(takeUntilDestroyed(this._destroyRef)).subscribe((data) => {
866
- this.optionsData = data;
867
- });
1290
+ ngDoCheck() {
1291
+ const currentDomain = this.props.domain;
1292
+ const currentOptions = this.field.props?.options;
1293
+ let shouldRefresh = false;
1294
+ // 1. 检查 domain 变化
1295
+ if (!isEqual(currentDomain, this._lastDomain)) {
1296
+ this._lastDomain = currentDomain;
1297
+ shouldRefresh = true;
868
1298
  }
869
- const url = this.field.props?.domain?.url;
870
- if (url && this.field.props?.domain?.code && this.field.props?.domain?.key && this.field.props?.domain?.value) {
871
- this._http.get(url).pipe(takeUntilDestroyed(this._destroyRef)).subscribe((data) => {
872
- if (data) {
873
- const key = this.field.props?.domain?.key;
874
- const code = this.field.props?.domain?.code;
875
- const datas = data.filter((i) => {
876
- if (key)
877
- return i[key] === code;
878
- return false;
879
- });
880
- if (datas && this.field.props?.domain?.value) {
881
- this._urlData = datas[0][this.field.props?.domain?.value] ?? [];
882
- }
883
- else {
884
- this._urlData = [];
885
- }
886
- }
887
- else {
888
- this._urlData = [];
889
- }
890
- this.filteredCache = this.datas.slice();
891
- this.filteredCustomDetails.next(this.filteredCache);
892
- });
1299
+ // 2. 检查 options 变化 (仅当 domain 未配置时,options 才生效,但为了稳妥,只要变了就更新)
1300
+ // 注意:如果 domain 存在,urlData 优先级更高,但更新 optionsData 也无妨,因为 allOptions computed 会优先取 urlData
1301
+ if (!isEqual(currentOptions, this._lastOptions)) {
1302
+ this._lastOptions = currentOptions;
1303
+ shouldRefresh = true;
1304
+ }
1305
+ if (shouldRefresh) {
1306
+ this._refreshData();
1307
+ }
1308
+ }
1309
+ toggleSelectAll(selectAllValue) {
1310
+ const visibleOptions = this.filteredOptions().filter(o => !o.disabled);
1311
+ if (selectAllValue) {
1312
+ this.formControl.setValue([...visibleOptions]);
893
1313
  }
894
1314
  else {
895
- this._urlData = [];
896
- this.filteredCache = this.datas.slice();
897
- this.filteredCustomDetails.next(this.filteredCache);
898
- }
899
- of(this.props.multiple).pipe(takeUntilDestroyed(this._destroyRef))
900
- .subscribe((multiple) => {
901
- if (!isUndefined(this.formControl.value) && !isArray(this.formControl.value) && multiple) {
902
- const value = [this.formControl.value];
903
- this.formControl.setValue(value);
904
- }
905
- });
906
- this.multiFilterCtrl.valueChanges
907
- .pipe(takeUntilDestroyed(this._destroyRef))
908
- .subscribe(() => {
909
- this.filterMulti();
910
- if (this.props.multiple)
911
- this.setToggleAllCheckboxState();
912
- });
913
- this.formControl.valueChanges
914
- .pipe(takeUntilDestroyed(this._destroyRef))
915
- .subscribe(() => {
916
- if (this.props.multiple)
917
- this.setToggleAllCheckboxState();
918
- });
1315
+ this.formControl.setValue([]);
1316
+ }
1317
+ this.formControl.markAsDirty();
919
1318
  }
920
1319
  getAriaLabelledby() {
921
1320
  if (this.props.attributes?.['aria-labelledby']) {
@@ -926,51 +1325,6 @@ class CmatSelectTypeComponent extends FieldType {
926
1325
  getAriaLabel() {
927
1326
  return this.props.attributes?.['aria-label'];
928
1327
  }
929
- toggleSelectAll(selectAllValue) {
930
- this.filteredCustomDetails.pipe(take(1), takeUntilDestroyed(this._destroyRef))
931
- .subscribe((val) => {
932
- if (selectAllValue) {
933
- this.formControl.setValue(val.filter((o) => !o.disabled));
934
- }
935
- else {
936
- this.formControl.setValue([]);
937
- }
938
- this.formControl.markAsDirty();
939
- });
940
- }
941
- filterMulti() {
942
- if (!this.datas) {
943
- return;
944
- }
945
- const search = (this.multiFilterCtrl.value ?? '').toLowerCase();
946
- if (!search) {
947
- this.filteredCache = this.datas.slice();
948
- this.filteredCustomDetails.next(this.filteredCache);
949
- return;
950
- }
951
- this.filteredCache = this.datas.filter((items) => this._toSearchText(items.value).toLowerCase().includes(search) || this._toSearchText(items.label).toLowerCase().includes(search));
952
- this.filteredCustomDetails.next(this.filteredCache);
953
- }
954
- setToggleAllCheckboxState() {
955
- let filteredLength = 0;
956
- if (this.formControl.value && this.props.search) {
957
- const cache = this.filteredCache.filter((o) => !o.disabled);
958
- const currentValue = this.formControl.value;
959
- const v = isArray(currentValue) || isUndefined(currentValue) ? currentValue : [currentValue];
960
- if (v)
961
- cache.forEach((el) => {
962
- if (v.findIndex(t => t != null && this._isSameSelectValue(t, el)) > -1) {
963
- filteredLength++;
964
- }
965
- });
966
- this.isIndeterminate = filteredLength > 0 && filteredLength < cache.length;
967
- this.isChecked = filteredLength > 0 && filteredLength === cache.length;
968
- }
969
- else {
970
- this.isIndeterminate = false;
971
- this.isChecked = false;
972
- }
973
- }
974
1328
  compareWithFn(o1, o2) {
975
1329
  if (!o1 || !o2) {
976
1330
  return o1 === o2;
@@ -980,15 +1334,27 @@ class CmatSelectTypeComponent extends FieldType {
980
1334
  _isSameSelectValue(left, right) {
981
1335
  return left.value === right.value && left.label === right.label;
982
1336
  }
983
- _toSearchText(value) {
984
- return typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean' ? String(value) : '';
1337
+ _refreshData() {
1338
+ const domain = this.props.domain;
1339
+ // 使用 DomainDataService 加载远程数据
1340
+ this._domainDataService.load(domain, this._destroyRef, {
1341
+ onSuccess: data => this.urlData.set(data),
1342
+ componentName: 'CmatSelectTypeComponent'
1343
+ });
1344
+ // 处理静态 options(当没有 domain 时)
1345
+ if (!domain?.url && this.field.props?.options && isArray(this.field.props?.options)) {
1346
+ this.optionsData.set(this.field.props.options || []);
1347
+ }
1348
+ else if (!domain?.url) {
1349
+ this.optionsData.set([]);
1350
+ }
985
1351
  }
986
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatSelectTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
987
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: CmatSelectTypeComponent, isStandalone: true, selector: "cmat-select-search-type", usesInheritance: true, ngImport: i0, template: "@if(props.multiple){\r\n<mat-select #multiSelect multiple [id]=\"id\" [formControl]=\"formControl\" [placeholder]=\"props.placeholder??''\"\r\n [required]=\"required\" [tabIndex]=\"props.tabindex\" [compareWith]=\"compareWithFn\"\r\n [errorStateMatcher]=\"errorStateMatcher\" [aria-label]=\"getAriaLabel()\" [aria-labelledby]=\"getAriaLabelledby()\"\r\n [disableOptionCentering]=\"props.disableOptionCentering\"\r\n [typeaheadDebounceInterval]=\"props.typeaheadDebounceInterval\"\r\n [panelClass]=\"'overflow-y-auto scrollbar-custom'\">\r\n @if ((filteredCustomDetails | async); as customDetails) {\r\n @if (props.search) {\r\n <mat-option>\r\n <cmat-select-search [formControl]=\"multiFilterCtrl\" [showToggleAllCheckbox]=\"props.showToggleAllCheckbox\"\r\n [toggleAllCheckboxIndeterminate]=\"isIndeterminate\" [toggleAllCheckboxChecked]=\"isChecked\"\r\n (toggleAll)=\"toggleSelectAll($event)\">\r\n </cmat-select-search>\r\n </mat-option>\r\n }\r\n @if (customDetails?.length!==0&&props.canNull&&!props.multiple) {\r\n <mat-option>\u7A7A</mat-option>\r\n }\r\n @for (i of customDetails; track $index) {\r\n @if(i.label){\r\n @if(i.group){\r\n <mat-optgroup [label]=\"i.label\">\r\n @for (child of i.group; track $index) {\r\n <mat-option [value]=\"child\" [disabled]=\"child.disabled\">\r\n {{ child.label }}\r\n </mat-option>\r\n }\r\n </mat-optgroup>\r\n }@else {\r\n <mat-option [value]=\"i\" [disabled]=\"i.disabled\">{{i.label}}</mat-option>\r\n }\r\n }@else {\r\n <mat-option [value]=\"i\">{{i}}</mat-option>\r\n }\r\n }\r\n }\r\n</mat-select>\r\n}@else {\r\n<mat-select #multiSelect [id]=\"id\" [formControl]=\"formControl\" [placeholder]=\"props.placeholder??''\"\r\n [required]=\"required\" [tabIndex]=\"props.tabindex\" [compareWith]=\"compareWithFn\"\r\n [errorStateMatcher]=\"errorStateMatcher\" [aria-label]=\"getAriaLabel()\" [aria-labelledby]=\"getAriaLabelledby()\"\r\n [disableOptionCentering]=\"props.disableOptionCentering\"\r\n [typeaheadDebounceInterval]=\"props.typeaheadDebounceInterval\"\r\n [panelClass]=\"'overflow-y-auto scrollbar-custom'\">\r\n @if ((filteredCustomDetails | async); as customDetails) {\r\n @if (props.search) {\r\n <mat-option>\r\n <cmat-select-search [formControl]=\"multiFilterCtrl\" [showToggleAllCheckbox]=\"props.showToggleAllCheckbox\"\r\n [toggleAllCheckboxIndeterminate]=\"isIndeterminate\" [toggleAllCheckboxChecked]=\"isChecked\"\r\n (toggleAll)=\"toggleSelectAll($event)\">\r\n </cmat-select-search>\r\n </mat-option>\r\n }\r\n @if (customDetails?.length!==0&&props.canNull&&!props.multiple) {\r\n <mat-option>\u7A7A</mat-option>\r\n }\r\n @for (i of customDetails; track $index) {\r\n @if(i.label){\r\n @if(i.group){\r\n <mat-optgroup [label]=\"i.label\">\r\n @for (child of i.group; track $index) {\r\n <mat-option [value]=\"child\" [disabled]=\"child.disabled\">\r\n {{ child.label }}\r\n </mat-option>\r\n }\r\n </mat-optgroup>\r\n }@else {\r\n <mat-option [value]=\"i\" [disabled]=\"i.disabled\">{{i.label}}</mat-option>\r\n }\r\n }@else {\r\n <mat-option [value]=\"i\">{{i}}</mat-option>\r\n }\r\n }\r\n }\r\n</mat-select>\r\n}", styles: [":host{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: MatCheckboxModule }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i1$8.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i1$8.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i1$8.MatOptgroup, selector: "mat-optgroup", inputs: ["label", "disabled"], exportAs: ["matOptgroup"] }, { kind: "component", type: CmatSelectSearchComponent, selector: "cmat-select-search", inputs: ["placeholderLabel", "type", "noEntriesFoundLabel", "showNoFoundLabel", "clearSearchInput", "searching", "disableInitialFocus", "enableClearOnEscapePressed", "preventHomeEndKeyPropagation", "disableScrollToActiveOnOptionsChanged", "ariaLabel", "showToggleAllCheckbox", "toggleAllCheckboxChecked", "toggleAllCheckboxIndeterminate", "toggleAllCheckboxTooltipMessage", "toggleAllCheckboxTooltipPosition", "hideClearSearchButton", "alwaysRestoreSelectedOptionsMulti"], outputs: ["toggleAll"], exportAs: ["cmatSelectSearch"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1352
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatSelectTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1353
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: CmatSelectTypeComponent, isStandalone: true, selector: "cmat-select-search-type", usesInheritance: true, ngImport: i0, template: "@if(props.multiple){\r\n<mat-select #multiSelect multiple [id]=\"id\" [formControl]=\"formControl\" [placeholder]=\"props.placeholder??''\"\r\n [required]=\"required\" [tabIndex]=\"props.tabindex\" [compareWith]=\"compareWithFn\"\r\n [errorStateMatcher]=\"errorStateMatcher\" [aria-label]=\"getAriaLabel()\" [aria-labelledby]=\"getAriaLabelledby()\"\r\n [disableOptionCentering]=\"props.disableOptionCentering\"\r\n [typeaheadDebounceInterval]=\"props.typeaheadDebounceInterval\">\r\n \r\n @if (props.search) {\r\n <mat-option>\r\n <cmat-select-search [formControl]=\"searchControl\" [showToggleAllCheckbox]=\"props.showToggleAllCheckbox\"\r\n [toggleAllCheckboxIndeterminate]=\"isIndeterminate()\" [toggleAllCheckboxChecked]=\"isChecked()\"\r\n (toggleAll)=\"toggleSelectAll($event)\">\r\n </cmat-select-search>\r\n </mat-option>\r\n }\r\n\r\n @if (allOptions().length !== 0 && props.canNull && !props.multiple) {\r\n <mat-option value=\"\">\u7A7A</mat-option>\r\n }\r\n\r\n @for (i of filteredOptions(); track i.value || $index) {\r\n @if(i.label){\r\n @if(i.group){\r\n <mat-optgroup [label]=\"i.label\">\r\n @for (child of i.group; track child.value || $index) {\r\n <mat-option [value]=\"child\" [disabled]=\"child.disabled\">\r\n {{ child.label }}\r\n </mat-option>\r\n }\r\n </mat-optgroup>\r\n }@else {\r\n <mat-option [value]=\"i\" [disabled]=\"i.disabled\">{{i.label}}</mat-option>\r\n }\r\n }@else {\r\n <mat-option [value]=\"i\">{{i}}</mat-option>\r\n }\r\n }\r\n</mat-select>\r\n}@else {\r\n<mat-select #multiSelect [id]=\"id\" [formControl]=\"formControl\" [placeholder]=\"props.placeholder??''\"\r\n [required]=\"required\" [tabIndex]=\"props.tabindex\" [compareWith]=\"compareWithFn\"\r\n [errorStateMatcher]=\"errorStateMatcher\" [aria-label]=\"getAriaLabel()\" [aria-labelledby]=\"getAriaLabelledby()\"\r\n [disableOptionCentering]=\"props.disableOptionCentering\"\r\n [typeaheadDebounceInterval]=\"props.typeaheadDebounceInterval\">\r\n \r\n @if (props.search) {\r\n <mat-option>\r\n <cmat-select-search [formControl]=\"searchControl\" [showToggleAllCheckbox]=\"props.showToggleAllCheckbox\"\r\n [toggleAllCheckboxIndeterminate]=\"isIndeterminate()\" [toggleAllCheckboxChecked]=\"isChecked()\"\r\n (toggleAll)=\"toggleSelectAll($event)\">\r\n </cmat-select-search>\r\n </mat-option>\r\n }\r\n\r\n @if (allOptions().length !== 0 && props.canNull && !props.multiple) {\r\n <mat-option value=\"\">\u7A7A</mat-option>\r\n }\r\n\r\n\r\n @for (i of filteredOptions(); track i.value || $index) {\r\n @if(i.label){\r\n @if(i.group){\r\n <mat-optgroup [label]=\"i.label\">\r\n @for (child of i.group; track child.value || $index) {\r\n <mat-option [value]=\"child\" [disabled]=\"child.disabled\">\r\n {{ child.label }}\r\n </mat-option>\r\n }\r\n </mat-optgroup>\r\n }@else {\r\n <mat-option [value]=\"i\" [disabled]=\"i.disabled\">{{i.label}}</mat-option>\r\n }\r\n }@else {\r\n <mat-option [value]=\"i\">{{i}}</mat-option>\r\n }\r\n }\r\n</mat-select>\r\n}", styles: [":host{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: MatCheckboxModule }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i1$8.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i1$8.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i1$8.MatOptgroup, selector: "mat-optgroup", inputs: ["label", "disabled"], exportAs: ["matOptgroup"] }, { kind: "component", type: CmatSelectSearchComponent, selector: "cmat-select-search", inputs: ["placeholderLabel", "type", "noEntriesFoundLabel", "showNoFoundLabel", "clearSearchInput", "searching", "disableInitialFocus", "enableClearOnEscapePressed", "preventHomeEndKeyPropagation", "disableScrollToActiveOnOptionsChanged", "ariaLabel", "showToggleAllCheckbox", "toggleAllCheckboxChecked", "toggleAllCheckboxIndeterminate", "toggleAllCheckboxTooltipMessage", "toggleAllCheckboxTooltipPosition", "hideClearSearchButton", "alwaysRestoreSelectedOptionsMulti", "debounceTime", "optionsCount"], outputs: ["toggleAll"], exportAs: ["cmatSelectSearch"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
988
1354
  }
989
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatSelectTypeComponent, decorators: [{
1355
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatSelectTypeComponent, decorators: [{
990
1356
  type: Component,
991
- args: [{ selector: 'cmat-select-search-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatCheckboxModule, MatSelectModule, CmatSelectSearchComponent, ReactiveFormsModule, AsyncPipe], template: "@if(props.multiple){\r\n<mat-select #multiSelect multiple [id]=\"id\" [formControl]=\"formControl\" [placeholder]=\"props.placeholder??''\"\r\n [required]=\"required\" [tabIndex]=\"props.tabindex\" [compareWith]=\"compareWithFn\"\r\n [errorStateMatcher]=\"errorStateMatcher\" [aria-label]=\"getAriaLabel()\" [aria-labelledby]=\"getAriaLabelledby()\"\r\n [disableOptionCentering]=\"props.disableOptionCentering\"\r\n [typeaheadDebounceInterval]=\"props.typeaheadDebounceInterval\"\r\n [panelClass]=\"'overflow-y-auto scrollbar-custom'\">\r\n @if ((filteredCustomDetails | async); as customDetails) {\r\n @if (props.search) {\r\n <mat-option>\r\n <cmat-select-search [formControl]=\"multiFilterCtrl\" [showToggleAllCheckbox]=\"props.showToggleAllCheckbox\"\r\n [toggleAllCheckboxIndeterminate]=\"isIndeterminate\" [toggleAllCheckboxChecked]=\"isChecked\"\r\n (toggleAll)=\"toggleSelectAll($event)\">\r\n </cmat-select-search>\r\n </mat-option>\r\n }\r\n @if (customDetails?.length!==0&&props.canNull&&!props.multiple) {\r\n <mat-option>\u7A7A</mat-option>\r\n }\r\n @for (i of customDetails; track $index) {\r\n @if(i.label){\r\n @if(i.group){\r\n <mat-optgroup [label]=\"i.label\">\r\n @for (child of i.group; track $index) {\r\n <mat-option [value]=\"child\" [disabled]=\"child.disabled\">\r\n {{ child.label }}\r\n </mat-option>\r\n }\r\n </mat-optgroup>\r\n }@else {\r\n <mat-option [value]=\"i\" [disabled]=\"i.disabled\">{{i.label}}</mat-option>\r\n }\r\n }@else {\r\n <mat-option [value]=\"i\">{{i}}</mat-option>\r\n }\r\n }\r\n }\r\n</mat-select>\r\n}@else {\r\n<mat-select #multiSelect [id]=\"id\" [formControl]=\"formControl\" [placeholder]=\"props.placeholder??''\"\r\n [required]=\"required\" [tabIndex]=\"props.tabindex\" [compareWith]=\"compareWithFn\"\r\n [errorStateMatcher]=\"errorStateMatcher\" [aria-label]=\"getAriaLabel()\" [aria-labelledby]=\"getAriaLabelledby()\"\r\n [disableOptionCentering]=\"props.disableOptionCentering\"\r\n [typeaheadDebounceInterval]=\"props.typeaheadDebounceInterval\"\r\n [panelClass]=\"'overflow-y-auto scrollbar-custom'\">\r\n @if ((filteredCustomDetails | async); as customDetails) {\r\n @if (props.search) {\r\n <mat-option>\r\n <cmat-select-search [formControl]=\"multiFilterCtrl\" [showToggleAllCheckbox]=\"props.showToggleAllCheckbox\"\r\n [toggleAllCheckboxIndeterminate]=\"isIndeterminate\" [toggleAllCheckboxChecked]=\"isChecked\"\r\n (toggleAll)=\"toggleSelectAll($event)\">\r\n </cmat-select-search>\r\n </mat-option>\r\n }\r\n @if (customDetails?.length!==0&&props.canNull&&!props.multiple) {\r\n <mat-option>\u7A7A</mat-option>\r\n }\r\n @for (i of customDetails; track $index) {\r\n @if(i.label){\r\n @if(i.group){\r\n <mat-optgroup [label]=\"i.label\">\r\n @for (child of i.group; track $index) {\r\n <mat-option [value]=\"child\" [disabled]=\"child.disabled\">\r\n {{ child.label }}\r\n </mat-option>\r\n }\r\n </mat-optgroup>\r\n }@else {\r\n <mat-option [value]=\"i\" [disabled]=\"i.disabled\">{{i.label}}</mat-option>\r\n }\r\n }@else {\r\n <mat-option [value]=\"i\">{{i}}</mat-option>\r\n }\r\n }\r\n }\r\n</mat-select>\r\n}", styles: [":host{width:100%}\n"] }]
1357
+ args: [{ selector: 'cmat-select-search-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatCheckboxModule, MatSelectModule, CmatSelectSearchComponent, ReactiveFormsModule], template: "@if(props.multiple){\r\n<mat-select #multiSelect multiple [id]=\"id\" [formControl]=\"formControl\" [placeholder]=\"props.placeholder??''\"\r\n [required]=\"required\" [tabIndex]=\"props.tabindex\" [compareWith]=\"compareWithFn\"\r\n [errorStateMatcher]=\"errorStateMatcher\" [aria-label]=\"getAriaLabel()\" [aria-labelledby]=\"getAriaLabelledby()\"\r\n [disableOptionCentering]=\"props.disableOptionCentering\"\r\n [typeaheadDebounceInterval]=\"props.typeaheadDebounceInterval\">\r\n \r\n @if (props.search) {\r\n <mat-option>\r\n <cmat-select-search [formControl]=\"searchControl\" [showToggleAllCheckbox]=\"props.showToggleAllCheckbox\"\r\n [toggleAllCheckboxIndeterminate]=\"isIndeterminate()\" [toggleAllCheckboxChecked]=\"isChecked()\"\r\n (toggleAll)=\"toggleSelectAll($event)\">\r\n </cmat-select-search>\r\n </mat-option>\r\n }\r\n\r\n @if (allOptions().length !== 0 && props.canNull && !props.multiple) {\r\n <mat-option value=\"\">\u7A7A</mat-option>\r\n }\r\n\r\n @for (i of filteredOptions(); track i.value || $index) {\r\n @if(i.label){\r\n @if(i.group){\r\n <mat-optgroup [label]=\"i.label\">\r\n @for (child of i.group; track child.value || $index) {\r\n <mat-option [value]=\"child\" [disabled]=\"child.disabled\">\r\n {{ child.label }}\r\n </mat-option>\r\n }\r\n </mat-optgroup>\r\n }@else {\r\n <mat-option [value]=\"i\" [disabled]=\"i.disabled\">{{i.label}}</mat-option>\r\n }\r\n }@else {\r\n <mat-option [value]=\"i\">{{i}}</mat-option>\r\n }\r\n }\r\n</mat-select>\r\n}@else {\r\n<mat-select #multiSelect [id]=\"id\" [formControl]=\"formControl\" [placeholder]=\"props.placeholder??''\"\r\n [required]=\"required\" [tabIndex]=\"props.tabindex\" [compareWith]=\"compareWithFn\"\r\n [errorStateMatcher]=\"errorStateMatcher\" [aria-label]=\"getAriaLabel()\" [aria-labelledby]=\"getAriaLabelledby()\"\r\n [disableOptionCentering]=\"props.disableOptionCentering\"\r\n [typeaheadDebounceInterval]=\"props.typeaheadDebounceInterval\">\r\n \r\n @if (props.search) {\r\n <mat-option>\r\n <cmat-select-search [formControl]=\"searchControl\" [showToggleAllCheckbox]=\"props.showToggleAllCheckbox\"\r\n [toggleAllCheckboxIndeterminate]=\"isIndeterminate()\" [toggleAllCheckboxChecked]=\"isChecked()\"\r\n (toggleAll)=\"toggleSelectAll($event)\">\r\n </cmat-select-search>\r\n </mat-option>\r\n }\r\n\r\n @if (allOptions().length !== 0 && props.canNull && !props.multiple) {\r\n <mat-option value=\"\">\u7A7A</mat-option>\r\n }\r\n\r\n\r\n @for (i of filteredOptions(); track i.value || $index) {\r\n @if(i.label){\r\n @if(i.group){\r\n <mat-optgroup [label]=\"i.label\">\r\n @for (child of i.group; track child.value || $index) {\r\n <mat-option [value]=\"child\" [disabled]=\"child.disabled\">\r\n {{ child.label }}\r\n </mat-option>\r\n }\r\n </mat-optgroup>\r\n }@else {\r\n <mat-option [value]=\"i\" [disabled]=\"i.disabled\">{{i.label}}</mat-option>\r\n }\r\n }@else {\r\n <mat-option [value]=\"i\">{{i}}</mat-option>\r\n }\r\n }\r\n</mat-select>\r\n}", styles: [":host{width:100%}\n"] }]
992
1358
  }], ctorParameters: () => [] });
993
1359
 
994
1360
  class CmatSelectTreeTypeComponent extends FieldType$1 {
@@ -1004,47 +1370,42 @@ class CmatSelectTreeTypeComponent extends FieldType$1 {
1004
1370
  customTriggerLabelTemplate: '${name}'
1005
1371
  },
1006
1372
  };
1007
- this.urlData = [];
1008
- this.refreshVersion = signal(0, ...(ngDevMode ? [{ debugName: "refreshVersion" }] : /* istanbul ignore next */ []));
1009
- this._http = inject(HttpClient);
1373
+ this.urlData = signal([], /* @ts-ignore */
1374
+ ...(ngDevMode ? [{ debugName: "urlData" }] : /* istanbul ignore next */ []));
1375
+ this._lastDomain = undefined;
1010
1376
  this._destroyRef = inject(DestroyRef);
1377
+ this._domainDataService = inject(DomainDataService);
1011
1378
  }
1012
1379
  ngOnInit() {
1013
- const url = this.field.props?.domain?.url;
1014
- if (url && this.field.props?.domain?.code && this.field.props?.domain?.key && this.field.props?.domain?.value) {
1015
- this._http.get(url).pipe(takeUntilDestroyed(this._destroyRef)).subscribe((data) => {
1016
- if (data) {
1017
- const key = this.field.props?.domain?.key;
1018
- const code = this.field.props?.domain?.code;
1019
- const datas = data.filter((i) => {
1020
- if (key)
1021
- return i[key] === code;
1022
- return false;
1023
- });
1024
- if (datas && this.field.props?.domain?.value) {
1025
- this.urlData = datas[0][this.field.props?.domain?.value];
1026
- }
1027
- else {
1028
- this.urlData = [];
1029
- }
1030
- }
1031
- else {
1032
- this.urlData = [];
1033
- }
1034
- this.refreshVersion.update(value => value + 1);
1035
- });
1036
- }
1037
- else {
1038
- this.urlData = [];
1039
- this.refreshVersion.update(value => value + 1);
1040
- }
1380
+ this._lastDomain = this.props.domain;
1381
+ this._refreshData();
1382
+ }
1383
+ ngDoCheck() {
1384
+ const currentDomain = this.props.domain;
1385
+ let shouldRefresh = false;
1386
+ // 1. 检查 domain 变化
1387
+ if (!isEqual(currentDomain, this._lastDomain)) {
1388
+ this._lastDomain = currentDomain;
1389
+ shouldRefresh = true;
1390
+ }
1391
+ if (shouldRefresh) {
1392
+ this._refreshData();
1393
+ }
1394
+ }
1395
+ _refreshData() {
1396
+ const domain = this.props.domain;
1397
+ // 使用 DomainDataService 加载远程数据
1398
+ this._domainDataService.load(domain, this._destroyRef, {
1399
+ onSuccess: data => this.urlData.set(data),
1400
+ componentName: 'CmatSelectTreeTypeComponent'
1401
+ });
1041
1402
  }
1042
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatSelectTreeTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1043
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.11", type: CmatSelectTreeTypeComponent, isStandalone: true, selector: "cmat-select-tree-type", usesInheritance: true, ngImport: i0, template: "<cmat-select-tree [formControl]=\"formControl\" [dataSource]=\"urlData\" [customTriggerLabelTemplate]=\"'${name}'\"\r\n [multiple]=\"props.multiple\" [overallSearchEnabled]=\"props.search\" [canNull]=\"props.canNull\"\r\n [showToggleAllCheckbox]=\"props.showToggleAllCheckbox\" [expandable]=\"props.expandable\" [placeholder]=\"placeholder\"\r\n [tabIndex]=\"props.tabindex\" [required]=\"required\"></cmat-select-tree>", styles: [":host{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: CmatSelectTreeComponent, selector: "cmat-select-tree", inputs: ["id", "dataSource", "noEntriesFoundLabel", "showNoFoundLabel", "multiple", "overallSearchEnabled", "canNull", "customTriggerLabelFn", "customTriggerLabelTemplate", "expandable", "showToggleAllCheckbox", "compareWith", "placeholder", "value", "required", "disabled"], exportAs: ["cmatSelectTree"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1403
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatSelectTreeTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1404
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.6", type: CmatSelectTreeTypeComponent, isStandalone: true, selector: "cmat-select-tree-type", usesInheritance: true, ngImport: i0, template: "<cmat-select-tree \r\n [formControl]=\"formControl\" \r\n [dataSource]=\"urlData()\" \r\n [customTriggerLabelTemplate]=\"'${name}'\"\r\n [multiple]=\"props.multiple\" \r\n [overallSearchEnabled]=\"props.search\" \r\n [canNull]=\"props.canNull\"\r\n [showToggleAllCheckbox]=\"props.showToggleAllCheckbox\" \r\n [expandable]=\"props.expandable\" \r\n [placeholder]=\"placeholder\"\r\n [tabIndex]=\"props.tabindex\" \r\n [required]=\"required\">\r\n</cmat-select-tree>", styles: [":host{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: CmatSelectTreeComponent, selector: "cmat-select-tree", inputs: ["dataSource", "noEntriesFoundLabel", "showNoFoundLabel", "multiple", "overallSearchEnabled", "canNull", "customTriggerLabelFn", "customTriggerLabelTemplate", "expandable", "showToggleAllCheckbox", "compareWith", "placeholder", "value", "required", "disabled"], exportAs: ["cmatSelectTree"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1044
1405
  }
1045
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatSelectTreeTypeComponent, decorators: [{
1406
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatSelectTreeTypeComponent, decorators: [{
1046
1407
  type: Component,
1047
- args: [{ selector: 'cmat-select-tree-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [ReactiveFormsModule, CmatSelectTreeComponent], template: "<cmat-select-tree [formControl]=\"formControl\" [dataSource]=\"urlData\" [customTriggerLabelTemplate]=\"'${name}'\"\r\n [multiple]=\"props.multiple\" [overallSearchEnabled]=\"props.search\" [canNull]=\"props.canNull\"\r\n [showToggleAllCheckbox]=\"props.showToggleAllCheckbox\" [expandable]=\"props.expandable\" [placeholder]=\"placeholder\"\r\n [tabIndex]=\"props.tabindex\" [required]=\"required\"></cmat-select-tree>", styles: [":host{width:100%}\n"] }]
1408
+ args: [{ selector: 'cmat-select-tree-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [ReactiveFormsModule, CmatSelectTreeComponent], template: "<cmat-select-tree \r\n [formControl]=\"formControl\" \r\n [dataSource]=\"urlData()\" \r\n [customTriggerLabelTemplate]=\"'${name}'\"\r\n [multiple]=\"props.multiple\" \r\n [overallSearchEnabled]=\"props.search\" \r\n [canNull]=\"props.canNull\"\r\n [showToggleAllCheckbox]=\"props.showToggleAllCheckbox\" \r\n [expandable]=\"props.expandable\" \r\n [placeholder]=\"placeholder\"\r\n [tabIndex]=\"props.tabindex\" \r\n [required]=\"required\">\r\n</cmat-select-tree>", styles: [":host{width:100%}\n"] }]
1048
1409
  }], ctorParameters: () => [] });
1049
1410
 
1050
1411
  class CmatSelectTableTypeComponent extends FieldType$1 {
@@ -1058,47 +1419,65 @@ class CmatSelectTableTypeComponent extends FieldType$1 {
1058
1419
  customTriggerLabelTemplate: '${name}'
1059
1420
  },
1060
1421
  };
1061
- this.urlData = { columns: [], data: [] };
1062
- this.refreshVersion = signal(0, ...(ngDevMode ? [{ debugName: "refreshVersion" }] : /* istanbul ignore next */ []));
1063
- this._http = inject(HttpClient);
1422
+ this.urlData = signal({ columns: [], data: [] }, /* @ts-ignore */
1423
+ ...(ngDevMode ? [{ debugName: "urlData" }] : /* istanbul ignore next */ []));
1424
+ this._lastDomain = undefined;
1064
1425
  this._destroyRef = inject(DestroyRef);
1426
+ this._domainDataService = inject(DomainDataService);
1065
1427
  }
1066
1428
  ngOnInit() {
1067
- const url = this.field.props?.domain?.url;
1068
- if (url && this.field.props?.domain?.code && this.field.props?.domain?.key && this.field.props?.domain?.value) {
1069
- this._http.get(url).pipe(takeUntilDestroyed(this._destroyRef)).subscribe((data) => {
1070
- if (data) {
1071
- const key = this.field.props?.domain?.key;
1072
- const code = this.field.props?.domain?.code;
1073
- const datas = data.filter((i) => {
1074
- if (key)
1075
- return i[key] === code;
1076
- return false;
1077
- });
1078
- if (datas && this.field.props?.domain?.value) {
1079
- this.urlData = datas[0][this.field.props?.domain?.value];
1080
- }
1081
- else {
1082
- this.urlData = { columns: [], data: [] };
1083
- }
1429
+ this._lastDomain = this.props.domain;
1430
+ this._refreshData();
1431
+ }
1432
+ ngDoCheck() {
1433
+ const currentDomain = this.props.domain;
1434
+ let shouldRefresh = false;
1435
+ // 1. 检查 domain 变化
1436
+ if (!isEqual(currentDomain, this._lastDomain)) {
1437
+ this._lastDomain = currentDomain;
1438
+ shouldRefresh = true;
1439
+ }
1440
+ if (shouldRefresh) {
1441
+ this._refreshData();
1442
+ }
1443
+ }
1444
+ _refreshData() {
1445
+ const domain = this.props.domain;
1446
+ // 使用 DomainDataService 加载远程数据
1447
+ this._domainDataService.load(domain, this._destroyRef, {
1448
+ transform: (rawData) => {
1449
+ // Select-Table 需要特殊验证数据结构
1450
+ if (this._isValidDataSource(rawData)) {
1451
+ return rawData;
1452
+ }
1453
+ console.warn('Invalid select-table data structure');
1454
+ return [];
1455
+ },
1456
+ onSuccess: (data) => {
1457
+ if (data.length > 0) {
1458
+ this.urlData.set(data[0]);
1084
1459
  }
1085
1460
  else {
1086
- this.urlData = { columns: [], data: [] };
1461
+ this.urlData.set({ columns: [], data: [] });
1087
1462
  }
1088
- this.refreshVersion.update(value => value + 1);
1089
- });
1090
- }
1091
- else {
1092
- this.urlData = { columns: [], data: [] };
1093
- this.refreshVersion.update(value => value + 1);
1094
- }
1463
+ },
1464
+ componentName: 'CmatSelectTableTypeComponent'
1465
+ });
1095
1466
  }
1096
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatSelectTableTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1097
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.11", type: CmatSelectTableTypeComponent, isStandalone: true, selector: "cmat-select-table-type", usesInheritance: true, ngImport: i0, template: "<cmat-select-table [formControl]=\"formControl\" [dataSource]=\"urlData\" [customTriggerLabelTemplate]=\"'${name}'\"\r\n [multiple]=\"props.multiple\" [overallSearchEnabled]=\"props.search\" [canNull]=\"props.canNull\"\r\n [placeholder]=\"placeholder\" [tabIndex]=\"props.tabindex\" [required]=\"required\"></cmat-select-table>", styles: [":host{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: CmatSelectTableComponent, selector: "cmat-select-table", inputs: ["id", "dataSource", "noEntriesFoundLabel", "showNoFoundLabel", "isPhone", "multiple", "overallSearchEnabled", "overallSearchVisible", "resetSortOnOpen", "resetFiltersOnOpen", "customTriggerLabelFn", "triggerLabelSort", "customTriggerLabelTemplate", "canNull", "defaultSort", "resetOptionAction", "keyParam", "compareWith", "placeholder", "value", "required", "disabled"], outputs: ["closed"], exportAs: ["cmatSelectTable"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1467
+ _isValidDataSource(data) {
1468
+ return (typeof data === 'object' &&
1469
+ data !== null &&
1470
+ 'columns' in data &&
1471
+ 'data' in data &&
1472
+ Array.isArray(data.columns) &&
1473
+ Array.isArray(data.data));
1474
+ }
1475
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatSelectTableTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1476
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.6", type: CmatSelectTableTypeComponent, isStandalone: true, selector: "cmat-select-table-type", usesInheritance: true, ngImport: i0, template: "<cmat-select-table \r\n [formControl]=\"formControl\" \r\n [dataSource]=\"urlData()\" \r\n [customTriggerLabelTemplate]=\"'${name}'\"\r\n [multiple]=\"props.multiple\" \r\n [overallSearchEnabled]=\"props.search\" \r\n [canNull]=\"props.canNull\"\r\n [placeholder]=\"placeholder\" \r\n [tabIndex]=\"props.tabindex\" \r\n [required]=\"required\">\r\n</cmat-select-table>", styles: [":host{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: CmatSelectTableComponent, selector: "cmat-select-table", inputs: ["dataSource", "noEntriesFoundLabel", "showNoFoundLabel", "isPhone", "multiple", "overallSearchEnabled", "overallSearchVisible", "resetSortOnOpen", "resetFiltersOnOpen", "customTriggerLabelFn", "triggerLabelSort", "customTriggerLabelTemplate", "canNull", "defaultSort", "resetOptionAction", "keyParam", "compareWith", "placeholder", "value", "required", "disabled"], outputs: ["closed"], exportAs: ["cmatSelectTable"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1098
1477
  }
1099
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatSelectTableTypeComponent, decorators: [{
1478
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatSelectTableTypeComponent, decorators: [{
1100
1479
  type: Component,
1101
- args: [{ selector: 'cmat-select-table-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [ReactiveFormsModule, CmatSelectTableComponent], template: "<cmat-select-table [formControl]=\"formControl\" [dataSource]=\"urlData\" [customTriggerLabelTemplate]=\"'${name}'\"\r\n [multiple]=\"props.multiple\" [overallSearchEnabled]=\"props.search\" [canNull]=\"props.canNull\"\r\n [placeholder]=\"placeholder\" [tabIndex]=\"props.tabindex\" [required]=\"required\"></cmat-select-table>", styles: [":host{width:100%}\n"] }]
1480
+ args: [{ selector: 'cmat-select-table-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [ReactiveFormsModule, CmatSelectTableComponent], template: "<cmat-select-table \r\n [formControl]=\"formControl\" \r\n [dataSource]=\"urlData()\" \r\n [customTriggerLabelTemplate]=\"'${name}'\"\r\n [multiple]=\"props.multiple\" \r\n [overallSearchEnabled]=\"props.search\" \r\n [canNull]=\"props.canNull\"\r\n [placeholder]=\"placeholder\" \r\n [tabIndex]=\"props.tabindex\" \r\n [required]=\"required\">\r\n</cmat-select-table>", styles: [":host{width:100%}\n"] }]
1102
1481
  }], ctorParameters: () => [] });
1103
1482
 
1104
1483
  class CmatStepperHorizontalTypeComponent extends FieldType$2 {
@@ -1110,10 +1489,10 @@ class CmatStepperHorizontalTypeComponent extends FieldType$2 {
1110
1489
  }
1111
1490
  return field.fieldGroup ? field.fieldGroup.every(f => this.isValid(f)) : true;
1112
1491
  }
1113
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatStepperHorizontalTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1114
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: CmatStepperHorizontalTypeComponent, isStandalone: true, selector: "cmat-stepper-horizontal-type", usesInheritance: true, ngImport: i0, template: "<mat-horizontal-stepper [linear]=\"props.isLinear\" [tabIndex]=\"props.tabindex\">\r\n\r\n <ng-template matStepperIcon=\"edit\">\r\n <mat-icon class=\"icon-size-4\" [svgIcon]=\"'heroicons_solid:pencil'\"></mat-icon>\r\n </ng-template>\r\n <ng-template matStepperIcon=\"done\">\r\n <mat-icon class=\"icon-size-4\" [svgIcon]=\"'heroicons_outline:check'\"></mat-icon>\r\n </ng-template>\r\n\r\n @for (step of field.fieldGroup; track $index) {\r\n <mat-step [stepControl]=\"step.formControl!\" [editable]=\"step.props?.isEditable||$last\" [optional]=\"step.props?.isOptional\">\r\n <ng-template matStepLabel>{{ step.props?.label||'' }}</ng-template>\r\n <div class=\"py-2\">\r\n <formly-field [field]=\"step\"></formly-field>\r\n </div>\r\n <div class=\"mt-2 flex flex-row gap-2\">\r\n @if($index !== 0){\r\n <button matStepperPrevious matButton=\"filled\" color=\"primary\" type=\"button\">\u4E0A\u4E00\u6B65</button>\r\n }\r\n\r\n @if(!$last){\r\n <button matStepperNext matButton=\"filled\" color=\"primary\" type=\"button\" [disabled]=\"!isValid(step)\">\r\n \u4E0B\u4E00\u6B65\r\n </button>\r\n }\r\n </div>\r\n </mat-step>\r\n }\r\n\r\n</mat-horizontal-stepper>", styles: [":host{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: FormlyModule }, { kind: "component", type: i1$3.LegacyFormlyField, selector: "formly-field" }, { kind: "ngmodule", type: MatStepperModule }, { kind: "component", type: i2$3.MatStep, selector: "mat-step", inputs: ["color"], exportAs: ["matStep"] }, { kind: "directive", type: i2$3.MatStepLabel, selector: "[matStepLabel]" }, { kind: "component", type: i2$3.MatStepper, selector: "mat-stepper, mat-vertical-stepper, mat-horizontal-stepper, [matStepper]", inputs: ["disableRipple", "color", "labelPosition", "headerPosition", "aria-label", "headerPrefix", "animationDuration"], outputs: ["animationDone"], exportAs: ["matStepper", "matVerticalStepper", "matHorizontalStepper"] }, { kind: "directive", type: i2$3.MatStepperNext, selector: "button[matStepperNext]" }, { kind: "directive", type: i2$3.MatStepperPrevious, selector: "button[matStepperPrevious]" }, { kind: "directive", type: i2$3.MatStepperIcon, selector: "ng-template[matStepperIcon]", inputs: ["matStepperIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1492
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatStepperHorizontalTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1493
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: CmatStepperHorizontalTypeComponent, isStandalone: true, selector: "cmat-stepper-horizontal-type", usesInheritance: true, ngImport: i0, template: "<mat-horizontal-stepper [linear]=\"props.isLinear\" [tabIndex]=\"props.tabindex\">\r\n\r\n <ng-template matStepperIcon=\"edit\">\r\n <mat-icon class=\"icon-size-4\" [svgIcon]=\"'heroicons_solid:pencil'\"></mat-icon>\r\n </ng-template>\r\n <ng-template matStepperIcon=\"done\">\r\n <mat-icon class=\"icon-size-4\" [svgIcon]=\"'heroicons_outline:check'\"></mat-icon>\r\n </ng-template>\r\n\r\n @for (step of field.fieldGroup; track $index) {\r\n <mat-step [stepControl]=\"step.formControl!\" [editable]=\"step.props?.isEditable||$last\" [optional]=\"step.props?.isOptional\">\r\n <ng-template matStepLabel>{{ step.props?.label||'' }}</ng-template>\r\n <div class=\"py-2\">\r\n <formly-field [field]=\"step\"></formly-field>\r\n </div>\r\n <div class=\"mt-2 flex flex-row gap-2\">\r\n @if($index !== 0){\r\n <button matStepperPrevious matButton=\"filled\" color=\"primary\" type=\"button\">\u4E0A\u4E00\u6B65</button>\r\n }\r\n\r\n @if(!$last){\r\n <button matStepperNext matButton=\"filled\" color=\"primary\" type=\"button\" [disabled]=\"!isValid(step)\">\r\n \u4E0B\u4E00\u6B65\r\n </button>\r\n }\r\n </div>\r\n </mat-step>\r\n }\r\n\r\n</mat-horizontal-stepper>", styles: [":host{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: FormlyModule }, { kind: "component", type: i1$3.LegacyFormlyField, selector: "formly-field" }, { kind: "ngmodule", type: MatStepperModule }, { kind: "component", type: i2$3.MatStep, selector: "mat-step", inputs: ["color"], exportAs: ["matStep"] }, { kind: "directive", type: i2$3.MatStepLabel, selector: "[matStepLabel]" }, { kind: "component", type: i2$3.MatStepper, selector: "mat-stepper, mat-vertical-stepper, mat-horizontal-stepper, [matStepper]", inputs: ["disableRipple", "color", "labelPosition", "headerPosition", "aria-label", "headerPrefix", "animationDuration"], outputs: ["animationDone"], exportAs: ["matStepper", "matVerticalStepper", "matHorizontalStepper"] }, { kind: "directive", type: i2$3.MatStepperNext, selector: "button[matStepperNext]" }, { kind: "directive", type: i2$3.MatStepperPrevious, selector: "button[matStepperPrevious]" }, { kind: "directive", type: i2$3.MatStepperIcon, selector: "ng-template[matStepperIcon]", inputs: ["matStepperIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1115
1494
  }
1116
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatStepperHorizontalTypeComponent, decorators: [{
1495
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatStepperHorizontalTypeComponent, decorators: [{
1117
1496
  type: Component,
1118
1497
  args: [{ selector: 'cmat-stepper-horizontal-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [FormlyModule, MatStepperModule, MatButtonModule, ReactiveFormsModule, MatIconModule], template: "<mat-horizontal-stepper [linear]=\"props.isLinear\" [tabIndex]=\"props.tabindex\">\r\n\r\n <ng-template matStepperIcon=\"edit\">\r\n <mat-icon class=\"icon-size-4\" [svgIcon]=\"'heroicons_solid:pencil'\"></mat-icon>\r\n </ng-template>\r\n <ng-template matStepperIcon=\"done\">\r\n <mat-icon class=\"icon-size-4\" [svgIcon]=\"'heroicons_outline:check'\"></mat-icon>\r\n </ng-template>\r\n\r\n @for (step of field.fieldGroup; track $index) {\r\n <mat-step [stepControl]=\"step.formControl!\" [editable]=\"step.props?.isEditable||$last\" [optional]=\"step.props?.isOptional\">\r\n <ng-template matStepLabel>{{ step.props?.label||'' }}</ng-template>\r\n <div class=\"py-2\">\r\n <formly-field [field]=\"step\"></formly-field>\r\n </div>\r\n <div class=\"mt-2 flex flex-row gap-2\">\r\n @if($index !== 0){\r\n <button matStepperPrevious matButton=\"filled\" color=\"primary\" type=\"button\">\u4E0A\u4E00\u6B65</button>\r\n }\r\n\r\n @if(!$last){\r\n <button matStepperNext matButton=\"filled\" color=\"primary\" type=\"button\" [disabled]=\"!isValid(step)\">\r\n \u4E0B\u4E00\u6B65\r\n </button>\r\n }\r\n </div>\r\n </mat-step>\r\n }\r\n\r\n</mat-horizontal-stepper>", styles: [":host{width:100%}\n"] }]
1119
1498
  }] });
@@ -1127,10 +1506,10 @@ class CmatStepperVerticalTypeComponent extends FieldType$2 {
1127
1506
  }
1128
1507
  return field.fieldGroup ? field.fieldGroup.every(f => this.isValid(f)) : true;
1129
1508
  }
1130
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatStepperVerticalTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1131
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: CmatStepperVerticalTypeComponent, isStandalone: true, selector: "cmat-stepper-vertical-type", usesInheritance: true, ngImport: i0, template: "<mat-vertical-stepper [linear]=\"props.isLinear\" [tabIndex]=\"props.tabindex\">\r\n <ng-template matStepperIcon=\"edit\">\r\n <mat-icon class=\"icon-size-4\" [svgIcon]=\"'heroicons_solid:pencil'\"></mat-icon>\r\n </ng-template>\r\n <ng-template matStepperIcon=\"done\">\r\n <mat-icon class=\"icon-size-4\" [svgIcon]=\"'heroicons_outline:check'\"></mat-icon>\r\n </ng-template>\r\n\r\n @for (step of field.fieldGroup; track $index) {\r\n <mat-step [stepControl]=\"step.formControl!\" [editable]=\"step.props?.isEditable||$last\" [optional]=\"step.props?.isOptional\">\r\n <ng-template matStepLabel>{{ step.props?.label||'' }}</ng-template>\r\n <div class=\"py-2\">\r\n <formly-field [field]=\"step\"></formly-field>\r\n </div>\r\n\r\n <div class=\"mt-2 flex flex-row gap-2\">\r\n @if($index!==0){\r\n <button matStepperPrevious matButton=\"filled\" color=\"primary\" type=\"button\">\u4E0A\u4E00\u6B65</button>\r\n }\r\n\r\n @if(!$last){\r\n <button matStepperNext matButton=\"filled\" color=\"primary\" type=\"button\" [disabled]=\"!isValid(step)\">\r\n \u4E0B\u4E00\u6B65\r\n </button>\r\n }\r\n </div>\r\n </mat-step>\r\n }\r\n</mat-vertical-stepper>", styles: [":host{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: FormlyModule }, { kind: "component", type: i1$3.LegacyFormlyField, selector: "formly-field" }, { kind: "ngmodule", type: MatStepperModule }, { kind: "component", type: i2$3.MatStep, selector: "mat-step", inputs: ["color"], exportAs: ["matStep"] }, { kind: "directive", type: i2$3.MatStepLabel, selector: "[matStepLabel]" }, { kind: "component", type: i2$3.MatStepper, selector: "mat-stepper, mat-vertical-stepper, mat-horizontal-stepper, [matStepper]", inputs: ["disableRipple", "color", "labelPosition", "headerPosition", "aria-label", "headerPrefix", "animationDuration"], outputs: ["animationDone"], exportAs: ["matStepper", "matVerticalStepper", "matHorizontalStepper"] }, { kind: "directive", type: i2$3.MatStepperNext, selector: "button[matStepperNext]" }, { kind: "directive", type: i2$3.MatStepperPrevious, selector: "button[matStepperPrevious]" }, { kind: "directive", type: i2$3.MatStepperIcon, selector: "ng-template[matStepperIcon]", inputs: ["matStepperIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1509
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatStepperVerticalTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1510
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: CmatStepperVerticalTypeComponent, isStandalone: true, selector: "cmat-stepper-vertical-type", usesInheritance: true, ngImport: i0, template: "<mat-vertical-stepper [linear]=\"props.isLinear\" [tabIndex]=\"props.tabindex\">\r\n <ng-template matStepperIcon=\"edit\">\r\n <mat-icon class=\"icon-size-4\" [svgIcon]=\"'heroicons_solid:pencil'\"></mat-icon>\r\n </ng-template>\r\n <ng-template matStepperIcon=\"done\">\r\n <mat-icon class=\"icon-size-4\" [svgIcon]=\"'heroicons_outline:check'\"></mat-icon>\r\n </ng-template>\r\n\r\n @for (step of field.fieldGroup; track $index) {\r\n <mat-step [stepControl]=\"step.formControl!\" [editable]=\"step.props?.isEditable||$last\" [optional]=\"step.props?.isOptional\">\r\n <ng-template matStepLabel>{{ step.props?.label||'' }}</ng-template>\r\n <div class=\"py-2\">\r\n <formly-field [field]=\"step\"></formly-field>\r\n </div>\r\n\r\n <div class=\"mt-2 flex flex-row gap-2\">\r\n @if($index!==0){\r\n <button matStepperPrevious matButton=\"filled\" color=\"primary\" type=\"button\">\u4E0A\u4E00\u6B65</button>\r\n }\r\n\r\n @if(!$last){\r\n <button matStepperNext matButton=\"filled\" color=\"primary\" type=\"button\" [disabled]=\"!isValid(step)\">\r\n \u4E0B\u4E00\u6B65\r\n </button>\r\n }\r\n </div>\r\n </mat-step>\r\n }\r\n</mat-vertical-stepper>", styles: [":host{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: FormlyModule }, { kind: "component", type: i1$3.LegacyFormlyField, selector: "formly-field" }, { kind: "ngmodule", type: MatStepperModule }, { kind: "component", type: i2$3.MatStep, selector: "mat-step", inputs: ["color"], exportAs: ["matStep"] }, { kind: "directive", type: i2$3.MatStepLabel, selector: "[matStepLabel]" }, { kind: "component", type: i2$3.MatStepper, selector: "mat-stepper, mat-vertical-stepper, mat-horizontal-stepper, [matStepper]", inputs: ["disableRipple", "color", "labelPosition", "headerPosition", "aria-label", "headerPrefix", "animationDuration"], outputs: ["animationDone"], exportAs: ["matStepper", "matVerticalStepper", "matHorizontalStepper"] }, { kind: "directive", type: i2$3.MatStepperNext, selector: "button[matStepperNext]" }, { kind: "directive", type: i2$3.MatStepperPrevious, selector: "button[matStepperPrevious]" }, { kind: "directive", type: i2$3.MatStepperIcon, selector: "ng-template[matStepperIcon]", inputs: ["matStepperIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1132
1511
  }
1133
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatStepperVerticalTypeComponent, decorators: [{
1512
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatStepperVerticalTypeComponent, decorators: [{
1134
1513
  type: Component,
1135
1514
  args: [{ selector: 'cmat-stepper-vertical-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [FormlyModule, MatStepperModule, MatButtonModule, ReactiveFormsModule, MatIconModule], template: "<mat-vertical-stepper [linear]=\"props.isLinear\" [tabIndex]=\"props.tabindex\">\r\n <ng-template matStepperIcon=\"edit\">\r\n <mat-icon class=\"icon-size-4\" [svgIcon]=\"'heroicons_solid:pencil'\"></mat-icon>\r\n </ng-template>\r\n <ng-template matStepperIcon=\"done\">\r\n <mat-icon class=\"icon-size-4\" [svgIcon]=\"'heroicons_outline:check'\"></mat-icon>\r\n </ng-template>\r\n\r\n @for (step of field.fieldGroup; track $index) {\r\n <mat-step [stepControl]=\"step.formControl!\" [editable]=\"step.props?.isEditable||$last\" [optional]=\"step.props?.isOptional\">\r\n <ng-template matStepLabel>{{ step.props?.label||'' }}</ng-template>\r\n <div class=\"py-2\">\r\n <formly-field [field]=\"step\"></formly-field>\r\n </div>\r\n\r\n <div class=\"mt-2 flex flex-row gap-2\">\r\n @if($index!==0){\r\n <button matStepperPrevious matButton=\"filled\" color=\"primary\" type=\"button\">\u4E0A\u4E00\u6B65</button>\r\n }\r\n\r\n @if(!$last){\r\n <button matStepperNext matButton=\"filled\" color=\"primary\" type=\"button\" [disabled]=\"!isValid(step)\">\r\n \u4E0B\u4E00\u6B65\r\n </button>\r\n }\r\n </div>\r\n </mat-step>\r\n }\r\n</mat-vertical-stepper>", styles: [":host{width:100%}\n"] }]
1136
1515
  }] });
@@ -1139,15 +1518,41 @@ class CmatTableTypeComponent extends FieldArrayType {
1139
1518
  constructor() {
1140
1519
  super();
1141
1520
  this.inlineform = new FormGroup({});
1142
- this.currentMode = {};
1143
- this.displayedColumns = [];
1144
- this.refreshVersion = signal(0, ...(ngDevMode ? [{ debugName: "refreshVersion" }] : /* istanbul ignore next */ []));
1145
- this.dialogType = '';
1521
+ this.columns = computed(() => {
1522
+ const fieldGroup = this._fieldModel.fieldArray?.fieldGroup?.[0]?.fieldGroup ?? [];
1523
+ return fieldGroup
1524
+ .filter(field => field.props?.showColumn)
1525
+ .map(field => ({
1526
+ key: String(field.key ?? ''),
1527
+ label: field.props?.label ?? '',
1528
+ }));
1529
+ }, /* @ts-ignore */
1530
+ ...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
1531
+ this.displayedColumns = computed(() => {
1532
+ const cols = this.columns().map(c => c.key);
1533
+ if (this.props.disabled) {
1534
+ return cols;
1535
+ }
1536
+ return [...cols, 'operate'];
1537
+ }, /* @ts-ignore */
1538
+ ...(ngDevMode ? [{ debugName: "displayedColumns" }] : /* istanbul ignore next */ []));
1539
+ this.refreshVersion = signal(0, /* @ts-ignore */
1540
+ ...(ngDevMode ? [{ debugName: "refreshVersion" }] : /* istanbul ignore next */ []));
1541
+ this.currentMode = signal({}, /* @ts-ignore */
1542
+ ...(ngDevMode ? [{ debugName: "currentMode" }] : /* istanbul ignore next */ []));
1543
+ this.currentIndex = signal(-1, /* @ts-ignore */
1544
+ ...(ngDevMode ? [{ debugName: "currentIndex" }] : /* istanbul ignore next */ []));
1545
+ this.dialogType = signal('', /* @ts-ignore */
1546
+ ...(ngDevMode ? [{ debugName: "dialogType" }] : /* istanbul ignore next */ []));
1146
1547
  this.defaultOptions = {
1147
1548
  props: {
1148
1549
  addText: '新增'
1149
1550
  },
1150
1551
  };
1552
+ this.dialogRef = viewChild('dialogRef', /* @ts-ignore */
1553
+ ...(ngDevMode ? [{ debugName: "dialogRef" }] : /* istanbul ignore next */ []));
1554
+ this.table = viewChild('table', /* @ts-ignore */
1555
+ ...(ngDevMode ? [{ debugName: "table" }] : /* istanbul ignore next */ []));
1151
1556
  this._dialog = inject(MatDialog);
1152
1557
  this._viewContainerRef = inject(ViewContainerRef);
1153
1558
  }
@@ -1155,7 +1560,7 @@ class CmatTableTypeComponent extends FieldArrayType {
1155
1560
  return this._fieldModel.fieldArray?.fieldGroup ?? [];
1156
1561
  }
1157
1562
  get key() {
1158
- return this._fieldModel.fieldArray?.fieldGroup?.[0]?.id ?? '';
1563
+ return this._fieldModel.fieldArray?.fieldGroup?.[0]?.key ?? 'data';
1159
1564
  }
1160
1565
  get _tableProps() {
1161
1566
  return this.props;
@@ -1163,48 +1568,24 @@ class CmatTableTypeComponent extends FieldArrayType {
1163
1568
  get _fieldModel() {
1164
1569
  return this.field;
1165
1570
  }
1166
- ngOnInit() {
1167
- this.columns = (this._fieldModel.fieldArray?.fieldGroup?.[0]?.fieldGroup ?? [])
1168
- .filter(field => field.props?.showColumn).map(field => ({
1169
- key: String(field.key ?? ''),
1170
- label: field.props?.label ?? '',
1171
- }));
1172
- if (this._tableProps.disabled) {
1173
- this.displayedColumns = [...this.columns.map(column => column.key)];
1174
- }
1175
- else {
1176
- this.displayedColumns = [...this.columns.map(column => column.key), 'operate'];
1177
- }
1178
- }
1179
1571
  addRow() {
1180
- this._dialogRef = this._dialog
1181
- .open(this.dialogRef, {
1182
- panelClass: ['cmat-table-dialog-container'],
1183
- viewContainerRef: this._viewContainerRef
1184
- });
1185
- this._dialogRef.afterClosed()
1186
- .subscribe(() => { this.dialogType = ''; });
1187
- this.dialogType = 'add';
1188
- this.currentMode = {};
1572
+ this.dialogType.set('add');
1573
+ this.currentMode.set({});
1189
1574
  this.inlineform.reset();
1575
+ this._openDialog();
1190
1576
  }
1191
1577
  editRow(item, index) {
1192
- this.currentIndex = index;
1193
- this._dialogRef = this._dialog
1194
- .open(this.dialogRef, {
1195
- panelClass: ['cmat-table-dialog-container'],
1196
- viewContainerRef: this._viewContainerRef
1578
+ this.currentIndex.set(index);
1579
+ this.dialogType.set('edit');
1580
+ this.currentMode.set({
1581
+ [this.key]: { ...item } // 浅拷贝以防止直接修改原数据直到确认
1197
1582
  });
1198
- this._dialogRef.afterClosed()
1199
- .subscribe(() => { this.dialogType = ''; });
1200
- this.dialogType = 'edit';
1201
- this.currentMode = {
1202
- [this.key]: item
1203
- };
1583
+ this._openDialog();
1204
1584
  }
1205
- deleteRow(id) {
1206
- this.remove(id);
1207
- this.table.renderRows();
1585
+ deleteRow(index) {
1586
+ this.remove(index);
1587
+ // 触发变更检测以更新表格视图
1588
+ this.refreshVersion.update(v => v + 1);
1208
1589
  }
1209
1590
  confirm() {
1210
1591
  if (this.inlineform.invalid) {
@@ -1212,37 +1593,53 @@ class CmatTableTypeComponent extends FieldArrayType {
1212
1593
  return;
1213
1594
  }
1214
1595
  const model = this.model;
1215
- const currentValue = this.currentMode[this.key];
1216
- if (this.dialogType === 'add' && currentValue) {
1596
+ // 获取表单中编辑/新增的实际数据对象
1597
+ const currentValue = this.currentMode()[this.key];
1598
+ if (!currentValue) {
1599
+ this._dialogRef.close();
1600
+ return;
1601
+ }
1602
+ if (this.dialogType() === 'add') {
1217
1603
  this.add(model?.length ?? 0, currentValue);
1218
1604
  }
1219
- else if (this.dialogType === 'edit' && currentValue && model) {
1220
- model[this.currentIndex] = currentValue;
1605
+ else if (this.dialogType() === 'edit') {
1606
+ const index = this.currentIndex();
1607
+ if (index > -1 && model) {
1608
+ model[index] = currentValue;
1609
+ this.formControl.patchValue([...model]);
1610
+ }
1221
1611
  }
1222
- this.table.renderRows();
1223
- this.refreshVersion.update(value => value + 1);
1612
+ this.refreshVersion.update(v => v + 1);
1613
+ this.table()?.renderRows();
1224
1614
  this._dialogRef.close();
1225
1615
  }
1226
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatTableTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1227
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: CmatTableTypeComponent, isStandalone: true, selector: "cmat-table-type", viewQueries: [{ propertyName: "dialogRef", first: true, predicate: ["dialogRef"], descendants: true }, { propertyName: "table", first: true, predicate: ["table"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"relative flex flex-col sm:flex-row flex-none sm:items-center sm:justify-between p-2 border-b mb-1\">\r\n <div>\r\n @if(props.label){\r\n <legend class=\"text-lg\">\r\n {{ props.label }}\r\n @if(props.required){\r\n <span>*</span>\r\n }\r\n </legend>\r\n }\r\n @if(props.description){\r\n <p>{{ props.description }}</p>\r\n }\r\n </div>\r\n\r\n <div class=\"cmat-table-type\" [attr.data-refresh]=\"refreshVersion()\">\r\n @if(!props.disabled){\r\n <div class=\"flex shrink-0 items-center mt-6 sm:mt-0 sm:ml-4 print:hidden\">\r\n <button class=\"ml-4\" matButton=\"filled\" [color]=\"'primary'\" (click)=\"addRow()\">\r\n <mat-icon [svgIcon]=\"'heroicons_outline:plus'\"></mat-icon>\r\n <span class=\"ml-2\">{{props.addText}}</span>\r\n </button>\r\n </div>\r\n }\r\n</div>\r\n\r\n\r\n<table #table mat-table class=\"w-full\" [dataSource]=\"model||[]\" [tabIndex]=\"props.tabindex\">\r\n @for (column of columns; track $index) {\r\n <ng-container [matColumnDef]=\"column.key\">\r\n <th *matHeaderCellDef mat-header-cell> {{ column.label }} </th>\r\n <td *matCellDef=\"let element; let i = index\" mat-cell>\r\n <div class=\" has-label-on-mobile\" [attr.data-label]=\"column.label +':'\">\r\n {{element[column.key]}}\r\n </div>\r\n </td>\r\n </ng-container>\r\n }\r\n\r\n <ng-container matColumnDef=\"operate\" stickyEnd>\r\n <th *matHeaderCellDef mat-header-cell class=\"print:hidden\">\u64CD\u4F5C</th>\r\n <td *matCellDef=\"let element; let i = index\" mat-cell class=\"w-24 print:hidden\">\r\n <div class=\"flex flex-col lg:w-full\">\r\n <div class=\"relative flex flex-row gap-2 lg:m-2 justify-center\">\r\n <button type=\"button\" class=\"w-8 min-h-8 h-8 max-w-8 lg:opacity-0 lg:group-hover:opacity-100\"\r\n matIconButton [matTooltip]=\"'\u7F16\u8F91'\" (click)=\"editRow(element,i)\">\r\n <mat-icon class=\"icon-size-5\" color=\"primary\" [svgIcon]=\"'heroicons_solid:pencil-square'\">\r\n </mat-icon>\r\n </button>\r\n \r\n <button type=\"button\" class=\"w-8 min-h-8 h-8 max-w-8 lg:opacity-0 lg:group-hover:opacity-100\"\r\n matIconButton [matTooltip]=\"'\u79FB\u9664'\" (click)=\"deleteRow(i)\">\r\n <mat-icon class=\"icon-size-5\" color=\"warn\" [svgIcon]=\"'heroicons_solid:trash'\"></mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n </td>\r\n </ng-container>\r\n\r\n <tr *matHeaderRowDef=\"displayedColumns\" mat-header-row></tr>\r\n <tr *matRowDef=\"let row; columns: displayedColumns;\" mat-row class=\"group\"></tr>\r\n</table>\r\n\r\n<ng-template #inlineTable>\r\n <div class=\"overflow-y-auto scrollbar-custom w-full\">\r\n <form [formGroup]=\"inlineform\">\r\n <formly-form [fields]=\"fieldArray\" [model]=\"currentMode\" [form]=\"inlineform\"></formly-form>\r\n </form>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #dialogRef>\r\n <div mat-dialog-title cdkDrag class=\"-mt-6\" cdkDragRootElement=\".cdk-overlay-pane\" cdkDragHandle>\r\n <h2 class=\"pointer-events-none text-xl\">{{ props.label +'\u8BE6\u7EC6\u9875'}}</h2>\r\n </div>\r\n\r\n <mat-dialog-content>\r\n <ng-container *ngTemplateOutlet=\"inlineTable\"></ng-container>\r\n </mat-dialog-content>\r\n\r\n <mat-dialog-actions>\r\n <div class=\"w-full flex justify-end items-center\">\r\n <button matButton=\"filled\" color=\"primary\" cdkFocusInitial (click)=\"confirm()\">\r\n \u786E\u5B9A\r\n </button>\r\n <button matButton=\"outlined\" mat-dialog-close>\r\n \u53D6\u6D88\r\n </button>\r\n </div>\r\n </mat-dialog-actions>\r\n</ng-template>\r\n", styles: [":host{width:100%}.mat-column-operate{width:8rem;text-align:center}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i3$2.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i3$2.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i3$2.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i3$2.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i3$2.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i3$2.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i3$2.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i3$2.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i3$2.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i3$2.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$4.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: FormlyModule }, { kind: "component", type: i1$3.LegacyFormlyForm, selector: "formly-form" }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i6.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i6.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i6.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i6.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i7.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1616
+ _openDialog() {
1617
+ const template = this.dialogRef();
1618
+ if (!template)
1619
+ return;
1620
+ this._dialogRef = this._dialog.open(template, {
1621
+ panelClass: ['cmat-table-dialog-container'],
1622
+ viewContainerRef: this._viewContainerRef
1623
+ });
1624
+ this._dialogRef.afterClosed().subscribe(() => {
1625
+ this.dialogType.set('');
1626
+ this.currentIndex.set(-1);
1627
+ });
1628
+ }
1629
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatTableTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1630
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: CmatTableTypeComponent, isStandalone: true, selector: "cmat-table-type", viewQueries: [{ propertyName: "dialogRef", first: true, predicate: ["dialogRef"], descendants: true, isSignal: true }, { propertyName: "table", first: true, predicate: ["table"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"relative flex flex-row flex-none items-center justify-between p-2 border-b\">\r\n <div>\r\n @if(props.label){\r\n <legend class=\"text-lg\">\r\n {{ props.label }}\r\n @if(props.required){\r\n <span>*</span>\r\n }\r\n </legend>\r\n }\r\n @if(props.description){\r\n <p>{{ props.description }}</p>\r\n }\r\n </div>\r\n\r\n <div class=\"cmat-table-type\" [attr.data-refresh]=\"refreshVersion()\">\r\n @if(!props.disabled){\r\n <div class=\"flex shrink-0 items-center ml-0 md:ml-4 print:hidden\">\r\n <button matButton=\"filled\" [color]=\"'primary'\" (click)=\"addRow()\">\r\n <mat-icon [svgIcon]=\"'heroicons_outline:plus'\"></mat-icon>\r\n <span class=\"ml-2\">{{props.addText}}</span>\r\n </button>\r\n </div>\r\n }\r\n </div>\r\n</div>\r\n\r\n<table #table mat-table class=\"w-full\" [dataSource]=\"model||[]\" [tabIndex]=\"props.tabindex\">\r\n @for (column of columns(); track $index) {\r\n <ng-container [matColumnDef]=\"column.key\">\r\n <th *matHeaderCellDef mat-header-cell> {{ column.label }} </th>\r\n <td *matCellDef=\"let element; let i = index\" mat-cell>\r\n <div class=\" has-label-on-mobile\" [attr.data-label]=\"column.label +':'\">\r\n {{element[column.key]}}\r\n </div>\r\n </td>\r\n </ng-container>\r\n }\r\n\r\n <ng-container matColumnDef=\"operate\" stickyEnd>\r\n <th *matHeaderCellDef mat-header-cell class=\"print:hidden\">\u64CD\u4F5C</th>\r\n <td *matCellDef=\"let element; let i = index\" mat-cell class=\"w-24 print:hidden\">\r\n <div class=\"flex flex-col lg:w-full\">\r\n <div class=\"relative flex flex-row gap-2 lg:m-2 justify-center\">\r\n <button type=\"button\" class=\"w-8 min-h-8 h-8 max-w-8 lg:opacity-0 lg:group-hover:opacity-100\"\r\n matIconButton [matTooltip]=\"'\u7F16\u8F91'\" (click)=\"editRow(element,i)\">\r\n <mat-icon class=\"icon-size-5\" color=\"primary\" [svgIcon]=\"'heroicons_solid:pencil-square'\">\r\n </mat-icon>\r\n </button>\r\n\r\n <button type=\"button\" class=\"w-8 min-h-8 h-8 max-w-8 lg:opacity-0 lg:group-hover:opacity-100\"\r\n matIconButton [matTooltip]=\"'\u79FB\u9664'\" (click)=\"deleteRow(i)\">\r\n <mat-icon class=\"icon-size-5\" color=\"warn\" [svgIcon]=\"'heroicons_solid:trash'\"></mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n </td>\r\n </ng-container>\r\n\r\n <tr *matHeaderRowDef=\"displayedColumns()\" mat-header-row></tr>\r\n <tr *matRowDef=\"let row; columns: displayedColumns();\" mat-row class=\"group\"></tr>\r\n</table>\r\n\r\n<ng-template #inlineTable>\r\n <div class=\"overflow-y-auto scrollbar-custom w-full\">\r\n <form [formGroup]=\"inlineform\">\r\n <formly-form [fields]=\"fieldArray\" [model]=\"currentMode()\" [form]=\"inlineform\"></formly-form>\r\n </form>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #dialogRef>\r\n <div mat-dialog-title cdkDrag class=\"-mt-6\" cdkDragRootElement=\".cdk-overlay-pane\" cdkDragHandle>\r\n <h2 class=\"pointer-events-none text-xl\">{{ props.label +'\u8BE6\u7EC6\u9875'}}</h2>\r\n </div>\r\n\r\n <mat-dialog-content>\r\n <ng-container *ngTemplateOutlet=\"inlineTable\"></ng-container>\r\n </mat-dialog-content>\r\n\r\n <mat-dialog-actions>\r\n <div class=\"w-full flex justify-end items-center\">\r\n <button matButton=\"filled\" color=\"primary\" cdkFocusInitial (click)=\"confirm()\">\r\n \u786E\u5B9A\r\n </button>\r\n <button matButton=\"outlined\" mat-dialog-close>\r\n \u53D6\u6D88\r\n </button>\r\n </div>\r\n </mat-dialog-actions>\r\n</ng-template>", styles: [":host{width:100%}.mat-column-operate{width:8rem;text-align:center}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i3$2.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i3$2.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i3$2.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i3$2.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i3$2.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i3$2.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i3$2.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i3$2.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i3$2.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i3$2.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$4.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: FormlyModule }, { kind: "component", type: i1$3.LegacyFormlyForm, selector: "formly-form" }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i6.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i6.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i6.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i6.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i7.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1228
1631
  }
1229
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatTableTypeComponent, decorators: [{
1632
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatTableTypeComponent, decorators: [{
1230
1633
  type: Component,
1231
1634
  args: [{ selector: 'cmat-table-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatButtonModule, MatIconModule, MatTableModule, FormsModule, FormlyModule, CdkDrag,
1232
- ReactiveFormsModule, MatDialogModule, NgTemplateOutlet, MatTooltipModule], template: "<div class=\"relative flex flex-col sm:flex-row flex-none sm:items-center sm:justify-between p-2 border-b mb-1\">\r\n <div>\r\n @if(props.label){\r\n <legend class=\"text-lg\">\r\n {{ props.label }}\r\n @if(props.required){\r\n <span>*</span>\r\n }\r\n </legend>\r\n }\r\n @if(props.description){\r\n <p>{{ props.description }}</p>\r\n }\r\n </div>\r\n\r\n <div class=\"cmat-table-type\" [attr.data-refresh]=\"refreshVersion()\">\r\n @if(!props.disabled){\r\n <div class=\"flex shrink-0 items-center mt-6 sm:mt-0 sm:ml-4 print:hidden\">\r\n <button class=\"ml-4\" matButton=\"filled\" [color]=\"'primary'\" (click)=\"addRow()\">\r\n <mat-icon [svgIcon]=\"'heroicons_outline:plus'\"></mat-icon>\r\n <span class=\"ml-2\">{{props.addText}}</span>\r\n </button>\r\n </div>\r\n }\r\n</div>\r\n\r\n\r\n<table #table mat-table class=\"w-full\" [dataSource]=\"model||[]\" [tabIndex]=\"props.tabindex\">\r\n @for (column of columns; track $index) {\r\n <ng-container [matColumnDef]=\"column.key\">\r\n <th *matHeaderCellDef mat-header-cell> {{ column.label }} </th>\r\n <td *matCellDef=\"let element; let i = index\" mat-cell>\r\n <div class=\" has-label-on-mobile\" [attr.data-label]=\"column.label +':'\">\r\n {{element[column.key]}}\r\n </div>\r\n </td>\r\n </ng-container>\r\n }\r\n\r\n <ng-container matColumnDef=\"operate\" stickyEnd>\r\n <th *matHeaderCellDef mat-header-cell class=\"print:hidden\">\u64CD\u4F5C</th>\r\n <td *matCellDef=\"let element; let i = index\" mat-cell class=\"w-24 print:hidden\">\r\n <div class=\"flex flex-col lg:w-full\">\r\n <div class=\"relative flex flex-row gap-2 lg:m-2 justify-center\">\r\n <button type=\"button\" class=\"w-8 min-h-8 h-8 max-w-8 lg:opacity-0 lg:group-hover:opacity-100\"\r\n matIconButton [matTooltip]=\"'\u7F16\u8F91'\" (click)=\"editRow(element,i)\">\r\n <mat-icon class=\"icon-size-5\" color=\"primary\" [svgIcon]=\"'heroicons_solid:pencil-square'\">\r\n </mat-icon>\r\n </button>\r\n \r\n <button type=\"button\" class=\"w-8 min-h-8 h-8 max-w-8 lg:opacity-0 lg:group-hover:opacity-100\"\r\n matIconButton [matTooltip]=\"'\u79FB\u9664'\" (click)=\"deleteRow(i)\">\r\n <mat-icon class=\"icon-size-5\" color=\"warn\" [svgIcon]=\"'heroicons_solid:trash'\"></mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n </td>\r\n </ng-container>\r\n\r\n <tr *matHeaderRowDef=\"displayedColumns\" mat-header-row></tr>\r\n <tr *matRowDef=\"let row; columns: displayedColumns;\" mat-row class=\"group\"></tr>\r\n</table>\r\n\r\n<ng-template #inlineTable>\r\n <div class=\"overflow-y-auto scrollbar-custom w-full\">\r\n <form [formGroup]=\"inlineform\">\r\n <formly-form [fields]=\"fieldArray\" [model]=\"currentMode\" [form]=\"inlineform\"></formly-form>\r\n </form>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #dialogRef>\r\n <div mat-dialog-title cdkDrag class=\"-mt-6\" cdkDragRootElement=\".cdk-overlay-pane\" cdkDragHandle>\r\n <h2 class=\"pointer-events-none text-xl\">{{ props.label +'\u8BE6\u7EC6\u9875'}}</h2>\r\n </div>\r\n\r\n <mat-dialog-content>\r\n <ng-container *ngTemplateOutlet=\"inlineTable\"></ng-container>\r\n </mat-dialog-content>\r\n\r\n <mat-dialog-actions>\r\n <div class=\"w-full flex justify-end items-center\">\r\n <button matButton=\"filled\" color=\"primary\" cdkFocusInitial (click)=\"confirm()\">\r\n \u786E\u5B9A\r\n </button>\r\n <button matButton=\"outlined\" mat-dialog-close>\r\n \u53D6\u6D88\r\n </button>\r\n </div>\r\n </mat-dialog-actions>\r\n</ng-template>\r\n", styles: [":host{width:100%}.mat-column-operate{width:8rem;text-align:center}\n"] }]
1233
- }], ctorParameters: () => [], propDecorators: { dialogRef: [{
1234
- type: ViewChild,
1235
- args: ['dialogRef']
1236
- }], table: [{
1237
- type: ViewChild,
1238
- args: ['table']
1239
- }] } });
1635
+ ReactiveFormsModule, MatDialogModule, NgTemplateOutlet, MatTooltipModule], template: "<div class=\"relative flex flex-row flex-none items-center justify-between p-2 border-b\">\r\n <div>\r\n @if(props.label){\r\n <legend class=\"text-lg\">\r\n {{ props.label }}\r\n @if(props.required){\r\n <span>*</span>\r\n }\r\n </legend>\r\n }\r\n @if(props.description){\r\n <p>{{ props.description }}</p>\r\n }\r\n </div>\r\n\r\n <div class=\"cmat-table-type\" [attr.data-refresh]=\"refreshVersion()\">\r\n @if(!props.disabled){\r\n <div class=\"flex shrink-0 items-center ml-0 md:ml-4 print:hidden\">\r\n <button matButton=\"filled\" [color]=\"'primary'\" (click)=\"addRow()\">\r\n <mat-icon [svgIcon]=\"'heroicons_outline:plus'\"></mat-icon>\r\n <span class=\"ml-2\">{{props.addText}}</span>\r\n </button>\r\n </div>\r\n }\r\n </div>\r\n</div>\r\n\r\n<table #table mat-table class=\"w-full\" [dataSource]=\"model||[]\" [tabIndex]=\"props.tabindex\">\r\n @for (column of columns(); track $index) {\r\n <ng-container [matColumnDef]=\"column.key\">\r\n <th *matHeaderCellDef mat-header-cell> {{ column.label }} </th>\r\n <td *matCellDef=\"let element; let i = index\" mat-cell>\r\n <div class=\" has-label-on-mobile\" [attr.data-label]=\"column.label +':'\">\r\n {{element[column.key]}}\r\n </div>\r\n </td>\r\n </ng-container>\r\n }\r\n\r\n <ng-container matColumnDef=\"operate\" stickyEnd>\r\n <th *matHeaderCellDef mat-header-cell class=\"print:hidden\">\u64CD\u4F5C</th>\r\n <td *matCellDef=\"let element; let i = index\" mat-cell class=\"w-24 print:hidden\">\r\n <div class=\"flex flex-col lg:w-full\">\r\n <div class=\"relative flex flex-row gap-2 lg:m-2 justify-center\">\r\n <button type=\"button\" class=\"w-8 min-h-8 h-8 max-w-8 lg:opacity-0 lg:group-hover:opacity-100\"\r\n matIconButton [matTooltip]=\"'\u7F16\u8F91'\" (click)=\"editRow(element,i)\">\r\n <mat-icon class=\"icon-size-5\" color=\"primary\" [svgIcon]=\"'heroicons_solid:pencil-square'\">\r\n </mat-icon>\r\n </button>\r\n\r\n <button type=\"button\" class=\"w-8 min-h-8 h-8 max-w-8 lg:opacity-0 lg:group-hover:opacity-100\"\r\n matIconButton [matTooltip]=\"'\u79FB\u9664'\" (click)=\"deleteRow(i)\">\r\n <mat-icon class=\"icon-size-5\" color=\"warn\" [svgIcon]=\"'heroicons_solid:trash'\"></mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n </td>\r\n </ng-container>\r\n\r\n <tr *matHeaderRowDef=\"displayedColumns()\" mat-header-row></tr>\r\n <tr *matRowDef=\"let row; columns: displayedColumns();\" mat-row class=\"group\"></tr>\r\n</table>\r\n\r\n<ng-template #inlineTable>\r\n <div class=\"overflow-y-auto scrollbar-custom w-full\">\r\n <form [formGroup]=\"inlineform\">\r\n <formly-form [fields]=\"fieldArray\" [model]=\"currentMode()\" [form]=\"inlineform\"></formly-form>\r\n </form>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #dialogRef>\r\n <div mat-dialog-title cdkDrag class=\"-mt-6\" cdkDragRootElement=\".cdk-overlay-pane\" cdkDragHandle>\r\n <h2 class=\"pointer-events-none text-xl\">{{ props.label +'\u8BE6\u7EC6\u9875'}}</h2>\r\n </div>\r\n\r\n <mat-dialog-content>\r\n <ng-container *ngTemplateOutlet=\"inlineTable\"></ng-container>\r\n </mat-dialog-content>\r\n\r\n <mat-dialog-actions>\r\n <div class=\"w-full flex justify-end items-center\">\r\n <button matButton=\"filled\" color=\"primary\" cdkFocusInitial (click)=\"confirm()\">\r\n \u786E\u5B9A\r\n </button>\r\n <button matButton=\"outlined\" mat-dialog-close>\r\n \u53D6\u6D88\r\n </button>\r\n </div>\r\n </mat-dialog-actions>\r\n</ng-template>", styles: [":host{width:100%}.mat-column-operate{width:8rem;text-align:center}\n"] }]
1636
+ }], ctorParameters: () => [], propDecorators: { dialogRef: [{ type: i0.ViewChild, args: ['dialogRef', { isSignal: true }] }], table: [{ type: i0.ViewChild, args: ['table', { isSignal: true }] }] } });
1240
1637
 
1241
1638
  class CmatTabTypeComponent extends FieldType$1 {
1242
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatTabTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1243
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: CmatTabTypeComponent, isStandalone: true, selector: "cmat-tab-type", usesInheritance: true, ngImport: i0, template: "<mat-tab-group [tabIndex]=\"props.tabindex\">\r\n @for (tab of field.fieldGroup; track $index) {\r\n <mat-tab [label]=\"tab.props?.label||''\" [disabled]=\"tab.props?.disabled\">\r\n <div class=\"py-2\">\r\n <formly-field [field]=\"tab\"></formly-field>\r\n </div>\r\n </mat-tab>\r\n }\r\n</mat-tab-group>", styles: [":host{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i1$9.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i1$9.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: FormlyModule }, { kind: "component", type: i1$3.LegacyFormlyField, selector: "formly-field" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1639
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatTabTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1640
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: CmatTabTypeComponent, isStandalone: true, selector: "cmat-tab-type", usesInheritance: true, ngImport: i0, template: "<mat-tab-group [tabIndex]=\"props.tabindex\">\r\n @for (tab of field.fieldGroup; track $index) {\r\n <mat-tab [label]=\"tab.props?.label||''\" [disabled]=\"tab.props?.disabled\">\r\n <div class=\"py-2\">\r\n <formly-field [field]=\"tab\"></formly-field>\r\n </div>\r\n </mat-tab>\r\n }\r\n</mat-tab-group>", styles: [":host{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i1$9.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i1$9.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: FormlyModule }, { kind: "component", type: i1$3.LegacyFormlyField, selector: "formly-field" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1244
1641
  }
1245
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatTabTypeComponent, decorators: [{
1642
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatTabTypeComponent, decorators: [{
1246
1643
  type: Component,
1247
1644
  args: [{ selector: 'cmat-tab-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatTabsModule, FormlyModule], template: "<mat-tab-group [tabIndex]=\"props.tabindex\">\r\n @for (tab of field.fieldGroup; track $index) {\r\n <mat-tab [label]=\"tab.props?.label||''\" [disabled]=\"tab.props?.disabled\">\r\n <div class=\"py-2\">\r\n <formly-field [field]=\"tab\"></formly-field>\r\n </div>\r\n </mat-tab>\r\n }\r\n</mat-tab-group>", styles: [":host{width:100%}\n"] }]
1248
1645
  }] });
@@ -1250,71 +1647,72 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
1250
1647
  class CmatTagsTypeComponent extends FieldType {
1251
1648
  constructor() {
1252
1649
  super();
1253
- this.urlData = [];
1254
- this.optionsData = [];
1255
- this.refreshVersion = signal(0, ...(ngDevMode ? [{ debugName: "refreshVersion" }] : /* istanbul ignore next */ []));
1256
- this._http = inject(HttpClient);
1650
+ this.allTags = computed(() => {
1651
+ const domainData = this._urlDataSignal();
1652
+ if (domainData.length > 0) {
1653
+ return domainData;
1654
+ }
1655
+ return this._staticOptionsSignal();
1656
+ }, /* @ts-ignore */
1657
+ ...(ngDevMode ? [{ debugName: "allTags" }] : /* istanbul ignore next */ []));
1658
+ this.filteredItems = signal([], /* @ts-ignore */
1659
+ ...(ngDevMode ? [{ debugName: "filteredItems" }] : /* istanbul ignore next */ []));
1660
+ this.refreshVersion = signal(0, /* @ts-ignore */
1661
+ ...(ngDevMode ? [{ debugName: "refreshVersion" }] : /* istanbul ignore next */ []));
1662
+ this._urlDataSignal = signal([], /* @ts-ignore */
1663
+ ...(ngDevMode ? [{ debugName: "_urlDataSignal" }] : /* istanbul ignore next */ []));
1664
+ this._staticOptionsSignal = signal([], /* @ts-ignore */
1665
+ ...(ngDevMode ? [{ debugName: "_staticOptionsSignal" }] : /* istanbul ignore next */ []));
1666
+ this._tagsPanelOrigin = viewChild('tagsPanelOrigin', /* @ts-ignore */
1667
+ ...(ngDevMode ? [{ debugName: "_tagsPanelOrigin" }] : /* istanbul ignore next */ []));
1668
+ this._tagsPanel = viewChild('tagsPanel', /* @ts-ignore */
1669
+ ...(ngDevMode ? [{ debugName: "_tagsPanel" }] : /* istanbul ignore next */ []));
1670
+ this._lastDomain = undefined;
1671
+ this._lastOptions = undefined;
1257
1672
  this._overlay = inject(Overlay);
1258
1673
  this._viewContainerRef = inject(ViewContainerRef);
1259
1674
  this._destroyRef = inject(DestroyRef);
1260
- this._filteredItems = signal(null, ...(ngDevMode ? [{ debugName: "_filteredItems" }] : /* istanbul ignore next */ []));
1261
- this._filteredItems$ = toObservable(this._filteredItems);
1262
- }
1263
- get filteredItems$() {
1264
- return this._filteredItems$;
1265
- }
1266
- get tags() {
1267
- if (isArray(this.field.props?.options)) {
1268
- return this.urlData?.length > 0 ? this.urlData : this.field.props?.options ?? [];
1269
- }
1270
- else {
1271
- return this.urlData?.length > 0 ? this.urlData : this.optionsData || [];
1272
- }
1675
+ this._domainDataService = inject(DomainDataService);
1273
1676
  }
1274
1677
  ngOnInit() {
1275
- if (this.field.props?.options && !isArray(this.field.props?.options)) {
1276
- this.field.props?.options.pipe(takeUntilDestroyed(this._destroyRef)).subscribe((data) => {
1277
- this.optionsData = data;
1278
- });
1279
- }
1280
- const url = this.field.props?.domain?.url;
1281
- if (url && this.field.props?.domain?.code && this.field.props?.domain?.key && this.field.props?.domain?.value) {
1282
- this._http.get(url).pipe(takeUntilDestroyed(this._destroyRef)).subscribe((data) => {
1283
- if (data) {
1284
- const key = this.field.props?.domain?.key;
1285
- const code = this.field.props?.domain?.code;
1286
- const datas = data.filter((i) => {
1287
- if (key)
1288
- return i[key] === code;
1289
- return false;
1290
- });
1291
- if (datas && this.field.props?.domain?.value) {
1292
- this.urlData = datas[0][this.field.props?.domain?.value] ?? [];
1293
- }
1294
- else {
1295
- this.urlData = [];
1296
- }
1297
- }
1298
- else {
1299
- this.urlData = [];
1300
- }
1301
- this._filteredItems.set(this.tags);
1302
- this.refreshVersion.update(value => value + 1);
1303
- });
1304
- }
1305
- else {
1306
- this.urlData = [];
1307
- this._filteredItems.set(this.tags);
1308
- this.refreshVersion.update(value => value + 1);
1309
- }
1310
- }
1678
+ this._lastDomain = this.props.domain;
1679
+ this._lastOptions = this.field.props?.options;
1680
+ this._refreshDomainData();
1681
+ this._refreshOptionData();
1682
+ }
1683
+ ngDoCheck() {
1684
+ const currentDomain = this.props.domain;
1685
+ const currentOptions = this.field.props?.options;
1686
+ // 1. 检查 domain 变化
1687
+ if (!isEqual(currentDomain, this._lastDomain)) {
1688
+ this._lastDomain = currentDomain;
1689
+ this._refreshDomainData();
1690
+ }
1691
+ // 2. 检查 options 变化 (仅当 domain 未配置时,options 才生效,但为了稳妥,只要变了就更新)
1692
+ // 注意:如果 domain 存在,urlData 优先级更高,但更新 optionsData 也无妨,因为 allOptions computed 会优先取 urlData
1693
+ if (!isEqual(currentOptions, this._lastOptions)) {
1694
+ this._lastOptions = currentOptions;
1695
+ this._refreshOptionData();
1696
+ }
1697
+ }
1698
+ // --- 业务逻辑方法 ---
1311
1699
  openTagsPanel() {
1700
+ // 每次打开时,重置过滤列表为所有可用标签
1701
+ this._syncFilteredItems();
1702
+ const origin = this._tagsPanelOrigin();
1703
+ const template = this._tagsPanel();
1704
+ if (!origin || !template)
1705
+ return;
1706
+ // 如果已经打开,先关闭
1707
+ if (this._tagsPanelOverlayRef?.hasAttached()) {
1708
+ this._tagsPanelOverlayRef.detach();
1709
+ }
1312
1710
  this._tagsPanelOverlayRef = this._overlay.create({
1313
1711
  backdropClass: '',
1314
1712
  hasBackdrop: true,
1315
1713
  scrollStrategy: this._overlay.scrollStrategies.block(),
1316
1714
  positionStrategy: this._overlay.position()
1317
- .flexibleConnectedTo(this._tagsPanelOrigin.nativeElement)
1715
+ .flexibleConnectedTo(origin.nativeElement)
1318
1716
  .withFlexibleDimensions(true)
1319
1717
  .withViewportMargin(64)
1320
1718
  .withLockedPosition(true)
@@ -1327,59 +1725,92 @@ class CmatTagsTypeComponent extends FieldType {
1327
1725
  }
1328
1726
  ])
1329
1727
  });
1330
- this._tagsPanelOverlayRef.attachments().subscribe(() => {
1331
- this._tagsPanelOverlayRef.overlayElement.querySelector('input')?.focus();
1332
- });
1333
- const templatePortal = new TemplatePortal(this._tagsPanel, this._viewContainerRef);
1728
+ const templatePortal = new TemplatePortal(template, this._viewContainerRef);
1334
1729
  this._tagsPanelOverlayRef.attach(templatePortal);
1730
+ // 聚焦输入框
1731
+ setTimeout(() => {
1732
+ this._tagsPanelOverlayRef.overlayElement.querySelector('input')?.focus();
1733
+ }, 0);
1335
1734
  this._tagsPanelOverlayRef.backdropClick().subscribe(() => {
1336
- if (this._tagsPanelOverlayRef?.hasAttached()) {
1337
- this._tagsPanelOverlayRef.detach();
1338
- this._filteredItems.set(this.tags);
1339
- this.refreshVersion.update(value => value + 1);
1340
- }
1341
- if (templatePortal?.isAttached) {
1342
- templatePortal.detach();
1343
- }
1735
+ this.closeTagsPanel();
1344
1736
  });
1345
1737
  }
1738
+ closeTagsPanel() {
1739
+ if (this._tagsPanelOverlayRef?.hasAttached()) {
1740
+ this._tagsPanelOverlayRef.detach();
1741
+ this._tagsPanelOverlayRef.dispose();
1742
+ }
1743
+ }
1346
1744
  filterTags(event) {
1347
1745
  const value = (event.target?.value ?? '').toLowerCase();
1348
- this._filteredItems.set(this.tags.filter((tag) => this._toSearchText(tag.label).toLowerCase().includes(value) || this._toSearchText(tag.value).toLowerCase().includes(value)));
1746
+ const all = this.allTags();
1747
+ if (!value) {
1748
+ this.filteredItems.set(all);
1749
+ return;
1750
+ }
1751
+ const filtered = all.filter((tag) => this._toSearchText(tag.label).toLowerCase().includes(value) ||
1752
+ this._toSearchText(tag.value).toLowerCase().includes(value));
1753
+ this.filteredItems.set(filtered);
1349
1754
  }
1350
1755
  toggleTag(tag) {
1351
1756
  if (tag.disabled)
1352
1757
  return;
1353
- const data = this.formControl.value ?? [];
1354
- const existsTag = data.findIndex((i) => i.value === tag.value);
1355
- if (existsTag > -1) {
1356
- data.splice(existsTag, 1);
1758
+ const currentVal = this.formControl.value ?? [];
1759
+ // 使用不可变方式更新数组
1760
+ const existsIndex = currentVal.findIndex((i) => i.value === tag.value);
1761
+ let newVal;
1762
+ if (existsIndex > -1) {
1763
+ newVal = currentVal.filter((_, index) => index !== existsIndex);
1357
1764
  }
1358
1765
  else {
1359
- data.unshift(tag);
1766
+ newVal = [tag, ...currentVal];
1360
1767
  }
1361
- this.formControl.setValue(data);
1362
- this.refreshVersion.update(value => value + 1);
1768
+ this.formControl.setValue(newVal);
1769
+ this.refreshVersion.update(v => v + 1);
1363
1770
  }
1364
1771
  isCheck(tag) {
1365
- return (this.formControl.value?.filter((i) => i.value === tag.value).length ?? 0) > 0;
1772
+ const currentVal = this.formControl.value;
1773
+ if (!currentVal)
1774
+ return false;
1775
+ return currentVal.some((i) => i.value === tag.value);
1776
+ }
1777
+ _syncFilteredItems() {
1778
+ this.filteredItems.set(this.allTags());
1366
1779
  }
1367
1780
  _toSearchText(value) {
1368
1781
  return typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean' ? String(value) : '';
1369
1782
  }
1370
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatTagsTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1371
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: CmatTagsTypeComponent, isStandalone: true, selector: "cmat-tags-type", viewQueries: [{ propertyName: "_tagsPanelOrigin", first: true, predicate: ["tagsPanelOrigin"], descendants: true }, { propertyName: "_tagsPanel", first: true, predicate: ["tagsPanel"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"text-lg mb-2\">\r\n {{ props.label }}\r\n @if(props.required){\r\n <span>*</span>\r\n }\r\n</div>\r\n<div class=\"flex flex-wrap items-center -m-2\" [attr.data-refresh]=\"refreshVersion()\" [tabIndex]=\"props.tabindex\">\r\n <ng-container>\r\n @for (selectedItem of formControl.value; track $index) {\r\n <div\r\n class=\"flex items-center justify-center px-4 m-1.5 rounded-full leading-9 text-gray-500 bg-slate-100 dark:text-gray-300 dark:bg-slate-700\">\r\n <span class=\"text-md font-medium whitespace-nowrap\">{{selectedItem.label}}</span>\r\n </div>\r\n }\r\n\r\n <div #tagsPanelOrigin\r\n class=\"flex items-center justify-center px-4 m-1.5 rounded-full leading-9 cursor-pointer text-gray-500 bg-slate-100 dark:text-gray-300 dark:bg-slate-700 print:hidden\" role=\"presentation\" (click)=\"openTagsPanel()\">\r\n\r\n @if(formControl.value?.length&&!disabled){\r\n <mat-icon class=\"icon-size-5\" [svgIcon]=\"'heroicons_solid:pencil-square'\"></mat-icon>\r\n <span class=\"ml-1.5 text-md font-medium whitespace-nowrap\">\u7F16\u8F91</span>\r\n }\r\n\r\n @if(!formControl.value?.length&&!disabled){\r\n <mat-icon class=\"icon-size-5\" [svgIcon]=\"'heroicons_solid:plus-circle'\"></mat-icon>\r\n <span class=\"ml-1.5 text-md font-medium whitespace-nowrap\">\u65B0\u589E</span>\r\n }\r\n\r\n <ng-template #tagsPanel>\r\n <div class=\"w-60 rounded-sm border shadow-md bg-card\">\r\n <div class=\"flex items-center m-3 mr-2\">\r\n <div class=\"flex items-center\">\r\n <mat-icon class=\"icon-size-5\" [svgIcon]=\"'heroicons_solid:magnifying-glass'\">\r\n </mat-icon>\r\n <div class=\"ml-2\">\r\n <input class=\"w-full min-w-0 py-1 border-none\" type=\"text\" placeholder=\"\u8F93\u5165\u6807\u7B7E\u540D\"\r\n [maxLength]=\"30\" (input)=\"filterTags($event)\">\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"flex flex-col max-h-64 py-2 border-t overflow-y-auto scrollbar-custom\">\r\n @if ((filteredItems$ | async); as filteredItems) {\r\n @if(filteredItems.length>0){\r\n @for (tag of filteredItems; track $index) {\r\n <div role=\"presentation\"\r\n class=\"flex items-center h-10 min-h-10 pl-1 pr-4 cursor-pointer hover:bg-hover\"\r\n matRipple (click)=\"toggleTag(tag)\">\r\n <mat-checkbox class=\"flex items-center h-10 min-h-10\" [color]=\"'primary'\"\r\n [disabled]=\"tag.disabled\" [checked]=\"isCheck(tag)\">\r\n {{tag.label}}\r\n </mat-checkbox>\r\n </div>\r\n }\r\n }@else {\r\n <div class=\"flex flex-auto flex-col justify-center px-4 h-10 min-h-10\">\r\n \u65E0\u7ED3\u679C\r\n </div>\r\n }\r\n }\r\n </div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </ng-container>\r\n</div>\r\n", styles: [":host{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i1$5.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1783
+ _refreshDomainData() {
1784
+ const domain = this.props.domain;
1785
+ // 使用 DomainDataService 加载远程数据
1786
+ this._domainDataService.load(domain, this._destroyRef, {
1787
+ onSuccess: (data) => {
1788
+ this._urlDataSignal.set(data);
1789
+ this._syncFilteredItems();
1790
+ },
1791
+ componentName: 'CmatTagsTypeComponent'
1792
+ });
1793
+ }
1794
+ _refreshOptionData() {
1795
+ if (isArray(this.field.props?.options)) {
1796
+ this._staticOptionsSignal.set(this.field.props?.options);
1797
+ this._syncFilteredItems();
1798
+ }
1799
+ else if (this.field.props?.options && !isArray(this.field.props?.options)) {
1800
+ // 处理 Observable options
1801
+ this.field.props.options.pipe(takeUntilDestroyed(this._destroyRef)).subscribe((data) => {
1802
+ this._staticOptionsSignal.set(data || []);
1803
+ this._syncFilteredItems();
1804
+ });
1805
+ }
1806
+ }
1807
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatTagsTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1808
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: CmatTagsTypeComponent, isStandalone: true, selector: "cmat-tags-type", viewQueries: [{ propertyName: "_tagsPanelOrigin", first: true, predicate: ["tagsPanelOrigin"], descendants: true, isSignal: true }, { propertyName: "_tagsPanel", first: true, predicate: ["tagsPanel"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"text-lg mb-2\">\r\n {{ props.label }}\r\n @if(props.required){\r\n <span>*</span>\r\n }\r\n</div>\r\n<div class=\"flex flex-wrap items-center -m-2\" [attr.data-refresh]=\"refreshVersion()\" [tabIndex]=\"props.tabindex\">\r\n <ng-container>\r\n @for (selectedItem of formControl.value; track selectedItem.value || $index) {\r\n <div\r\n class=\"flex items-center justify-center px-4 m-1.5 rounded-full leading-9 text-gray-500 bg-slate-100 dark:text-gray-300 dark:bg-slate-700\">\r\n <span class=\"text-md font-medium whitespace-nowrap\">{{selectedItem.label}}</span>\r\n </div>\r\n }\r\n\r\n <div #tagsPanelOrigin\r\n class=\"flex items-center justify-center px-4 m-1.5 rounded-full leading-9 cursor-pointer text-gray-500 bg-slate-100 dark:text-gray-300 dark:bg-slate-700 print:hidden\" \r\n role=\"presentation\" \r\n (click)=\"openTagsPanel()\">\r\n\r\n @if(formControl.value?.length && !disabled){\r\n <mat-icon class=\"icon-size-5\" [svgIcon]=\"'heroicons_solid:pencil-square'\"></mat-icon>\r\n <span class=\"ml-1.5 text-md font-medium whitespace-nowrap\">\u7F16\u8F91</span>\r\n }\r\n\r\n @if(!formControl.value?.length && !disabled){\r\n <mat-icon class=\"icon-size-5\" [svgIcon]=\"'heroicons_solid:plus-circle'\"></mat-icon>\r\n <span class=\"ml-1.5 text-md font-medium whitespace-nowrap\">\u65B0\u589E</span>\r\n }\r\n\r\n <ng-template #tagsPanel>\r\n <div class=\"w-60 rounded-sm border shadow-md bg-card\">\r\n <div class=\"flex items-center m-3 mr-2\">\r\n <div class=\"flex items-center\">\r\n <mat-icon class=\"icon-size-5\" [svgIcon]=\"'heroicons_solid:magnifying-glass'\">\r\n </mat-icon>\r\n <div class=\"ml-2\">\r\n <input class=\"w-full min-w-0 py-1 border-none\" type=\"text\" placeholder=\"\u8F93\u5165\u6807\u7B7E\u540D\"\r\n [maxLength]=\"30\" (input)=\"filterTags($event)\">\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"flex flex-col max-h-64 py-2 border-t overflow-y-auto scrollbar-custom\">\r\n @if (filteredItems().length > 0) {\r\n @for (tag of filteredItems(); track tag.value || $index) {\r\n <div role=\"presentation\"\r\n class=\"flex items-center h-10 min-h-10 pl-1 pr-4 cursor-pointer hover:bg-hover\"\r\n matRipple [matRippleDisabled]=\"disabled\" (click)=\"toggleTag(tag)\">\r\n <mat-checkbox class=\"flex items-center h-10 min-h-10\" [color]=\"'primary'\"\r\n [disabled]=\"tag.disabled\" [checked]=\"isCheck(tag)\">\r\n {{tag.label}}\r\n </mat-checkbox>\r\n </div>\r\n }\r\n } @else {\r\n <div class=\"flex flex-auto flex-col justify-center px-4 h-10 min-h-10\">\r\n \u65E0\u7ED3\u679C\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </ng-container>\r\n</div>", styles: [":host{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i1$5.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatRippleModule }, { kind: "directive", type: i3$1.MatRipple, selector: "[mat-ripple], [matRipple]", inputs: ["matRippleColor", "matRippleUnbounded", "matRippleCentered", "matRippleRadius", "matRippleAnimation", "matRippleDisabled", "matRippleTrigger"], exportAs: ["matRipple"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1372
1809
  }
1373
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatTagsTypeComponent, decorators: [{
1810
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatTagsTypeComponent, decorators: [{
1374
1811
  type: Component,
1375
- args: [{ selector: 'cmat-tags-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatIconModule, MatCheckboxModule, AsyncPipe], template: "<div class=\"text-lg mb-2\">\r\n {{ props.label }}\r\n @if(props.required){\r\n <span>*</span>\r\n }\r\n</div>\r\n<div class=\"flex flex-wrap items-center -m-2\" [attr.data-refresh]=\"refreshVersion()\" [tabIndex]=\"props.tabindex\">\r\n <ng-container>\r\n @for (selectedItem of formControl.value; track $index) {\r\n <div\r\n class=\"flex items-center justify-center px-4 m-1.5 rounded-full leading-9 text-gray-500 bg-slate-100 dark:text-gray-300 dark:bg-slate-700\">\r\n <span class=\"text-md font-medium whitespace-nowrap\">{{selectedItem.label}}</span>\r\n </div>\r\n }\r\n\r\n <div #tagsPanelOrigin\r\n class=\"flex items-center justify-center px-4 m-1.5 rounded-full leading-9 cursor-pointer text-gray-500 bg-slate-100 dark:text-gray-300 dark:bg-slate-700 print:hidden\" role=\"presentation\" (click)=\"openTagsPanel()\">\r\n\r\n @if(formControl.value?.length&&!disabled){\r\n <mat-icon class=\"icon-size-5\" [svgIcon]=\"'heroicons_solid:pencil-square'\"></mat-icon>\r\n <span class=\"ml-1.5 text-md font-medium whitespace-nowrap\">\u7F16\u8F91</span>\r\n }\r\n\r\n @if(!formControl.value?.length&&!disabled){\r\n <mat-icon class=\"icon-size-5\" [svgIcon]=\"'heroicons_solid:plus-circle'\"></mat-icon>\r\n <span class=\"ml-1.5 text-md font-medium whitespace-nowrap\">\u65B0\u589E</span>\r\n }\r\n\r\n <ng-template #tagsPanel>\r\n <div class=\"w-60 rounded-sm border shadow-md bg-card\">\r\n <div class=\"flex items-center m-3 mr-2\">\r\n <div class=\"flex items-center\">\r\n <mat-icon class=\"icon-size-5\" [svgIcon]=\"'heroicons_solid:magnifying-glass'\">\r\n </mat-icon>\r\n <div class=\"ml-2\">\r\n <input class=\"w-full min-w-0 py-1 border-none\" type=\"text\" placeholder=\"\u8F93\u5165\u6807\u7B7E\u540D\"\r\n [maxLength]=\"30\" (input)=\"filterTags($event)\">\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"flex flex-col max-h-64 py-2 border-t overflow-y-auto scrollbar-custom\">\r\n @if ((filteredItems$ | async); as filteredItems) {\r\n @if(filteredItems.length>0){\r\n @for (tag of filteredItems; track $index) {\r\n <div role=\"presentation\"\r\n class=\"flex items-center h-10 min-h-10 pl-1 pr-4 cursor-pointer hover:bg-hover\"\r\n matRipple (click)=\"toggleTag(tag)\">\r\n <mat-checkbox class=\"flex items-center h-10 min-h-10\" [color]=\"'primary'\"\r\n [disabled]=\"tag.disabled\" [checked]=\"isCheck(tag)\">\r\n {{tag.label}}\r\n </mat-checkbox>\r\n </div>\r\n }\r\n }@else {\r\n <div class=\"flex flex-auto flex-col justify-center px-4 h-10 min-h-10\">\r\n \u65E0\u7ED3\u679C\r\n </div>\r\n }\r\n }\r\n </div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </ng-container>\r\n</div>\r\n", styles: [":host{width:100%}\n"] }]
1376
- }], ctorParameters: () => [], propDecorators: { _tagsPanelOrigin: [{
1377
- type: ViewChild,
1378
- args: ['tagsPanelOrigin']
1379
- }], _tagsPanel: [{
1380
- type: ViewChild,
1381
- args: ['tagsPanel']
1382
- }] } });
1812
+ args: [{ selector: 'cmat-tags-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatIconModule, MatCheckboxModule, MatRippleModule], template: "<div class=\"text-lg mb-2\">\r\n {{ props.label }}\r\n @if(props.required){\r\n <span>*</span>\r\n }\r\n</div>\r\n<div class=\"flex flex-wrap items-center -m-2\" [attr.data-refresh]=\"refreshVersion()\" [tabIndex]=\"props.tabindex\">\r\n <ng-container>\r\n @for (selectedItem of formControl.value; track selectedItem.value || $index) {\r\n <div\r\n class=\"flex items-center justify-center px-4 m-1.5 rounded-full leading-9 text-gray-500 bg-slate-100 dark:text-gray-300 dark:bg-slate-700\">\r\n <span class=\"text-md font-medium whitespace-nowrap\">{{selectedItem.label}}</span>\r\n </div>\r\n }\r\n\r\n <div #tagsPanelOrigin\r\n class=\"flex items-center justify-center px-4 m-1.5 rounded-full leading-9 cursor-pointer text-gray-500 bg-slate-100 dark:text-gray-300 dark:bg-slate-700 print:hidden\" \r\n role=\"presentation\" \r\n (click)=\"openTagsPanel()\">\r\n\r\n @if(formControl.value?.length && !disabled){\r\n <mat-icon class=\"icon-size-5\" [svgIcon]=\"'heroicons_solid:pencil-square'\"></mat-icon>\r\n <span class=\"ml-1.5 text-md font-medium whitespace-nowrap\">\u7F16\u8F91</span>\r\n }\r\n\r\n @if(!formControl.value?.length && !disabled){\r\n <mat-icon class=\"icon-size-5\" [svgIcon]=\"'heroicons_solid:plus-circle'\"></mat-icon>\r\n <span class=\"ml-1.5 text-md font-medium whitespace-nowrap\">\u65B0\u589E</span>\r\n }\r\n\r\n <ng-template #tagsPanel>\r\n <div class=\"w-60 rounded-sm border shadow-md bg-card\">\r\n <div class=\"flex items-center m-3 mr-2\">\r\n <div class=\"flex items-center\">\r\n <mat-icon class=\"icon-size-5\" [svgIcon]=\"'heroicons_solid:magnifying-glass'\">\r\n </mat-icon>\r\n <div class=\"ml-2\">\r\n <input class=\"w-full min-w-0 py-1 border-none\" type=\"text\" placeholder=\"\u8F93\u5165\u6807\u7B7E\u540D\"\r\n [maxLength]=\"30\" (input)=\"filterTags($event)\">\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"flex flex-col max-h-64 py-2 border-t overflow-y-auto scrollbar-custom\">\r\n @if (filteredItems().length > 0) {\r\n @for (tag of filteredItems(); track tag.value || $index) {\r\n <div role=\"presentation\"\r\n class=\"flex items-center h-10 min-h-10 pl-1 pr-4 cursor-pointer hover:bg-hover\"\r\n matRipple [matRippleDisabled]=\"disabled\" (click)=\"toggleTag(tag)\">\r\n <mat-checkbox class=\"flex items-center h-10 min-h-10\" [color]=\"'primary'\"\r\n [disabled]=\"tag.disabled\" [checked]=\"isCheck(tag)\">\r\n {{tag.label}}\r\n </mat-checkbox>\r\n </div>\r\n }\r\n } @else {\r\n <div class=\"flex flex-auto flex-col justify-center px-4 h-10 min-h-10\">\r\n \u65E0\u7ED3\u679C\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </ng-container>\r\n</div>", styles: [":host{width:100%}\n"] }]
1813
+ }], ctorParameters: () => [], propDecorators: { _tagsPanelOrigin: [{ type: i0.ViewChild, args: ['tagsPanelOrigin', { isSignal: true }] }], _tagsPanel: [{ type: i0.ViewChild, args: ['tagsPanel', { isSignal: true }] }] } });
1383
1814
 
1384
1815
  class CmatTextareaTypeComponent extends FieldType$1 {
1385
1816
  constructor() {
@@ -1391,10 +1822,10 @@ class CmatTextareaTypeComponent extends FieldType$1 {
1391
1822
  },
1392
1823
  };
1393
1824
  }
1394
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatTextareaTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1395
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.11", type: CmatTextareaTypeComponent, isStandalone: true, selector: "cmat-textarea-type", usesInheritance: true, ngImport: i0, template: "<textarea matInput [placeholder]=\"placeholder\" \r\n [readonly]=\"props.readonly\" [errorStateMatcher]=\"errorStateMatcher\"\r\n [cols]=\"props.cols\"\r\n [rows]=\"props.rows\"\r\n [tabindex]=\"props.tabindex\"\r\n [formControl]=\"formControl\" [required]=\"required\">\r\n</textarea>", styles: [":host{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i1$6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1825
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatTextareaTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1826
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.6", type: CmatTextareaTypeComponent, isStandalone: true, selector: "cmat-textarea-type", usesInheritance: true, ngImport: i0, template: "<textarea matInput [placeholder]=\"placeholder\" \r\n [readonly]=\"props.readonly\" [errorStateMatcher]=\"errorStateMatcher\"\r\n [cols]=\"props.cols\"\r\n [rows]=\"props.rows\"\r\n [tabindex]=\"props.tabindex\"\r\n [formControl]=\"formControl\" [required]=\"required\">\r\n</textarea>", styles: [":host{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i1$6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1396
1827
  }
1397
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatTextareaTypeComponent, decorators: [{
1828
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatTextareaTypeComponent, decorators: [{
1398
1829
  type: Component,
1399
1830
  args: [{ selector: 'cmat-textarea-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatInputModule, ReactiveFormsModule], template: "<textarea matInput [placeholder]=\"placeholder\" \r\n [readonly]=\"props.readonly\" [errorStateMatcher]=\"errorStateMatcher\"\r\n [cols]=\"props.cols\"\r\n [rows]=\"props.rows\"\r\n [tabindex]=\"props.tabindex\"\r\n [formControl]=\"formControl\" [required]=\"required\">\r\n</textarea>", styles: [":host{width:100%}\n"] }]
1400
1831
  }] });
@@ -1413,53 +1844,110 @@ class CmatUploadTypeComponent extends FieldType {
1413
1844
  autoUpload: true
1414
1845
  }
1415
1846
  };
1847
+ this._rootGroup = null;
1416
1848
  }
1417
- ngAfterViewInit() {
1418
- if (!this.baseGroup)
1419
- this.baseGroup = this._getRootControl(this.formControl);
1420
- if (!this.baseGroup.contains('uploadId')) {
1421
- this.baseGroup.addControl('uploadId', new FormControl([]));
1422
- this.baseGroup.addControl('removeId', new FormControl([]));
1849
+ ngOnInit() {
1850
+ this._rootGroup = this._getRootGroup(this.field);
1851
+ if (this._rootGroup) {
1852
+ if (!this._rootGroup.contains('uploadId')) {
1853
+ this._rootGroup.addControl('uploadId', new FormControl([]));
1854
+ }
1855
+ if (!this._rootGroup.contains('removeId')) {
1856
+ this._rootGroup.addControl('removeId', new FormControl([]));
1857
+ }
1423
1858
  }
1424
1859
  }
1860
+ /**
1861
+ * 处理上传成功事件
1862
+ * @param id 新上传文件的 ID
1863
+ */
1425
1864
  upload(id) {
1426
- const rootValue = this.baseGroup.get('uploadId')?.value;
1427
- if (rootValue && !isNil(id)) {
1428
- this.baseGroup.get('uploadId')?.setValue([id, ...rootValue]);
1865
+ if (!id || !this._rootGroup)
1866
+ return;
1867
+ const control = this._rootGroup.get('uploadId');
1868
+ if (control) {
1869
+ const currentIds = control.value || [];
1870
+ // 避免重复添加
1871
+ if (!currentIds.includes(id)) {
1872
+ control.setValue([id, ...currentIds]);
1873
+ }
1429
1874
  }
1430
1875
  }
1876
+ /**
1877
+ * 处理移除事件
1878
+ * @param id 被移除文件的 ID
1879
+ */
1431
1880
  remove(id) {
1432
- const rootValue = this.baseGroup.get('removeId')?.value;
1433
- if (rootValue && !isNil(id)) {
1434
- this.baseGroup.get('removeId')?.setValue([id, ...rootValue]);
1881
+ if (!id || !this._rootGroup)
1882
+ return;
1883
+ const control = this._rootGroup.get('removeId');
1884
+ if (control) {
1885
+ const currentIds = control.value || [];
1886
+ // 避免重复添加
1887
+ if (!currentIds.includes(id)) {
1888
+ control.setValue([id, ...currentIds]);
1889
+ }
1435
1890
  }
1436
1891
  }
1437
- updateData(i) {
1438
- const data = Array.isArray(i) ? i : [i];
1439
- this.formControl.setValue(data.map((j) => {
1440
- if (typeof j === 'object' && j !== null && 'id' in j && typeof j.id === 'string')
1441
- return {
1442
- id: String((j).id),
1443
- name: typeof j.name === 'string' ? j.name : '',
1444
- type: typeof j.type === 'string' ? j.type : '',
1445
- size: Number(j.size ?? 0)
1446
- };
1447
- else
1448
- return j;
1449
- }));
1450
- }
1451
- _getRootControl(baseControl) {
1452
- if (baseControl.parent) {
1453
- return this._getRootControl(baseControl.parent);
1454
- }
1455
- return baseControl;
1892
+ /**
1893
+ * 处理文件列表更新事件
1894
+ * @param data 文件数据数组或单个对象
1895
+ */
1896
+ updateData(data) {
1897
+ const items = Array.isArray(data) ? data : [data];
1898
+ const standardizedFiles = items.map(item => this._standardizeFileItem(item));
1899
+ // 过滤掉无效项
1900
+ const validFiles = standardizedFiles.filter((item) => item !== null);
1901
+ this.formControl.setValue(validFiles);
1902
+ }
1903
+ /**
1904
+ * 递归查找根 FormGroup
1905
+ * @param field 当前 Formly 字段
1906
+ * @returns 根 FormGroup
1907
+ */
1908
+ _getRootGroup(field) {
1909
+ // Formly 字段通常有 parent 属性指向父字段,直到根字段
1910
+ // 根字段的 form 属性通常是根 FormGroup
1911
+ let currentField = field;
1912
+ while (currentField.parent) {
1913
+ currentField = currentField.parent;
1914
+ }
1915
+ // 尝试从根字段获取 form,或者直接使用 field.form 如果它是根
1916
+ // 注意:在某些 Formly 配置中,field.form 可能始终指向根表单
1917
+ if (currentField.form && currentField.form instanceof UntypedFormGroup) {
1918
+ return currentField.form;
1919
+ }
1920
+ // fallback: 如果找不到,返回 null,调用者需处理
1921
+ return null;
1922
+ }
1923
+ /**
1924
+ * 标准化文件对象,确保包含必要的字段
1925
+ * @param item 原始文件数据
1926
+ * @returns 标准化的文件对象或 null(如果无效)
1927
+ */
1928
+ _standardizeFileItem(item) {
1929
+ if (typeof item !== 'object' || item === null) {
1930
+ return null;
1931
+ }
1932
+ const obj = item;
1933
+ if (typeof obj.id !== 'string') {
1934
+ return null;
1935
+ }
1936
+ return {
1937
+ id: obj.id,
1938
+ name: typeof obj.name === 'string' ? obj.name : '',
1939
+ type: typeof obj.type === 'string' ? obj.type : '',
1940
+ size: typeof obj.size === 'number' ? obj.size : 0,
1941
+ // 保留其他额外属性
1942
+ ...obj
1943
+ };
1456
1944
  }
1457
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatUploadTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1458
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.11", type: CmatUploadTypeComponent, isStandalone: true, selector: "cmat-upload-type", usesInheritance: true, ngImport: i0, template: "<cmat-upload-queue [tabindex]=\"props.tabindex\" [fileAlias]=\"props.fileAlias\"\r\n [filePath]=\"props.filePath\" [required]=\"required\" [fileCategory]=\"props.fileCategory\" [multiple]=\"props.multiple\"\r\n [accept]=\"props.accept\" [title]=\"props.label??'\u9644\u4EF6'\" [editMode]=\"props.editMode&&!disabled\" [filesData]=\"formControl.value\"\r\n [autoUpload]=\"props.autoUpload\" (outputUploadIdEvent)=\"upload($event)\" (outputRemoveIdEvent)=\"remove($event)\" (outputFilesDataEvent)=\"updateData($event)\">\r\n</cmat-upload-queue>", styles: [":host{width:100%}\n"], dependencies: [{ kind: "component", type: CmatUploadQueueComponent, selector: "cmat-upload-queue", inputs: ["fileAlias", "filePath", "fileCategory", "isPublic", "required", "autoUpload", "multiple", "accept", "title", "editMode", "filesData"], outputs: ["outputRemoveIdEvent", "outputUploadIdEvent", "outputFilesDataEvent"], exportAs: ["cmatUploadQueue"] }, { kind: "ngmodule", type: ReactiveFormsModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1945
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatUploadTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1946
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.6", type: CmatUploadTypeComponent, isStandalone: true, selector: "cmat-upload-type", usesInheritance: true, ngImport: i0, template: "<cmat-upload-queue \r\n [tabindex]=\"props.tabindex\" \r\n [fileAlias]=\"props.fileAlias\"\r\n [filePath]=\"props.filePath\" \r\n [required]=\"required\" \r\n [fileCategory]=\"props.fileCategory\" \r\n [multiple]=\"props.multiple\"\r\n [accept]=\"props.accept\" \r\n [title]=\"props.label ?? '\u9644\u4EF6'\" \r\n [editMode]=\"props.editMode && !disabled\" \r\n [filesData]=\"formControl.value\"\r\n [autoUpload]=\"props.autoUpload\" \r\n (outputUploadIdEvent)=\"upload($event)\" \r\n (outputRemoveIdEvent)=\"remove($event)\" \r\n (outputFilesDataEvent)=\"updateData($event)\">\r\n</cmat-upload-queue>", styles: [":host{width:100%}\n"], dependencies: [{ kind: "component", type: CmatUploadQueueComponent, selector: "cmat-upload-queue", inputs: ["fileAlias", "filePath", "fileCategory", "isPublic", "required", "autoUpload", "multiple", "accept", "title", "editMode", "filesData"], outputs: ["outputRemoveIdEvent", "outputUploadIdEvent", "outputFilesDataEvent", "filesDataChange"], exportAs: ["cmatUploadQueue"] }, { kind: "ngmodule", type: ReactiveFormsModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1459
1947
  }
1460
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatUploadTypeComponent, decorators: [{
1948
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatUploadTypeComponent, decorators: [{
1461
1949
  type: Component,
1462
- args: [{ selector: 'cmat-upload-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CmatUploadQueueComponent, ReactiveFormsModule], template: "<cmat-upload-queue [tabindex]=\"props.tabindex\" [fileAlias]=\"props.fileAlias\"\r\n [filePath]=\"props.filePath\" [required]=\"required\" [fileCategory]=\"props.fileCategory\" [multiple]=\"props.multiple\"\r\n [accept]=\"props.accept\" [title]=\"props.label??'\u9644\u4EF6'\" [editMode]=\"props.editMode&&!disabled\" [filesData]=\"formControl.value\"\r\n [autoUpload]=\"props.autoUpload\" (outputUploadIdEvent)=\"upload($event)\" (outputRemoveIdEvent)=\"remove($event)\" (outputFilesDataEvent)=\"updateData($event)\">\r\n</cmat-upload-queue>", styles: [":host{width:100%}\n"] }]
1950
+ args: [{ selector: 'cmat-upload-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CmatUploadQueueComponent, ReactiveFormsModule], template: "<cmat-upload-queue \r\n [tabindex]=\"props.tabindex\" \r\n [fileAlias]=\"props.fileAlias\"\r\n [filePath]=\"props.filePath\" \r\n [required]=\"required\" \r\n [fileCategory]=\"props.fileCategory\" \r\n [multiple]=\"props.multiple\"\r\n [accept]=\"props.accept\" \r\n [title]=\"props.label ?? '\u9644\u4EF6'\" \r\n [editMode]=\"props.editMode && !disabled\" \r\n [filesData]=\"formControl.value\"\r\n [autoUpload]=\"props.autoUpload\" \r\n (outputUploadIdEvent)=\"upload($event)\" \r\n (outputRemoveIdEvent)=\"remove($event)\" \r\n (outputFilesDataEvent)=\"updateData($event)\">\r\n</cmat-upload-queue>", styles: [":host{width:100%}\n"] }]
1463
1951
  }] });
1464
1952
 
1465
1953
  Quill.register('modules/blotFormatter', BlotFormatter);
@@ -1500,16 +1988,20 @@ class CmatQuillTypeComponent extends FieldType {
1500
1988
  filePath: 'path'
1501
1989
  }
1502
1990
  };
1503
- this.refreshVersion = signal(0, ...(ngDevMode ? [{ debugName: "refreshVersion" }] : /* istanbul ignore next */ []));
1991
+ this.isExporting = signal(false, /* @ts-ignore */
1992
+ ...(ngDevMode ? [{ debugName: "isExporting" }] : /* istanbul ignore next */ []));
1993
+ this.imgInput = viewChild('imgInput', /* @ts-ignore */
1994
+ ...(ngDevMode ? [{ debugName: "imgInput" }] : /* istanbul ignore next */ []));
1995
+ this.videoInput = viewChild('videoInput', /* @ts-ignore */
1996
+ ...(ngDevMode ? [{ debugName: "videoInput" }] : /* istanbul ignore next */ []));
1997
+ this._editorInstance = signal(null, /* @ts-ignore */
1998
+ ...(ngDevMode ? [{ debugName: "_editorInstance" }] : /* istanbul ignore next */ []));
1999
+ this._imgIds = signal([], /* @ts-ignore */
2000
+ ...(ngDevMode ? [{ debugName: "_imgIds" }] : /* istanbul ignore next */ []));
1504
2001
  this._fileService = inject(CmatFilesUtilService);
1505
2002
  this._urlStateConfigService = inject(CmatUrlStateConfigService);
1506
2003
  this._destroyRef = inject(DestroyRef);
1507
- this._imgIds = [];
1508
- this._urlStateConfigService.config$
1509
- .pipe(takeUntilDestroyed(this._destroyRef))
1510
- .subscribe((config) => {
1511
- this._config = config;
1512
- });
2004
+ this._config = this._urlStateConfigService.config;
1513
2005
  }
1514
2006
  ngAfterViewInit() {
1515
2007
  const icons = Quill.import('ui/icons');
@@ -1546,70 +2038,109 @@ class CmatQuillTypeComponent extends FieldType {
1546
2038
  if (typeof fileId !== 'string') {
1547
2039
  return;
1548
2040
  }
1549
- this._editorInstance.insertEmbed(this._editorInstance.getSelection(true).index, this._getMediaType(file.type), `${this._config.fileUrl}/download/quill/${fileId}`);
1550
- this._editorInstance.setSelection(this._editorInstance.getSelection(true).index + 1);
1551
- this.formControl.setValue(this._editorInstance.container.innerHTML);
2041
+ const editor = this._editorInstance();
2042
+ const config = this._config(); // 获取配置
2043
+ if (editor && config?.fileUrl) { // 同时检查编辑器和服务配置
2044
+ const selection = editor.getSelection(true);
2045
+ const index = selection ? selection.index : editor.getLength();
2046
+ editor.insertEmbed(index, this._getMediaType(file.type), `${config.fileUrl}/download/quill/${fileId}`);
2047
+ editor.setSelection(index + 1);
2048
+ this.formControl.setValue(editor.container.innerHTML);
2049
+ }
2050
+ else {
2051
+ console.warn('无法插入图片:编辑器或文件服务配置未就绪');
2052
+ }
1552
2053
  this._upload(fileId);
1553
2054
  }
1554
- this.refreshVersion.update((value) => value + 1);
1555
2055
  });
1556
2056
  }
1557
2057
  editorCreated(editorInstance) {
1558
- this._editorInstance = editorInstance;
1559
- const dom = document.createElement('DIV');
1560
- dom.innerHTML = editorInstance.container.innerHTML;
1561
- const fileDom = dom.querySelectorAll('img, video');
1562
- fileDom.forEach((i) => {
1563
- if (i.src.includes(this._config.fileUrl)) {
1564
- this._imgIds.push(i.src.substring(`${this._config.fileUrl}/download/quill/`.length, i.src.length));
2058
+ this._editorInstance.set(editorInstance);
2059
+ // 1. 获取当前编辑器中的所有文件 ID
2060
+ const currentIds = this._extractFileIdsFromDelta(editorInstance.getContents());
2061
+ this._imgIds.set(currentIds);
2062
+ // 2. 同步清理 removeId,确保“已存在”的图片不在“待删除”列表中
2063
+ const removeControl = this.baseGroup.get('removeId');
2064
+ if (removeControl) {
2065
+ const existingRemoveIds = removeControl.value || [];
2066
+ // 过滤掉那些当前实际存在于编辑器中的 ID
2067
+ const cleanedRemoveIds = existingRemoveIds.filter(id => !currentIds.includes(id));
2068
+ // 只有当数组内容真正改变时才更新表单,避免无限循环或无效变更检测
2069
+ if (cleanedRemoveIds.length !== existingRemoveIds.length) {
2070
+ removeControl.setValue(cleanedRemoveIds);
1565
2071
  }
1566
- });
2072
+ }
1567
2073
  }
1568
2074
  contentChanged(contentChange) {
1569
- const dom = document.createElement('DIV');
1570
- dom.innerHTML = contentChange.editor.container.innerHTML;
1571
- const fileDom = dom.querySelectorAll('img, video');
1572
- const arr = [];
1573
- fileDom.forEach((i) => {
1574
- if (i.src.includes(this._config.fileUrl)) {
1575
- const id = i.src.substring(`${this._config.fileUrl}/download/quill/`.length, i.src.length);
1576
- this._imgIds.splice(this._imgIds.findIndex((k) => k === id), 1);
1577
- arr.push(id);
1578
- }
1579
- });
1580
- this._imgIds.forEach((i) => {
1581
- const rootValue = this.baseGroup.get('removeId')?.value;
1582
- if (rootValue && !isNil(i)) {
1583
- this.baseGroup.get('removeId')?.setValue([i, ...rootValue]);
1584
- }
1585
- });
1586
- this._imgIds = arr;
2075
+ const delta = contentChange.editor.getContents();
2076
+ const currentIds = this._extractFileIdsFromDelta(delta);
2077
+ const previousIds = this._imgIds();
2078
+ const removedIds = previousIds.filter(id => !currentIds.includes(id));
2079
+ if (removedIds.length > 0) {
2080
+ const removeControl = this.baseGroup.get('removeId');
2081
+ const currentRemoveList = removeControl?.value || [];
2082
+ const restoredIds = currentRemoveList.filter(id => currentIds.includes(id));
2083
+ let finalRemoveList = currentRemoveList.filter(id => !restoredIds.includes(id));
2084
+ // 添加新删除的
2085
+ finalRemoveList = [...new Set([...finalRemoveList, ...removedIds])];
2086
+ removeControl?.setValue(finalRemoveList);
2087
+ }
2088
+ this._imgIds.set(currentIds);
1587
2089
  }
1588
2090
  _imgFileHandler() {
1589
- this.imgInput.nativeElement.click();
2091
+ if (this.imgInput()) {
2092
+ this.imgInput().nativeElement.click();
2093
+ }
1590
2094
  }
1591
2095
  _videoFileHandler() {
1592
- this.videoInput.nativeElement.click();
2096
+ if (this.videoInput()) {
2097
+ this.videoInput().nativeElement.click();
2098
+ }
1593
2099
  }
1594
2100
  async _wordFileHandler() {
2101
+ const editor = this._editorInstance();
2102
+ if (!editor)
2103
+ return;
2104
+ this.isExporting.set(true);
1595
2105
  try {
1596
- const delta = this._editorInstance.getContents();
2106
+ const delta = editor.getContents();
1597
2107
  const children = await this._convertDeltaToDocxChildren(delta);
1598
2108
  const doc = new Document({
1599
- sections: [{
1600
- properties: {},
1601
- children: children
1602
- }]
2109
+ sections: [{ properties: {}, children: children }]
1603
2110
  });
1604
2111
  const blob = await Packer.toBlob(doc);
1605
- FileSaver.saveAs(blob, `${this.placeholder ?? '富文本内容下载'}${dayjs().format('YYYYMMDDHHmmss')}.docx`);
2112
+ FileSaver.saveAs(blob, `${this.placeholder ?? '文档'}_${dayjs().format('YYYYMMDD_HHmmss')}.docx`);
1606
2113
  }
1607
2114
  catch (error) {
1608
2115
  console.error('Word 导出失败:', error);
1609
2116
  }
2117
+ finally {
2118
+ this.isExporting.set(false);
2119
+ }
1610
2120
  }
1611
2121
  async _convertDeltaToDocxChildren(delta) {
1612
2122
  const children = [];
2123
+ // 1. 预加载所有图片数据 (并行)
2124
+ const imageCache = new Map();
2125
+ const imageOps = delta.ops.filter(op => typeof op.insert !== 'string' && op.insert?.image);
2126
+ await Promise.all(imageOps.map(async (op) => {
2127
+ if (typeof op.insert === 'object' && op.insert !== null && 'image' in op.insert && typeof op.insert.image === 'string') {
2128
+ const url = op.insert.image;
2129
+ if (!imageCache.has(url)) {
2130
+ const buffer = await this._getImageBuffer(url);
2131
+ const dims = await this._getImageDimensions(url);
2132
+ let type = 'png';
2133
+ if (url.toLowerCase().endsWith('.jpg') || url.toLowerCase().endsWith('.jpeg'))
2134
+ type = 'jpg';
2135
+ else if (url.toLowerCase().endsWith('.gif'))
2136
+ type = 'gif';
2137
+ else if (url.toLowerCase().endsWith('.svg'))
2138
+ type = 'svg';
2139
+ imageCache.set(url, { buffer, width: dims.width, height: dims.height, type });
2140
+ }
2141
+ }
2142
+ }));
2143
+ // 2. 构建文档结构 (同步)
1613
2144
  let currentRun = [];
1614
2145
  let currentListLevel = 0;
1615
2146
  let isList = false;
@@ -1619,11 +2150,14 @@ class CmatQuillTypeComponent extends FieldType {
1619
2150
  children.push(new Paragraph({ children: currentRun }));
1620
2151
  currentRun = [];
1621
2152
  }
1622
- const imageRun = await this._createImageRun(op.insert.image);
1623
- children.push(new Paragraph({
1624
- children: [imageRun],
1625
- alignment: AlignmentType.CENTER
1626
- }));
2153
+ const imgData = imageCache.get(op.insert.image);
2154
+ if (imgData) {
2155
+ const imageRun = this._createImageRunFromData(imgData); // 提取一个新方法
2156
+ children.push(new Paragraph({
2157
+ children: [imageRun],
2158
+ alignment: AlignmentType.CENTER
2159
+ }));
2160
+ }
1627
2161
  }
1628
2162
  else if (typeof op.insert === 'string') {
1629
2163
  const text = op.insert;
@@ -1656,6 +2190,24 @@ class CmatQuillTypeComponent extends FieldType {
1656
2190
  }
1657
2191
  return children;
1658
2192
  }
2193
+ _createImageRunFromData(data) {
2194
+ const maxWidth = 500;
2195
+ const maxHeight = 400;
2196
+ const scale = Math.min(maxWidth / data.width, maxHeight / data.height, 1);
2197
+ const imageType = data.type;
2198
+ return new ImageRun({
2199
+ data: data.buffer,
2200
+ transformation: {
2201
+ width: Math.round(data.width * scale),
2202
+ height: Math.round(data.height * scale)
2203
+ },
2204
+ type: imageType,
2205
+ fallback: {
2206
+ type: imageType !== 'svg' ? imageType : 'png',
2207
+ data: data.buffer
2208
+ }
2209
+ });
2210
+ }
1659
2211
  _createTextRun(text, attributes) {
1660
2212
  return new TextRun({
1661
2213
  text: text,
@@ -1684,46 +2236,21 @@ class CmatQuillTypeComponent extends FieldType {
1684
2236
  };
1685
2237
  return new Paragraph(paragraphOptions);
1686
2238
  }
1687
- async _createImageRun(imageUrl) {
1688
- const imageBuffer = await this._getImageBuffer(imageUrl);
1689
- let type = 'png';
1690
- if (imageUrl.toLowerCase().endsWith('.svg')) {
1691
- type = 'svg';
1692
- }
1693
- else if (imageUrl.toLowerCase().endsWith('.jpeg') || imageUrl.toLowerCase().endsWith('.jpg')) {
1694
- type = 'jpg';
1695
- }
1696
- else if (imageUrl.toLowerCase().endsWith('.gif')) {
1697
- type = 'gif';
1698
- }
1699
- const dimensions = await this._getImageDimensions(imageUrl);
1700
- const maxWidth = 500;
1701
- const maxHeight = 400;
1702
- const scale = Math.min(maxWidth / dimensions.width, maxHeight / dimensions.height, 1);
1703
- return new ImageRun({
1704
- data: imageBuffer,
1705
- transformation: {
1706
- width: Math.round(dimensions.width * scale),
1707
- height: Math.round(dimensions.height * scale)
1708
- },
1709
- type: type,
1710
- fallback: {
1711
- type: type != 'svg' ? type : 'png',
1712
- data: imageBuffer
1713
- }
1714
- });
1715
- }
1716
2239
  async _getImageBuffer(imageUrl) {
1717
2240
  if (imageUrl.startsWith('data:image')) {
1718
2241
  const base64 = imageUrl.split(',')[1];
1719
2242
  return this._base64ToUint8Array(base64);
1720
2243
  }
2244
+ const controller = new AbortController();
2245
+ const timeoutId = setTimeout(() => controller.abort(), 10000); // 10秒超时
1721
2246
  try {
1722
2247
  const response = await fetch(imageUrl, {
1723
2248
  method: 'GET',
1724
2249
  mode: 'cors',
1725
- credentials: 'omit'
2250
+ credentials: 'omit',
2251
+ signal: controller.signal
1726
2252
  });
2253
+ clearTimeout(timeoutId);
1727
2254
  if (!response.ok) {
1728
2255
  throw new Error(`图片获取失败: ${imageUrl}`);
1729
2256
  }
@@ -1731,6 +2258,7 @@ class CmatQuillTypeComponent extends FieldType {
1731
2258
  return new Uint8Array(arrayBuffer);
1732
2259
  }
1733
2260
  catch (error) {
2261
+ clearTimeout(timeoutId);
1734
2262
  console.error('图片加载失败:', imageUrl, error);
1735
2263
  return new Uint8Array(0);
1736
2264
  }
@@ -1738,10 +2266,18 @@ class CmatQuillTypeComponent extends FieldType {
1738
2266
  async _getImageDimensions(imageUrl) {
1739
2267
  return new Promise((resolve) => {
1740
2268
  const img = new Image();
2269
+ const timeout = setTimeout(() => {
2270
+ img.onload = null;
2271
+ img.onerror = null;
2272
+ // 超时也返回默认值,保证导出流程不中断
2273
+ resolve({ width: 400, height: 300 });
2274
+ }, 5000);
1741
2275
  img.onload = () => {
2276
+ clearTimeout(timeout);
1742
2277
  resolve({ width: img.width, height: img.height });
1743
2278
  };
1744
2279
  img.onerror = () => {
2280
+ clearTimeout(timeout);
1745
2281
  resolve({ width: 400, height: 300 });
1746
2282
  };
1747
2283
  img.src = imageUrl;
@@ -1833,9 +2369,15 @@ class CmatQuillTypeComponent extends FieldType {
1833
2369
  this.fileChangeEvent(fileData.toFile());
1834
2370
  }
1835
2371
  _upload(id) {
1836
- const rootValue = this.baseGroup.get('uploadId')?.value;
1837
- if (rootValue && !isNil(id)) {
1838
- this.baseGroup.get('uploadId')?.setValue([id, ...rootValue]);
2372
+ if (isNil(id))
2373
+ return;
2374
+ const uploadControl = this.baseGroup.get('uploadId');
2375
+ if (!uploadControl)
2376
+ return;
2377
+ const currentIds = uploadControl.value || [];
2378
+ // 如果 ID 已存在,则不重复添加
2379
+ if (!currentIds.includes(id)) {
2380
+ uploadControl.setValue([id, ...currentIds]);
1839
2381
  }
1840
2382
  }
1841
2383
  _getMediaType(accept) {
@@ -1861,19 +2403,35 @@ class CmatQuillTypeComponent extends FieldType {
1861
2403
  }
1862
2404
  return baseControl;
1863
2405
  }
1864
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatQuillTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1865
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.11", type: CmatQuillTypeComponent, isStandalone: true, selector: "cmat-quill-type", viewQueries: [{ propertyName: "imgInput", first: true, predicate: ["imgInput"], descendants: true }, { propertyName: "videoInput", first: true, predicate: ["videoInput"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<quill-editor class=\"w-full\" defaultEmptyValue=\"\" [formControl]=\"formControl\" [required]=\"required\" [placeholder]=\"placeholder\" [tabindex]=\"props.tabindex\"\r\n [readOnly]=\"disabled\" [modules]=\"quillModules\" (onEditorCreated)=\"editorCreated($event)\"\r\n (onContentChanged)=\"contentChanged($event)\">\r\n \r\n <input #imgInput type=\"file\" accept=\"image/png,image/jpeg,image/jpg,image/gif\" class=\"hidden\" (change)=\"fileChangeEvent(imgInput.files?.[0] ?? undefined)\" />\r\n <input #videoInput type=\"file\" accept=\"video/mpeg,video/mp4,audio/mp4\" class=\"hidden\" (change)=\"fileChangeEvent(videoInput.files?.[0] ?? undefined)\" />\r\n</quill-editor>\r\n<div class=\"cmat-quill-type\" [attr.data-refresh]=\"refreshVersion()\">\r\n", styles: [":host{display:block;width:100%}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: QuillModule }, { kind: "component", type: i2$4.QuillEditorComponent, selector: "quill-editor" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2406
+ _extractFileIdsFromDelta(delta) {
2407
+ const config = this._config();
2408
+ if (!config?.fileUrl)
2409
+ return [];
2410
+ // 构建标准前缀,确保以 / 结尾
2411
+ const baseUrl = `${config.fileUrl.replace(/\/$/, '')}/download/quill/`;
2412
+ const ids = new Set(); // 使用 Set 自动去重
2413
+ delta.ops.forEach((op) => {
2414
+ if (op.insert && typeof op.insert === 'object') {
2415
+ const url = op.insert.image ?? op.insert.video;
2416
+ if (url && typeof url === 'string' && url.startsWith(baseUrl)) {
2417
+ // 提取 baseUrl 之后的部分,并去除查询参数
2418
+ const relativePath = url.substring(baseUrl.length);
2419
+ const id = relativePath.split('?')[0].split('#')[0];
2420
+ if (id) {
2421
+ ids.add(id);
2422
+ }
2423
+ }
2424
+ }
2425
+ });
2426
+ return Array.from(ids);
2427
+ }
2428
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatQuillTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2429
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: CmatQuillTypeComponent, isStandalone: true, selector: "cmat-quill-type", viewQueries: [{ propertyName: "imgInput", first: true, predicate: ["imgInput"], descendants: true, isSignal: true }, { propertyName: "videoInput", first: true, predicate: ["videoInput"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"relative w-full\">\r\n <quill-editor \r\n class=\"w-full\" \r\n defaultEmptyValue=\"\" \r\n [formControl]=\"formControl\" \r\n [required]=\"required\" \r\n [placeholder]=\"placeholder\" \r\n [tabindex]=\"props.tabindex\"\r\n [readOnly]=\"disabled\" \r\n [modules]=\"quillModules\" \r\n (onEditorCreated)=\"editorCreated($event)\"\r\n (onContentChanged)=\"contentChanged($event)\">\r\n \r\n <input #imgInput type=\"file\" accept=\"image/png,image/jpeg,image/jpg,image/gif\" class=\"hidden\" (change)=\"fileChangeEvent(imgInput.files?.[0] ?? undefined)\" />\r\n <input #videoInput type=\"file\" accept=\"video/mpeg,video/mp4,audio/mp4\" class=\"hidden\" (change)=\"fileChangeEvent(videoInput.files?.[0] ?? undefined)\" />\r\n </quill-editor>\r\n\r\n @if (isExporting()) {\r\n <div class=\"absolute inset-0 flex items-center justify-center rounded-2xl border border-dashed border-default bg-card/80 px-4 py-6 text-sm text-secondary shadow-sm z-50 backdrop-blur-sm\">\r\n <span class=\"animate-pulse\">\u6B63\u5728\u751F\u6210 Word \u6587\u6863...</span>\r\n </div>\r\n }\r\n</div>\r\n", styles: [":host{display:block;width:100%}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: QuillModule }, { kind: "component", type: i2$4.QuillEditorComponent, selector: "quill-editor" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1866
2430
  }
1867
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatQuillTypeComponent, decorators: [{
2431
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatQuillTypeComponent, decorators: [{
1868
2432
  type: Component,
1869
- args: [{ selector: 'cmat-quill-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [ReactiveFormsModule, QuillModule], template: "<quill-editor class=\"w-full\" defaultEmptyValue=\"\" [formControl]=\"formControl\" [required]=\"required\" [placeholder]=\"placeholder\" [tabindex]=\"props.tabindex\"\r\n [readOnly]=\"disabled\" [modules]=\"quillModules\" (onEditorCreated)=\"editorCreated($event)\"\r\n (onContentChanged)=\"contentChanged($event)\">\r\n \r\n <input #imgInput type=\"file\" accept=\"image/png,image/jpeg,image/jpg,image/gif\" class=\"hidden\" (change)=\"fileChangeEvent(imgInput.files?.[0] ?? undefined)\" />\r\n <input #videoInput type=\"file\" accept=\"video/mpeg,video/mp4,audio/mp4\" class=\"hidden\" (change)=\"fileChangeEvent(videoInput.files?.[0] ?? undefined)\" />\r\n</quill-editor>\r\n<div class=\"cmat-quill-type\" [attr.data-refresh]=\"refreshVersion()\">\r\n", styles: [":host{display:block;width:100%}\n"] }]
1870
- }], ctorParameters: () => [], propDecorators: { imgInput: [{
1871
- type: ViewChild,
1872
- args: ['imgInput']
1873
- }], videoInput: [{
1874
- type: ViewChild,
1875
- args: ['videoInput']
1876
- }] } });
2433
+ args: [{ selector: 'cmat-quill-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [ReactiveFormsModule, QuillModule], template: "<div class=\"relative w-full\">\r\n <quill-editor \r\n class=\"w-full\" \r\n defaultEmptyValue=\"\" \r\n [formControl]=\"formControl\" \r\n [required]=\"required\" \r\n [placeholder]=\"placeholder\" \r\n [tabindex]=\"props.tabindex\"\r\n [readOnly]=\"disabled\" \r\n [modules]=\"quillModules\" \r\n (onEditorCreated)=\"editorCreated($event)\"\r\n (onContentChanged)=\"contentChanged($event)\">\r\n \r\n <input #imgInput type=\"file\" accept=\"image/png,image/jpeg,image/jpg,image/gif\" class=\"hidden\" (change)=\"fileChangeEvent(imgInput.files?.[0] ?? undefined)\" />\r\n <input #videoInput type=\"file\" accept=\"video/mpeg,video/mp4,audio/mp4\" class=\"hidden\" (change)=\"fileChangeEvent(videoInput.files?.[0] ?? undefined)\" />\r\n </quill-editor>\r\n\r\n @if (isExporting()) {\r\n <div class=\"absolute inset-0 flex items-center justify-center rounded-2xl border border-dashed border-default bg-card/80 px-4 py-6 text-sm text-secondary shadow-sm z-50 backdrop-blur-sm\">\r\n <span class=\"animate-pulse\">\u6B63\u5728\u751F\u6210 Word \u6587\u6863...</span>\r\n </div>\r\n }\r\n</div>\r\n", styles: [":host{display:block;width:100%}\n"] }]
2434
+ }], ctorParameters: () => [], propDecorators: { imgInput: [{ type: i0.ViewChild, args: ['imgInput', { isSignal: true }] }], videoInput: [{ type: i0.ViewChild, args: ['videoInput', { isSignal: true }] }] } });
1877
2435
 
1878
2436
  class CmatKnobTypeComponent extends FieldType {
1879
2437
  constructor() {
@@ -1893,10 +2451,10 @@ class CmatKnobTypeComponent extends FieldType {
1893
2451
  },
1894
2452
  };
1895
2453
  }
1896
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatKnobTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1897
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.11", type: CmatKnobTypeComponent, isStandalone: true, selector: "cmat-knob-type", usesInheritance: true, ngImport: i0, template: "<cmat-knob-input [formControl]=\"formControl\" [tabIndex]=\"props.tabindex\" [valueColor]=\"props.valueColor\"\r\n [rangeColor]=\"props.rangeColor\" [textColor]=\"props.textColor\" [valueTemplate]=\"props.valueTemplate\"\r\n [name]=\"props.name\" [size]=\"props.size\" [step]=\"props.step\" [min]=\"props.min\" [max]=\"props.max\"\r\n [strokeWidth]=\"props.strokeWidth\" [showValue]=\"props.showValue\">\r\n</cmat-knob-input>", styles: [":host{width:100%}\n"], dependencies: [{ kind: "component", type: CmatKnobInputComponent, selector: "cmat-knob-input", inputs: ["id", "valueColor", "rangeColor", "textColor", "valueTemplate", "name", "size", "step", "min", "max", "strokeWidth", "showValue", "placeholder", "value", "required", "disabled"], outputs: ["valueChange"], exportAs: ["cmatKnobInput"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2454
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatKnobTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2455
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.6", type: CmatKnobTypeComponent, isStandalone: true, selector: "cmat-knob-type", usesInheritance: true, ngImport: i0, template: "<cmat-knob-input [formControl]=\"formControl\" [tabIndex]=\"props.tabindex\" [valueColor]=\"props.valueColor\"\r\n [rangeColor]=\"props.rangeColor\" [textColor]=\"props.textColor\" [valueTemplate]=\"props.valueTemplate\"\r\n [name]=\"props.name\" [size]=\"props.size\" [step]=\"props.step\" [min]=\"props.min\" [max]=\"props.max\"\r\n [strokeWidth]=\"props.strokeWidth\" [showValue]=\"props.showValue\">\r\n</cmat-knob-input>", styles: [":host{width:100%}\n"], dependencies: [{ kind: "component", type: CmatKnobInputComponent, selector: "cmat-knob-input", inputs: ["valueColor", "rangeColor", "textColor", "valueTemplate", "name", "size", "step", "min", "max", "strokeWidth", "showValue", "value", "placeholder", "required", "disabled"], outputs: ["valueChange"], exportAs: ["cmatKnobInput"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1898
2456
  }
1899
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatKnobTypeComponent, decorators: [{
2457
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatKnobTypeComponent, decorators: [{
1900
2458
  type: Component,
1901
2459
  args: [{ selector: 'cmat-knob-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CmatKnobInputComponent, ReactiveFormsModule], template: "<cmat-knob-input [formControl]=\"formControl\" [tabIndex]=\"props.tabindex\" [valueColor]=\"props.valueColor\"\r\n [rangeColor]=\"props.rangeColor\" [textColor]=\"props.textColor\" [valueTemplate]=\"props.valueTemplate\"\r\n [name]=\"props.name\" [size]=\"props.size\" [step]=\"props.step\" [min]=\"props.min\" [max]=\"props.max\"\r\n [strokeWidth]=\"props.strokeWidth\" [showValue]=\"props.showValue\">\r\n</cmat-knob-input>", styles: [":host{width:100%}\n"] }]
1902
2460
  }] });
@@ -1912,10 +2470,10 @@ class CmatSliderTypeComponent extends FieldType$1 {
1912
2470
  }
1913
2471
  };
1914
2472
  }
1915
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatSliderTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1916
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.11", type: CmatSliderTypeComponent, isStandalone: true, selector: "cmat-slider-type", usesInheritance: true, ngImport: i0, template: "<mat-slider class=\"w-full\" [id]=\"id\" [tabIndex]=\"props.tabindex\" [color]=\"props.color\"\r\n [displayWith]=\"props.displayWith!\" [max]=\"props.max\" [min]=\"props.min\" [step]=\"props.step\" [discrete]=\"props.discrete\"\r\n [showTickMarks]=\"props.showTickMarks\" (input)=\"props.input && props.input(field, $event)\"\r\n (change)=\"props.change && props.change(field, $event)\">\r\n <input matSliderThumb [formControl]=\"formControl\" />\r\n</mat-slider>", styles: [":host{width:100%}:host .mdc-slider__input{padding:0!important}\n"], dependencies: [{ kind: "ngmodule", type: MatSliderModule }, { kind: "component", type: i1$a.MatSlider, selector: "mat-slider", inputs: ["disabled", "discrete", "showTickMarks", "min", "color", "disableRipple", "max", "step", "displayWith"], exportAs: ["matSlider"] }, { kind: "directive", type: i1$a.MatSliderThumb, selector: "input[matSliderThumb]", inputs: ["value"], outputs: ["valueChange", "dragStart", "dragEnd"], exportAs: ["matSliderThumb"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2473
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatSliderTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2474
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.6", type: CmatSliderTypeComponent, isStandalone: true, selector: "cmat-slider-type", usesInheritance: true, ngImport: i0, template: "<mat-slider class=\"w-full\" [id]=\"id\" [tabIndex]=\"props.tabindex\" [color]=\"props.color\"\r\n [displayWith]=\"props.displayWith!\" [max]=\"props.max\" [min]=\"props.min\" [step]=\"props.step\" [discrete]=\"props.discrete\"\r\n [showTickMarks]=\"props.showTickMarks\" (input)=\"props.input && props.input(field, $event)\"\r\n (change)=\"props.change && props.change(field, $event)\">\r\n <input matSliderThumb [formControl]=\"formControl\" />\r\n</mat-slider>", styles: [":host{width:100%}:host .mdc-slider__input{padding:0!important}\n"], dependencies: [{ kind: "ngmodule", type: MatSliderModule }, { kind: "component", type: i1$a.MatSlider, selector: "mat-slider", inputs: ["disabled", "discrete", "showTickMarks", "min", "color", "disableRipple", "max", "step", "displayWith"], exportAs: ["matSlider"] }, { kind: "directive", type: i1$a.MatSliderThumb, selector: "input[matSliderThumb]", inputs: ["value"], outputs: ["valueChange", "dragStart", "dragEnd"], exportAs: ["matSliderThumb"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1917
2475
  }
1918
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CmatSliderTypeComponent, decorators: [{
2476
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CmatSliderTypeComponent, decorators: [{
1919
2477
  type: Component,
1920
2478
  args: [{ selector: 'cmat-slider-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatSliderModule, ReactiveFormsModule], template: "<mat-slider class=\"w-full\" [id]=\"id\" [tabIndex]=\"props.tabindex\" [color]=\"props.color\"\r\n [displayWith]=\"props.displayWith!\" [max]=\"props.max\" [min]=\"props.min\" [step]=\"props.step\" [discrete]=\"props.discrete\"\r\n [showTickMarks]=\"props.showTickMarks\" (input)=\"props.input && props.input(field, $event)\"\r\n (change)=\"props.change && props.change(field, $event)\">\r\n <input matSliderThumb [formControl]=\"formControl\" />\r\n</mat-slider>", styles: [":host{width:100%}:host .mdc-slider__input{padding:0!important}\n"] }]
1921
2479
  }] });
@@ -1924,5 +2482,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
1924
2482
  * Generated bundle index. Do not edit.
1925
2483
  */
1926
2484
 
1927
- export { CmatAddonsWrapperComponent, CmatButtonTypeComponent, CmatCardWrapperComponent, CmatCascadeTypeComponent, CmatCheckListTypeComponent, CmatChipsInputTypeComponent, CmatColorPickerTypeComponent, CmatDateRangeTypeComponent, CmatDatepickerTypeComponent, CmatExpansionWrapperComponent, CmatFormFieldWrapperComponent, CmatKnobTypeComponent, CmatMultiCheckboxTypeComponent, CmatNumberTypeComponent, CmatPanelWrapperComponent, CmatQuillTypeComponent, CmatRadioTypeComponent, CmatRatingTypeComponent, CmatRepeatTypeComponent, CmatSelectTableTypeComponent, CmatSelectTreeTypeComponent, CmatSelectTypeComponent, CmatSliderTypeComponent, CmatStepperHorizontalTypeComponent, CmatStepperVerticalTypeComponent, CmatTabTypeComponent, CmatTableTypeComponent, CmatTagsTypeComponent, CmatTextareaTypeComponent, CmatUploadTypeComponent, addonsExtension };
2485
+ export { CmatAddonsWrapperComponent, CmatButtonTypeComponent, CmatCardWrapperComponent, CmatCascadeTypeComponent, CmatCheckListTypeComponent, CmatChipsInputTypeComponent, CmatColorPickerTypeComponent, CmatDataPickerTypeComponent, CmatDateRangeTypeComponent, CmatDatepickerTypeComponent, CmatExpansionWrapperComponent, CmatFormFieldWrapperComponent, CmatKnobTypeComponent, CmatMultiCheckboxTypeComponent, CmatNumberTypeComponent, CmatPanelWrapperComponent, CmatQuillTypeComponent, CmatRadioTypeComponent, CmatRatingTypeComponent, CmatRepeatTypeComponent, CmatSelectTableTypeComponent, CmatSelectTreeTypeComponent, CmatSelectTypeComponent, CmatSliderTypeComponent, CmatStepperHorizontalTypeComponent, CmatStepperVerticalTypeComponent, CmatTabTypeComponent, CmatTableTypeComponent, CmatTagsTypeComponent, CmatTextareaTypeComponent, CmatUploadTypeComponent, DomainDataService, addonsExtension };
1928
2486
  //# sourceMappingURL=cmat-components-custom-formly.mjs.map