cmat 0.0.86 → 0.0.88

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 +270 -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 +1395 -838
  18. package/fesm2022/cmat-components-custom-formly.mjs.map +1 -1
  19. package/fesm2022/cmat-components-data-picker.mjs +996 -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 +48 -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 +1212 -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 +95 -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 +190 -159
  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 +107 -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 +130 -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 +31 -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 +4 -4
  156. package/fesm2022/cmat-services-utils.mjs.map +1 -1
  157. package/fesm2022/cmat.mjs +9229 -7508
  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 +22 -1
  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.2", ngImport: i0, type: DomainDataService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
253
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: DomainDataService, providedIn: 'root' }); }
254
+ }
255
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", 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.10", ngImport: i0, type: CmatAddonsWrapperComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
100
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", 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.2", ngImport: i0, type: CmatAddonsWrapperComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
292
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", 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.10", ngImport: i0, type: CmatAddonsWrapperComponent, decorators: [{
323
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatAddonsWrapperComponent, decorators: [{
132
324
  type: Component,
133
325
  args: [{
134
326
  selector: 'cmat-addons-wrapper',
@@ -164,50 +356,45 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", 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.10", ngImport: i0, type: CmatCardWrapperComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
177
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", 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.2", ngImport: i0, type: CmatCardWrapperComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
363
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", 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.10", ngImport: i0, type: CmatCardWrapperComponent, decorators: [{
365
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", 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.10", ngImport: i0, type: CmatExpansionWrapperComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
186
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.10", 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.2", ngImport: i0, type: CmatExpansionWrapperComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
372
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.2", 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.10", ngImport: i0, type: CmatExpansionWrapperComponent, decorators: [{
374
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", 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.10", ngImport: i0, type: CmatPanelWrapperComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
195
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.10", 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.2", ngImport: i0, type: CmatPanelWrapperComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
381
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.2", 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.10", ngImport: i0, type: CmatPanelWrapperComponent, decorators: [{
383
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", 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);
205
392
  this._renderer = inject(Renderer2);
206
393
  this._elementRef = inject(ElementRef);
207
394
  this._focusMonitor = inject(FocusMonitor);
208
395
  }
209
396
  ngOnInit() {
210
- _defineHiddenProp(this.field, '_formField', this.formField);
397
+ _defineHiddenProp(this.field, '_formField', this.formField());
211
398
  this._focusMonitor.monitor(this._elementRef, true).subscribe((origin) => {
212
399
  if (!origin && this.field.focus) {
213
400
  this.field.focus = false;
@@ -215,9 +402,8 @@ class CmatFormFieldWrapperComponent extends FieldWrapper {
215
402
  });
216
403
  }
217
404
  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');
405
+ if (this.formField().appearance !== 'outline' && this.props.hideFieldUnderline === true) {
406
+ const underlineElement = this.formField()._elementRef.nativeElement.querySelector('.mat-form-field-underline');
221
407
  if (underlineElement?.parentNode) {
222
408
  this._renderer.removeChild(underlineElement.parentNode, underlineElement);
223
409
  }
@@ -227,16 +413,13 @@ class CmatFormFieldWrapperComponent extends FieldWrapper {
227
413
  delete this.field._formField;
228
414
  this._focusMonitor.stopMonitoring(this._elementRef);
229
415
  }
230
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatFormFieldWrapperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
231
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", 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 }); }
416
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatFormFieldWrapperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
417
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", 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
418
  }
233
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatFormFieldWrapperComponent, decorators: [{
419
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatFormFieldWrapperComponent, decorators: [{
234
420
  type: Component,
235
421
  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
- }] } });
422
+ }], ctorParameters: () => [], propDecorators: { formField: [{ type: i0.ViewChild, args: [i0.forwardRef(() => MatFormField), { isSignal: true }] }] } });
240
423
 
241
424
  const DANGEROUS_PATTERNS = [
242
425
  /\bdocument\s*\./i,
@@ -254,7 +437,8 @@ class CmatButtonTypeComponent extends FieldType {
254
437
  super(...arguments);
255
438
  this.defaultOptions = {
256
439
  props: {
257
- color: 'primary'
440
+ color: 'primary',
441
+ type: 'button'
258
442
  }
259
443
  };
260
444
  }
@@ -286,10 +470,10 @@ class CmatButtonTypeComponent extends FieldType {
286
470
  console.error('Error executing function from string:', error);
287
471
  }
288
472
  }
289
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatButtonTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
290
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.10", 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 }); }
473
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatButtonTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
474
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.2", 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
475
  }
292
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatButtonTypeComponent, decorators: [{
476
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatButtonTypeComponent, decorators: [{
293
477
  type: Component,
294
478
  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
479
  }] });
@@ -304,269 +488,427 @@ class CmatCascadeTypeComponent extends FieldType {
304
488
  changeOnSelect: false
305
489
  },
306
490
  };
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);
491
+ this.urlData = signal([], /* @ts-ignore */
492
+ ...(ngDevMode ? [{ debugName: "urlData" }] : /* istanbul ignore next */ []));
311
493
  this._cmatMediaWatcherService = inject(CmatMediaWatcherService);
494
+ // eslint-disable-next-line @typescript-eslint/member-ordering
495
+ this.isHandSet = computed(() => {
496
+ return !this._cmatMediaWatcherService.mediaChange().matchingAliases.includes('lg');
497
+ }, /* @ts-ignore */
498
+ ...(ngDevMode ? [{ debugName: "isHandSet" }] : /* istanbul ignore next */ []));
499
+ this._lastDomain = undefined;
312
500
  this._destroyRef = inject(DestroyRef);
501
+ this._domainDataService = inject(DomainDataService);
313
502
  }
314
503
  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);
504
+ this._lastDomain = this.props.domain;
505
+ this._refreshData();
506
+ }
507
+ ngDoCheck() {
508
+ const currentDomain = this.props.domain;
509
+ let shouldRefresh = false;
510
+ // 1. 检查 domain 变化
511
+ if (!isEqual(currentDomain, this._lastDomain)) {
512
+ this._lastDomain = currentDomain;
513
+ shouldRefresh = true;
514
+ }
515
+ if (shouldRefresh) {
516
+ this._refreshData();
517
+ }
518
+ }
519
+ _refreshData() {
520
+ const domain = this.props.domain;
521
+ // 使用 DomainDataService 加载远程数据
522
+ this._domainDataService.load(domain, this._destroyRef, {
523
+ onSuccess: data => this.urlData.set(data),
524
+ componentName: 'CmatCascadeTypeComponent'
348
525
  });
349
526
  }
350
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatCascadeTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
351
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.10", 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 }); }
527
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatCascadeTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
528
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.2", 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
529
  }
353
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatCascadeTypeComponent, decorators: [{
530
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatCascadeTypeComponent, decorators: [{
354
531
  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"] }]
532
+ 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
533
  }], ctorParameters: () => [] });
357
534
 
358
535
  class CmatCheckListTypeComponent extends FieldType {
359
536
  constructor() {
360
537
  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);
538
+ this.isIndeterminate = signal(false, /* @ts-ignore */
539
+ ...(ngDevMode ? [{ debugName: "isIndeterminate" }] : /* istanbul ignore next */ []));
540
+ this.isChecked = signal(false, /* @ts-ignore */
541
+ ...(ngDevMode ? [{ debugName: "isChecked" }] : /* istanbul ignore next */ []));
542
+ this.urlData = signal([], /* @ts-ignore */
543
+ ...(ngDevMode ? [{ debugName: "urlData" }] : /* istanbul ignore next */ []));
544
+ this.optionsData = signal([], /* @ts-ignore */
545
+ ...(ngDevMode ? [{ debugName: "optionsData" }] : /* istanbul ignore next */ []));
546
+ this.checklist = signal([], /* @ts-ignore */
547
+ ...(ngDevMode ? [{ debugName: "checklist" }] : /* istanbul ignore next */ []));
548
+ this.filteredItems = signal(null, /* @ts-ignore */
549
+ ...(ngDevMode ? [{ debugName: "filteredItems" }] : /* istanbul ignore next */ []));
550
+ // 响应式数据源
551
+ this.datas = computed(() => {
552
+ if (this.urlData().length > 0) {
553
+ return this.urlData();
554
+ }
555
+ return this.optionsData() || [];
556
+ }, /* @ts-ignore */
557
+ ...(ngDevMode ? [{ debugName: "datas" }] : /* istanbul ignore next */ []));
558
+ // 响应式过滤数据
559
+ this.filteredData = computed(() => {
560
+ const currentDatas = this.datas();
561
+ const query = this._filterQuery();
562
+ if (!query) {
563
+ return currentDatas;
564
+ }
565
+ return currentDatas.filter((data) => this._toSearchText(data.value).toLowerCase().includes(query.toLowerCase()) ||
566
+ this._toSearchText(data.label).toLowerCase().includes(query.toLowerCase()));
567
+ }, /* @ts-ignore */
568
+ ...(ngDevMode ? [{ debugName: "filteredData" }] : /* istanbul ignore next */ []));
569
+ this._lastDomain = undefined;
570
+ this._lastOptions = undefined;
368
571
  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
- }
572
+ this._domainDataService = inject(DomainDataService);
573
+ this._filterQuery = signal('', /* @ts-ignore */
574
+ ...(ngDevMode ? [{ debugName: "_filterQuery" }] : /* istanbul ignore next */ []));
382
575
  }
383
576
  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
- }
577
+ this._lastDomain = this.props.domain;
578
+ this._lastOptions = this.field.props?.options;
579
+ this._refreshData();
580
+ this._refreshFilteredData();
419
581
  this.formControl.valueChanges.pipe(takeUntilDestroyed(this._destroyRef)).subscribe((value) => {
420
- this.checklist = (value ?? []);
582
+ const newVal = (value ?? []);
583
+ this.checklist.set(newVal);
421
584
  this._getAllCheckCountState();
422
585
  });
423
586
  }
587
+ ngDoCheck() {
588
+ const currentDomain = this.props.domain;
589
+ const currentOptions = this.field.props?.options;
590
+ let shouldRefresh = false;
591
+ // 1. 检查 domain 变化
592
+ if (!isEqual(currentDomain, this._lastDomain)) {
593
+ this._lastDomain = currentDomain;
594
+ shouldRefresh = true;
595
+ }
596
+ // 2. 检查 options 变化 (仅当 domain 未配置时,options 才生效,但为了稳妥,只要变了就更新)
597
+ // 注意:如果 domain 存在,urlData 优先级更高,但更新 optionsData 也无妨,因为 allOptions computed 会优先取 urlData
598
+ if (!isEqual(currentOptions, this._lastOptions)) {
599
+ this._lastOptions = currentOptions;
600
+ shouldRefresh = true;
601
+ }
602
+ if (shouldRefresh) {
603
+ this._refreshData();
604
+ }
605
+ }
424
606
  trackByFn(index, item) {
425
- return item.id ?? index;
607
+ return item.id ?? item.value ?? index;
426
608
  }
427
609
  filterByQuery(event) {
428
610
  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);
