cmat 0.0.82 → 0.0.84
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 +19 -13
- package/fesm2022/cmat-components-adapter.mjs.map +1 -1
- package/fesm2022/cmat-components-breadcrumb.mjs.map +1 -1
- package/fesm2022/cmat-components-card.mjs.map +1 -1
- package/fesm2022/cmat-components-carousel.mjs +20 -20
- package/fesm2022/cmat-components-carousel.mjs.map +1 -1
- package/fesm2022/cmat-components-cascade.mjs +7 -5
- package/fesm2022/cmat-components-cascade.mjs.map +1 -1
- package/fesm2022/cmat-components-chip-input.mjs.map +1 -1
- package/fesm2022/cmat-components-code-editor.mjs +3 -2
- package/fesm2022/cmat-components-code-editor.mjs.map +1 -1
- package/fesm2022/cmat-components-custom-formly.mjs +228 -108
- package/fesm2022/cmat-components-custom-formly.mjs.map +1 -1
- package/fesm2022/cmat-components-date-range.mjs +20 -11
- package/fesm2022/cmat-components-date-range.mjs.map +1 -1
- package/fesm2022/cmat-components-date-time-display.mjs.map +1 -1
- package/fesm2022/cmat-components-drawer.mjs +0 -2
- package/fesm2022/cmat-components-drawer.mjs.map +1 -1
- package/fesm2022/cmat-components-empty-state.mjs.map +1 -1
- package/fesm2022/cmat-components-file-preview.mjs.map +1 -1
- package/fesm2022/cmat-components-filter-toolbar.mjs.map +1 -1
- package/fesm2022/cmat-components-form-actions.mjs.map +1 -1
- package/fesm2022/cmat-components-fullscreen.mjs +1 -1
- package/fesm2022/cmat-components-fullscreen.mjs.map +1 -1
- package/fesm2022/cmat-components-highlight.mjs +1 -1
- package/fesm2022/cmat-components-highlight.mjs.map +1 -1
- package/fesm2022/cmat-components-image-viewer.mjs +29 -11
- package/fesm2022/cmat-components-image-viewer.mjs.map +1 -1
- package/fesm2022/cmat-components-inline-loading.mjs.map +1 -1
- package/fesm2022/cmat-components-json-editor.mjs +16 -26
- package/fesm2022/cmat-components-json-editor.mjs.map +1 -1
- package/fesm2022/cmat-components-knob-input.mjs +8 -7
- package/fesm2022/cmat-components-knob-input.mjs.map +1 -1
- package/fesm2022/cmat-components-masonry.mjs.map +1 -1
- package/fesm2022/cmat-components-material-color-picker.mjs +3 -3
- package/fesm2022/cmat-components-material-color-picker.mjs.map +1 -1
- package/fesm2022/cmat-components-material-datetimepicker.mjs +28 -16
- package/fesm2022/cmat-components-material-datetimepicker.mjs.map +1 -1
- package/fesm2022/cmat-components-navigation.mjs +1 -0
- package/fesm2022/cmat-components-navigation.mjs.map +1 -1
- package/fesm2022/cmat-components-opt-input.mjs +2 -2
- package/fesm2022/cmat-components-opt-input.mjs.map +1 -1
- package/fesm2022/cmat-components-org-chart.mjs.map +1 -1
- package/fesm2022/cmat-components-page-header.mjs.map +1 -1
- package/fesm2022/cmat-components-password-strength.mjs +8 -5
- package/fesm2022/cmat-components-password-strength.mjs.map +1 -1
- package/fesm2022/cmat-components-popover.mjs +2 -2
- package/fesm2022/cmat-components-popover.mjs.map +1 -1
- package/fesm2022/cmat-components-qrcode.mjs +9 -2
- package/fesm2022/cmat-components-qrcode.mjs.map +1 -1
- package/fesm2022/cmat-components-rating.mjs +1 -1
- package/fesm2022/cmat-components-rating.mjs.map +1 -1
- package/fesm2022/cmat-components-rich-text-editor.mjs.map +1 -1
- package/fesm2022/cmat-components-select-search.mjs +25 -24
- package/fesm2022/cmat-components-select-search.mjs.map +1 -1
- package/fesm2022/cmat-components-select-table.mjs +42 -15
- package/fesm2022/cmat-components-select-table.mjs.map +1 -1
- package/fesm2022/cmat-components-select-tree.mjs +3 -1
- package/fesm2022/cmat-components-select-tree.mjs.map +1 -1
- package/fesm2022/cmat-components-skeleton.mjs.map +1 -1
- package/fesm2022/cmat-components-speed-dial.mjs +24 -5
- package/fesm2022/cmat-components-speed-dial.mjs.map +1 -1
- package/fesm2022/cmat-components-status-tag.mjs.map +1 -1
- package/fesm2022/cmat-components-table-toolbar.mjs.map +1 -1
- package/fesm2022/cmat-components-timeline.mjs.map +1 -1
- package/fesm2022/cmat-components-toast.mjs +20 -13
- package/fesm2022/cmat-components-toast.mjs.map +1 -1
- package/fesm2022/cmat-components-transfer-picker.mjs +11 -6
- package/fesm2022/cmat-components-transfer-picker.mjs.map +1 -1
- package/fesm2022/cmat-components-treetable.mjs +4 -3
- package/fesm2022/cmat-components-treetable.mjs.map +1 -1
- package/fesm2022/cmat-components-upload.mjs +29 -15
- package/fesm2022/cmat-components-upload.mjs.map +1 -1
- package/fesm2022/cmat-components-x6-angular-shape.mjs +2 -2
- package/fesm2022/cmat-components-x6-angular-shape.mjs.map +1 -1
- package/fesm2022/cmat-directives-animate-on-scroll.mjs.map +1 -1
- package/fesm2022/cmat-directives-autofocus.mjs.map +1 -1
- package/fesm2022/cmat-directives-data-exporter.mjs +1 -1
- package/fesm2022/cmat-directives-data-exporter.mjs.map +1 -1
- package/fesm2022/cmat-directives-debounce.mjs.map +1 -1
- package/fesm2022/cmat-directives-digit-only.mjs +12 -18
- package/fesm2022/cmat-directives-digit-only.mjs.map +1 -1
- package/fesm2022/cmat-directives-seamless-auto-scroll.mjs +3 -2
- package/fesm2022/cmat-directives-seamless-auto-scroll.mjs.map +1 -1
- package/fesm2022/cmat-lib-mock-api.mjs +7 -7
- package/fesm2022/cmat-lib-mock-api.mjs.map +1 -1
- package/fesm2022/cmat-pipes-find-by-key.mjs +1 -1
- package/fesm2022/cmat-pipes-find-by-key.mjs.map +1 -1
- package/fesm2022/cmat-pipes-group-by.mjs +9 -5
- package/fesm2022/cmat-pipes-group-by.mjs.map +1 -1
- package/fesm2022/cmat-pipes-keys.mjs.map +1 -1
- package/fesm2022/cmat-pipes-secure.mjs +9 -1
- package/fesm2022/cmat-pipes-secure.mjs.map +1 -1
- package/fesm2022/cmat-services-alert.mjs +16 -7
- package/fesm2022/cmat-services-alert.mjs.map +1 -1
- package/fesm2022/cmat-services-data.mjs.map +1 -1
- package/fesm2022/cmat-services-export-as.mjs +11 -10
- package/fesm2022/cmat-services-export-as.mjs.map +1 -1
- package/fesm2022/cmat-services-local-storage.mjs +42 -4
- package/fesm2022/cmat-services-local-storage.mjs.map +1 -1
- package/fesm2022/cmat-services-title.mjs +2 -2
- package/fesm2022/cmat-services-title.mjs.map +1 -1
- package/fesm2022/cmat-services-translation.mjs.map +1 -1
- package/fesm2022/cmat-services-utils.mjs +78 -57
- package/fesm2022/cmat-services-utils.mjs.map +1 -1
- package/fesm2022/cmat-validators.mjs +4 -1
- package/fesm2022/cmat-validators.mjs.map +1 -1
- package/fesm2022/cmat.mjs +746 -426
- package/fesm2022/cmat.mjs.map +1 -1
- package/package.json +1 -1
- package/types/cmat-components-adapter.d.ts +24 -24
- package/types/cmat-components-breadcrumb.d.ts +1 -1
- package/types/cmat-components-card.d.ts +1 -1
- package/types/cmat-components-carousel.d.ts +23 -23
- package/types/cmat-components-cascade.d.ts +12 -12
- package/types/cmat-components-chip-input.d.ts +8 -8
- package/types/cmat-components-code-editor.d.ts +2 -2
- package/types/cmat-components-custom-formly.d.ts +121 -44
- package/types/cmat-components-date-range.d.ts +31 -16
- package/types/cmat-components-drawer.d.ts +2 -3
- package/types/cmat-components-file-preview.d.ts +1 -1
- package/types/cmat-components-image-viewer.d.ts +5 -3
- package/types/cmat-components-json-editor.d.ts +7 -9
- package/types/cmat-components-knob-input.d.ts +3 -3
- package/types/cmat-components-masonry.d.ts +3 -3
- package/types/cmat-components-material-color-picker.d.ts +13 -9
- package/types/cmat-components-material-datetimepicker.d.ts +26 -10
- package/types/cmat-components-navigation.d.ts +1 -1
- package/types/cmat-components-opt-input.d.ts +8 -8
- package/types/cmat-components-popover.d.ts +1 -1
- package/types/cmat-components-qrcode.d.ts +2 -1
- package/types/cmat-components-rating.d.ts +13 -13
- package/types/cmat-components-select-search.d.ts +5 -5
- package/types/cmat-components-select-table.d.ts +12 -8
- package/types/cmat-components-select-tree.d.ts +1 -1
- package/types/cmat-components-speed-dial.d.ts +3 -0
- package/types/cmat-components-timeline.d.ts +2 -2
- package/types/cmat-components-toast.d.ts +2 -2
- package/types/cmat-components-transfer-picker.d.ts +5 -4
- package/types/cmat-components-treetable.d.ts +2 -2
- package/types/cmat-components-upload.d.ts +36 -29
- package/types/cmat-components-x6-angular-shape.d.ts +1 -1
- package/types/cmat-directives-autofocus.d.ts +1 -1
- package/types/cmat-directives-data-exporter.d.ts +3 -2
- package/types/cmat-directives-debounce.d.ts +5 -5
- package/types/cmat-directives-digit-only.d.ts +7 -7
- package/types/cmat-directives-seamless-auto-scroll.d.ts +2 -2
- package/types/cmat-lib-mock-api.d.ts +1 -1
- package/types/cmat-pipes-find-by-key.d.ts +2 -1
- package/types/cmat-pipes-group-by.d.ts +7 -1
- package/types/cmat-pipes-keys.d.ts +4 -1
- package/types/cmat-pipes-secure.d.ts +1 -0
- package/types/cmat-services-alert.d.ts +14 -13
- package/types/cmat-services-data.d.ts +3 -3
- package/types/cmat-services-export-as.d.ts +4 -3
- package/types/cmat-services-local-storage.d.ts +14 -2
- package/types/cmat-services-translation.d.ts +3 -3
- package/types/cmat-services-utils.d.ts +31 -15
- package/types/cmat-validators.d.ts +1 -1
- package/types/cmat.d.ts +465 -303
|
@@ -64,7 +64,7 @@ import BlotFormatter from '@enzedonline/quill-blot-formatter2';
|
|
|
64
64
|
import { CmatUrlStateConfigService } from 'cmat/services/config';
|
|
65
65
|
import { CmatUtilsService } from 'cmat/services/utils';
|
|
66
66
|
import dayjs from 'dayjs';
|
|
67
|
-
import { Document, Packer, Paragraph, AlignmentType, TextRun, BorderStyle, HeadingLevel, ImageRun } from 'docx';
|
|
67
|
+
import { Document, Packer, Paragraph, AlignmentType, TextRun, BorderStyle, HeadingLevel, ImageRun, HighlightColor } from 'docx';
|
|
68
68
|
import * as FileSaver from 'file-saver-es';
|
|
69
69
|
import * as i2$4 from 'ngx-quill';
|
|
70
70
|
import { QuillModule } from 'ngx-quill';
|
|
@@ -75,13 +75,14 @@ import * as i1$a from '@angular/material/slider';
|
|
|
75
75
|
import { MatSliderModule } from '@angular/material/slider';
|
|
76
76
|
|
|
77
77
|
function addonsExtension(field) {
|
|
78
|
-
|
|
78
|
+
const props = field.props;
|
|
79
|
+
if (!props || (field.wrappers?.includes('addons'))) {
|
|
79
80
|
return;
|
|
80
81
|
}
|
|
81
|
-
if ((
|
|
82
|
-
|| (!isNil(
|
|
83
|
-
|| (
|
|
84
|
-
|| (!isNil(
|
|
82
|
+
if ((props.addonLeft && ((!isNil(props.addonLeft.icon) && props.addonLeft.icon !== '')
|
|
83
|
+
|| (!isNil(props.addonLeft.text)) && props.addonLeft.text !== ''))
|
|
84
|
+
|| (props.addonRight && ((!isNil(props.addonRight.icon) && props.addonRight.icon !== '')
|
|
85
|
+
|| (!isNil(props.addonRight.text)) && props.addonRight.text !== ''))) {
|
|
85
86
|
field.wrappers = [...(field.wrappers ?? []), 'addons'];
|
|
86
87
|
}
|
|
87
88
|
}
|
|
@@ -215,8 +216,11 @@ class CmatFormFieldWrapperComponent extends FieldWrapper {
|
|
|
215
216
|
}
|
|
216
217
|
ngAfterViewInit() {
|
|
217
218
|
if (this.formField.appearance !== 'outline' && this.props.hideFieldUnderline === true) {
|
|
218
|
-
const
|
|
219
|
-
underlineElement
|
|
219
|
+
const formFieldElement = this._elementRef.nativeElement;
|
|
220
|
+
const underlineElement = formFieldElement.querySelector('.mat-form-field-underline');
|
|
221
|
+
if (underlineElement?.parentNode) {
|
|
222
|
+
this._renderer.removeChild(underlineElement.parentNode, underlineElement);
|
|
223
|
+
}
|
|
220
224
|
}
|
|
221
225
|
}
|
|
222
226
|
ngOnDestroy() {
|
|
@@ -234,9 +238,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
234
238
|
args: [MatFormField, { static: true }]
|
|
235
239
|
}] } });
|
|
236
240
|
|
|
241
|
+
const DANGEROUS_PATTERNS = [
|
|
242
|
+
/\bdocument\s*\./i,
|
|
243
|
+
/\bwindow\s*\./i,
|
|
244
|
+
/\beval\s*\(/i,
|
|
245
|
+
/\bfetch\s*\(/i,
|
|
246
|
+
/\bXMLHttpRequest\b/i,
|
|
247
|
+
/\bimport\s*\(/i,
|
|
248
|
+
/\b__proto__\b/i,
|
|
249
|
+
/\bconstructor\s*\(/i,
|
|
250
|
+
/\bprototype\b/i
|
|
251
|
+
];
|
|
237
252
|
class CmatButtonTypeComponent extends FieldType {
|
|
238
253
|
constructor() {
|
|
239
|
-
super();
|
|
254
|
+
super(...arguments);
|
|
240
255
|
this.defaultOptions = {
|
|
241
256
|
props: {
|
|
242
257
|
color: 'primary'
|
|
@@ -247,14 +262,21 @@ class CmatButtonTypeComponent extends FieldType {
|
|
|
247
262
|
$event.preventDefault();
|
|
248
263
|
if (this.props.onClick) {
|
|
249
264
|
if (isString(this.props.onClick)) {
|
|
250
|
-
this._executeFunctionFromString(this.props.onClick, $event, this);
|
|
265
|
+
this._executeFunctionFromString(this.props.onClick, $event, { props: this.props });
|
|
251
266
|
}
|
|
252
267
|
else {
|
|
253
268
|
this.props.onClick($event);
|
|
254
269
|
}
|
|
255
270
|
}
|
|
256
271
|
}
|
|
272
|
+
_isDangerousCode(code) {
|
|
273
|
+
return DANGEROUS_PATTERNS.some((pattern) => pattern.test(code));
|
|
274
|
+
}
|
|
257
275
|
_executeFunctionFromString(funcString, event, context) {
|
|
276
|
+
if (this._isDangerousCode(funcString)) {
|
|
277
|
+
console.error('Button onClick contains potentially dangerous code and was blocked:', funcString);
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
258
280
|
try {
|
|
259
281
|
// eslint-disable-next-line @typescript-eslint/no-implied-eval
|
|
260
282
|
const func = new Function('event', 'context', `with (context) { ${funcString} }`);
|
|
@@ -264,13 +286,13 @@ class CmatButtonTypeComponent extends FieldType {
|
|
|
264
286
|
console.error('Error executing function from string:', error);
|
|
265
287
|
}
|
|
266
288
|
}
|
|
267
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: CmatButtonTypeComponent, deps:
|
|
289
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: CmatButtonTypeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
268
290
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.9", 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 }); }
|
|
269
291
|
}
|
|
270
292
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: CmatButtonTypeComponent, decorators: [{
|
|
271
293
|
type: Component,
|
|
272
294
|
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>" }]
|
|
273
|
-
}]
|
|
295
|
+
}] });
|
|
274
296
|
|
|
275
297
|
class CmatCascadeTypeComponent extends FieldType {
|
|
276
298
|
constructor() {
|
|
@@ -294,9 +316,11 @@ class CmatCascadeTypeComponent extends FieldType {
|
|
|
294
316
|
if (url && this.props?.domain?.code && this.props?.domain?.key && this.props?.domain?.value) {
|
|
295
317
|
this._http.get(url).pipe(takeUntilDestroyed(this._destroyRef)).subscribe((data) => {
|
|
296
318
|
if (data) {
|
|
319
|
+
const key = this.field.props?.domain?.key;
|
|
320
|
+
const code = this.field.props?.domain?.code;
|
|
297
321
|
const datas = data.filter((i) => {
|
|
298
|
-
if (
|
|
299
|
-
return i[
|
|
322
|
+
if (key)
|
|
323
|
+
return i[key] === code;
|
|
300
324
|
return false;
|
|
301
325
|
});
|
|
302
326
|
if (datas && this.field.props?.domain?.value) {
|
|
@@ -336,6 +360,8 @@ class CmatCheckListTypeComponent extends FieldType {
|
|
|
336
360
|
super();
|
|
337
361
|
this.isIndeterminate = false;
|
|
338
362
|
this.isChecked = false;
|
|
363
|
+
this.urlData = [];
|
|
364
|
+
this.optionsData = [];
|
|
339
365
|
this.checklist = [];
|
|
340
366
|
this.filteredData = [];
|
|
341
367
|
this._http = inject(HttpClient);
|
|
@@ -364,13 +390,15 @@ class CmatCheckListTypeComponent extends FieldType {
|
|
|
364
390
|
if (url && this.field.props?.domain?.code && this.field.props?.domain?.key && this.field.props?.domain?.value) {
|
|
365
391
|
this._http.get(url).pipe(takeUntilDestroyed(this._destroyRef)).subscribe((data) => {
|
|
366
392
|
if (data) {
|
|
393
|
+
const key = this.field.props?.domain?.key;
|
|
394
|
+
const code = this.field.props?.domain?.code;
|
|
367
395
|
const datas = data.filter((i) => {
|
|
368
|
-
if (
|
|
369
|
-
return i[
|
|
396
|
+
if (key)
|
|
397
|
+
return i[key] === code;
|
|
370
398
|
return false;
|
|
371
399
|
});
|
|
372
400
|
if (datas && this.field.props?.domain?.value) {
|
|
373
|
-
this.urlData = datas[0][this.field.props?.domain?.value];
|
|
401
|
+
this.urlData = datas[0][this.field.props?.domain?.value] ?? [];
|
|
374
402
|
}
|
|
375
403
|
else {
|
|
376
404
|
this.urlData = [];
|
|
@@ -389,7 +417,7 @@ class CmatCheckListTypeComponent extends FieldType {
|
|
|
389
417
|
this._filteredItems.set(this.filteredData);
|
|
390
418
|
}
|
|
391
419
|
this.formControl.valueChanges.pipe(takeUntilDestroyed(this._destroyRef)).subscribe((value) => {
|
|
392
|
-
this.checklist = value ?? [];
|
|
420
|
+
this.checklist = (value ?? []);
|
|
393
421
|
this._getAllCheckCountState();
|
|
394
422
|
});
|
|
395
423
|
}
|
|
@@ -397,7 +425,9 @@ class CmatCheckListTypeComponent extends FieldType {
|
|
|
397
425
|
return item.id ?? index;
|
|
398
426
|
}
|
|
399
427
|
filterByQuery(event) {
|
|
400
|
-
|
|
428
|
+
const query = typeof event === 'string' ? event : event.target?.value ?? '';
|
|
429
|
+
const normalizedQuery = query.toLowerCase();
|
|
430
|
+
this.filteredData = this.datas.filter((data) => this._toSearchText(data.value).toLowerCase().includes(normalizedQuery) || this._toSearchText(data.label).toLowerCase().includes(normalizedQuery));
|
|
401
431
|
this._filteredItems.set(this.filteredData);
|
|
402
432
|
this._getAllCheckCountState();
|
|
403
433
|
}
|
|
@@ -432,7 +462,8 @@ class CmatCheckListTypeComponent extends FieldType {
|
|
|
432
462
|
this.formControl.setValue(this.checklist);
|
|
433
463
|
}
|
|
434
464
|
isCheck(data) {
|
|
435
|
-
|
|
465
|
+
const selected = (this.formControl.value ?? []);
|
|
466
|
+
return selected.filter((i) => i.value === data.value).length > 0;
|
|
436
467
|
}
|
|
437
468
|
_getAllCheckCountState() {
|
|
438
469
|
if (this.props.showAllCheck && !this.props.disabled) {
|
|
@@ -464,35 +495,47 @@ class CmatCheckListTypeComponent extends FieldType {
|
|
|
464
495
|
}
|
|
465
496
|
}
|
|
466
497
|
}
|
|
498
|
+
_toSearchText(value) {
|
|
499
|
+
return typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean' ? String(value) : '';
|
|
500
|
+
}
|
|
467
501
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: CmatCheckListTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
468
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: CmatCheckListTypeComponent, isStandalone: true, selector: "cmat-checklist-type", usesInheritance: true, ngImport: i0, template: "<div class=\"flex flex-col\">\r\n <div class=\"p-2\">\r\n @if(props.label){\r\n <legend class=\"text-lg\">\r\n {{ props.label }}\r\n @if(props.required){\r\n <span>*</span>\r\n }\r\n </legend>\r\n }\r\n @if(props.description){\r\n <p>{{ props.description }}</p>\r\n }\r\n </div>\r\n\r\n <div class=\"w-full h-full rounded-sm border shadow-sm bg-card\" [tabIndex]=\"props.tabindex\">\r\n <div class=\"flex items-center m-1 mr-2 min-h-12 print:hidden\">\r\n @if (props.showAllCheck&&!props.disabled) {\r\n <div>\r\n <mat-checkbox class=\"flex items-center h-10 min-h-10 m-1\" [color]=\"'primary'\" [checked]=\"isChecked\"\r\n [indeterminate]=\"isIndeterminate\" (change)=\"allCheckChange($event.checked)\">\r\n </mat-checkbox>\r\n </div>\r\n }\r\n <div class=\"flex items-center w-full\">\r\n <mat-icon class=\"icon-size-5\" [svgIcon]=\"'heroicons_solid:magnifying-glass'\"></mat-icon>\r\n <div class=\"ml-2\">\r\n <input #query class=\"w-full min-w-0 py-1 border-none\" type=\"text\"\r\n placeholder=\"\u8F93\u5165\u8FC7\u6EE4\u4FE1\u606F\" (input)=\"filterByQuery(query.value)\">\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"border-t overflow-y-auto scrollbar-custom\"\r\n [ngClass]=\"props.controlMaxHeight?'max-h-64 sm:max-h-128 lg:max-h-64':''\">\r\n @if ((filteredItems$ | async); as filteredItems) {\r\n @if(filteredItems.length>0){\r\n @for (data of filteredItems; track trackByFn($index, data)) {\r\n <div role=\"presentation\" class=\"flex items-center pl-2 pr-4 py-2 cursor-pointer hover:bg-hover\" matRipple\r\n (click)=\"toggleCheckList(data,$event)\">\r\n <mat-checkbox class=\"flex items-center h-10 min-h-10 pointer-events-none\" disableRipple [color]=\"'primary'\"\r\n [checked]=\"isCheck(data)\" [
|
|
502
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: CmatCheckListTypeComponent, isStandalone: true, selector: "cmat-checklist-type", usesInheritance: true, ngImport: i0, template: "<div class=\"flex flex-col\">\r\n <div class=\"p-2\">\r\n @if(props.label){\r\n <legend class=\"text-lg\">\r\n {{ props.label }}\r\n @if(props.required){\r\n <span>*</span>\r\n }\r\n </legend>\r\n }\r\n @if(props.description){\r\n <p>{{ props.description }}</p>\r\n }\r\n </div>\r\n\r\n <div class=\"w-full h-full rounded-sm border shadow-sm bg-card\" [tabIndex]=\"props.tabindex\">\r\n <div class=\"flex items-center m-1 mr-2 min-h-12 print:hidden\">\r\n @if (props.showAllCheck&&!props.disabled) {\r\n <div>\r\n <mat-checkbox class=\"flex items-center h-10 min-h-10 m-1\" [color]=\"'primary'\" [checked]=\"isChecked\"\r\n [indeterminate]=\"isIndeterminate\" (change)=\"allCheckChange($event.checked)\">\r\n </mat-checkbox>\r\n </div>\r\n }\r\n <div class=\"flex items-center w-full\">\r\n <mat-icon class=\"icon-size-5\" [svgIcon]=\"'heroicons_solid:magnifying-glass'\"></mat-icon>\r\n <div class=\"ml-2\">\r\n <input #query class=\"w-full min-w-0 py-1 border-none\" type=\"text\"\r\n placeholder=\"\u8F93\u5165\u8FC7\u6EE4\u4FE1\u606F\" (input)=\"filterByQuery(query.value)\">\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"border-t overflow-y-auto scrollbar-custom\"\r\n [ngClass]=\"props.controlMaxHeight?'max-h-64 sm:max-h-128 lg:max-h-64':''\">\r\n @if ((filteredItems$ | async); as filteredItems) {\r\n @if(filteredItems.length>0){\r\n @for (data of filteredItems; track trackByFn($index, data)) {\r\n <div role=\"presentation\" class=\"flex items-center pl-2 pr-4 py-2 cursor-pointer hover:bg-hover\" matRipple\r\n (click)=\"toggleCheckList(data,$event)\">\r\n <mat-checkbox class=\"flex items-center h-10 min-h-10 pointer-events-none\" disableRipple [color]=\"'primary'\"\r\n [checked]=\"isCheck(data)\" [disabled]=\"data.disabled||props.disabled\">\r\n <div class=\"flex flex-col flex-auto\">\r\n <div class=\"font-medium leading-5 truncate\">{{data.label}}</div>\r\n </div>\r\n </mat-checkbox>\r\n </div>\r\n }\r\n } @else {\r\n <div\r\n class=\"flex flex-auto flex-col items-center justify-center bg-slate-100 dark:bg-transparent h-64 sm:h-128 lg:h-64\">\r\n <mat-icon class=\"icon-size-24\" [svgIcon]=\"'heroicons_outline:document-magnifying-glass'\"></mat-icon>\r\n <div class=\"mt-4 text-2xl font-bold tracking-tight text-secondary\">\u6CA1\u6709\u6570\u636E!</div>\r\n </div>\r\n }\r\n }\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [":host{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i1$5.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatRippleModule }, { kind: "directive", type: i3$1.MatRipple, selector: "[mat-ripple], [matRipple]", inputs: ["matRippleColor", "matRippleUnbounded", "matRippleCentered", "matRippleRadius", "matRippleAnimation", "matRippleDisabled", "matRippleTrigger"], exportAs: ["matRipple"] }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
469
503
|
}
|
|
470
504
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: CmatCheckListTypeComponent, decorators: [{
|
|
471
505
|
type: Component,
|
|
472
|
-
args: [{ selector: 'cmat-checklist-type', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatCheckboxModule, MatIconModule, NgClass, MatRippleModule, AsyncPipe], template: "<div class=\"flex flex-col\">\r\n <div class=\"p-2\">\r\n @if(props.label){\r\n <legend class=\"text-lg\">\r\n {{ props.label }}\r\n @if(props.required){\r\n <span>*</span>\r\n }\r\n </legend>\r\n }\r\n @if(props.description){\r\n <p>{{ props.description }}</p>\r\n }\r\n </div>\r\n\r\n <div class=\"w-full h-full rounded-sm border shadow-sm bg-card\" [tabIndex]=\"props.tabindex\">\r\n <div class=\"flex items-center m-1 mr-2 min-h-12 print:hidden\">\r\n @if (props.showAllCheck&&!props.disabled) {\r\n <div>\r\n <mat-checkbox class=\"flex items-center h-10 min-h-10 m-1\" [color]=\"'primary'\" [checked]=\"isChecked\"\r\n [indeterminate]=\"isIndeterminate\" (change)=\"allCheckChange($event.checked)\">\r\n </mat-checkbox>\r\n </div>\r\n }\r\n <div class=\"flex items-center w-full\">\r\n <mat-icon class=\"icon-size-5\" [svgIcon]=\"'heroicons_solid:magnifying-glass'\"></mat-icon>\r\n <div class=\"ml-2\">\r\n <input #query class=\"w-full min-w-0 py-1 border-none\" type=\"text\"\r\n placeholder=\"\u8F93\u5165\u8FC7\u6EE4\u4FE1\u606F\" (input)=\"filterByQuery(query.value)\">\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"border-t overflow-y-auto scrollbar-custom\"\r\n [ngClass]=\"props.controlMaxHeight?'max-h-64 sm:max-h-128 lg:max-h-64':''\">\r\n @if ((filteredItems$ | async); as filteredItems) {\r\n @if(filteredItems.length>0){\r\n @for (data of filteredItems; track trackByFn($index, data)) {\r\n <div role=\"presentation\" class=\"flex items-center pl-2 pr-4 py-2 cursor-pointer hover:bg-hover\" matRipple\r\n (click)=\"toggleCheckList(data,$event)\">\r\n <mat-checkbox class=\"flex items-center h-10 min-h-10 pointer-events-none\" disableRipple [color]=\"'primary'\"\r\n [checked]=\"isCheck(data)\" [
|
|
506
|
+
args: [{ selector: 'cmat-checklist-type', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatCheckboxModule, MatIconModule, NgClass, MatRippleModule, AsyncPipe], template: "<div class=\"flex flex-col\">\r\n <div class=\"p-2\">\r\n @if(props.label){\r\n <legend class=\"text-lg\">\r\n {{ props.label }}\r\n @if(props.required){\r\n <span>*</span>\r\n }\r\n </legend>\r\n }\r\n @if(props.description){\r\n <p>{{ props.description }}</p>\r\n }\r\n </div>\r\n\r\n <div class=\"w-full h-full rounded-sm border shadow-sm bg-card\" [tabIndex]=\"props.tabindex\">\r\n <div class=\"flex items-center m-1 mr-2 min-h-12 print:hidden\">\r\n @if (props.showAllCheck&&!props.disabled) {\r\n <div>\r\n <mat-checkbox class=\"flex items-center h-10 min-h-10 m-1\" [color]=\"'primary'\" [checked]=\"isChecked\"\r\n [indeterminate]=\"isIndeterminate\" (change)=\"allCheckChange($event.checked)\">\r\n </mat-checkbox>\r\n </div>\r\n }\r\n <div class=\"flex items-center w-full\">\r\n <mat-icon class=\"icon-size-5\" [svgIcon]=\"'heroicons_solid:magnifying-glass'\"></mat-icon>\r\n <div class=\"ml-2\">\r\n <input #query class=\"w-full min-w-0 py-1 border-none\" type=\"text\"\r\n placeholder=\"\u8F93\u5165\u8FC7\u6EE4\u4FE1\u606F\" (input)=\"filterByQuery(query.value)\">\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"border-t overflow-y-auto scrollbar-custom\"\r\n [ngClass]=\"props.controlMaxHeight?'max-h-64 sm:max-h-128 lg:max-h-64':''\">\r\n @if ((filteredItems$ | async); as filteredItems) {\r\n @if(filteredItems.length>0){\r\n @for (data of filteredItems; track trackByFn($index, data)) {\r\n <div role=\"presentation\" class=\"flex items-center pl-2 pr-4 py-2 cursor-pointer hover:bg-hover\" matRipple\r\n (click)=\"toggleCheckList(data,$event)\">\r\n <mat-checkbox class=\"flex items-center h-10 min-h-10 pointer-events-none\" disableRipple [color]=\"'primary'\"\r\n [checked]=\"isCheck(data)\" [disabled]=\"data.disabled||props.disabled\">\r\n <div class=\"flex flex-col flex-auto\">\r\n <div class=\"font-medium leading-5 truncate\">{{data.label}}</div>\r\n </div>\r\n </mat-checkbox>\r\n </div>\r\n }\r\n } @else {\r\n <div\r\n class=\"flex flex-auto flex-col items-center justify-center bg-slate-100 dark:bg-transparent h-64 sm:h-128 lg:h-64\">\r\n <mat-icon class=\"icon-size-24\" [svgIcon]=\"'heroicons_outline:document-magnifying-glass'\"></mat-icon>\r\n <div class=\"mt-4 text-2xl font-bold tracking-tight text-secondary\">\u6CA1\u6709\u6570\u636E!</div>\r\n </div>\r\n }\r\n }\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [":host{width:100%}\n"] }]
|
|
473
507
|
}], ctorParameters: () => [] });
|
|
474
508
|
|
|
475
509
|
class CmatChipsInputTypeComponent extends FieldType {
|
|
476
510
|
constructor() {
|
|
477
511
|
super();
|
|
512
|
+
this.autocompleteUrlData = [];
|
|
478
513
|
this._http = inject(HttpClient);
|
|
479
514
|
this._destroyRef = inject(DestroyRef);
|
|
480
515
|
}
|
|
481
516
|
get autocompleteText() {
|
|
482
|
-
|
|
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(',') ?? [];
|
|
483
522
|
}
|
|
484
523
|
ngOnInit() {
|
|
485
524
|
const url = this.props?.domain?.url;
|
|
486
525
|
if (url && this.props?.domain?.code && this.props?.domain?.key && this.props?.domain?.value) {
|
|
487
526
|
this._http.get(url).pipe(takeUntilDestroyed(this._destroyRef)).subscribe((data) => {
|
|
488
527
|
if (data) {
|
|
489
|
-
const
|
|
490
|
-
|
|
491
|
-
|
|
528
|
+
const key = this.field.props?.domain?.key;
|
|
529
|
+
const code = this.field.props?.domain?.code;
|
|
530
|
+
const datas = data
|
|
531
|
+
.filter((i) => typeof i === 'object' && i !== null)
|
|
532
|
+
.filter((i) => {
|
|
533
|
+
if (key)
|
|
534
|
+
return i[key] === code;
|
|
492
535
|
return false;
|
|
493
536
|
});
|
|
494
537
|
if (datas && this.field.props?.domain?.value) {
|
|
495
|
-
this.autocompleteUrlData = datas[0][this.field.props?.domain?.value];
|
|
538
|
+
this.autocompleteUrlData = [datas[0][this.field.props?.domain?.value]];
|
|
496
539
|
}
|
|
497
540
|
else {
|
|
498
541
|
this.autocompleteUrlData = [];
|
|
@@ -597,15 +640,17 @@ class CmatMultiCheckboxTypeComponent extends FieldType {
|
|
|
597
640
|
get urlData$() {
|
|
598
641
|
return this._urlData$;
|
|
599
642
|
}
|
|
600
|
-
onChange(
|
|
643
|
+
onChange(optionValue, checked) {
|
|
644
|
+
const value = optionValue ?? '';
|
|
601
645
|
this.formControl.markAsDirty();
|
|
602
646
|
if (this.props.type === 'array') {
|
|
647
|
+
const currentValue = (this.formControl.value ?? []);
|
|
603
648
|
this.formControl.patchValue(checked
|
|
604
|
-
? [...
|
|
605
|
-
:
|
|
649
|
+
? [...currentValue, value]
|
|
650
|
+
: currentValue.filter(o => o !== value));
|
|
606
651
|
}
|
|
607
652
|
else {
|
|
608
|
-
this.formControl.patchValue({ ...this.formControl.value, [value]: checked });
|
|
653
|
+
this.formControl.patchValue({ ...(this.formControl.value ?? {}), [value]: checked });
|
|
609
654
|
}
|
|
610
655
|
this.formControl.markAsTouched();
|
|
611
656
|
}
|
|
@@ -614,13 +659,15 @@ class CmatMultiCheckboxTypeComponent extends FieldType {
|
|
|
614
659
|
if (url && this.field.props?.domain?.code && this.field.props?.domain?.key && this.field.props?.domain?.value) {
|
|
615
660
|
this._http.get(url).pipe(takeUntilDestroyed(this._destroyRef)).subscribe((data) => {
|
|
616
661
|
if (data) {
|
|
662
|
+
const key = this.field.props?.domain?.key;
|
|
663
|
+
const code = this.field.props?.domain?.code;
|
|
617
664
|
const datas = data.filter((i) => {
|
|
618
|
-
if (
|
|
619
|
-
return i[
|
|
665
|
+
if (key)
|
|
666
|
+
return i[key] === code;
|
|
620
667
|
return false;
|
|
621
668
|
});
|
|
622
669
|
if (datas && this.field.props?.domain?.value) {
|
|
623
|
-
this._urlData.set(datas[0][this.field.props?.domain?.value]);
|
|
670
|
+
this._urlData.set(datas[0][this.field.props?.domain?.value] ?? []);
|
|
624
671
|
}
|
|
625
672
|
else {
|
|
626
673
|
this._urlData.set([]);
|
|
@@ -636,18 +683,19 @@ class CmatMultiCheckboxTypeComponent extends FieldType {
|
|
|
636
683
|
}
|
|
637
684
|
}
|
|
638
685
|
isChecked(option) {
|
|
639
|
-
const
|
|
640
|
-
|
|
686
|
+
const formValue = this.formControl.value;
|
|
687
|
+
const optionValue = option.value ?? '';
|
|
688
|
+
return !!formValue && (this.props.type === 'array' ? formValue.includes(optionValue) : !!formValue[optionValue]);
|
|
641
689
|
}
|
|
642
690
|
trackByFn(index) {
|
|
643
691
|
return index;
|
|
644
692
|
}
|
|
645
693
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: CmatMultiCheckboxTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
646
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: CmatMultiCheckboxTypeComponent, isStandalone: true, selector: "cmat-multicheckbox-type", viewQueries: [{ propertyName: "checkboxes", predicate: MatCheckbox, descendants: true }], usesInheritance: true, ngImport: i0, template: "@if ((urlData$ | async); as urlData) {\r\n@for (option of (urlData.length > 0 ? urlData : (props.options | formlySelectOptions : field | async)); track\r\ntrackByFn($index)) {\r\n<mat-checkbox [tabIndex]=\"props.tabindex\" [color]=\"props.color\" [labelPosition]=\"props.labelPosition\"\r\n [checked]=\"isChecked(option)\" [disabled]=\"formControl.disabled || option.disabled\"\r\n (change)=\"onChange(option.value, $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 }); }
|
|
694
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: CmatMultiCheckboxTypeComponent, isStandalone: true, selector: "cmat-multicheckbox-type", viewQueries: [{ propertyName: "checkboxes", predicate: MatCheckbox, descendants: true }], usesInheritance: true, ngImport: i0, template: "@if ((urlData$ | async); as urlData) {\r\n@for (option of (urlData.length > 0 ? urlData : (props.options | formlySelectOptions : field | async)); track\r\ntrackByFn($index)) {\r\n<mat-checkbox [tabIndex]=\"props.tabindex\" [color]=\"props.color\" [labelPosition]=\"props.labelPosition\"\r\n [checked]=\"isChecked(option)\" [disabled]=\"formControl.disabled || option.disabled\"\r\n (change)=\"onChange(option.value?.toString(), $event.checked)\">\r\n {{ option.label }}\r\n</mat-checkbox>\r\n}\r\n}", styles: [":host{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i1$5.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: FormlySelectModule }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: i2$2.LegacyFormlySelectOptionsPipe, name: "formlySelectOptions" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
647
695
|
}
|
|
648
696
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: CmatMultiCheckboxTypeComponent, decorators: [{
|
|
649
697
|
type: Component,
|
|
650
|
-
args: [{ selector: 'cmat-multicheckbox-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatCheckboxModule, AsyncPipe, FormlySelectModule], template: "@if ((urlData$ | async); as urlData) {\r\n@for (option of (urlData.length > 0 ? urlData : (props.options | formlySelectOptions : field | async)); track\r\ntrackByFn($index)) {\r\n<mat-checkbox [tabIndex]=\"props.tabindex\" [color]=\"props.color\" [labelPosition]=\"props.labelPosition\"\r\n [checked]=\"isChecked(option)\" [disabled]=\"formControl.disabled || option.disabled\"\r\n (change)=\"onChange(option.value, $event.checked)\">\r\n {{ option.label }}\r\n</mat-checkbox>\r\n}\r\n}", styles: [":host{width:100%}\n"] }]
|
|
698
|
+
args: [{ selector: 'cmat-multicheckbox-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatCheckboxModule, AsyncPipe, FormlySelectModule], template: "@if ((urlData$ | async); as urlData) {\r\n@for (option of (urlData.length > 0 ? urlData : (props.options | formlySelectOptions : field | async)); track\r\ntrackByFn($index)) {\r\n<mat-checkbox [tabIndex]=\"props.tabindex\" [color]=\"props.color\" [labelPosition]=\"props.labelPosition\"\r\n [checked]=\"isChecked(option)\" [disabled]=\"formControl.disabled || option.disabled\"\r\n (change)=\"onChange(option.value?.toString(), $event.checked)\">\r\n {{ option.label }}\r\n</mat-checkbox>\r\n}\r\n}", styles: [":host{width:100%}\n"] }]
|
|
651
699
|
}], ctorParameters: () => [], propDecorators: { checkboxes: [{
|
|
652
700
|
type: ViewChildren,
|
|
653
701
|
args: [MatCheckbox]
|
|
@@ -716,13 +764,15 @@ class CmatRadioTypeComponent extends FieldType {
|
|
|
716
764
|
if (url && this.field.props?.domain?.code && this.field.props?.domain?.key && this.field.props?.domain?.value) {
|
|
717
765
|
this._http.get(url).pipe(takeUntilDestroyed(this._destroyRef)).subscribe((data) => {
|
|
718
766
|
if (data) {
|
|
767
|
+
const key = this.field.props?.domain?.key;
|
|
768
|
+
const code = this.field.props?.domain?.code;
|
|
719
769
|
const datas = data.filter((i) => {
|
|
720
|
-
if (
|
|
721
|
-
return i[
|
|
770
|
+
if (key)
|
|
771
|
+
return i[key] === code;
|
|
722
772
|
return false;
|
|
723
773
|
});
|
|
724
774
|
if (datas && this.field.props?.domain?.value) {
|
|
725
|
-
this._urlData.set(datas[0][this.field.props?.domain?.value]);
|
|
775
|
+
this._urlData.set(datas[0][this.field.props?.domain?.value] ?? []);
|
|
726
776
|
}
|
|
727
777
|
else {
|
|
728
778
|
this._urlData.set([]);
|
|
@@ -792,6 +842,7 @@ class CmatSelectTypeComponent extends FieldType {
|
|
|
792
842
|
showToggleAllCheckbox: false
|
|
793
843
|
},
|
|
794
844
|
};
|
|
845
|
+
this.optionsData = [];
|
|
795
846
|
this.filteredCustomDetails = new ReplaySubject(1);
|
|
796
847
|
this.filteredCache = [];
|
|
797
848
|
this.isIndeterminate = false;
|
|
@@ -803,7 +854,7 @@ class CmatSelectTypeComponent extends FieldType {
|
|
|
803
854
|
}
|
|
804
855
|
get datas() {
|
|
805
856
|
if (isArray(this.field.props?.options)) {
|
|
806
|
-
return this._urlData?.length > 0 ? this._urlData : this.field.props?.options
|
|
857
|
+
return this._urlData?.length > 0 ? this._urlData : this.field.props?.options ?? [];
|
|
807
858
|
}
|
|
808
859
|
else {
|
|
809
860
|
return this._urlData?.length > 0 ? this._urlData : this.optionsData || [];
|
|
@@ -819,13 +870,15 @@ class CmatSelectTypeComponent extends FieldType {
|
|
|
819
870
|
if (url && this.field.props?.domain?.code && this.field.props?.domain?.key && this.field.props?.domain?.value) {
|
|
820
871
|
this._http.get(url).pipe(takeUntilDestroyed(this._destroyRef)).subscribe((data) => {
|
|
821
872
|
if (data) {
|
|
873
|
+
const key = this.field.props?.domain?.key;
|
|
874
|
+
const code = this.field.props?.domain?.code;
|
|
822
875
|
const datas = data.filter((i) => {
|
|
823
|
-
if (
|
|
824
|
-
return i[
|
|
876
|
+
if (key)
|
|
877
|
+
return i[key] === code;
|
|
825
878
|
return false;
|
|
826
879
|
});
|
|
827
880
|
if (datas && this.field.props?.domain?.value) {
|
|
828
|
-
this._urlData = datas[0][this.field.props?.domain?.value];
|
|
881
|
+
this._urlData = datas[0][this.field.props?.domain?.value] ?? [];
|
|
829
882
|
}
|
|
830
883
|
else {
|
|
831
884
|
this._urlData = [];
|
|
@@ -877,7 +930,7 @@ class CmatSelectTypeComponent extends FieldType {
|
|
|
877
930
|
this.filteredCustomDetails.pipe(take(1), takeUntilDestroyed(this._destroyRef))
|
|
878
931
|
.subscribe((val) => {
|
|
879
932
|
if (selectAllValue) {
|
|
880
|
-
this.formControl.setValue(val.filter(o => !o.disabled));
|
|
933
|
+
this.formControl.setValue(val.filter((o) => !o.disabled));
|
|
881
934
|
}
|
|
882
935
|
else {
|
|
883
936
|
this.formControl.setValue([]);
|
|
@@ -889,26 +942,24 @@ class CmatSelectTypeComponent extends FieldType {
|
|
|
889
942
|
if (!this.datas) {
|
|
890
943
|
return;
|
|
891
944
|
}
|
|
892
|
-
|
|
945
|
+
const search = (this.multiFilterCtrl.value ?? '').toLowerCase();
|
|
893
946
|
if (!search) {
|
|
894
947
|
this.filteredCache = this.datas.slice();
|
|
895
948
|
this.filteredCustomDetails.next(this.filteredCache);
|
|
896
949
|
return;
|
|
897
950
|
}
|
|
898
|
-
|
|
899
|
-
search = search.toLowerCase();
|
|
900
|
-
}
|
|
901
|
-
this.filteredCache = this.datas.filter(items => isString(items) ? items.toString().toLowerCase().includes(search) : (items?.value.toString().toLowerCase().includes(search) ?? items?.label.toString().toLowerCase().includes(search)));
|
|
951
|
+
this.filteredCache = this.datas.filter((items) => this._toSearchText(items.value).toLowerCase().includes(search) || this._toSearchText(items.label).toLowerCase().includes(search));
|
|
902
952
|
this.filteredCustomDetails.next(this.filteredCache);
|
|
903
953
|
}
|
|
904
954
|
setToggleAllCheckboxState() {
|
|
905
955
|
let filteredLength = 0;
|
|
906
956
|
if (this.formControl.value && this.props.search) {
|
|
907
|
-
const cache = this.filteredCache.filter(o => !o.disabled);
|
|
908
|
-
const
|
|
957
|
+
const cache = this.filteredCache.filter((o) => !o.disabled);
|
|
958
|
+
const currentValue = this.formControl.value;
|
|
959
|
+
const v = isArray(currentValue) || isUndefined(currentValue) ? currentValue : [currentValue];
|
|
909
960
|
if (v)
|
|
910
961
|
cache.forEach((el) => {
|
|
911
|
-
if (v.findIndex(
|
|
962
|
+
if (v.findIndex(t => t != null && this._isSameSelectValue(t, el)) > -1) {
|
|
912
963
|
filteredLength++;
|
|
913
964
|
}
|
|
914
965
|
});
|
|
@@ -921,7 +972,16 @@ class CmatSelectTypeComponent extends FieldType {
|
|
|
921
972
|
}
|
|
922
973
|
}
|
|
923
974
|
compareWithFn(o1, o2) {
|
|
924
|
-
|
|
975
|
+
if (!o1 || !o2) {
|
|
976
|
+
return o1 === o2;
|
|
977
|
+
}
|
|
978
|
+
return o1.label === o2.label && o1.value === o2.value;
|
|
979
|
+
}
|
|
980
|
+
_isSameSelectValue(left, right) {
|
|
981
|
+
return left.value === right.value && left.label === right.label;
|
|
982
|
+
}
|
|
983
|
+
_toSearchText(value) {
|
|
984
|
+
return typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean' ? String(value) : '';
|
|
925
985
|
}
|
|
926
986
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: CmatSelectTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
927
987
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: CmatSelectTypeComponent, isStandalone: true, selector: "cmat-select-search-type", usesInheritance: true, ngImport: i0, template: "@if(props.multiple){\r\n<mat-select #multiSelect multiple [id]=\"id\" [formControl]=\"formControl\" [placeholder]=\"props.placeholder??''\"\r\n [required]=\"required\" [tabIndex]=\"props.tabindex\" [compareWith]=\"compareWithFn\"\r\n [errorStateMatcher]=\"errorStateMatcher\" [aria-label]=\"getAriaLabel()\" [aria-labelledby]=\"getAriaLabelledby()\"\r\n [disableOptionCentering]=\"props.disableOptionCentering\"\r\n [typeaheadDebounceInterval]=\"props.typeaheadDebounceInterval\"\r\n [panelClass]=\"'overflow-y-auto scrollbar-custom'\">\r\n @if ((filteredCustomDetails | async); as customDetails) {\r\n @if (props.search) {\r\n <mat-option>\r\n <cmat-select-search [formControl]=\"multiFilterCtrl\" [showToggleAllCheckbox]=\"props.showToggleAllCheckbox\"\r\n [toggleAllCheckboxIndeterminate]=\"isIndeterminate\" [toggleAllCheckboxChecked]=\"isChecked\"\r\n (toggleAll)=\"toggleSelectAll($event)\">\r\n </cmat-select-search>\r\n </mat-option>\r\n }\r\n @if (customDetails?.length!==0&&props.canNull&&!props.multiple) {\r\n <mat-option>\u7A7A</mat-option>\r\n }\r\n @for (i of customDetails; track $index) {\r\n @if(i.label){\r\n @if(i.group){\r\n <mat-optgroup [label]=\"i.label\">\r\n @for (child of i.group; track $index) {\r\n <mat-option [value]=\"child\" [disabled]=\"child.disabled\">\r\n {{ child.label }}\r\n </mat-option>\r\n }\r\n </mat-optgroup>\r\n }@else {\r\n <mat-option [value]=\"i\" [disabled]=\"i.disabled\">{{i.label}}</mat-option>\r\n }\r\n }@else {\r\n <mat-option [value]=\"i\">{{i}}</mat-option>\r\n }\r\n }\r\n }\r\n</mat-select>\r\n}@else {\r\n<mat-select #multiSelect [id]=\"id\" [formControl]=\"formControl\" [placeholder]=\"props.placeholder??''\"\r\n [required]=\"required\" [tabIndex]=\"props.tabindex\" [compareWith]=\"compareWithFn\"\r\n [errorStateMatcher]=\"errorStateMatcher\" [aria-label]=\"getAriaLabel()\" [aria-labelledby]=\"getAriaLabelledby()\"\r\n [disableOptionCentering]=\"props.disableOptionCentering\"\r\n [typeaheadDebounceInterval]=\"props.typeaheadDebounceInterval\"\r\n [panelClass]=\"'overflow-y-auto scrollbar-custom'\">\r\n @if ((filteredCustomDetails | async); as customDetails) {\r\n @if (props.search) {\r\n <mat-option>\r\n <cmat-select-search [formControl]=\"multiFilterCtrl\" [showToggleAllCheckbox]=\"props.showToggleAllCheckbox\"\r\n [toggleAllCheckboxIndeterminate]=\"isIndeterminate\" [toggleAllCheckboxChecked]=\"isChecked\"\r\n (toggleAll)=\"toggleSelectAll($event)\">\r\n </cmat-select-search>\r\n </mat-option>\r\n }\r\n @if (customDetails?.length!==0&&props.canNull&&!props.multiple) {\r\n <mat-option>\u7A7A</mat-option>\r\n }\r\n @for (i of customDetails; track $index) {\r\n @if(i.label){\r\n @if(i.group){\r\n <mat-optgroup [label]=\"i.label\">\r\n @for (child of i.group; track $index) {\r\n <mat-option [value]=\"child\" [disabled]=\"child.disabled\">\r\n {{ child.label }}\r\n </mat-option>\r\n }\r\n </mat-optgroup>\r\n }@else {\r\n <mat-option [value]=\"i\" [disabled]=\"i.disabled\">{{i.label}}</mat-option>\r\n }\r\n }@else {\r\n <mat-option [value]=\"i\">{{i}}</mat-option>\r\n }\r\n }\r\n }\r\n</mat-select>\r\n}", styles: [":host{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: MatCheckboxModule }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i1$8.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i1$8.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i1$8.MatOptgroup, selector: "mat-optgroup", inputs: ["label", "disabled"], exportAs: ["matOptgroup"] }, { kind: "component", type: CmatSelectSearchComponent, selector: "cmat-select-search", inputs: ["placeholderLabel", "type", "noEntriesFoundLabel", "showNoFoundLabel", "clearSearchInput", "searching", "disableInitialFocus", "enableClearOnEscapePressed", "preventHomeEndKeyPropagation", "disableScrollToActiveOnOptionsChanged", "ariaLabel", "showToggleAllCheckbox", "toggleAllCheckboxChecked", "toggleAllCheckboxIndeterminate", "toggleAllCheckboxTooltipMessage", "toggleAllCheckboxTooltipPosition", "hideClearSearchButton", "alwaysRestoreSelectedOptionsMulti"], outputs: ["toggleAll"], exportAs: ["cmatSelectSearch"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
@@ -954,9 +1014,11 @@ class CmatSelectTreeTypeComponent extends FieldType$1 {
|
|
|
954
1014
|
if (url && this.field.props?.domain?.code && this.field.props?.domain?.key && this.field.props?.domain?.value) {
|
|
955
1015
|
this._http.get(url).pipe(takeUntilDestroyed(this._destroyRef)).subscribe((data) => {
|
|
956
1016
|
if (data) {
|
|
1017
|
+
const key = this.field.props?.domain?.key;
|
|
1018
|
+
const code = this.field.props?.domain?.code;
|
|
957
1019
|
const datas = data.filter((i) => {
|
|
958
|
-
if (
|
|
959
|
-
return i[
|
|
1020
|
+
if (key)
|
|
1021
|
+
return i[key] === code;
|
|
960
1022
|
return false;
|
|
961
1023
|
});
|
|
962
1024
|
if (datas && this.field.props?.domain?.value) {
|
|
@@ -1006,9 +1068,11 @@ class CmatSelectTableTypeComponent extends FieldType$1 {
|
|
|
1006
1068
|
if (url && this.field.props?.domain?.code && this.field.props?.domain?.key && this.field.props?.domain?.value) {
|
|
1007
1069
|
this._http.get(url).pipe(takeUntilDestroyed(this._destroyRef)).subscribe((data) => {
|
|
1008
1070
|
if (data) {
|
|
1071
|
+
const key = this.field.props?.domain?.key;
|
|
1072
|
+
const code = this.field.props?.domain?.code;
|
|
1009
1073
|
const datas = data.filter((i) => {
|
|
1010
|
-
if (
|
|
1011
|
-
return i[
|
|
1074
|
+
if (key)
|
|
1075
|
+
return i[key] === code;
|
|
1012
1076
|
return false;
|
|
1013
1077
|
});
|
|
1014
1078
|
if (datas && this.field.props?.domain?.value) {
|
|
@@ -1088,18 +1152,24 @@ class CmatTableTypeComponent extends FieldArrayType {
|
|
|
1088
1152
|
this._viewContainerRef = inject(ViewContainerRef);
|
|
1089
1153
|
}
|
|
1090
1154
|
get fieldArray() {
|
|
1091
|
-
return this.
|
|
1155
|
+
return this._fieldModel.fieldArray?.fieldGroup ?? [];
|
|
1092
1156
|
}
|
|
1093
1157
|
get key() {
|
|
1094
|
-
return this.
|
|
1158
|
+
return this._fieldModel.fieldArray?.fieldGroup?.[0]?.id ?? '';
|
|
1159
|
+
}
|
|
1160
|
+
get _tableProps() {
|
|
1161
|
+
return this.props;
|
|
1162
|
+
}
|
|
1163
|
+
get _fieldModel() {
|
|
1164
|
+
return this.field;
|
|
1095
1165
|
}
|
|
1096
1166
|
ngOnInit() {
|
|
1097
|
-
this.columns = this.
|
|
1098
|
-
filter(field => field.props?.showColumn).map(field => ({
|
|
1099
|
-
key: field.key,
|
|
1167
|
+
this.columns = (this._fieldModel.fieldArray?.fieldGroup?.[0]?.fieldGroup ?? [])
|
|
1168
|
+
.filter(field => field.props?.showColumn).map(field => ({
|
|
1169
|
+
key: String(field.key ?? ''),
|
|
1100
1170
|
label: field.props?.label ?? '',
|
|
1101
1171
|
}));
|
|
1102
|
-
if (this.
|
|
1172
|
+
if (this._tableProps.disabled) {
|
|
1103
1173
|
this.displayedColumns = [...this.columns.map(column => column.key)];
|
|
1104
1174
|
}
|
|
1105
1175
|
else {
|
|
@@ -1141,11 +1211,13 @@ class CmatTableTypeComponent extends FieldArrayType {
|
|
|
1141
1211
|
this.inlineform.markAllAsTouched();
|
|
1142
1212
|
return;
|
|
1143
1213
|
}
|
|
1144
|
-
|
|
1145
|
-
|
|
1214
|
+
const model = this.model;
|
|
1215
|
+
const currentValue = this.currentMode[this.key];
|
|
1216
|
+
if (this.dialogType === 'add' && currentValue) {
|
|
1217
|
+
this.add(model?.length ?? 0, currentValue);
|
|
1146
1218
|
}
|
|
1147
|
-
else if (this.dialogType
|
|
1148
|
-
|
|
1219
|
+
else if (this.dialogType === 'edit' && currentValue && model) {
|
|
1220
|
+
model[this.currentIndex] = currentValue;
|
|
1149
1221
|
}
|
|
1150
1222
|
this.table.renderRows();
|
|
1151
1223
|
this.refreshVersion.update(value => value + 1);
|
|
@@ -1178,6 +1250,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
1178
1250
|
class CmatTagsTypeComponent extends FieldType {
|
|
1179
1251
|
constructor() {
|
|
1180
1252
|
super();
|
|
1253
|
+
this.urlData = [];
|
|
1254
|
+
this.optionsData = [];
|
|
1181
1255
|
this.refreshVersion = signal(0, ...(ngDevMode ? [{ debugName: "refreshVersion" }] : /* istanbul ignore next */ []));
|
|
1182
1256
|
this._http = inject(HttpClient);
|
|
1183
1257
|
this._overlay = inject(Overlay);
|
|
@@ -1207,13 +1281,15 @@ class CmatTagsTypeComponent extends FieldType {
|
|
|
1207
1281
|
if (url && this.field.props?.domain?.code && this.field.props?.domain?.key && this.field.props?.domain?.value) {
|
|
1208
1282
|
this._http.get(url).pipe(takeUntilDestroyed(this._destroyRef)).subscribe((data) => {
|
|
1209
1283
|
if (data) {
|
|
1284
|
+
const key = this.field.props?.domain?.key;
|
|
1285
|
+
const code = this.field.props?.domain?.code;
|
|
1210
1286
|
const datas = data.filter((i) => {
|
|
1211
|
-
if (
|
|
1212
|
-
return i[
|
|
1287
|
+
if (key)
|
|
1288
|
+
return i[key] === code;
|
|
1213
1289
|
return false;
|
|
1214
1290
|
});
|
|
1215
1291
|
if (datas && this.field.props?.domain?.value) {
|
|
1216
|
-
this.urlData = datas[0][this.field.props?.domain?.value];
|
|
1292
|
+
this.urlData = datas[0][this.field.props?.domain?.value] ?? [];
|
|
1217
1293
|
}
|
|
1218
1294
|
else {
|
|
1219
1295
|
this.urlData = [];
|
|
@@ -1268,8 +1344,8 @@ class CmatTagsTypeComponent extends FieldType {
|
|
|
1268
1344
|
});
|
|
1269
1345
|
}
|
|
1270
1346
|
filterTags(event) {
|
|
1271
|
-
const value = event.target
|
|
1272
|
-
this._filteredItems.set(this.tags.filter(tag => tag.label
|
|
1347
|
+
const value = (event.target?.value ?? '').toLowerCase();
|
|
1348
|
+
this._filteredItems.set(this.tags.filter((tag) => this._toSearchText(tag.label).toLowerCase().includes(value) || this._toSearchText(tag.value).toLowerCase().includes(value)));
|
|
1273
1349
|
}
|
|
1274
1350
|
toggleTag(tag) {
|
|
1275
1351
|
if (tag.disabled)
|
|
@@ -1286,7 +1362,10 @@ class CmatTagsTypeComponent extends FieldType {
|
|
|
1286
1362
|
this.refreshVersion.update(value => value + 1);
|
|
1287
1363
|
}
|
|
1288
1364
|
isCheck(tag) {
|
|
1289
|
-
return this.formControl.value?.filter((i) => i.value === tag.value).length > 0;
|
|
1365
|
+
return (this.formControl.value?.filter((i) => i.value === tag.value).length ?? 0) > 0;
|
|
1366
|
+
}
|
|
1367
|
+
_toSearchText(value) {
|
|
1368
|
+
return typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean' ? String(value) : '';
|
|
1290
1369
|
}
|
|
1291
1370
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: CmatTagsTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1292
1371
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: CmatTagsTypeComponent, isStandalone: true, selector: "cmat-tags-type", viewQueries: [{ propertyName: "_tagsPanelOrigin", first: true, predicate: ["tagsPanelOrigin"], descendants: true }, { propertyName: "_tagsPanel", first: true, predicate: ["tagsPanel"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"text-lg mb-2\">\r\n {{ props.label }}\r\n @if(props.required){\r\n <span>*</span>\r\n }\r\n</div>\r\n<div class=\"flex flex-wrap items-center -m-2\" [attr.data-refresh]=\"refreshVersion()\" [tabIndex]=\"props.tabindex\">\r\n <ng-container>\r\n @for (selectedItem of formControl.value; track $index) {\r\n <div\r\n class=\"flex items-center justify-center px-4 m-1.5 rounded-full leading-9 text-gray-500 bg-slate-100 dark:text-gray-300 dark:bg-slate-700\">\r\n <span class=\"text-md font-medium whitespace-nowrap\">{{selectedItem.label}}</span>\r\n </div>\r\n }\r\n\r\n <div #tagsPanelOrigin\r\n class=\"flex items-center justify-center px-4 m-1.5 rounded-full leading-9 cursor-pointer text-gray-500 bg-slate-100 dark:text-gray-300 dark:bg-slate-700 print:hidden\" role=\"presentation\" (click)=\"openTagsPanel()\">\r\n\r\n @if(formControl.value?.length&&!disabled){\r\n <mat-icon class=\"icon-size-5\" [svgIcon]=\"'heroicons_solid:pencil-square'\"></mat-icon>\r\n <span class=\"ml-1.5 text-md font-medium whitespace-nowrap\">\u7F16\u8F91</span>\r\n }\r\n\r\n @if(!formControl.value?.length&&!disabled){\r\n <mat-icon class=\"icon-size-5\" [svgIcon]=\"'heroicons_solid:plus-circle'\"></mat-icon>\r\n <span class=\"ml-1.5 text-md font-medium whitespace-nowrap\">\u65B0\u589E</span>\r\n }\r\n\r\n <ng-template #tagsPanel>\r\n <div class=\"w-60 rounded-sm border shadow-md bg-card\">\r\n <div class=\"flex items-center m-3 mr-2\">\r\n <div class=\"flex items-center\">\r\n <mat-icon class=\"icon-size-5\" [svgIcon]=\"'heroicons_solid:magnifying-glass'\">\r\n </mat-icon>\r\n <div class=\"ml-2\">\r\n <input class=\"w-full min-w-0 py-1 border-none\" type=\"text\" placeholder=\"\u8F93\u5165\u6807\u7B7E\u540D\"\r\n [maxLength]=\"30\" (input)=\"filterTags($event)\">\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"flex flex-col max-h-64 py-2 border-t overflow-y-auto scrollbar-custom\">\r\n @if ((filteredItems$ | async); as filteredItems) {\r\n @if(filteredItems.length>0){\r\n @for (tag of filteredItems; track $index) {\r\n <div role=\"presentation\"\r\n class=\"flex items-center h-10 min-h-10 pl-1 pr-4 cursor-pointer hover:bg-hover\"\r\n matRipple (click)=\"toggleTag(tag)\">\r\n <mat-checkbox class=\"flex items-center h-10 min-h-10\" [color]=\"'primary'\"\r\n [disabled]=\"tag.disabled\" [checked]=\"isCheck(tag)\">\r\n {{tag.label}}\r\n </mat-checkbox>\r\n </div>\r\n }\r\n }@else {\r\n <div class=\"flex flex-auto flex-col justify-center px-4 h-10 min-h-10\">\r\n \u65E0\u7ED3\u679C\r\n </div>\r\n }\r\n }\r\n </div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </ng-container>\r\n</div>\r\n", styles: [":host{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i1$5.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
@@ -1344,13 +1423,13 @@ class CmatUploadTypeComponent extends FieldType {
|
|
|
1344
1423
|
}
|
|
1345
1424
|
}
|
|
1346
1425
|
upload(id) {
|
|
1347
|
-
|
|
1426
|
+
const rootValue = this.baseGroup.get('uploadId')?.value;
|
|
1348
1427
|
if (rootValue && !isNil(id)) {
|
|
1349
1428
|
this.baseGroup.get('uploadId')?.setValue([id, ...rootValue]);
|
|
1350
1429
|
}
|
|
1351
1430
|
}
|
|
1352
1431
|
remove(id) {
|
|
1353
|
-
|
|
1432
|
+
const rootValue = this.baseGroup.get('removeId')?.value;
|
|
1354
1433
|
if (rootValue && !isNil(id)) {
|
|
1355
1434
|
this.baseGroup.get('removeId')?.setValue([id, ...rootValue]);
|
|
1356
1435
|
}
|
|
@@ -1358,12 +1437,12 @@ class CmatUploadTypeComponent extends FieldType {
|
|
|
1358
1437
|
updateData(i) {
|
|
1359
1438
|
const data = Array.isArray(i) ? i : [i];
|
|
1360
1439
|
this.formControl.setValue(data.map((j) => {
|
|
1361
|
-
if (j.id)
|
|
1440
|
+
if (typeof j === 'object' && j !== null && 'id' in j && typeof j.id === 'string')
|
|
1362
1441
|
return {
|
|
1363
|
-
id: j.id,
|
|
1364
|
-
name: j.name,
|
|
1365
|
-
type: j.type,
|
|
1366
|
-
size: j.size
|
|
1442
|
+
id: String((j).id),
|
|
1443
|
+
name: typeof j.name === 'string' ? j.name : '',
|
|
1444
|
+
type: typeof j.type === 'string' ? j.type : '',
|
|
1445
|
+
size: Number(j.size ?? 0)
|
|
1367
1446
|
};
|
|
1368
1447
|
else
|
|
1369
1448
|
return j;
|
|
@@ -1403,7 +1482,7 @@ class CmatQuillTypeComponent extends FieldType {
|
|
|
1403
1482
|
image: this._imgFileHandler.bind(this),
|
|
1404
1483
|
video: this._videoFileHandler.bind(this),
|
|
1405
1484
|
word: () => {
|
|
1406
|
-
this._wordFileHandler().catch(err => console.error('Word 导出失败:', err));
|
|
1485
|
+
this._wordFileHandler().catch((err) => console.error('Word 导出失败:', err));
|
|
1407
1486
|
},
|
|
1408
1487
|
},
|
|
1409
1488
|
},
|
|
@@ -1445,6 +1524,9 @@ class CmatQuillTypeComponent extends FieldType {
|
|
|
1445
1524
|
}
|
|
1446
1525
|
}
|
|
1447
1526
|
fileChangeEvent(file) {
|
|
1527
|
+
if (!file) {
|
|
1528
|
+
return;
|
|
1529
|
+
}
|
|
1448
1530
|
const fileModel = {
|
|
1449
1531
|
id: null,
|
|
1450
1532
|
fileName: file.name,
|
|
@@ -1461,12 +1543,16 @@ class CmatQuillTypeComponent extends FieldType {
|
|
|
1461
1543
|
formData.append('fileInfo', JSON.stringify(fileModel));
|
|
1462
1544
|
this._fileService.uploadFile(formData).pipe(takeUntilDestroyed(this._destroyRef)).subscribe((event) => {
|
|
1463
1545
|
if (event.type === HttpEventType.Response) {
|
|
1464
|
-
|
|
1546
|
+
const fileId = typeof event.body?.id === 'string' ? event.body.id : undefined;
|
|
1547
|
+
if (typeof fileId !== 'string') {
|
|
1548
|
+
return;
|
|
1549
|
+
}
|
|
1550
|
+
this._editorInstance.insertEmbed(this._editorInstance.getSelection(true).index, this._getMediaType(file.type), `${this._config.fileUrl}/download/quill/${fileId}`);
|
|
1465
1551
|
this._editorInstance.setSelection(this._editorInstance.getSelection(true).index + 1);
|
|
1466
1552
|
this.formControl.setValue(this._editorInstance.container.innerHTML);
|
|
1467
|
-
this._upload(
|
|
1553
|
+
this._upload(fileId);
|
|
1468
1554
|
}
|
|
1469
|
-
this.refreshVersion.update(value => value + 1);
|
|
1555
|
+
this.refreshVersion.update((value) => value + 1);
|
|
1470
1556
|
});
|
|
1471
1557
|
}
|
|
1472
1558
|
editorCreated(editorInstance) {
|
|
@@ -1480,20 +1566,20 @@ class CmatQuillTypeComponent extends FieldType {
|
|
|
1480
1566
|
}
|
|
1481
1567
|
});
|
|
1482
1568
|
}
|
|
1483
|
-
contentChanged(
|
|
1569
|
+
contentChanged(contentChange) {
|
|
1484
1570
|
const dom = document.createElement('DIV');
|
|
1485
|
-
dom.innerHTML =
|
|
1571
|
+
dom.innerHTML = contentChange.editor.container.innerHTML;
|
|
1486
1572
|
const fileDom = dom.querySelectorAll('img, video');
|
|
1487
1573
|
const arr = [];
|
|
1488
1574
|
fileDom.forEach((i) => {
|
|
1489
1575
|
if (i.src.includes(this._config.fileUrl)) {
|
|
1490
1576
|
const id = i.src.substring(`${this._config.fileUrl}/download/quill/`.length, i.src.length);
|
|
1491
|
-
this._imgIds.splice(this._imgIds.findIndex(k => k === id), 1);
|
|
1577
|
+
this._imgIds.splice(this._imgIds.findIndex((k) => k === id), 1);
|
|
1492
1578
|
arr.push(id);
|
|
1493
1579
|
}
|
|
1494
1580
|
});
|
|
1495
1581
|
this._imgIds.forEach((i) => {
|
|
1496
|
-
|
|
1582
|
+
const rootValue = this.baseGroup.get('removeId')?.value;
|
|
1497
1583
|
if (rootValue && !isNil(i)) {
|
|
1498
1584
|
this.baseGroup.get('removeId')?.setValue([i, ...rootValue]);
|
|
1499
1585
|
}
|
|
@@ -1529,7 +1615,7 @@ class CmatQuillTypeComponent extends FieldType {
|
|
|
1529
1615
|
let currentListLevel = 0;
|
|
1530
1616
|
let isList = false;
|
|
1531
1617
|
for (const op of delta.ops) {
|
|
1532
|
-
if (op.insert?.image) {
|
|
1618
|
+
if (typeof op.insert !== 'string' && op.insert?.image) {
|
|
1533
1619
|
if (currentRun.length > 0) {
|
|
1534
1620
|
children.push(new Paragraph({ children: currentRun }));
|
|
1535
1621
|
currentRun = [];
|
|
@@ -1567,7 +1653,7 @@ class CmatQuillTypeComponent extends FieldType {
|
|
|
1567
1653
|
}
|
|
1568
1654
|
}
|
|
1569
1655
|
if (currentRun.length > 0) {
|
|
1570
|
-
children.push(this._createParagraph(currentRun,
|
|
1656
|
+
children.push(this._createParagraph(currentRun, undefined, isList, currentListLevel));
|
|
1571
1657
|
}
|
|
1572
1658
|
return children;
|
|
1573
1659
|
}
|
|
@@ -1580,25 +1666,23 @@ class CmatQuillTypeComponent extends FieldType {
|
|
|
1580
1666
|
size: this._mapFontSize(attributes?.size),
|
|
1581
1667
|
font: attributes?.font ?? undefined,
|
|
1582
1668
|
color: attributes?.color ? this._parseColor(attributes.color) : undefined,
|
|
1583
|
-
highlight: attributes?.background ? this.
|
|
1669
|
+
highlight: attributes?.background ? this._mapHighlightColor(attributes.background) : undefined
|
|
1584
1670
|
});
|
|
1585
1671
|
}
|
|
1586
1672
|
_createParagraph(runs, attributes, isList, listLevel) {
|
|
1673
|
+
const headerLevel = attributes?.header ? (typeof attributes.header === 'number' ? attributes.header : parseInt(attributes.header)) : undefined;
|
|
1587
1674
|
const paragraphOptions = {
|
|
1588
1675
|
children: runs,
|
|
1589
1676
|
alignment: this._mapAlignment(attributes?.align),
|
|
1677
|
+
...(headerLevel && headerLevel >= 1 && headerLevel <= 6 ? {
|
|
1678
|
+
heading: HeadingLevel[`HEADING_${headerLevel}`]
|
|
1679
|
+
} : {}),
|
|
1680
|
+
...(isList && attributes?.list ? {
|
|
1681
|
+
bullet: {
|
|
1682
|
+
level: listLevel ?? 0
|
|
1683
|
+
}
|
|
1684
|
+
} : {})
|
|
1590
1685
|
};
|
|
1591
|
-
if (attributes?.header) {
|
|
1592
|
-
const headerLevel = parseInt(attributes.header);
|
|
1593
|
-
if (headerLevel >= 1 && headerLevel <= 6) {
|
|
1594
|
-
paragraphOptions.heading = HeadingLevel[`HEADING_${headerLevel}`];
|
|
1595
|
-
}
|
|
1596
|
-
}
|
|
1597
|
-
if (isList && attributes?.list) {
|
|
1598
|
-
paragraphOptions.bullet = {
|
|
1599
|
-
level: listLevel ?? 0
|
|
1600
|
-
};
|
|
1601
|
-
}
|
|
1602
1686
|
return new Paragraph(paragraphOptions);
|
|
1603
1687
|
}
|
|
1604
1688
|
async _createImageRun(imageUrl) {
|
|
@@ -1710,11 +1794,47 @@ class CmatQuillTypeComponent extends FieldType {
|
|
|
1710
1794
|
}
|
|
1711
1795
|
return undefined;
|
|
1712
1796
|
}
|
|
1713
|
-
|
|
1797
|
+
_mapHighlightColor(color) {
|
|
1798
|
+
const hex = this._parseColor(color);
|
|
1799
|
+
if (!hex)
|
|
1800
|
+
return HighlightColor.NONE;
|
|
1801
|
+
const r = parseInt(hex.substring(0, 2), 16);
|
|
1802
|
+
const g = parseInt(hex.substring(2, 4), 16);
|
|
1803
|
+
const b = parseInt(hex.substring(4, 6), 16);
|
|
1804
|
+
const colorMap = {
|
|
1805
|
+
[HighlightColor.YELLOW]: [255, 255, 0],
|
|
1806
|
+
[HighlightColor.GREEN]: [0, 128, 0],
|
|
1807
|
+
[HighlightColor.CYAN]: [0, 255, 255],
|
|
1808
|
+
[HighlightColor.RED]: [255, 0, 0],
|
|
1809
|
+
[HighlightColor.BLUE]: [0, 0, 255],
|
|
1810
|
+
[HighlightColor.MAGENTA]: [255, 0, 255],
|
|
1811
|
+
[HighlightColor.DARK_BLUE]: [0, 0, 139],
|
|
1812
|
+
[HighlightColor.DARK_CYAN]: [0, 139, 139],
|
|
1813
|
+
[HighlightColor.DARK_GREEN]: [0, 100, 0],
|
|
1814
|
+
[HighlightColor.DARK_MAGENTA]: [139, 0, 139],
|
|
1815
|
+
[HighlightColor.DARK_RED]: [139, 0, 0],
|
|
1816
|
+
[HighlightColor.DARK_YELLOW]: [128, 128, 0],
|
|
1817
|
+
[HighlightColor.DARK_GRAY]: [169, 169, 169],
|
|
1818
|
+
[HighlightColor.LIGHT_GRAY]: [211, 211, 211],
|
|
1819
|
+
[HighlightColor.BLACK]: [0, 0, 0],
|
|
1820
|
+
[HighlightColor.WHITE]: [255, 255, 255],
|
|
1821
|
+
};
|
|
1822
|
+
let closestColor = HighlightColor.NONE;
|
|
1823
|
+
let minDistance = Infinity;
|
|
1824
|
+
for (const [name, [cr, cg, cb]] of Object.entries(colorMap)) {
|
|
1825
|
+
const distance = (r - cr) ** 2 + (g - cg) ** 2 + (b - cb) ** 2;
|
|
1826
|
+
if (distance < minDistance) {
|
|
1827
|
+
minDistance = distance;
|
|
1828
|
+
closestColor = name;
|
|
1829
|
+
}
|
|
1830
|
+
}
|
|
1831
|
+
return closestColor;
|
|
1832
|
+
}
|
|
1833
|
+
_dropFileHandler(_dataUrl, _type, fileData) {
|
|
1714
1834
|
this.fileChangeEvent(fileData.toFile());
|
|
1715
1835
|
}
|
|
1716
1836
|
_upload(id) {
|
|
1717
|
-
|
|
1837
|
+
const rootValue = this.baseGroup.get('uploadId')?.value;
|
|
1718
1838
|
if (rootValue && !isNil(id)) {
|
|
1719
1839
|
this.baseGroup.get('uploadId')?.setValue([id, ...rootValue]);
|
|
1720
1840
|
}
|
|
@@ -1743,11 +1863,11 @@ class CmatQuillTypeComponent extends FieldType {
|
|
|
1743
1863
|
return baseControl;
|
|
1744
1864
|
}
|
|
1745
1865
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: CmatQuillTypeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1746
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.9", type: CmatQuillTypeComponent, isStandalone: true, selector: "cmat-quill-type", viewQueries: [{ propertyName: "imgInput", first: true, predicate: ["imgInput"], descendants: true }, { propertyName: "videoInput", first: true, predicate: ["videoInput"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<quill-editor class=\"w-full\" defaultEmptyValue=\"\" [formControl]=\"formControl\" [required]=\"required\" [placeholder]=\"placeholder\" [tabindex]=\"props.tabindex\"\r\n [readOnly]=\"disabled\" [modules]=\"quillModules\" (onEditorCreated)=\"editorCreated($event)\"\r\n (onContentChanged)=\"contentChanged($event)\">\r\n \r\n <input #imgInput type=\"file\" accept=\"image/png,image/jpeg,image/jpg,image/gif\" class=\"hidden\" (change)=\"fileChangeEvent(imgInput.files?.[0])\" />\r\n <input #videoInput type=\"file\" accept=\"video/mpeg,video/mp4,audio/mp4\" class=\"hidden\" (change)=\"fileChangeEvent(videoInput.files?.[0])\" />\r\n</quill-editor>\r\n<div class=\"cmat-quill-type\" [attr.data-refresh]=\"refreshVersion()\">\r\n", styles: [":host{display:block;width:100%}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: QuillModule }, { kind: "component", type: i2$4.QuillEditorComponent, selector: "quill-editor" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1866
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.9", type: CmatQuillTypeComponent, isStandalone: true, selector: "cmat-quill-type", viewQueries: [{ propertyName: "imgInput", first: true, predicate: ["imgInput"], descendants: true }, { propertyName: "videoInput", first: true, predicate: ["videoInput"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<quill-editor class=\"w-full\" defaultEmptyValue=\"\" [formControl]=\"formControl\" [required]=\"required\" [placeholder]=\"placeholder\" [tabindex]=\"props.tabindex\"\r\n [readOnly]=\"disabled\" [modules]=\"quillModules\" (onEditorCreated)=\"editorCreated($event)\"\r\n (onContentChanged)=\"contentChanged($event)\">\r\n \r\n <input #imgInput type=\"file\" accept=\"image/png,image/jpeg,image/jpg,image/gif\" class=\"hidden\" (change)=\"fileChangeEvent(imgInput.files?.[0] ?? undefined)\" />\r\n <input #videoInput type=\"file\" accept=\"video/mpeg,video/mp4,audio/mp4\" class=\"hidden\" (change)=\"fileChangeEvent(videoInput.files?.[0] ?? undefined)\" />\r\n</quill-editor>\r\n<div class=\"cmat-quill-type\" [attr.data-refresh]=\"refreshVersion()\">\r\n", styles: [":host{display:block;width:100%}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: QuillModule }, { kind: "component", type: i2$4.QuillEditorComponent, selector: "quill-editor" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1747
1867
|
}
|
|
1748
1868
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: CmatQuillTypeComponent, decorators: [{
|
|
1749
1869
|
type: Component,
|
|
1750
|
-
args: [{ selector: 'cmat-quill-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [ReactiveFormsModule, QuillModule], template: "<quill-editor class=\"w-full\" defaultEmptyValue=\"\" [formControl]=\"formControl\" [required]=\"required\" [placeholder]=\"placeholder\" [tabindex]=\"props.tabindex\"\r\n [readOnly]=\"disabled\" [modules]=\"quillModules\" (onEditorCreated)=\"editorCreated($event)\"\r\n (onContentChanged)=\"contentChanged($event)\">\r\n \r\n <input #imgInput type=\"file\" accept=\"image/png,image/jpeg,image/jpg,image/gif\" class=\"hidden\" (change)=\"fileChangeEvent(imgInput.files?.[0])\" />\r\n <input #videoInput type=\"file\" accept=\"video/mpeg,video/mp4,audio/mp4\" class=\"hidden\" (change)=\"fileChangeEvent(videoInput.files?.[0])\" />\r\n</quill-editor>\r\n<div class=\"cmat-quill-type\" [attr.data-refresh]=\"refreshVersion()\">\r\n", styles: [":host{display:block;width:100%}\n"] }]
|
|
1870
|
+
args: [{ selector: 'cmat-quill-type', changeDetection: ChangeDetectionStrategy.OnPush, imports: [ReactiveFormsModule, QuillModule], template: "<quill-editor class=\"w-full\" defaultEmptyValue=\"\" [formControl]=\"formControl\" [required]=\"required\" [placeholder]=\"placeholder\" [tabindex]=\"props.tabindex\"\r\n [readOnly]=\"disabled\" [modules]=\"quillModules\" (onEditorCreated)=\"editorCreated($event)\"\r\n (onContentChanged)=\"contentChanged($event)\">\r\n \r\n <input #imgInput type=\"file\" accept=\"image/png,image/jpeg,image/jpg,image/gif\" class=\"hidden\" (change)=\"fileChangeEvent(imgInput.files?.[0] ?? undefined)\" />\r\n <input #videoInput type=\"file\" accept=\"video/mpeg,video/mp4,audio/mp4\" class=\"hidden\" (change)=\"fileChangeEvent(videoInput.files?.[0] ?? undefined)\" />\r\n</quill-editor>\r\n<div class=\"cmat-quill-type\" [attr.data-refresh]=\"refreshVersion()\">\r\n", styles: [":host{display:block;width:100%}\n"] }]
|
|
1751
1871
|
}], ctorParameters: () => [], propDecorators: { imgInput: [{
|
|
1752
1872
|
type: ViewChild,
|
|
1753
1873
|
args: ['imgInput']
|