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.
- package/fesm2022/cmat-components-adapter.mjs +9 -9
- package/fesm2022/cmat-components-adapter.mjs.map +1 -1
- package/fesm2022/cmat-components-breadcrumb.mjs +98 -80
- package/fesm2022/cmat-components-breadcrumb.mjs.map +1 -1
- package/fesm2022/cmat-components-card.mjs +26 -34
- package/fesm2022/cmat-components-card.mjs.map +1 -1
- package/fesm2022/cmat-components-carousel.mjs +467 -556
- package/fesm2022/cmat-components-carousel.mjs.map +1 -1
- package/fesm2022/cmat-components-cascade.mjs +270 -259
- package/fesm2022/cmat-components-cascade.mjs.map +1 -1
- package/fesm2022/cmat-components-chip-input.mjs +200 -116
- package/fesm2022/cmat-components-chip-input.mjs.map +1 -1
- package/fesm2022/cmat-components-code-editor.mjs +85 -38
- package/fesm2022/cmat-components-code-editor.mjs.map +1 -1
- package/fesm2022/cmat-components-color-picker.mjs +841 -0
- package/fesm2022/cmat-components-color-picker.mjs.map +1 -0
- package/fesm2022/cmat-components-custom-formly.mjs +1395 -838
- package/fesm2022/cmat-components-custom-formly.mjs.map +1 -1
- package/fesm2022/cmat-components-data-picker.mjs +996 -0
- package/fesm2022/cmat-components-data-picker.mjs.map +1 -0
- package/fesm2022/cmat-components-date-range.mjs +310 -264
- package/fesm2022/cmat-components-date-range.mjs.map +1 -1
- package/fesm2022/cmat-components-date-time-display.mjs +16 -20
- package/fesm2022/cmat-components-date-time-display.mjs.map +1 -1
- package/fesm2022/cmat-components-drawer.mjs +120 -137
- package/fesm2022/cmat-components-drawer.mjs.map +1 -1
- package/fesm2022/cmat-components-empty-state.mjs +17 -24
- package/fesm2022/cmat-components-empty-state.mjs.map +1 -1
- package/fesm2022/cmat-components-file-preview.mjs +18 -24
- package/fesm2022/cmat-components-file-preview.mjs.map +1 -1
- package/fesm2022/cmat-components-filter-toolbar.mjs +30 -39
- package/fesm2022/cmat-components-filter-toolbar.mjs.map +1 -1
- package/fesm2022/cmat-components-form-actions.mjs +12 -12
- package/fesm2022/cmat-components-form-actions.mjs.map +1 -1
- package/fesm2022/cmat-components-fullscreen.mjs +10 -10
- package/fesm2022/cmat-components-fullscreen.mjs.map +1 -1
- package/fesm2022/cmat-components-highlight.mjs +48 -41
- package/fesm2022/cmat-components-highlight.mjs.map +1 -1
- package/fesm2022/cmat-components-image-viewer.mjs +104 -107
- package/fesm2022/cmat-components-image-viewer.mjs.map +1 -1
- package/fesm2022/cmat-components-inline-loading.mjs +12 -15
- package/fesm2022/cmat-components-inline-loading.mjs.map +1 -1
- package/fesm2022/cmat-components-json-editor.mjs +118 -75
- package/fesm2022/cmat-components-json-editor.mjs.map +1 -1
- package/fesm2022/cmat-components-knob-input.mjs +196 -178
- package/fesm2022/cmat-components-knob-input.mjs.map +1 -1
- package/fesm2022/cmat-components-masonry.mjs +26 -41
- package/fesm2022/cmat-components-masonry.mjs.map +1 -1
- package/fesm2022/cmat-components-material-color-picker.mjs +81 -80
- package/fesm2022/cmat-components-material-color-picker.mjs.map +1 -1
- package/fesm2022/cmat-components-material-datetimepicker.mjs +1212 -1287
- package/fesm2022/cmat-components-material-datetimepicker.mjs.map +1 -1
- package/fesm2022/cmat-components-navigation.mjs +467 -450
- package/fesm2022/cmat-components-navigation.mjs.map +1 -1
- package/fesm2022/cmat-components-opt-input.mjs +143 -132
- package/fesm2022/cmat-components-opt-input.mjs.map +1 -1
- package/fesm2022/cmat-components-org-chart.mjs +68 -83
- package/fesm2022/cmat-components-org-chart.mjs.map +1 -1
- package/fesm2022/cmat-components-page-header.mjs +18 -24
- package/fesm2022/cmat-components-page-header.mjs.map +1 -1
- package/fesm2022/cmat-components-pagination.mjs +220 -136
- package/fesm2022/cmat-components-pagination.mjs.map +1 -1
- package/fesm2022/cmat-components-password-strength.mjs +262 -215
- package/fesm2022/cmat-components-password-strength.mjs.map +1 -1
- package/fesm2022/cmat-components-popover.mjs +227 -195
- package/fesm2022/cmat-components-popover.mjs.map +1 -1
- package/fesm2022/cmat-components-progress-bar.mjs +15 -34
- package/fesm2022/cmat-components-progress-bar.mjs.map +1 -1
- package/fesm2022/cmat-components-qrcode.mjs +95 -88
- package/fesm2022/cmat-components-qrcode.mjs.map +1 -1
- package/fesm2022/cmat-components-rating.mjs +70 -67
- package/fesm2022/cmat-components-rating.mjs.map +1 -1
- package/fesm2022/cmat-components-rich-text-editor.mjs +23 -26
- package/fesm2022/cmat-components-rich-text-editor.mjs.map +1 -1
- package/fesm2022/cmat-components-select-search.mjs +190 -159
- package/fesm2022/cmat-components-select-search.mjs.map +1 -1
- package/fesm2022/cmat-components-select-table.mjs +276 -213
- package/fesm2022/cmat-components-select-table.mjs.map +1 -1
- package/fesm2022/cmat-components-select-tree.mjs +178 -128
- package/fesm2022/cmat-components-select-tree.mjs.map +1 -1
- package/fesm2022/cmat-components-skeleton.mjs +44 -28
- package/fesm2022/cmat-components-skeleton.mjs.map +1 -1
- package/fesm2022/cmat-components-speed-dial.mjs +107 -163
- package/fesm2022/cmat-components-speed-dial.mjs.map +1 -1
- package/fesm2022/cmat-components-status-tag.mjs +29 -36
- package/fesm2022/cmat-components-status-tag.mjs.map +1 -1
- package/fesm2022/cmat-components-table-toolbar.mjs +14 -18
- package/fesm2022/cmat-components-table-toolbar.mjs.map +1 -1
- package/fesm2022/cmat-components-timeline.mjs +111 -118
- package/fesm2022/cmat-components-timeline.mjs.map +1 -1
- package/fesm2022/cmat-components-toast.mjs +65 -66
- package/fesm2022/cmat-components-toast.mjs.map +1 -1
- package/fesm2022/cmat-components-transfer-picker.mjs +130 -160
- package/fesm2022/cmat-components-transfer-picker.mjs.map +1 -1
- package/fesm2022/cmat-components-treetable.mjs +32 -39
- package/fesm2022/cmat-components-treetable.mjs.map +1 -1
- package/fesm2022/cmat-components-upload.mjs +186 -176
- package/fesm2022/cmat-components-upload.mjs.map +1 -1
- package/fesm2022/cmat-directives-animate-on-scroll.mjs +25 -28
- package/fesm2022/cmat-directives-animate-on-scroll.mjs.map +1 -1
- package/fesm2022/cmat-directives-arrow-cursor.mjs +85 -92
- package/fesm2022/cmat-directives-arrow-cursor.mjs.map +1 -1
- package/fesm2022/cmat-directives-autofocus.mjs +3 -3
- package/fesm2022/cmat-directives-autofocus.mjs.map +1 -1
- package/fesm2022/cmat-directives-data-exporter.mjs +49 -50
- package/fesm2022/cmat-directives-data-exporter.mjs.map +1 -1
- package/fesm2022/cmat-directives-debounce.mjs +16 -19
- package/fesm2022/cmat-directives-debounce.mjs.map +1 -1
- package/fesm2022/cmat-directives-digit-only.mjs +60 -69
- package/fesm2022/cmat-directives-digit-only.mjs.map +1 -1
- package/fesm2022/cmat-directives-equal-validator.mjs +3 -3
- package/fesm2022/cmat-directives-equal-validator.mjs.map +1 -1
- package/fesm2022/cmat-directives-seamless-auto-scroll.mjs +31 -30
- package/fesm2022/cmat-directives-seamless-auto-scroll.mjs.map +1 -1
- package/fesm2022/cmat-lib-mock-api.mjs +6 -6
- package/fesm2022/cmat-lib-mock-api.mjs.map +1 -1
- package/fesm2022/cmat-pipes-bytes.mjs +3 -3
- package/fesm2022/cmat-pipes-bytes.mjs.map +1 -1
- package/fesm2022/cmat-pipes-date-format.mjs +3 -3
- package/fesm2022/cmat-pipes-date-format.mjs.map +1 -1
- package/fesm2022/cmat-pipes-find-by-key.mjs +3 -3
- package/fesm2022/cmat-pipes-find-by-key.mjs.map +1 -1
- package/fesm2022/cmat-pipes-group-by.mjs +3 -3
- package/fesm2022/cmat-pipes-group-by.mjs.map +1 -1
- package/fesm2022/cmat-pipes-keys.mjs +3 -3
- package/fesm2022/cmat-pipes-keys.mjs.map +1 -1
- package/fesm2022/cmat-pipes-secure.mjs +7 -13
- package/fesm2022/cmat-pipes-secure.mjs.map +1 -1
- package/fesm2022/cmat-pipes-uppercase.mjs +3 -3
- package/fesm2022/cmat-pipes-uppercase.mjs.map +1 -1
- package/fesm2022/cmat-services-alert.mjs +26 -27
- package/fesm2022/cmat-services-alert.mjs.map +1 -1
- package/fesm2022/cmat-services-config.mjs +14 -23
- package/fesm2022/cmat-services-config.mjs.map +1 -1
- package/fesm2022/cmat-services-confirmation.mjs +8 -8
- package/fesm2022/cmat-services-confirmation.mjs.map +1 -1
- package/fesm2022/cmat-services-data.mjs +6 -10
- package/fesm2022/cmat-services-data.mjs.map +1 -1
- package/fesm2022/cmat-services-export-as.mjs +3 -3
- package/fesm2022/cmat-services-export-as.mjs.map +1 -1
- package/fesm2022/cmat-services-loading.mjs +30 -47
- package/fesm2022/cmat-services-loading.mjs.map +1 -1
- package/fesm2022/cmat-services-local-storage.mjs +3 -3
- package/fesm2022/cmat-services-local-storage.mjs.map +1 -1
- package/fesm2022/cmat-services-media-watcher.mjs +43 -34
- package/fesm2022/cmat-services-media-watcher.mjs.map +1 -1
- package/fesm2022/cmat-services-platform.mjs +3 -3
- package/fesm2022/cmat-services-platform.mjs.map +1 -1
- package/fesm2022/cmat-services-splash-screen.mjs +3 -3
- package/fesm2022/cmat-services-splash-screen.mjs.map +1 -1
- package/fesm2022/cmat-services-title.mjs +3 -3
- package/fesm2022/cmat-services-title.mjs.map +1 -1
- package/fesm2022/cmat-services-translation.mjs +11 -11
- package/fesm2022/cmat-services-translation.mjs.map +1 -1
- package/fesm2022/cmat-services-utils.mjs +4 -4
- package/fesm2022/cmat-services-utils.mjs.map +1 -1
- package/fesm2022/cmat.mjs +9229 -7508
- package/fesm2022/cmat.mjs.map +1 -1
- package/icons/material-icons/heroicons-outline.svg +3 -0
- package/icons/material-icons/heroicons-solid.svg +3 -0
- package/package.json +10 -1
- package/styles/components/bundle.scss +21 -0
- package/styles/overrides/angular-material.scss +22 -1
- package/tailwind/plugins/theming.js +183 -183
- package/types/cmat-components-breadcrumb.d.ts +40 -37
- package/types/cmat-components-card.d.ts +11 -13
- package/types/cmat-components-carousel.d.ts +87 -113
- package/types/cmat-components-cascade.d.ts +84 -65
- package/types/cmat-components-chip-input.d.ts +29 -24
- package/types/cmat-components-code-editor.d.ts +28 -12
- package/types/cmat-components-color-picker.d.ts +236 -0
- package/types/cmat-components-custom-formly.d.ts +316 -184
- package/types/cmat-components-data-picker.d.ts +372 -0
- package/types/cmat-components-date-range.d.ts +31 -36
- package/types/cmat-components-date-time-display.d.ts +8 -8
- package/types/cmat-components-drawer.d.ts +30 -32
- package/types/cmat-components-empty-state.d.ts +9 -10
- package/types/cmat-components-file-preview.d.ts +9 -9
- package/types/cmat-components-filter-toolbar.d.ts +15 -15
- package/types/cmat-components-form-actions.d.ts +5 -5
- package/types/cmat-components-fullscreen.d.ts +5 -5
- package/types/cmat-components-highlight.d.ts +13 -14
- package/types/cmat-components-image-viewer.d.ts +29 -33
- package/types/cmat-components-inline-loading.d.ts +6 -6
- package/types/cmat-components-json-editor.d.ts +15 -17
- package/types/cmat-components-knob-input.d.ts +58 -55
- package/types/cmat-components-masonry.d.ts +9 -12
- package/types/cmat-components-material-color-picker.d.ts +16 -21
- package/types/cmat-components-material-datetimepicker.d.ts +174 -216
- package/types/cmat-components-navigation.d.ts +34 -39
- package/types/cmat-components-opt-input.d.ts +35 -33
- package/types/cmat-components-org-chart.d.ts +8 -9
- package/types/cmat-components-page-header.d.ts +9 -9
- package/types/cmat-components-pagination.d.ts +36 -40
- package/types/cmat-components-password-strength.d.ts +58 -64
- package/types/cmat-components-popover.d.ts +22 -32
- package/types/cmat-components-progress-bar.d.ts +7 -10
- package/types/cmat-components-qrcode.d.ts +22 -22
- package/types/cmat-components-rating.d.ts +17 -19
- package/types/cmat-components-rich-text-editor.d.ts +11 -12
- package/types/cmat-components-select-search.d.ts +48 -36
- package/types/cmat-components-select-table.d.ts +38 -34
- package/types/cmat-components-select-tree.d.ts +17 -15
- package/types/cmat-components-skeleton.d.ts +27 -10
- package/types/cmat-components-speed-dial.d.ts +24 -33
- package/types/cmat-components-status-tag.d.ts +19 -9
- package/types/cmat-components-table-toolbar.d.ts +7 -7
- package/types/cmat-components-timeline.d.ts +33 -34
- package/types/cmat-components-toast.d.ts +26 -30
- package/types/cmat-components-transfer-picker.d.ts +51 -56
- package/types/cmat-components-treetable.d.ts +12 -13
- package/types/cmat-components-upload.d.ts +33 -38
- package/types/cmat-components-x6-angular-shape.d.ts +1 -1
- package/types/cmat-directives-animate-on-scroll.d.ts +7 -7
- package/types/cmat-directives-arrow-cursor.d.ts +18 -20
- package/types/cmat-directives-data-exporter.d.ts +10 -10
- package/types/cmat-directives-debounce.d.ts +5 -5
- package/types/cmat-directives-digit-only.d.ts +13 -13
- package/types/cmat-directives-seamless-auto-scroll.d.ts +7 -7
- package/types/cmat-pipes-secure.d.ts +1 -3
- package/types/cmat-services-alert.d.ts +11 -12
- package/types/cmat-services-config.d.ts +2 -7
- package/types/cmat-services-confirmation.d.ts +2 -2
- package/types/cmat-services-data.d.ts +0 -1
- package/types/cmat-services-loading.d.ts +14 -22
- package/types/cmat-services-media-watcher.d.ts +5 -5
- package/types/cmat-services-translation.d.ts +4 -5
- package/types/cmat.d.ts +2167 -1746
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { HttpClient, HttpEventType } from '@angular/common/http';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
|
-
import {
|
|
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 {
|
|
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
|
|
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 {
|
|
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 {
|
|
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,
|
|
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: "
|
|
100
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
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: "
|
|
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: "
|
|
177
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
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: "
|
|
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: "
|
|
186
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
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: "
|
|
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: "
|
|
195
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
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: "
|
|
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\">{{
|
|
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
|
|
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: "
|
|
231
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
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: "
|
|
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: "
|
|
290
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
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: "
|
|
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
|
-
|
|
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
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
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: "
|
|
351
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
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: "
|
|
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()\"
|
|
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
|
-
|
|
363
|
-
this.
|
|
364
|
-
|
|
365
|
-
this.
|
|
366
|
-
|
|
367
|
-
this.
|
|
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.
|
|
370
|
-
this.
|
|
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
|
-
|
|
385
|
-
|
|
386
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
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
|
-
|
|
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
|
|
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 =
|
|
466
|
-
return selected.
|
|
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
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
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
|
-
|
|
502
|
-
|
|
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: "
|
|
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
|
|
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.
|
|
513
|
-
|
|
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
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
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
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
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.
|
|
774
|
+
this.urlData.set(data);
|
|
546
775
|
}
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
this.autocompleteUrlData = [];
|
|
551
|
-
}
|
|
776
|
+
},
|
|
777
|
+
componentName: 'CmatChipsInputTypeComponent'
|
|
778
|
+
});
|
|
552
779
|
}
|
|
553
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
554
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
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: "
|
|
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 [
|
|
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: "
|
|
563
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
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: "
|
|
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,
|
|
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: "
|
|
582
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
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: "
|
|
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
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
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: "
|
|
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.
|
|
973
|
+
this.urlData = [];
|
|
974
|
+
this._lastDomain = undefined;
|
|
975
|
+
this._lastOptions = undefined;
|
|
636
976
|
this._destroyRef = inject(DestroyRef);
|
|
637
|
-
this.
|
|
638
|
-
|
|
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
|
-
|
|
641
|
-
|
|
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
|
-
|
|
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,
|
|
650
|
-
: currentValue.filter(o => o !==
|
|
1009
|
+
? [...currentValue, optionValue]
|
|
1010
|
+
: currentValue.filter(o => o !== optionValue));
|
|
651
1011
|
}
|
|
652
1012
|
else {
|
|
653
|
-
|
|
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
|
-
|
|
658
|
-
const
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
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
|
-
|
|
1044
|
+
if (typeof formValue === 'object' && formValue !== null) {
|
|
1045
|
+
return !!formValue[safeOptionValue];
|
|
1046
|
+
}
|
|
1047
|
+
return false;
|
|
683
1048
|
}
|
|
684
1049
|
}
|
|
685
|
-
|
|
686
|
-
|
|
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
|
-
|
|
691
|
-
return
|
|
1053
|
+
getData() {
|
|
1054
|
+
return this.urlData;
|
|
692
1055
|
}
|
|
693
|
-
|
|
694
|
-
|
|
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: "
|
|
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 (
|
|
699
|
-
}], ctorParameters: () => []
|
|
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: "
|
|
716
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
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: "
|
|
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: "
|
|
736
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
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: "
|
|
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.
|
|
755
|
-
|
|
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.
|
|
758
|
-
}
|
|
759
|
-
get urlData$() {
|
|
760
|
-
return this._urlData$;
|
|
1138
|
+
this._domainDataService = inject(DomainDataService);
|
|
761
1139
|
}
|
|
762
1140
|
ngOnInit() {
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
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
|
-
|
|
787
|
-
this.
|
|
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.
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
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: "
|
|
808
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
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: "
|
|
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 ((
|
|
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: "
|
|
828
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
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: "
|
|
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.
|
|
846
|
-
this.
|
|
847
|
-
|
|
848
|
-
this.
|
|
849
|
-
|
|
850
|
-
this.
|
|
851
|
-
|
|
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
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
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
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
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
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
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.
|
|
896
|
-
|
|
897
|
-
|
|
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
|
-
|
|
984
|
-
|
|
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: "
|
|
987
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
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: "
|
|
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\"
|
|
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
|
-
|
|
1009
|
-
this.
|
|
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
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
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: "
|
|
1043
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
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: "
|
|
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\"
|
|
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
|
-
|
|
1063
|
-
this.
|
|
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
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
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
|
|
1460
|
+
this.urlData.set({ columns: [], data: [] });
|
|
1087
1461
|
}
|
|
1088
|
-
|
|
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
|
-
|
|
1097
|
-
|
|
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: "
|
|
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\"
|
|
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: "
|
|
1114
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
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: "
|
|
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: "
|
|
1131
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
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: "
|
|
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.
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
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]?.
|
|
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.
|
|
1181
|
-
|
|
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
|
|
1193
|
-
this.
|
|
1194
|
-
|
|
1195
|
-
|
|
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.
|
|
1199
|
-
.subscribe(() => { this.dialogType = ''; });
|
|
1200
|
-
this.dialogType = 'edit';
|
|
1201
|
-
this.currentMode = {
|
|
1202
|
-
[this.key]: item
|
|
1203
|
-
};
|
|
1582
|
+
this._openDialog();
|
|
1204
1583
|
}
|
|
1205
|
-
deleteRow(
|
|
1206
|
-
this.remove(
|
|
1207
|
-
|
|
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
|
-
|
|
1216
|
-
|
|
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'
|
|
1220
|
-
|
|
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.
|
|
1223
|
-
this.
|
|
1611
|
+
this.refreshVersion.update(v => v + 1);
|
|
1612
|
+
this.table()?.renderRows();
|
|
1224
1613
|
this._dialogRef.close();
|
|
1225
1614
|
}
|
|
1226
|
-
|
|
1227
|
-
|
|
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: "
|
|
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-
|
|
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: "
|
|
1243
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
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: "
|
|
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.
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
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.
|
|
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
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
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(
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
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
|
-
|
|
1765
|
+
newVal = [tag, ...currentVal];
|
|
1360
1766
|
}
|
|
1361
|
-
this.formControl.setValue(
|
|
1362
|
-
this.refreshVersion.update(
|
|
1767
|
+
this.formControl.setValue(newVal);
|
|
1768
|
+
this.refreshVersion.update(v => v + 1);
|
|
1363
1769
|
}
|
|
1364
1770
|
isCheck(tag) {
|
|
1365
|
-
|
|
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
|
-
|
|
1371
|
-
|
|
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: "
|
|
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,
|
|
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: "
|
|
1395
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
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: "
|
|
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
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
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
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
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
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
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
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
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: "
|
|
1458
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
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: "
|
|
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
|
|
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.
|
|
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.
|
|
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
|
|
1550
|
-
this.
|
|
1551
|
-
|
|
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
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
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
|
|
1570
|
-
|
|
1571
|
-
const
|
|
1572
|
-
const
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
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
|
|
2090
|
+
if (this.imgInput()) {
|
|
2091
|
+
this.imgInput().nativeElement.click();
|
|
2092
|
+
}
|
|
1590
2093
|
}
|
|
1591
2094
|
_videoFileHandler() {
|
|
1592
|
-
this.videoInput
|
|
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 =
|
|
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 ?? '
|
|
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
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
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
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
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
|
-
|
|
1865
|
-
|
|
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: "
|
|
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
|
|
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: "
|
|
1897
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
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: "
|
|
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: "
|
|
1916
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
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: "
|
|
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
|