611
+ this._filterQuery.set(query.toLowerCase());
432
612
  this._getAllCheckCountState();
433
613
  }
434
614
  toggleCheckList(data, event) {
435
615
  event.preventDefault();
436
616
  if (data.disabled || this.props.disabled)
437
617
  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);
618
+ this.checklist.update((currentList) => {
619
+ const index = currentList.findIndex(item => item.value === data.value);
620
+ let newList;
621
+ if (index > -1) {
622
+ newList = currentList.filter(item => item.value !== data.value);
623
+ }
624
+ else {
625
+ newList = [...currentList, data];
626
+ }
627
+ return newList;
628
+ });
629
+ // 同步表单值
630
+ this.formControl.setValue(this.checklist());
631
+ this._getAllCheckCountState();
446
632
  }
447
633
  allCheckChange(check) {
634
+ const itemsToAdd = this.filteredData().filter((t) => {
635
+ const index = this.checklist().findIndex(item => item.value === t.value);
636
+ return index < 0 && !t.disabled;
637
+ });
448
638
  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];
639
+ this.checklist.set([...this.checklist(), ...itemsToAdd]);
454
640
  }
455
641
  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;
642
+ this.checklist.set(this.checklist().filter((item) => {
643
+ const existsInFiltered = this.filteredData().some(t => t.value === item.value);
644
+ const shouldRemove = existsInFiltered && this.filteredData().find(t => t.value === item.value)?.disabled === false;
459
645
  return !shouldRemove;
460
- });
646
+ }));
461
647
  }
462
- this.formControl.setValue(this.checklist);
648
+ this.formControl.setValue(this.checklist());
649
+ this._getAllCheckCountState();
463
650
  }
464
651
  isCheck(data) {
465
- const selected = (this.formControl.value ?? []);
466
- return selected.filter((i) => i.value === data.value).length > 0;
652
+ const selected = this.checklist();
653
+ return selected.some((i) => i.value === data.value);
654
+ }
655
+ _refreshFilteredData() {
656
+ this.filteredItems.set(this.filteredData());
657
+ this._getAllCheckCountState();
467
658
  }
468
659
  _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
- }
660
+ if (!this.props.showAllCheck || this.props.disabled)
661
+ return;
662
+ const currentChecklist = this.checklist();
663
+ const currentFiltered = this.filteredData();
664
+ const enabledFilteredItems = currentFiltered.filter(i => !i.disabled);
665
+ const totalEnabled = enabledFilteredItems.length;
666
+ if (totalEnabled === 0) {
667
+ this.isChecked.set(false);
668
+ this.isIndeterminate.set(false);
669
+ return;
670
+ }
671
+ const allCheckCount = enabledFilteredItems.filter(t => currentChecklist.some(item => item.value === t.value)).length;
672
+ if (allCheckCount === 0) {
673
+ this.isChecked.set(false);
674
+ this.isIndeterminate.set(false);
675
+ }
676
+ else if (allCheckCount === totalEnabled) {
677
+ this.isChecked.set(true);
678
+ this.isIndeterminate.set(false);
679
+ }
680
+ else {
681
+ this.isChecked.set(false);
682
+ this.isIndeterminate.set(true);
496
683
  }
497
684
  }
498
685
  _toSearchText(value) {
499
686
  return typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean' ? String(value) : '';
500
687
  }
501
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatCheckListTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
502
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", 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 }); }
688
+ _refreshData() {
689
+ const domain = this.props.domain;
690
+ // 使用 DomainDataService 加载远程数据
691
+ this._domainDataService.load(domain, this._destroyRef, {
692
+ onSuccess: (data) => {
693
+ this.urlData.set(data);
694
+ this._refreshFilteredData();
695
+ },
696
+ componentName: 'CmatCheckListTypeComponent'
697
+ });
698
+ // 处理静态 options
699
+ if (!domain?.url && this.field.props?.options && isArray(this.field.props?.options)) {
700
+ this.optionsData.set(this.field.props.options || []);
701
+ }
702
+ else if (!domain?.url) {
703
+ this.optionsData.set([]);
704
+ }
705
+ }
706
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatCheckListTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
707
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", 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
708
  }
504
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatCheckListTypeComponent, decorators: [{
709
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatCheckListTypeComponent, decorators: [{
505
710
  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"] }]
711
+ 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
712
  }], ctorParameters: () => [] });
508
713
 
509
714
  class CmatChipsInputTypeComponent extends FieldType {
510
715
  constructor() {
511
716
  super();
512
- this.autocompleteUrlData = [];
513
- this._http = inject(HttpClient);
717
+ this.urlData = signal([], /* @ts-ignore */
718
+ ...(ngDevMode ? [{ debugName: "urlData" }] : /* istanbul ignore next */ []));
719
+ this.autocompleteOptions = computed(() => {
720
+ const data = this.urlData();
721
+ if (data && data.length > 0) {
722
+ return data.filter((item) => typeof item === 'string');
723
+ }
724
+ const staticText = this.props?.autocompleteText;
725
+ if (staticText) {
726
+ return staticText.split(',').map(s => s.trim()).filter(s => s.length > 0);
727
+ }
728
+ return [];
729
+ }, /* @ts-ignore */
730
+ ...(ngDevMode ? [{ debugName: "autocompleteOptions" }] : /* istanbul ignore next */ []));
731
+ this._lastDomain = undefined;
514
732
  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(',') ?? [];
733
+ this._domainDataService = inject(DomainDataService);
522
734
  }
523
735
  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;
736
+ this._lastDomain = this.props.domain;
737
+ this._refreshData();
738
+ }
739
+ ngDoCheck() {
740
+ const currentDomain = this.props.domain;
741
+ let shouldRefresh = false;
742
+ if (!isEqual(currentDomain, this._lastDomain)) {
743
+ this._lastDomain = currentDomain;
744
+ shouldRefresh = true;
745
+ }
746
+ if (shouldRefresh) {
747
+ this._refreshData();
748
+ }
749
+ }
750
+ _refreshData() {
751
+ const domain = this.props.domain;
752
+ // 使用 DomainDataService 加载远程数据
753
+ this._domainDataService.load(domain, this._destroyRef, {
754
+ transform: (rawData) => {
755
+ // Chips 特殊处理:支持字符串数组或逗号分隔的字符串
756
+ if (rawData.length > 0 && typeof rawData[0] === 'string') {
757
+ return rawData;
758
+ }
759
+ else if (rawData.length > 0 && typeof rawData[0] === 'object' && rawData[0] !== null) {
760
+ // 如果是对象数组,尝试提取 label/name/text 字段
761
+ return rawData.map((item) => {
762
+ const obj = item;
763
+ return (obj.label ?? obj.name ?? obj.text ?? obj.value ?? item);
536
764
  });
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
- }
765
+ }
766
+ return rawData;
767
+ },
768
+ onSuccess: (data) => {
769
+ // 如果提取的是字符串,转换为数组
770
+ if (data.length === 1 && typeof data[0] === 'string') {
771
+ this.urlData.set((data[0]).split(',').map(s => s.trim()));
543
772
  }
544
773
  else {
545
- this.autocompleteUrlData = [];
774
+ this.urlData.set(data);
546
775
  }
547
- });
548
- }
549
- else {
550
- this.autocompleteUrlData = [];
551
- }
776
+ },
777
+ componentName: 'CmatChipsInputTypeComponent'
778
+ });
552
779
  }
553
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatChipsInputTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
554
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.10", 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 }); }
780
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatChipsInputTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
781
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.2", 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
782
  }
556
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatChipsInputTypeComponent, decorators: [{
783
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatChipsInputTypeComponent, decorators: [{
557
784
  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"] }]
785
+ 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
786
  }], ctorParameters: () => [] });
560
787
 
561
788
  class CmatColorPickerTypeComponent extends FieldType$1 {
562
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatColorPickerTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
563
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.10", 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 }); }
789
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatColorPickerTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
790
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.2", 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
791
  }
565
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatColorPickerTypeComponent, decorators: [{
792
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatColorPickerTypeComponent, decorators: [{
566
793
  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"] }]
794
+ 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
795
  }] });
569
796
 
797
+ class CmatDataPickerTypeComponent extends FieldType {
798
+ constructor() {
799
+ super();
800
+ this.dataProviderSignal = signal(undefined, /* @ts-ignore */
801
+ ...(ngDevMode ? [{ debugName: "dataProviderSignal" }] : /* istanbul ignore next */ []));
802
+ this._http = inject(HttpClient);
803
+ this._destroyRef = inject(DestroyRef);
804
+ // 用于记录上一次的配置快照
805
+ this._lastDomain = undefined;
806
+ this._lastApiUrl = undefined;
807
+ }
808
+ ngOnInit() {
809
+ // 初始化快照
810
+ this._lastDomain = this.props.domain;
811
+ this._lastApiUrl = this.props.apiUrl;
812
+ // 执行初始创建逻辑
813
+ this._createDataProvider();
814
+ }
815
+ ngDoCheck() {
816
+ const currentDomain = this.props.domain;
817
+ const currentApiUrl = this.props.apiUrl;
818
+ let shouldRefresh = false;
819
+ // 检查 domain 变化
820
+ if (!isEqual(currentDomain, this._lastDomain)) {
821
+ this._lastDomain = currentDomain;
822
+ shouldRefresh = true;
823
+ }
824
+ // 检查 apiUrl 变化
825
+ if (currentApiUrl !== this._lastApiUrl) {
826
+ this._lastApiUrl = currentApiUrl;
827
+ shouldRefresh = true;
828
+ }
829
+ if (shouldRefresh) {
830
+ this._createDataProvider();
831
+ }
832
+ }
833
+ /**
834
+ * 统一创建 dataProvider 的方法
835
+ */
836
+ _createDataProvider() {
837
+ const domain = this.props.domain;
838
+ const apiUrl = this.props.apiUrl;
839
+ if (domain?.url && domain?.key && domain?.code && domain?.value) {
840
+ this._createDataProviderFromDomain(domain);
841
+ }
842
+ else if (apiUrl) {
843
+ // 如果提供了 apiUrl,创建简单的 HTTP provider
844
+ this._createDataProviderFromUrl(apiUrl);
845
+ }
846
+ else {
847
+ // 没有配置,清空 provider
848
+ this.dataProviderSignal.set(undefined);
849
+ }
850
+ }
851
+ /**
852
+ * 从 domain 配置创建 dataProvider
853
+ */
854
+ _createDataProviderFromDomain(domain) {
855
+ if (!domain.url || !domain.key || !domain.code || !domain.value)
856
+ return;
857
+ const provider = {
858
+ loadPage: (query) => {
859
+ const params = {
860
+ page: query.page,
861
+ size: query.size,
862
+ };
863
+ if (query.search) {
864
+ params[domain.key] = domain.code;
865
+ params['search'] = query.search;
866
+ }
867
+ if (query.orderBy) {
868
+ params['orderBy'] = query.orderBy;
869
+ params['desc'] = query.desc ?? false;
870
+ }
871
+ return this._http.post(domain.url, params).pipe(takeUntilDestroyed(this._destroyRef), catchError((error) => {
872
+ console.error('Failed to load data picker data:', error);
873
+ return of({ data: [], total: 0 });
874
+ }));
875
+ },
876
+ };
877
+ this.dataProviderSignal.set(provider);
878
+ }
879
+ /**
880
+ * 从 URL 创建简单的 dataProvider
881
+ */
882
+ _createDataProviderFromUrl(url) {
883
+ const provider = {
884
+ loadPage: (query) => {
885
+ const params = {
886
+ page: query.page,
887
+ size: query.size,
888
+ };
889
+ if (query.search) {
890
+ params['search'] = query.search;
891
+ }
892
+ if (query.orderBy) {
893
+ params['orderBy'] = query.orderBy;
894
+ params['desc'] = query.desc ?? false;
895
+ }
896
+ return this._http.post(url, params).pipe(takeUntilDestroyed(this._destroyRef), catchError((error) => {
897
+ console.error('Failed to load data picker data:', error);
898
+ return of({ data: [], total: 0 });
899
+ }));
900
+ },
901
+ };
902
+ this.dataProviderSignal.set(provider);
903
+ }
904
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatDataPickerTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
905
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.2", 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 }); }
906
+ }
907
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatDataPickerTypeComponent, decorators: [{
908
+ type: Component,
909
+ 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"] }]
910
+ }], ctorParameters: () => [] });
911
+
570
912
  class CmatDateRangeTypeComponent extends FieldType {
571
913
  constructor() {
572
914
  super(...arguments);
@@ -578,10 +920,10 @@ class CmatDateRangeTypeComponent extends FieldType {
578
920
  },
579
921
  };
580
922
  }
581
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatDateRangeTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
582
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.10", 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 }); }
923
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatDateRangeTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
924
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.2", 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
925
  }
584
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatDateRangeTypeComponent, decorators: [{
926
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatDateRangeTypeComponent, decorators: [{
585
927
  type: Component,
586
928
  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
929
  }] });
@@ -602,21 +944,17 @@ class CmatDatepickerTypeComponent extends FieldType {
602
944
  twelvehour: false
603
945
  }
604
946
  };
605
- this.isHandSet = signal(false, ...(ngDevMode ? [{ debugName: "isHandSet" }] : /* istanbul ignore next */ []));
606
947
  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.10", ngImport: i0, type: CmatDatepickerTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
617
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", 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 }); }
948
+ // eslint-disable-next-line @typescript-eslint/member-ordering
949
+ this.isHandSet = computed(() => {
950
+ return !this._cmatMediaWatcherService.mediaChange().matchingAliases.includes('lg');
951
+ }, /* @ts-ignore */
952
+ ...(ngDevMode ? [{ debugName: "isHandSet" }] : /* istanbul ignore next */ []));
953
+ }
954
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatDatepickerTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
955
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", 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
956
  }
619
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatDatepickerTypeComponent, decorators: [{
957
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatDatepickerTypeComponent, decorators: [{
620
958
  type: Component,
621
959
  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
960
  }], ctorParameters: () => [] });
@@ -632,74 +970,113 @@ class CmatMultiCheckboxTypeComponent extends FieldType {
632
970
  labelPosition: 'after'
633
971
  },
634
972
  };
635
- this._http = inject(HttpClient);
973
+ this.urlData = [];
974
+ this._lastDomain = undefined;
975
+ this._lastOptions = undefined;
636
976
  this._destroyRef = inject(DestroyRef);
637
- this._urlData = signal([], ...(ngDevMode ? [{ debugName: "_urlData" }] : /* istanbul ignore next */ []));
638
- this._urlData$ = toObservable(this._urlData);
977
+ this._domainDataService = inject(DomainDataService);
978
+ }
979
+ ngOnInit() {
980
+ this._lastDomain = this.props.domain;
981
+ this._lastOptions = this.field.props?.options;
982
+ this._refreshData();
639
983
  }
640
- get urlData$() {
641
- return this._urlData$;
984
+ ngDoCheck() {
985
+ const currentDomain = this.props.domain;
986
+ const currentOptions = this.field.props?.options;
987
+ let shouldRefresh = false;
988
+ // 1. 检查 domain 变化
989
+ if (!isEqual(currentDomain, this._lastDomain)) {
990
+ this._lastDomain = currentDomain;
991
+ shouldRefresh = true;
992
+ }
993
+ // 2. 检查 options 变化
994
+ if (!isEqual(currentOptions, this._lastOptions)) {
995
+ this._lastOptions = currentOptions;
996
+ shouldRefresh = true;
997
+ }
998
+ if (shouldRefresh) {
999
+ this._refreshData();
1000
+ }
642
1001
  }
643
1002
  onChange(optionValue, checked) {
644
- const value = optionValue ?? '';
1003
+ if (optionValue === undefined || optionValue === null)
1004
+ return;
645
1005
  this.formControl.markAsDirty();
646
1006
  if (this.props.type === 'array') {
647
1007
  const currentValue = (this.formControl.value ?? []);
648
1008
  this.formControl.patchValue(checked
649
- ? [...currentValue, value]
650
- : currentValue.filter(o => o !== value));
1009
+ ? [...currentValue, optionValue]
1010
+ : currentValue.filter(o => o !== optionValue));
651
1011
  }
652
1012
  else {
653
- this.formControl.patchValue({ ...(this.formControl.value ?? {}), [value]: checked });
1013
+ const currentObj = this.formControl.value ?? {};
1014
+ this.formControl.patchValue({
1015
+ ...currentObj,
1016
+ [optionValue]: checked
1017
+ });
654
1018
  }
655
1019
  this.formControl.markAsTouched();
656
1020
  }
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
- });
1021
+ isChecked(option) {
1022
+ const formValue = this.formControl.value;
1023
+ let optionValue;
1024
+ if (option.value !== undefined) {
1025
+ optionValue = option.value;
1026
+ }
1027
+ else if (option.value !== undefined) {
1028
+ optionValue = option.value;
1029
+ }
1030
+ if (optionValue === undefined || optionValue === null) {
1031
+ return false;
1032
+ }
1033
+ if (!formValue) {
1034
+ return false;
1035
+ }
1036
+ const safeOptionValue = String(optionValue);
1037
+ if (this.props.type === 'array') {
1038
+ if (Array.isArray(formValue)) {
1039
+ return formValue.some(v => String(v) === safeOptionValue);
1040
+ }
1041
+ return false;
680
1042
  }
681
1043
  else {
682
- this._urlData.set([]);
1044
+ if (typeof formValue === 'object' && formValue !== null) {
1045
+ return !!formValue[safeOptionValue];
1046
+ }
1047
+ return false;
683
1048
  }
684
1049
  }
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]);
1050
+ trackByFn(index, option) {
1051
+ return option.value ?? index;
689
1052
  }
690
- trackByFn(index) {
691
- return index;
1053
+ getData() {
1054
+ return this.urlData;
692
1055
  }
693
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatMultiCheckboxTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
694
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", 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 }); }
1056
+ _refreshData() {
1057
+ const domain = this.props.domain;
1058
+ // 使用 DomainDataService 加载远程数据
1059
+ this._domainDataService.load(domain, this._destroyRef, {
1060
+ onSuccess: (data) => {
1061
+ this.urlData = data;
1062
+ },
1063
+ componentName: 'CmatMultiCheckboxTypeComponent'
1064
+ });
1065
+ // 处理静态 options(当没有 domain 时)
1066
+ if (!domain?.url && this.field.props?.options) {
1067
+ const options = this.field.props.options;
1068
+ if (Array.isArray(options)) {
1069
+ this.urlData = options;
1070
+ }
1071
+ }
1072
+ }
1073
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatMultiCheckboxTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1074
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", 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
1075
  }
696
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatMultiCheckboxTypeComponent, decorators: [{
1076
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatMultiCheckboxTypeComponent, decorators: [{
697
1077
  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
- }] } });
1078
+ 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"] }]
1079
+ }], ctorParameters: () => [] });
703
1080
 
704
1081
  class CmatNumberTypeComponent extends FieldType {
705
1082
  constructor() {
@@ -712,10 +1089,10 @@ class CmatNumberTypeComponent extends FieldType {
712
1089
  },
713
1090
  };
714
1091
  }
715
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatNumberTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
716
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.10", 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 }); }
1092
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatNumberTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1093
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.2", 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
1094
  }
718
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatNumberTypeComponent, decorators: [{
1095
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatNumberTypeComponent, decorators: [{
719
1096
  type: Component,
720
1097
  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
1098
  }] });
@@ -728,14 +1105,15 @@ class CmatRatingTypeComponent extends FieldType {
728
1105
  stars: 5,
729
1106
  readonly: false,
730
1107
  hover: true,
731
- half: true
1108
+ half: true,
1109
+ showMode: 'horizontal'
732
1110
  },
733
1111
  };
734
1112
  }
735
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatRatingTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
736
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", 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 }); }
1113
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatRatingTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1114
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", 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
1115
  }
738
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatRatingTypeComponent, decorators: [{
1116
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatRatingTypeComponent, decorators: [{
739
1117
  type: Component,
740
1118
  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
1119
  }] });
@@ -751,49 +1129,39 @@ class CmatRadioTypeComponent extends FieldType {
751
1129
  labelPosition: 'after'
752
1130
  },
753
1131
  };
754
- this._http = inject(HttpClient);
755
- this._urlData = signal([], ...(ngDevMode ? [{ debugName: "_urlData" }] : /* istanbul ignore next */ []));
1132
+ this.urlData = signal([], /* @ts-ignore */
1133
+ ...(ngDevMode ? [{ debugName: "urlData" }] : /* istanbul ignore next */ []));
1134
+ this.radioGroup = viewChild(MatRadioGroup, /* @ts-ignore */
1135
+ ...(ngDevMode ? [{ debugName: "radioGroup" }] : /* istanbul ignore next */ []));
1136
+ this._lastDomain = undefined;
756
1137
  this._destroyRef = inject(DestroyRef);
757
- this._urlData$ = toObservable(this._urlData);
758
- }
759
- get urlData$() {
760
- return this._urlData$;
1138
+ this._domainDataService = inject(DomainDataService);
761
1139
  }
762
1140
  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
- });
1141
+ this._lastDomain = this.props.domain;
1142
+ this._refreshData();
1143
+ }
1144
+ ngDoCheck() {
1145
+ const currentDomain = this.props.domain;
1146
+ let shouldRefresh = false;
1147
+ // 1. 检查 domain 变化
1148
+ if (!isEqual(currentDomain, this._lastDomain)) {
1149
+ this._lastDomain = currentDomain;
1150
+ shouldRefresh = true;
785
1151
  }
786
- else {
787
- this._urlData.set([]);
1152
+ if (shouldRefresh) {
1153
+ this._refreshData();
788
1154
  }
789
1155
  }
790
1156
  ngAfterViewInit() {
791
1157
  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
- });
1158
+ if (this.radioGroup()) {
1159
+ if (this.props.tabindex === -1 && currentValue && this.radioGroup()._radios.length > 0) {
1160
+ setTimeout(() => {
1161
+ const radio = this.radioGroup().selected ?? this.radioGroup()._radios.first;
1162
+ radio?.focus();
1163
+ });
1164
+ }
797
1165
  }
798
1166
  });
799
1167
  }
@@ -801,19 +1169,24 @@ class CmatRadioTypeComponent extends FieldType {
801
1169
  super.ngOnDestroy();
802
1170
  this.focusObserver?.unsubscribe();
803
1171
  }
804
- trackByFn(index) {
805
- return index;
1172
+ trackByFn(index, option) {
1173
+ return option.value ?? index;
1174
+ }
1175
+ _refreshData() {
1176
+ const domain = this.props.domain;
1177
+ // 使用 DomainDataService 加载远程数据
1178
+ this._domainDataService.load(domain, this._destroyRef, {
1179
+ onSuccess: data => this.urlData.set(data),
1180
+ componentName: 'CmatRadioTypeComponent'
1181
+ });
806
1182
  }
807
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatRadioTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
808
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", 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 }); }
1183
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatRadioTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1184
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", 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
1185
  }
810
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatRadioTypeComponent, decorators: [{
1186
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatRadioTypeComponent, decorators: [{
811
1187
  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
- }] } });
1188
+ 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"] }]
1189
+ }], ctorParameters: () => [], propDecorators: { radioGroup: [{ type: i0.ViewChild, args: [i0.forwardRef(() => MatRadioGroup), { isSignal: true }] }] } });
817
1190
 
818
1191
  class CmatRepeatTypeComponent extends FieldArrayType {
819
1192
  constructor() {
@@ -824,10 +1197,10 @@ class CmatRepeatTypeComponent extends FieldArrayType {
824
1197
  },
825
1198
  };
826
1199
  }
827
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatRepeatTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
828
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", 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 }); }
1200
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatRepeatTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1201
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", 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
1202
  }
830
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatRepeatTypeComponent, decorators: [{
1203
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatRepeatTypeComponent, decorators: [{
831
1204
  type: Component,
832
1205
  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
1206
  }] });
@@ -842,80 +1215,105 @@ class CmatSelectTypeComponent extends FieldType {
842
1215
  showToggleAllCheckbox: false
843
1216
  },
844
1217
  };
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);
1218
+ this.searchControl = new FormControl('');
1219
+ this.urlData = signal([], /* @ts-ignore */
1220
+ ...(ngDevMode ? [{ debugName: "urlData" }] : /* istanbul ignore next */ []));
1221
+ this.optionsData = signal([], /* @ts-ignore */
1222
+ ...(ngDevMode ? [{ debugName: "optionsData" }] : /* istanbul ignore next */ []));
1223
+ this.filteredOptions = computed(() => {
1224
+ const allData = this.allOptions();
1225
+ const search = this._searchText();
1226
+ if (!search) {
1227
+ return allData;
1228
+ }
1229
+ return allData.filter((item) => {
1230
+ const labelMatch = item.label?.toString().toLowerCase().includes(search);
1231
+ const valueMatch = item.value?.toString().toLowerCase().includes(search);
1232
+ return labelMatch ?? valueMatch;
1233
+ });
1234
+ }, /* @ts-ignore */
1235
+ ...(ngDevMode ? [{ debugName: "filteredOptions" }] : /* istanbul ignore next */ []));
1236
+ this.isIndeterminate = computed(() => {
1237
+ if (!this.props.multiple || !this.props.search)
1238
+ return false;
1239
+ const visibleOptions = this.filteredOptions().filter(o => !o.disabled);
1240
+ if (visibleOptions.length === 0)
1241
+ return false;
1242
+ const currentValue = this.formControl.value;
1243
+ if (!isArray(currentValue))
1244
+ return false;
1245
+ const selectedVisibleCount = visibleOptions.filter(opt => currentValue.some(sel => this._isSameSelectValue(sel, opt))).length;
1246
+ return selectedVisibleCount > 0 && selectedVisibleCount < visibleOptions.length;
1247
+ }, /* @ts-ignore */
1248
+ ...(ngDevMode ? [{ debugName: "isIndeterminate" }] : /* istanbul ignore next */ []));
1249
+ this.isChecked = computed(() => {
1250
+ if (!this.props.multiple || !this.props.search)
1251
+ return false;
1252
+ const visibleOptions = this.filteredOptions().filter(o => !o.disabled);
1253
+ if (visibleOptions.length === 0)
1254
+ return false;
1255
+ const currentValue = this.formControl.value;
1256
+ if (!isArray(currentValue))
1257
+ return false;
1258
+ const selectedVisibleCount = visibleOptions.filter(opt => currentValue.some(sel => this._isSameSelectValue(sel, opt))).length;
1259
+ return selectedVisibleCount > 0 && selectedVisibleCount === visibleOptions.length;
1260
+ }, /* @ts-ignore */
1261
+ ...(ngDevMode ? [{ debugName: "isChecked" }] : /* istanbul ignore next */ []));
1262
+ this.allOptions = computed(() => {
1263
+ if (this.urlData().length > 0) {
1264
+ return this.urlData();
1265
+ }
1266
+ return this.optionsData() || [];
1267
+ }, /* @ts-ignore */
1268
+ ...(ngDevMode ? [{ debugName: "allOptions" }] : /* istanbul ignore next */ []));
1269
+ this._searchText = signal('', /* @ts-ignore */
1270
+ ...(ngDevMode ? [{ debugName: "_searchText" }] : /* istanbul ignore next */ []));
1271
+ this._lastDomain = undefined;
1272
+ this._lastOptions = undefined;
1273
+ this._domainDataService = inject(DomainDataService);
852
1274
  this._destroyRef = inject(DestroyRef);
853
- this._urlData = [];
854
1275
  }
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 || [];
1276
+ ngOnInit() {
1277
+ this._lastDomain = this.props.domain;
1278
+ this._lastOptions = this.field.props?.options;
1279
+ this._refreshData();
1280
+ if (!isUndefined(this.formControl.value) && !isArray(this.formControl.value) && this.props.multiple) {
1281
+ this.formControl.setValue([this.formControl.value]);
861
1282
  }
1283
+ this.searchControl.valueChanges
1284
+ .pipe(takeUntilDestroyed(this._destroyRef))
1285
+ .subscribe((value) => {
1286
+ this._searchText.set(value ?? '');
1287
+ });
862
1288
  }
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
- });
1289
+ ngDoCheck() {
1290
+ const currentDomain = this.props.domain;
1291
+ const currentOptions = this.field.props?.options;
1292
+ let shouldRefresh = false;
1293
+ // 1. 检查 domain 变化
1294
+ if (!isEqual(currentDomain, this._lastDomain)) {
1295
+ this._lastDomain = currentDomain;
1296
+ shouldRefresh = true;
868
1297
  }
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
- });
1298
+ // 2. 检查 options 变化 (仅当 domain 未配置时,options 才生效,但为了稳妥,只要变了就更新)
1299
+ // 注意:如果 domain 存在,urlData 优先级更高,但更新 optionsData 也无妨,因为 allOptions computed 会优先取 urlData
1300
+ if (!isEqual(currentOptions, this._lastOptions)) {
1301
+ this._lastOptions = currentOptions;
1302
+ shouldRefresh = true;
1303
+ }
1304
+ if (shouldRefresh) {
1305
+ this._refreshData();
1306
+ }
1307
+ }
1308
+ toggleSelectAll(selectAllValue) {
1309
+ const visibleOptions = this.filteredOptions().filter(o => !o.disabled);
1310
+ if (selectAllValue) {
1311
+ this.formControl.setValue([...visibleOptions]);
893
1312
  }
894
1313
  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
- });
1314
+ this.formControl.setValue([]);
1315
+ }
1316
+ this.formControl.markAsDirty();
919
1317
  }
920
1318
  getAriaLabelledby() {
921
1319
  if (this.props.attributes?.['aria-labelledby']) {
@@ -926,51 +1324,6 @@ class CmatSelectTypeComponent extends FieldType {
926
1324
  getAriaLabel() {
927
1325
  return this.props.attributes?.['aria-label'];
928
1326
  }
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
1327
  compareWithFn(o1, o2) {
975
1328
  if (!o1 || !o2) {
976
1329
  return o1 === o2;
@@ -980,15 +1333,27 @@ class CmatSelectTypeComponent extends FieldType {
980
1333
  _isSameSelectValue(left, right) {
981
1334
  return left.value === right.value && left.label === right.label;
982
1335
  }
983
- _toSearchText(value) {
984
- return typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean' ? String(value) : '';
1336
+ _refreshData() {
1337
+ const domain = this.props.domain;
1338
+ // 使用 DomainDataService 加载远程数据
1339
+ this._domainDataService.load(domain, this._destroyRef, {
1340
+ onSuccess: data => this.urlData.set(data),
1341
+ componentName: 'CmatSelectTypeComponent'
1342
+ });
1343
+ // 处理静态 options(当没有 domain 时)
1344
+ if (!domain?.url && this.field.props?.options && isArray(this.field.props?.options)) {
1345
+ this.optionsData.set(this.field.props.options || []);
1346
+ }
1347
+ else if (!domain?.url) {
1348
+ this.optionsData.set([]);
1349
+ }
985
1350
  }
986
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatSelectTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
987
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", 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 }); }
1351
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatSelectTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1352
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", 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
1353
  }
989
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatSelectTypeComponent, decorators: [{
1354
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatSelectTypeComponent, decorators: [{
990
1355
  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"] }]
1356
+ 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 \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
1357
  }], ctorParameters: () => [] });
993
1358
 
994
1359
  class CmatSelectTreeTypeComponent extends FieldType$1 {
@@ -1004,47 +1369,42 @@ class CmatSelectTreeTypeComponent extends FieldType$1 {
1004
1369
  customTriggerLabelTemplate: '${name}'
1005
1370
  },
1006
1371
  };
1007
- this.urlData = [];
1008
- this.refreshVersion = signal(0, ...(ngDevMode ? [{ debugName: "refreshVersion" }] : /* istanbul ignore next */ []));
1009
- this._http = inject(HttpClient);
1372
+ this.urlData = signal([], /* @ts-ignore */
1373
+ ...(ngDevMode ? [{ debugName: "urlData" }] : /* istanbul ignore next */ []));
1374
+ this._lastDomain = undefined;
1010
1375
  this._destroyRef = inject(DestroyRef);
1376
+ this._domainDataService = inject(DomainDataService);
1011
1377
  }
1012
1378
  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
- }
1379
+ this._lastDomain = this.props.domain;
1380
+ this._refreshData();
1381
+ }
1382
+ ngDoCheck() {
1383
+ const currentDomain = this.props.domain;
1384
+ let shouldRefresh = false;
1385
+ // 1. 检查 domain 变化
1386
+ if (!isEqual(currentDomain, this._lastDomain)) {
1387
+ this._lastDomain = currentDomain;
1388
+ shouldRefresh = true;
1389
+ }
1390
+ if (shouldRefresh) {
1391
+ this._refreshData();
1392
+ }
1393
+ }
1394
+ _refreshData() {
1395
+ const domain = this.props.domain;
1396
+ // 使用 DomainDataService 加载远程数据
1397
+ this._domainDataService.load(domain, this._destroyRef, {
1398
+ onSuccess: data => this.urlData.set(data),
1399
+ componentName: 'CmatSelectTreeTypeComponent'
1400
+ });
1041
1401
  }
1042
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatSelectTreeTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1043
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.10", 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 }); }
1402
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatSelectTreeTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1403
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.2", 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
1404
  }
1045
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatSelectTreeTypeComponent, decorators: [{
1405
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatSelectTreeTypeComponent, decorators: [{
1046
1406
  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"] }]
1407
+ 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
1408
  }], ctorParameters: () => [] });
1049
1409
 
1050
1410
  class CmatSelectTableTypeComponent extends FieldType$1 {
@@ -1058,47 +1418,65 @@ class CmatSelectTableTypeComponent extends FieldType$1 {
1058
1418
  customTriggerLabelTemplate: '${name}'
1059
1419
  },
1060
1420
  };
1061
- this.urlData = { columns: [], data: [] };
1062
- this.refreshVersion = signal(0, ...(ngDevMode ? [{ debugName: "refreshVersion" }] : /* istanbul ignore next */ []));
1063
- this._http = inject(HttpClient);
1421
+ this.urlData = signal({ columns: [], data: [] }, /* @ts-ignore */
1422
+ ...(ngDevMode ? [{ debugName: "urlData" }] : /* istanbul ignore next */ []));
1423
+ this._lastDomain = undefined;
1064
1424
  this._destroyRef = inject(DestroyRef);
1425
+ this._domainDataService = inject(DomainDataService);
1065
1426
  }
1066
1427
  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
- }
1428
+ this._lastDomain = this.props.domain;
1429
+ this._refreshData();
1430
+ }
1431
+ ngDoCheck() {
1432
+ const currentDomain = this.props.domain;
1433
+ let shouldRefresh = false;
1434
+ // 1. 检查 domain 变化
1435
+ if (!isEqual(currentDomain, this._lastDomain)) {
1436
+ this._lastDomain = currentDomain;
1437
+ shouldRefresh = true;
1438
+ }
1439
+ if (shouldRefresh) {
1440
+ this._refreshData();
1441
+ }
1442
+ }
1443
+ _refreshData() {
1444
+ const domain = this.props.domain;
1445
+ // 使用 DomainDataService 加载远程数据
1446
+ this._domainDataService.load(domain, this._destroyRef, {
1447
+ transform: (rawData) => {
1448
+ // Select-Table 需要特殊验证数据结构
1449
+ if (this._isValidDataSource(rawData)) {
1450
+ return rawData;
1451
+ }
1452
+ console.warn('Invalid select-table data structure');
1453
+ return [];
1454
+ },
1455
+ onSuccess: (data) => {
1456
+ if (data.length > 0) {
1457
+ this.urlData.set(data[0]);
1084
1458
  }
1085
1459
  else {
1086
- this.urlData = { columns: [], data: [] };
1460
+ this.urlData.set({ columns: [], data: [] });
1087
1461
  }
1088
- this.refreshVersion.update(value => value + 1);
1089
- });
1090
- }
1091
- else {
1092
- this.urlData = { columns: [], data: [] };
1093
- this.refreshVersion.update(value => value + 1);
1094
- }
1462
+ },
1463
+ componentName: 'CmatSelectTableTypeComponent'
1464
+ });
1095
1465
  }
1096
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatSelectTableTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1097
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.10", 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 }); }
1466
+ _isValidDataSource(data) {
1467
+ return (typeof data === 'object' &&
1468
+ data !== null &&
1469
+ 'columns' in data &&
1470
+ 'data' in data &&
1471
+ Array.isArray(data.columns) &&
1472
+ Array.isArray(data.data));
1473
+ }
1474
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatSelectTableTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1475
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.2", 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
1476
  }
1099
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatSelectTableTypeComponent, decorators: [{
1477
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatSelectTableTypeComponent, decorators: [{
1100
1478
  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"] }]
1479
+ 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
1480
  }], ctorParameters: () => [] });
1103
1481
 
1104
1482
  class CmatStepperHorizontalTypeComponent extends FieldType$2 {
@@ -1110,10 +1488,10 @@ class CmatStepperHorizontalTypeComponent extends FieldType$2 {
1110
1488
  }
1111
1489
  return field.fieldGroup ? field.fieldGroup.every(f => this.isValid(f)) : true;
1112
1490
  }
1113
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatStepperHorizontalTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1114
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", 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", "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 }); }
1491
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatStepperHorizontalTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1492
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", 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
1493
  }
1116
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatStepperHorizontalTypeComponent, decorators: [{
1494
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatStepperHorizontalTypeComponent, decorators: [{
1117
1495
  type: Component,
1118
1496
  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
1497
  }] });
@@ -1127,10 +1505,10 @@ class CmatStepperVerticalTypeComponent extends FieldType$2 {
1127
1505
  }
1128
1506
  return field.fieldGroup ? field.fieldGroup.every(f => this.isValid(f)) : true;
1129
1507
  }
1130
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatStepperVerticalTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1131
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", 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", "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 }); }
1508
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatStepperVerticalTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1509
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", 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
1510
  }
1133
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatStepperVerticalTypeComponent, decorators: [{
1511
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatStepperVerticalTypeComponent, decorators: [{
1134
1512
  type: Component,
1135
1513
  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
1514
  }] });
@@ -1139,15 +1517,41 @@ class CmatTableTypeComponent extends FieldArrayType {
1139
1517
  constructor() {
1140
1518
  super();
1141
1519
  this.inlineform = new FormGroup({});
1142
- this.currentMode = {};
1143
- this.displayedColumns = [];
1144
- this.refreshVersion = signal(0, ...(ngDevMode ? [{ debugName: "refreshVersion" }] : /* istanbul ignore next */ []));
1145
- this.dialogType = '';
1520
+ this.columns = computed(() => {
1521
+ const fieldGroup = this._fieldModel.fieldArray?.fieldGroup?.[0]?.fieldGroup ?? [];
1522
+ return fieldGroup
1523
+ .filter(field => field.props?.showColumn)
1524
+ .map(field => ({
1525
+ key: String(field.key ?? ''),
1526
+ label: field.props?.label ?? '',
1527
+ }));
1528
+ }, /* @ts-ignore */
1529
+ ...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
1530
+ this.displayedColumns = computed(() => {
1531
+ const cols = this.columns().map(c => c.key);
1532
+ if (this.props.disabled) {
1533
+ return cols;
1534
+ }
1535
+ return [...cols, 'operate'];
1536
+ }, /* @ts-ignore */
1537
+ ...(ngDevMode ? [{ debugName: "displayedColumns" }] : /* istanbul ignore next */ []));
1538
+ this.refreshVersion = signal(0, /* @ts-ignore */
1539
+ ...(ngDevMode ? [{ debugName: "refreshVersion" }] : /* istanbul ignore next */ []));
1540
+ this.currentMode = signal({}, /* @ts-ignore */
1541
+ ...(ngDevMode ? [{ debugName: "currentMode" }] : /* istanbul ignore next */ []));
1542
+ this.currentIndex = signal(-1, /* @ts-ignore */
1543
+ ...(ngDevMode ? [{ debugName: "currentIndex" }] : /* istanbul ignore next */ []));
1544
+ this.dialogType = signal('', /* @ts-ignore */
1545
+ ...(ngDevMode ? [{ debugName: "dialogType" }] : /* istanbul ignore next */ []));
1146
1546
  this.defaultOptions = {
1147
1547
  props: {
1148
1548
  addText: '新增'
1149
1549
  },
1150
1550
  };
1551
+ this.dialogRef = viewChild('dialogRef', /* @ts-ignore */
1552
+ ...(ngDevMode ? [{ debugName: "dialogRef" }] : /* istanbul ignore next */ []));
1553
+ this.table = viewChild('table', /* @ts-ignore */
1554
+ ...(ngDevMode ? [{ debugName: "table" }] : /* istanbul ignore next */ []));
1151
1555
  this._dialog = inject(MatDialog);
1152
1556
  this._viewContainerRef = inject(ViewContainerRef);
1153
1557
  }
@@ -1155,7 +1559,7 @@ class CmatTableTypeComponent extends FieldArrayType {
1155
1559
  return this._fieldModel.fieldArray?.fieldGroup ?? [];
1156
1560
  }
1157
1561
  get key() {
1158
- return this._fieldModel.fieldArray?.fieldGroup?.[0]?.id ?? '';
1562
+ return this._fieldModel.fieldArray?.fieldGroup?.[0]?.key ?? 'data';
1159
1563
  }
1160
1564
  get _tableProps() {
1161
1565
  return this.props;
@@ -1163,48 +1567,24 @@ class CmatTableTypeComponent extends FieldArrayType {
1163
1567
  get _fieldModel() {
1164
1568
  return this.field;
1165
1569
  }
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
1570
  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 = {};
1571
+ this.dialogType.set('add');
1572
+ this.currentMode.set({});
1189
1573
  this.inlineform.reset();
1574
+ this._openDialog();
1190
1575
  }
1191
1576
  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
1577
+ this.currentIndex.set(index);
1578
+ this.dialogType.set('edit');
1579
+ this.currentMode.set({
1580
+ [this.key]: { ...item } // 浅拷贝以防止直接修改原数据直到确认
1197
1581
  });
1198
- this._dialogRef.afterClosed()
1199
- .subscribe(() => { this.dialogType = ''; });
1200
- this.dialogType = 'edit';
1201
- this.currentMode = {
1202
- [this.key]: item
1203
- };
1582
+ this._openDialog();
1204
1583
  }
1205
- deleteRow(id) {
1206
- this.remove(id);
1207
- this.table.renderRows();
1584
+ deleteRow(index) {
1585
+ this.remove(index);
1586
+ // 触发变更检测以更新表格视图
1587
+ this.refreshVersion.update(v => v + 1);
1208
1588
  }
1209
1589
  confirm() {
1210
1590
  if (this.inlineform.invalid) {
@@ -1212,37 +1592,53 @@ class CmatTableTypeComponent extends FieldArrayType {
1212
1592
  return;
1213
1593
  }
1214
1594
  const model = this.model;
1215
- const currentValue = this.currentMode[this.key];
1216
- if (this.dialogType === 'add' && currentValue) {
1595
+ // 获取表单中编辑/新增的实际数据对象
1596
+ const currentValue = this.currentMode()[this.key];
1597
+ if (!currentValue) {
1598
+ this._dialogRef.close();
1599
+ return;
1600
+ }
1601
+ if (this.dialogType() === 'add') {
1217
1602
  this.add(model?.length ?? 0, currentValue);
1218
1603
  }
1219
- else if (this.dialogType === 'edit' && currentValue && model) {
1220
- model[this.currentIndex] = currentValue;
1604
+ else if (this.dialogType() === 'edit') {
1605
+ const index = this.currentIndex();
1606
+ if (index > -1 && model) {
1607
+ model[index] = currentValue;
1608
+ this.formControl.patchValue([...model]);
1609
+ }
1221
1610
  }
1222
- this.table.renderRows();
1223
- this.refreshVersion.update(value => value + 1);
1611
+ this.refreshVersion.update(v => v + 1);
1612
+ this.table()?.renderRows();
1224
1613
  this._dialogRef.close();
1225
1614
  }
1226
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatTableTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1227
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", 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 }); }
1615
+ _openDialog() {
1616
+ const template = this.dialogRef();
1617
+ if (!template)
1618
+ return;
1619
+ this._dialogRef = this._dialog.open(template, {
1620
+ panelClass: ['cmat-table-dialog-container'],
1621
+ viewContainerRef: this._viewContainerRef
1622
+ });
1623
+ this._dialogRef.afterClosed().subscribe(() => {
1624
+ this.dialogType.set('');
1625
+ this.currentIndex.set(-1);
1626
+ });
1627
+ }
1628
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatTableTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1629
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", 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
1630
  }
1229
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatTableTypeComponent, decorators: [{
1631
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatTableTypeComponent, decorators: [{
1230
1632
  type: Component,
1231
1633
  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
- }] } });
1634
+ 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"] }]
1635
+ }], ctorParameters: () => [], propDecorators: { dialogRef: [{ type: i0.ViewChild, args: ['dialogRef', { isSignal: true }] }], table: [{ type: i0.ViewChild, args: ['table', { isSignal: true }] }] } });
1240
1636
 
1241
1637
  class CmatTabTypeComponent extends FieldType$1 {
1242
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatTabTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1243
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", 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 }); }
1638
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatTabTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1639
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", 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
1640
  }
1245
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatTabTypeComponent, decorators: [{
1641
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatTabTypeComponent, decorators: [{
1246
1642
  type: Component,
1247
1643
  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
1644
  }] });
@@ -1250,71 +1646,72 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImpo
1250
1646
  class CmatTagsTypeComponent extends FieldType {
1251
1647
  constructor() {
1252
1648
  super();
1253
- this.urlData = [];
1254
- this.optionsData = [];
1255
- this.refreshVersion = signal(0, ...(ngDevMode ? [{ debugName: "refreshVersion" }] : /* istanbul ignore next */ []));
1256
- this._http = inject(HttpClient);
1649
+ this.allTags = computed(() => {
1650
+ const domainData = this._urlDataSignal();
1651
+ if (domainData.length > 0) {
1652
+ return domainData;
1653
+ }
1654
+ return this._staticOptionsSignal();
1655
+ }, /* @ts-ignore */
1656
+ ...(ngDevMode ? [{ debugName: "allTags" }] : /* istanbul ignore next */ []));
1657
+ this.filteredItems = signal([], /* @ts-ignore */
1658
+ ...(ngDevMode ? [{ debugName: "filteredItems" }] : /* istanbul ignore next */ []));
1659
+ this.refreshVersion = signal(0, /* @ts-ignore */
1660
+ ...(ngDevMode ? [{ debugName: "refreshVersion" }] : /* istanbul ignore next */ []));
1661
+ this._urlDataSignal = signal([], /* @ts-ignore */
1662
+ ...(ngDevMode ? [{ debugName: "_urlDataSignal" }] : /* istanbul ignore next */ []));
1663
+ this._staticOptionsSignal = signal([], /* @ts-ignore */
1664
+ ...(ngDevMode ? [{ debugName: "_staticOptionsSignal" }] : /* istanbul ignore next */ []));
1665
+ this._tagsPanelOrigin = viewChild('tagsPanelOrigin', /* @ts-ignore */
1666
+ ...(ngDevMode ? [{ debugName: "_tagsPanelOrigin" }] : /* istanbul ignore next */ []));
1667
+ this._tagsPanel = viewChild('tagsPanel', /* @ts-ignore */
1668
+ ...(ngDevMode ? [{ debugName: "_tagsPanel" }] : /* istanbul ignore next */ []));
1669
+ this._lastDomain = undefined;
1670
+ this._lastOptions = undefined;
1257
1671
  this._overlay = inject(Overlay);
1258
1672
  this._viewContainerRef = inject(ViewContainerRef);
1259
1673
  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
- }
1674
+ this._domainDataService = inject(DomainDataService);
1273
1675
  }
1274
1676
  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
- }
1677
+ this._lastDomain = this.props.domain;
1678
+ this._lastOptions = this.field.props?.options;
1679
+ this._refreshDomainData();
1680
+ this._refreshOptionData();
1681
+ }
1682
+ ngDoCheck() {
1683
+ const currentDomain = this.props.domain;
1684
+ const currentOptions = this.field.props?.options;
1685
+ // 1. 检查 domain 变化
1686
+ if (!isEqual(currentDomain, this._lastDomain)) {
1687
+ this._lastDomain = currentDomain;
1688
+ this._refreshDomainData();
1689
+ }
1690
+ // 2. 检查 options 变化 (仅当 domain 未配置时,options 才生效,但为了稳妥,只要变了就更新)
1691
+ // 注意:如果 domain 存在,urlData 优先级更高,但更新 optionsData 也无妨,因为 allOptions computed 会优先取 urlData
1692
+ if (!isEqual(currentOptions, this._lastOptions)) {
1693
+ this._lastOptions = currentOptions;
1694
+ this._refreshOptionData();
1695
+ }
1696
+ }
1697
+ // --- 业务逻辑方法 ---
1311
1698
  openTagsPanel() {
1699
+ // 每次打开时,重置过滤列表为所有可用标签
1700
+ this._syncFilteredItems();
1701
+ const origin = this._tagsPanelOrigin();
1702
+ const template = this._tagsPanel();
1703
+ if (!origin || !template)
1704
+ return;
1705
+ // 如果已经打开,先关闭
1706
+ if (this._tagsPanelOverlayRef?.hasAttached()) {
1707
+ this._tagsPanelOverlayRef.detach();
1708
+ }
1312
1709
  this._tagsPanelOverlayRef = this._overlay.create({
1313
1710
  backdropClass: '',
1314
1711
  hasBackdrop: true,
1315
1712
  scrollStrategy: this._overlay.scrollStrategies.block(),
1316
1713
  positionStrategy: this._overlay.position()
1317
- .flexibleConnectedTo(this._tagsPanelOrigin.nativeElement)
1714
+ .flexibleConnectedTo(origin.nativeElement)
1318
1715
  .withFlexibleDimensions(true)
1319
1716
  .withViewportMargin(64)
1320
1717
  .withLockedPosition(true)
@@ -1327,59 +1724,92 @@ class CmatTagsTypeComponent extends FieldType {
1327
1724
  }
1328
1725
  ])
1329
1726
  });
1330
- this._tagsPanelOverlayRef.attachments().subscribe(() => {
1331
- this._tagsPanelOverlayRef.overlayElement.querySelector('input')?.focus();
1332
- });
1333
- const templatePortal = new TemplatePortal(this._tagsPanel, this._viewContainerRef);
1727
+ const templatePortal = new TemplatePortal(template, this._viewContainerRef);
1334
1728
  this._tagsPanelOverlayRef.attach(templatePortal);
1729
+ // 聚焦输入框
1730
+ setTimeout(() => {
1731
+ this._tagsPanelOverlayRef.overlayElement.querySelector('input')?.focus();
1732
+ }, 0);
1335
1733
  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
- }
1734
+ this.closeTagsPanel();
1344
1735
  });
1345
1736
  }
1737
+ closeTagsPanel() {
1738
+ if (this._tagsPanelOverlayRef?.hasAttached()) {
1739
+ this._tagsPanelOverlayRef.detach();
1740
+ this._tagsPanelOverlayRef.dispose();
1741
+ }
1742
+ }
1346
1743
  filterTags(event) {
1347
1744
  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)));
1745
+ const all = this.allTags();
1746
+ if (!value) {
1747
+ this.filteredItems.set(all);
1748
+ return;
1749
+ }
1750
+ const filtered = all.filter((tag) => this._toSearchText(tag.label).toLowerCase().includes(value) ||
1751
+ this._toSearchText(tag.value).toLowerCase().includes(value));
1752
+ this.filteredItems.set(filtered);
1349
1753
  }
1350
1754
  toggleTag(tag) {
1351
1755
  if (tag.disabled)
1352
1756
  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);
1757
+ const currentVal = this.formControl.value ?? [];
1758
+ // 使用不可变方式更新数组
1759
+ const existsIndex = currentVal.findIndex((i) => i.value === tag.value);
1760
+ let newVal;
1761
+ if (existsIndex > -1) {
1762
+ newVal = currentVal.filter((_, index) => index !== existsIndex);
1357
1763
  }
1358
1764
  else {
1359
- data.unshift(tag);
1765
+ newVal = [tag, ...currentVal];
1360
1766
  }
1361
- this.formControl.setValue(data);
1362
- this.refreshVersion.update(value => value + 1);
1767
+ this.formControl.setValue(newVal);
1768
+ this.refreshVersion.update(v => v + 1);
1363
1769
  }
1364
1770
  isCheck(tag) {
1365
- return (this.formControl.value?.filter((i) => i.value === tag.value).length ?? 0) > 0;
1771
+ const currentVal = this.formControl.value;
1772
+ if (!currentVal)
1773
+ return false;
1774
+ return currentVal.some((i) => i.value === tag.value);
1775
+ }
1776
+ _syncFilteredItems() {
1777
+ this.filteredItems.set(this.allTags());
1366
1778
  }
1367
1779
  _toSearchText(value) {
1368
1780
  return typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean' ? String(value) : '';
1369
1781
  }
1370
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatTagsTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1371
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", 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 }); }
1782
+ _refreshDomainData() {
1783
+ const domain = this.props.domain;
1784
+ // 使用 DomainDataService 加载远程数据
1785
+ this._domainDataService.load(domain, this._destroyRef, {
1786
+ onSuccess: (data) => {
1787
+ this._urlDataSignal.set(data);
1788
+ this._syncFilteredItems();
1789
+ },
1790
+ componentName: 'CmatTagsTypeComponent'
1791
+ });
1792
+ }
1793
+ _refreshOptionData() {
1794
+ if (isArray(this.field.props?.options)) {
1795
+ this._staticOptionsSignal.set(this.field.props?.options);
1796
+ this._syncFilteredItems();
1797
+ }
1798
+ else if (this.field.props?.options && !isArray(this.field.props?.options)) {
1799
+ // 处理 Observable options
1800
+ this.field.props.options.pipe(takeUntilDestroyed(this._destroyRef)).subscribe((data) => {
1801
+ this._staticOptionsSignal.set(data || []);
1802
+ this._syncFilteredItems();
1803
+ });
1804
+ }
1805
+ }
1806
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatTagsTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1807
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", 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
1808
  }
1373
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatTagsTypeComponent, decorators: [{
1809
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatTagsTypeComponent, decorators: [{
1374
1810
  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
- }] } });
1811
+ 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"] }]
1812
+ }], ctorParameters: () => [], propDecorators: { _tagsPanelOrigin: [{ type: i0.ViewChild, args: ['tagsPanelOrigin', { isSignal: true }] }], _tagsPanel: [{ type: i0.ViewChild, args: ['tagsPanel', { isSignal: true }] }] } });
1383
1813
 
1384
1814
  class CmatTextareaTypeComponent extends FieldType$1 {
1385
1815
  constructor() {
@@ -1391,10 +1821,10 @@ class CmatTextareaTypeComponent extends FieldType$1 {
1391
1821
  },
1392
1822
  };
1393
1823
  }
1394
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatTextareaTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1395
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.10", 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 }); }
1824
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatTextareaTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1825
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.2", 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
1826
  }
1397
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatTextareaTypeComponent, decorators: [{
1827
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatTextareaTypeComponent, decorators: [{
1398
1828
  type: Component,
1399
1829
  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
1830
  }] });
@@ -1413,53 +1843,110 @@ class CmatUploadTypeComponent extends FieldType {
1413
1843
  autoUpload: true
1414
1844
  }
1415
1845
  };
1846
+ this._rootGroup = null;
1416
1847
  }
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([]));
1848
+ ngOnInit() {
1849
+ this._rootGroup = this._getRootGroup(this.field);
1850
+ if (this._rootGroup) {
1851
+ if (!this._rootGroup.contains('uploadId')) {
1852
+ this._rootGroup.addControl('uploadId', new FormControl([]));
1853
+ }
1854
+ if (!this._rootGroup.contains('removeId')) {
1855
+ this._rootGroup.addControl('removeId', new FormControl([]));
1856
+ }
1423
1857
  }
1424
1858
  }
1859
+ /**
1860
+ * 处理上传成功事件
1861
+ * @param id 新上传文件的 ID
1862
+ */
1425
1863
  upload(id) {
1426
- const rootValue = this.baseGroup.get('uploadId')?.value;
1427
- if (rootValue && !isNil(id)) {
1428
- this.baseGroup.get('uploadId')?.setValue([id, ...rootValue]);
1864
+ if (!id || !this._rootGroup)
1865
+ return;
1866
+ const control = this._rootGroup.get('uploadId');
1867
+ if (control) {
1868
+ const currentIds = control.value || [];
1869
+ // 避免重复添加
1870
+ if (!currentIds.includes(id)) {
1871
+ control.setValue([id, ...currentIds]);
1872
+ }
1429
1873
  }
1430
1874
  }
1875
+ /**
1876
+ * 处理移除事件
1877
+ * @param id 被移除文件的 ID
1878
+ */
1431
1879
  remove(id) {
1432
- const rootValue = this.baseGroup.get('removeId')?.value;
1433
- if (rootValue && !isNil(id)) {
1434
- this.baseGroup.get('removeId')?.setValue([id, ...rootValue]);
1880
+ if (!id || !this._rootGroup)
1881
+ return;
1882
+ const control = this._rootGroup.get('removeId');
1883
+ if (control) {
1884
+ const currentIds = control.value || [];
1885
+ // 避免重复添加
1886
+ if (!currentIds.includes(id)) {
1887
+ control.setValue([id, ...currentIds]);
1888
+ }
1435
1889
  }
1436
1890
  }
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;
1891
+ /**
1892
+ * 处理文件列表更新事件
1893
+ * @param data 文件数据数组或单个对象
1894
+ */
1895
+ updateData(data) {
1896
+ const items = Array.isArray(data) ? data : [data];
1897
+ const standardizedFiles = items.map(item => this._standardizeFileItem(item));
1898
+ // 过滤掉无效项
1899
+ const validFiles = standardizedFiles.filter((item) => item !== null);
1900
+ this.formControl.setValue(validFiles);
1901
+ }
1902
+ /**
1903
+ * 递归查找根 FormGroup
1904
+ * @param field 当前 Formly 字段
1905
+ * @returns 根 FormGroup
1906
+ */
1907
+ _getRootGroup(field) {
1908
+ // Formly 字段通常有 parent 属性指向父字段,直到根字段
1909
+ // 根字段的 form 属性通常是根 FormGroup
1910
+ let currentField = field;
1911
+ while (currentField.parent) {
1912
+ currentField = currentField.parent;
1913
+ }
1914
+ // 尝试从根字段获取 form,或者直接使用 field.form 如果它是根
1915
+ // 注意:在某些 Formly 配置中,field.form 可能始终指向根表单
1916
+ if (currentField.form && currentField.form instanceof UntypedFormGroup) {
1917
+ return currentField.form;
1918
+ }
1919
+ // fallback: 如果找不到,返回 null,调用者需处理
1920
+ return null;
1921
+ }
1922
+ /**
1923
+ * 标准化文件对象,确保包含必要的字段
1924
+ * @param item 原始文件数据
1925
+ * @returns 标准化的文件对象或 null(如果无效)
1926
+ */
1927
+ _standardizeFileItem(item) {
1928
+ if (typeof item !== 'object' || item === null) {
1929
+ return null;
1930
+ }
1931
+ const obj = item;
1932
+ if (typeof obj.id !== 'string') {
1933
+ return null;
1934
+ }
1935
+ return {
1936
+ id: obj.id,
1937
+ name: typeof obj.name === 'string' ? obj.name : '',
1938
+ type: typeof obj.type === 'string' ? obj.type : '',
1939
+ size: typeof obj.size === 'number' ? obj.size : 0,
1940
+ // 保留其他额外属性
1941
+ ...obj
1942
+ };
1456
1943
  }
1457
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatUploadTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1458
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.10", 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 }); }
1944
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatUploadTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1945
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.2", 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
1946
  }
1460
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatUploadTypeComponent, decorators: [{
1947
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatUploadTypeComponent, decorators: [{
1461
1948
  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"] }]
1949
+ 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
1950
  }] });
1464
1951
 
1465
1952
  Quill.register('modules/blotFormatter', BlotFormatter);
@@ -1500,16 +1987,20 @@ class CmatQuillTypeComponent extends FieldType {
1500
1987
  filePath: 'path'
1501
1988
  }
1502
1989
  };
1503
- this.refreshVersion = signal(0, ...(ngDevMode ? [{ debugName: "refreshVersion" }] : /* istanbul ignore next */ []));
1990
+ this.isExporting = signal(false, /* @ts-ignore */
1991
+ ...(ngDevMode ? [{ debugName: "isExporting" }] : /* istanbul ignore next */ []));
1992
+ this.imgInput = viewChild('imgInput', /* @ts-ignore */
1993
+ ...(ngDevMode ? [{ debugName: "imgInput" }] : /* istanbul ignore next */ []));
1994
+ this.videoInput = viewChild('videoInput', /* @ts-ignore */
1995
+ ...(ngDevMode ? [{ debugName: "videoInput" }] : /* istanbul ignore next */ []));
1996
+ this._editorInstance = signal(null, /* @ts-ignore */
1997
+ ...(ngDevMode ? [{ debugName: "_editorInstance" }] : /* istanbul ignore next */ []));
1998
+ this._imgIds = signal([], /* @ts-ignore */
1999
+ ...(ngDevMode ? [{ debugName: "_imgIds" }] : /* istanbul ignore next */ []));
1504
2000
  this._fileService = inject(CmatFilesUtilService);
1505
2001
  this._urlStateConfigService = inject(CmatUrlStateConfigService);
1506
2002
  this._destroyRef = inject(DestroyRef);
1507
- this._imgIds = [];
1508
- this._urlStateConfigService.config$
1509
- .pipe(takeUntilDestroyed(this._destroyRef))
1510
- .subscribe((config) => {
1511
- this._config = config;
1512
- });
2003
+ this._config = this._urlStateConfigService.config;
1513
2004
  }
1514
2005
  ngAfterViewInit() {
1515
2006
  const icons = Quill.import('ui/icons');
@@ -1546,70 +2037,109 @@ class CmatQuillTypeComponent extends FieldType {
1546
2037
  if (typeof fileId !== 'string') {
1547
2038
  return;
1548
2039
  }
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);
2040
+ const editor = this._editorInstance();
2041
+ const config = this._config(); // 获取配置
2042
+ if (editor && config?.fileUrl) { // 同时检查编辑器和服务配置
2043
+ const selection = editor.getSelection(true);
2044
+ const index = selection ? selection.index : editor.getLength();
2045
+ editor.insertEmbed(index, this._getMediaType(file.type), `${config.fileUrl}/download/quill/${fileId}`);
2046
+ editor.setSelection(index + 1);
2047
+ this.formControl.setValue(editor.container.innerHTML);
2048
+ }
2049
+ else {
2050
+ console.warn('无法插入图片:编辑器或文件服务配置未就绪');
2051
+ }
1552
2052
  this._upload(fileId);
1553
2053
  }
1554
- this.refreshVersion.update((value) => value + 1);
1555
2054
  });
1556
2055
  }
1557
2056
  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));
2057
+ this._editorInstance.set(editorInstance);
2058
+ // 1. 获取当前编辑器中的所有文件 ID
2059
+ const currentIds = this._extractFileIdsFromDelta(editorInstance.getContents());
2060
+ this._imgIds.set(currentIds);
2061
+ // 2. 同步清理 removeId,确保“已存在”的图片不在“待删除”列表中
2062
+ const removeControl = this.baseGroup.get('removeId');
2063
+ if (removeControl) {
2064
+ const existingRemoveIds = removeControl.value || [];
2065
+ // 过滤掉那些当前实际存在于编辑器中的 ID
2066
+ const cleanedRemoveIds = existingRemoveIds.filter(id => !currentIds.includes(id));
2067
+ // 只有当数组内容真正改变时才更新表单,避免无限循环或无效变更检测
2068
+ if (cleanedRemoveIds.length !== existingRemoveIds.length) {
2069
+ removeControl.setValue(cleanedRemoveIds);
1565
2070
  }
1566
- });
2071
+ }
1567
2072
  }
1568
2073
  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;
2074
+ const delta = contentChange.editor.getContents();
2075
+ const currentIds = this._extractFileIdsFromDelta(delta);
2076
+ const previousIds = this._imgIds();
2077
+ const removedIds = previousIds.filter(id => !currentIds.includes(id));
2078
+ if (removedIds.length > 0) {
2079
+ const removeControl = this.baseGroup.get('removeId');
2080
+ const currentRemoveList = removeControl?.value || [];
2081
+ const restoredIds = currentRemoveList.filter(id => currentIds.includes(id));
2082
+ let finalRemoveList = currentRemoveList.filter(id => !restoredIds.includes(id));
2083
+ // 添加新删除的
2084
+ finalRemoveList = [...new Set([...finalRemoveList, ...removedIds])];
2085
+ removeControl?.setValue(finalRemoveList);
2086
+ }
2087
+ this._imgIds.set(currentIds);
1587
2088
  }
1588
2089
  _imgFileHandler() {
1589
- this.imgInput.nativeElement.click();
2090
+ if (this.imgInput()) {
2091
+ this.imgInput().nativeElement.click();
2092
+ }
1590
2093
  }
1591
2094
  _videoFileHandler() {
1592
- this.videoInput.nativeElement.click();
2095
+ if (this.videoInput()) {
2096
+ this.videoInput().nativeElement.click();
2097
+ }
1593
2098
  }
1594
2099
  async _wordFileHandler() {
2100
+ const editor = this._editorInstance();
2101
+ if (!editor)
2102
+ return;
2103
+ this.isExporting.set(true);
1595
2104
  try {
1596
- const delta = this._editorInstance.getContents();
2105
+ const delta = editor.getContents();
1597
2106
  const children = await this._convertDeltaToDocxChildren(delta);
1598
2107
  const doc = new Document({
1599
- sections: [{
1600
- properties: {},
1601
- children: children
1602
- }]
2108
+ sections: [{ properties: {}, children: children }]
1603
2109
  });
1604
2110
  const blob = await Packer.toBlob(doc);
1605
- FileSaver.saveAs(blob, `${this.placeholder ?? '富文本内容下载'}${dayjs().format('YYYYMMDDHHmmss')}.docx`);
2111
+ FileSaver.saveAs(blob, `${this.placeholder ?? '文档'}_${dayjs().format('YYYYMMDD_HHmmss')}.docx`);
1606
2112
  }
1607
2113
  catch (error) {
1608
2114
  console.error('Word 导出失败:', error);
1609
2115
  }
2116
+ finally {
2117
+ this.isExporting.set(false);
2118
+ }
1610
2119
  }
1611
2120
  async _convertDeltaToDocxChildren(delta) {
1612
2121
  const children = [];
2122
+ // 1. 预加载所有图片数据 (并行)
2123
+ const imageCache = new Map();
2124
+ const imageOps = delta.ops.filter(op => typeof op.insert !== 'string' && op.insert?.image);
2125
+ await Promise.all(imageOps.map(async (op) => {
2126
+ if (typeof op.insert === 'object' && op.insert !== null && 'image' in op.insert && typeof op.insert.image === 'string') {
2127
+ const url = op.insert.image;
2128
+ if (!imageCache.has(url)) {
2129
+ const buffer = await this._getImageBuffer(url);
2130
+ const dims = await this._getImageDimensions(url);
2131
+ let type = 'png';
2132
+ if (url.toLowerCase().endsWith('.jpg') || url.toLowerCase().endsWith('.jpeg'))
2133
+ type = 'jpg';
2134
+ else if (url.toLowerCase().endsWith('.gif'))
2135
+ type = 'gif';
2136
+ else if (url.toLowerCase().endsWith('.svg'))
2137
+ type = 'svg';
2138
+ imageCache.set(url, { buffer, width: dims.width, height: dims.height, type });
2139
+ }
2140
+ }
2141
+ }));
2142
+ // 2. 构建文档结构 (同步)
1613
2143
  let currentRun = [];
1614
2144
  let currentListLevel = 0;
1615
2145
  let isList = false;
@@ -1619,11 +2149,14 @@ class CmatQuillTypeComponent extends FieldType {
1619
2149
  children.push(new Paragraph({ children: currentRun }));
1620
2150
  currentRun = [];
1621
2151
  }
1622
- const imageRun = await this._createImageRun(op.insert.image);
1623
- children.push(new Paragraph({
1624
- children: [imageRun],
1625
- alignment: AlignmentType.CENTER
1626
- }));
2152
+ const imgData = imageCache.get(op.insert.image);
2153
+ if (imgData) {
2154
+ const imageRun = this._createImageRunFromData(imgData); // 提取一个新方法
2155
+ children.push(new Paragraph({
2156
+ children: [imageRun],
2157
+ alignment: AlignmentType.CENTER
2158
+ }));
2159
+ }
1627
2160
  }
1628
2161
  else if (typeof op.insert === 'string') {
1629
2162
  const text = op.insert;
@@ -1656,6 +2189,24 @@ class CmatQuillTypeComponent extends FieldType {
1656
2189
  }
1657
2190
  return children;
1658
2191
  }
2192
+ _createImageRunFromData(data) {
2193
+ const maxWidth = 500;
2194
+ const maxHeight = 400;
2195
+ const scale = Math.min(maxWidth / data.width, maxHeight / data.height, 1);
2196
+ const imageType = data.type;
2197
+ return new ImageRun({
2198
+ data: data.buffer,
2199
+ transformation: {
2200
+ width: Math.round(data.width * scale),
2201
+ height: Math.round(data.height * scale)
2202
+ },
2203
+ type: imageType,
2204
+ fallback: {
2205
+ type: imageType !== 'svg' ? imageType : 'png',
2206
+ data: data.buffer
2207
+ }
2208
+ });
2209
+ }
1659
2210
  _createTextRun(text, attributes) {
1660
2211
  return new TextRun({
1661
2212
  text: text,
@@ -1684,46 +2235,21 @@ class CmatQuillTypeComponent extends FieldType {
1684
2235
  };
1685
2236
  return new Paragraph(paragraphOptions);
1686
2237
  }
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
2238
  async _getImageBuffer(imageUrl) {
1717
2239
  if (imageUrl.startsWith('data:image')) {
1718
2240
  const base64 = imageUrl.split(',')[1];
1719
2241
  return this._base64ToUint8Array(base64);
1720
2242
  }
2243
+ const controller = new AbortController();
2244
+ const timeoutId = setTimeout(() => controller.abort(), 10000); // 10秒超时
1721
2245
  try {
1722
2246
  const response = await fetch(imageUrl, {
1723
2247
  method: 'GET',
1724
2248
  mode: 'cors',
1725
- credentials: 'omit'
2249
+ credentials: 'omit',
2250
+ signal: controller.signal
1726
2251
  });
2252
+ clearTimeout(timeoutId);
1727
2253
  if (!response.ok) {
1728
2254
  throw new Error(`图片获取失败: ${imageUrl}`);
1729
2255
  }
@@ -1731,6 +2257,7 @@ class CmatQuillTypeComponent extends FieldType {
1731
2257
  return new Uint8Array(arrayBuffer);
1732
2258
  }
1733
2259
  catch (error) {
2260
+ clearTimeout(timeoutId);
1734
2261
  console.error('图片加载失败:', imageUrl, error);
1735
2262
  return new Uint8Array(0);
1736
2263
  }
@@ -1738,10 +2265,18 @@ class CmatQuillTypeComponent extends FieldType {
1738
2265
  async _getImageDimensions(imageUrl) {
1739
2266
  return new Promise((resolve) => {
1740
2267
  const img = new Image();
2268
+ const timeout = setTimeout(() => {
2269
+ img.onload = null;
2270
+ img.onerror = null;
2271
+ // 超时也返回默认值,保证导出流程不中断
2272
+ resolve({ width: 400, height: 300 });
2273
+ }, 5000);
1741
2274
  img.onload = () => {
2275
+ clearTimeout(timeout);
1742
2276
  resolve({ width: img.width, height: img.height });
1743
2277
  };
1744
2278
  img.onerror = () => {
2279
+ clearTimeout(timeout);
1745
2280
  resolve({ width: 400, height: 300 });
1746
2281
  };
1747
2282
  img.src = imageUrl;
@@ -1833,9 +2368,15 @@ class CmatQuillTypeComponent extends FieldType {
1833
2368
  this.fileChangeEvent(fileData.toFile());
1834
2369
  }
1835
2370
  _upload(id) {
1836
- const rootValue = this.baseGroup.get('uploadId')?.value;
1837
- if (rootValue && !isNil(id)) {
1838
- this.baseGroup.get('uploadId')?.setValue([id, ...rootValue]);
2371
+ if (isNil(id))
2372
+ return;
2373
+ const uploadControl = this.baseGroup.get('uploadId');
2374
+ if (!uploadControl)
2375
+ return;
2376
+ const currentIds = uploadControl.value || [];
2377
+ // 如果 ID 已存在,则不重复添加
2378
+ if (!currentIds.includes(id)) {
2379
+ uploadControl.setValue([id, ...currentIds]);
1839
2380
  }
1840
2381
  }
1841
2382
  _getMediaType(accept) {
@@ -1861,19 +2402,35 @@ class CmatQuillTypeComponent extends FieldType {
1861
2402
  }
1862
2403
  return baseControl;
1863
2404
  }
1864
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatQuillTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1865
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.10", 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 }); }
2405
+ _extractFileIdsFromDelta(delta) {
2406
+ const config = this._config();
2407
+ if (!config?.fileUrl)
2408
+ return [];
2409
+ // 构建标准前缀,确保以 / 结尾
2410
+ const baseUrl = `${config.fileUrl.replace(/\/$/, '')}/download/quill/`;
2411
+ const ids = new Set(); // 使用 Set 自动去重
2412
+ delta.ops.forEach((op) => {
2413
+ if (op.insert && typeof op.insert === 'object') {
2414
+ const url = op.insert.image ?? op.insert.video;
2415
+ if (url && typeof url === 'string' && url.startsWith(baseUrl)) {
2416
+ // 提取 baseUrl 之后的部分,并去除查询参数
2417
+ const relativePath = url.substring(baseUrl.length);
2418
+ const id = relativePath.split('?')[0].split('#')[0];
2419
+ if (id) {
2420
+ ids.add(id);
2421
+ }
2422
+ }
2423
+ }
2424
+ });
2425
+ return Array.from(ids);
2426
+ }
2427
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatQuillTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2428
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", 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
2429
  }
1867
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatQuillTypeComponent, decorators: [{
2430
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatQuillTypeComponent, decorators: [{
1868
2431
  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
- }] } });
2432
+ 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"] }]
2433
+ }], ctorParameters: () => [], propDecorators: { imgInput: [{ type: i0.ViewChild, args: ['imgInput', { isSignal: true }] }], videoInput: [{ type: i0.ViewChild, args: ['videoInput', { isSignal: true }] }] } });
1877
2434
 
1878
2435
  class CmatKnobTypeComponent extends FieldType {
1879
2436
  constructor() {
@@ -1893,10 +2450,10 @@ class CmatKnobTypeComponent extends FieldType {
1893
2450
  },
1894
2451
  };
1895
2452
  }
1896
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatKnobTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1897
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.10", 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 }); }
2453
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatKnobTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2454
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.2", 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
2455
  }
1899
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatKnobTypeComponent, decorators: [{
2456
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatKnobTypeComponent, decorators: [{
1900
2457
  type: Component,
1901
2458
  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
2459
  }] });
@@ -1912,10 +2469,10 @@ class CmatSliderTypeComponent extends FieldType$1 {
1912
2469
  }
1913
2470
  };
1914
2471
  }
1915
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatSliderTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1916
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.10", 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 }); }
2472
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatSliderTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2473
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.2", 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
2474
  }
1918
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CmatSliderTypeComponent, decorators: [{
2475
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CmatSliderTypeComponent, decorators: [{
1919
2476
  type: Component,
1920
2477
  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
2478
  }] });
@@ -1924,5 +2481,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImpo
1924
2481
  * Generated bundle index. Do not edit.
1925
2482
  */
1926
2483
 
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 };
2484
+ 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
2485
  //# sourceMappingURL=cmat-components-custom-formly.mjs.map