@yourself.create/ngx-form-designer 0.0.7 → 0.0.9
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/uch-web-ngx-form-designer.mjs +709 -432
- package/fesm2022/uch-web-ngx-form-designer.mjs.map +1 -1
- package/lib/data/data-provider.d.ts +3 -1
- package/lib/form-core/form-engine.d.ts +3 -0
- package/lib/form-core/models.d.ts +7 -12
- package/lib/form-designer/data-panel/data-panel.component.d.ts +4 -3
- package/lib/form-designer/dynamic-properties/dynamic-properties.component.d.ts +0 -7
- package/lib/form-designer/rules-editor/rules-panel/rules-panel.component.d.ts +1 -0
- package/lib/form-designer/widget-inspector.component.d.ts +1 -1
- package/lib/form-renderer/json-form-renderer.component.d.ts +14 -5
- package/lib/widgets/field-widgets/search/search-widget.component.d.ts +3 -0
- package/lib/widgets/field-widgets/select/select-widget.component.d.ts +1 -0
- package/lib/widgets/field-widgets/text-field/text-field.component.d.ts +10 -0
- package/lib/widgets/widget-definition.d.ts +1 -1
- package/package.json +1 -1
|
@@ -23,6 +23,15 @@ import Quill from 'quill';
|
|
|
23
23
|
import { DomSanitizer } from '@angular/platform-browser';
|
|
24
24
|
import { HttpClient, provideHttpClient } from '@angular/common/http';
|
|
25
25
|
|
|
26
|
+
function usesFieldThousandSeparator(field) {
|
|
27
|
+
return field?.useThousandSeparator === true;
|
|
28
|
+
}
|
|
29
|
+
function isFieldReadonly(field) {
|
|
30
|
+
return field?.html5?.readonly === true;
|
|
31
|
+
}
|
|
32
|
+
function isFieldDisabled(field) {
|
|
33
|
+
return field?.html5?.disabled === true;
|
|
34
|
+
}
|
|
26
35
|
const CURRENT_SCHEMA_VERSION = '1.0.0';
|
|
27
36
|
|
|
28
37
|
/**
|
|
@@ -446,8 +455,8 @@ class FormEngine {
|
|
|
446
455
|
setValue(fieldName, value) {
|
|
447
456
|
this.values[fieldName] = value;
|
|
448
457
|
this.valueSubject.next({ ...this.values }); // Emit new state
|
|
449
|
-
//
|
|
450
|
-
this.
|
|
458
|
+
// Rules and dependencies can affect other fields, so revalidate the full form.
|
|
459
|
+
this.validate();
|
|
451
460
|
}
|
|
452
461
|
getValues() {
|
|
453
462
|
return { ...this.values };
|
|
@@ -502,7 +511,7 @@ class FormEngine {
|
|
|
502
511
|
if (!field)
|
|
503
512
|
return false;
|
|
504
513
|
// 1. Dependencies (Legacy)
|
|
505
|
-
let enabled = this.evaluateDependencyRules(field, 'enable', 'disable',
|
|
514
|
+
let enabled = this.evaluateDependencyRules(field, 'enable', 'disable', !isFieldDisabled(field));
|
|
506
515
|
// 2. Enterprise Rules
|
|
507
516
|
enabled = this.evaluateEnterpriseRules(field, 'enable', 'disable', enabled);
|
|
508
517
|
return enabled;
|
|
@@ -535,10 +544,16 @@ class FormEngine {
|
|
|
535
544
|
return;
|
|
536
545
|
const value = this.values[fieldName];
|
|
537
546
|
const fieldErrors = [];
|
|
547
|
+
const ruleErrors = this.getRuleValidationErrors(field);
|
|
538
548
|
// Visibility check
|
|
539
549
|
const isVisible = this.isFieldVisible(field.id);
|
|
540
550
|
if (!isVisible) {
|
|
541
|
-
|
|
551
|
+
if (ruleErrors.length > 0) {
|
|
552
|
+
this.errors[fieldName] = ruleErrors;
|
|
553
|
+
}
|
|
554
|
+
else {
|
|
555
|
+
delete this.errors[fieldName];
|
|
556
|
+
}
|
|
542
557
|
return;
|
|
543
558
|
}
|
|
544
559
|
const isRequired = this.isFieldRequired(field.id);
|
|
@@ -568,30 +583,9 @@ class FormEngine {
|
|
|
568
583
|
}
|
|
569
584
|
}
|
|
570
585
|
}
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
let isValid = true;
|
|
575
|
-
if (rule.type === 'builtin') {
|
|
576
|
-
if (rule.name === 'email') {
|
|
577
|
-
isValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(String(value));
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
else if (rule.type === 'expression' && rule.expression) {
|
|
581
|
-
try {
|
|
582
|
-
const checkFn = new Function('value', 'form', `return ${rule.expression}`);
|
|
583
|
-
isValid = checkFn(value, this.values);
|
|
584
|
-
}
|
|
585
|
-
catch (e) {
|
|
586
|
-
console.error('Validation expression error', e);
|
|
587
|
-
isValid = false;
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
|
-
if (!isValid) {
|
|
591
|
-
fieldErrors.push(rule.message || 'Validation failed.');
|
|
592
|
-
}
|
|
593
|
-
});
|
|
594
|
-
}
|
|
586
|
+
}
|
|
587
|
+
if (ruleErrors.length > 0) {
|
|
588
|
+
fieldErrors.push(...ruleErrors);
|
|
595
589
|
}
|
|
596
590
|
if (fieldErrors.length > 0) {
|
|
597
591
|
this.errors[fieldName] = fieldErrors;
|
|
@@ -600,6 +594,11 @@ class FormEngine {
|
|
|
600
594
|
delete this.errors[fieldName];
|
|
601
595
|
}
|
|
602
596
|
}
|
|
597
|
+
getRuleValidationErrors(field) {
|
|
598
|
+
return this.getEnterpriseRuleOutcomes(field)
|
|
599
|
+
.filter(({ rule, conditionMet }) => rule.severity === 'error' && !conditionMet && rule.elseAction === undefined)
|
|
600
|
+
.map(({ rule }) => this.getRuleValidationMessage(rule));
|
|
601
|
+
}
|
|
603
602
|
// Generic rule evaluator
|
|
604
603
|
evaluateDependencyRules(field, positiveEffect, negativeEffect, startValue) {
|
|
605
604
|
if (!field.dependencies)
|
|
@@ -638,13 +637,31 @@ class FormEngine {
|
|
|
638
637
|
if (hasPositiveRules && startValue === true) {
|
|
639
638
|
currentState = false; // Implicitly hide/disable
|
|
640
639
|
}
|
|
641
|
-
field.
|
|
642
|
-
const conditionMet = this.ruleEvaluator.evaluateRule(rule, this.values, this.schema.fields);
|
|
643
|
-
const nextAction = conditionMet ? rule.action : rule.elseAction;
|
|
640
|
+
this.getEnterpriseRuleOutcomes(field).forEach(({ nextAction }) => {
|
|
644
641
|
currentState = this.applyRuleAction(currentState, nextAction, positiveAction, negativeAction);
|
|
645
642
|
});
|
|
646
643
|
return currentState;
|
|
647
644
|
}
|
|
645
|
+
getEnterpriseRuleOutcomes(field) {
|
|
646
|
+
if (!field.rules || field.rules.length === 0) {
|
|
647
|
+
return [];
|
|
648
|
+
}
|
|
649
|
+
return field.rules.map((rule) => {
|
|
650
|
+
const conditionMet = this.ruleEvaluator.evaluateRule(rule, this.values, this.schema.fields);
|
|
651
|
+
return {
|
|
652
|
+
rule,
|
|
653
|
+
conditionMet,
|
|
654
|
+
nextAction: conditionMet ? rule.action : rule.elseAction
|
|
655
|
+
};
|
|
656
|
+
});
|
|
657
|
+
}
|
|
658
|
+
getRuleValidationMessage(rule) {
|
|
659
|
+
const name = rule.name?.trim();
|
|
660
|
+
if (name) {
|
|
661
|
+
return name;
|
|
662
|
+
}
|
|
663
|
+
return `Rule "${rule.action}" failed.`;
|
|
664
|
+
}
|
|
648
665
|
applyRuleAction(currentState, action, positiveAction, negativeAction) {
|
|
649
666
|
if (action === positiveAction) {
|
|
650
667
|
return true;
|
|
@@ -4496,6 +4513,7 @@ class FormEventRunner {
|
|
|
4496
4513
|
const target = fields.find(f => f.id === action.targetFieldId);
|
|
4497
4514
|
if (!target)
|
|
4498
4515
|
return;
|
|
4516
|
+
const previousValue = this.engine.getValue(target.name);
|
|
4499
4517
|
let val;
|
|
4500
4518
|
if (action.valueFrom === 'literal') {
|
|
4501
4519
|
val = action.valueLiteral;
|
|
@@ -4510,6 +4528,14 @@ class FormEventRunner {
|
|
|
4510
4528
|
}
|
|
4511
4529
|
}
|
|
4512
4530
|
this.engine.setValue(target.name, val);
|
|
4531
|
+
if (!Object.is(previousValue, val)) {
|
|
4532
|
+
this.engine.emitUiEvent({
|
|
4533
|
+
fieldId: target.id,
|
|
4534
|
+
fieldName: target.name,
|
|
4535
|
+
type: 'change',
|
|
4536
|
+
value: val
|
|
4537
|
+
});
|
|
4538
|
+
}
|
|
4513
4539
|
}
|
|
4514
4540
|
async handleApiAction(action, eventId, evt, fields) {
|
|
4515
4541
|
if (!this.apiExecutor) {
|
|
@@ -5181,6 +5207,7 @@ class JsonFormRendererComponent {
|
|
|
5181
5207
|
uploadClient = inject(FILE_UPLOAD_CLIENT, { optional: true }) ?? inject(DefaultFileUploadClient);
|
|
5182
5208
|
runtimeFieldDataAccessRegistry = inject(RuntimeFieldDataAccessRegistryService);
|
|
5183
5209
|
dataCatalog = inject(DataCatalog, { optional: true });
|
|
5210
|
+
ruleEvaluationService = inject(RuleEvaluationService);
|
|
5184
5211
|
constructor(designerState) {
|
|
5185
5212
|
this.designerState = designerState;
|
|
5186
5213
|
}
|
|
@@ -5257,7 +5284,7 @@ class JsonFormRendererComponent {
|
|
|
5257
5284
|
this.runtimeFieldDataAccessRegistry.unregister(this.engine);
|
|
5258
5285
|
}
|
|
5259
5286
|
async emitValuePayload(values) {
|
|
5260
|
-
const fieldValueMap = await this.buildFieldValueMap(values);
|
|
5287
|
+
const fieldValueMap = await this.buildFieldValueMap(values, { normalizeFileFieldsForSubmit: true });
|
|
5261
5288
|
const groupedValues = this.buildGroupedValues(fieldValueMap);
|
|
5262
5289
|
const combinedValues = this.buildCombinedValues(fieldValueMap);
|
|
5263
5290
|
this.valueChange.emit(fieldValueMap);
|
|
@@ -5419,16 +5446,10 @@ class JsonFormRendererComponent {
|
|
|
5419
5446
|
this.validationChange.emit(validation);
|
|
5420
5447
|
// Notify all widgets to show errors if any
|
|
5421
5448
|
this.engine?.submit();
|
|
5422
|
-
const preUploadFieldValueMap = this.uploadOnSubmit
|
|
5423
|
-
? await this.buildFieldValueMap(this.engine?.getValues() ?? {}, { normalizeFileFieldsForSubmit: true })
|
|
5424
|
-
: undefined;
|
|
5425
5449
|
const uploadedFiles = this.uploadOnSubmit ? await this.uploadPendingFiles() : {};
|
|
5426
5450
|
this.uploadedFilesChange.emit(uploadedFiles);
|
|
5427
5451
|
const values = this.engine?.getValues() ?? {};
|
|
5428
|
-
const
|
|
5429
|
-
const submitValues = preUploadFieldValueMap
|
|
5430
|
-
? this.mergeFileMetadata(fieldValueMap, preUploadFieldValueMap)
|
|
5431
|
-
: fieldValueMap;
|
|
5452
|
+
const submitValues = await this.buildFieldValueMap(values, { normalizeFileFieldsForSubmit: true });
|
|
5432
5453
|
this.formSubmit.emit({
|
|
5433
5454
|
values: submitValues,
|
|
5434
5455
|
groupedValues: this.buildGroupedValues(submitValues),
|
|
@@ -5441,10 +5462,12 @@ class JsonFormRendererComponent {
|
|
|
5441
5462
|
const errors = revalidate
|
|
5442
5463
|
? (this.engine?.validate() ?? {})
|
|
5443
5464
|
: (this.engine?.getErrors() ?? {});
|
|
5465
|
+
const fields = this.buildFieldValidationState(errors);
|
|
5444
5466
|
return {
|
|
5445
5467
|
errors: { ...errors },
|
|
5446
5468
|
isValid: Object.keys(errors).length === 0,
|
|
5447
|
-
|
|
5469
|
+
isSeverityError: Object.values(fields).some(field => field.isSeverityError),
|
|
5470
|
+
fields
|
|
5448
5471
|
};
|
|
5449
5472
|
}
|
|
5450
5473
|
buildFieldValidationState(errors) {
|
|
@@ -5465,71 +5488,99 @@ class JsonFormRendererComponent {
|
|
|
5465
5488
|
visible,
|
|
5466
5489
|
required,
|
|
5467
5490
|
valid: fieldErrors.length === 0,
|
|
5491
|
+
isSeverityError: false,
|
|
5468
5492
|
errors: fieldErrors,
|
|
5469
|
-
validators: this.describeFieldValidators(field, visible, required)
|
|
5493
|
+
validators: this.describeFieldValidators(field, visible, required, fieldErrors)
|
|
5470
5494
|
};
|
|
5495
|
+
states[field.name].isSeverityError = states[field.name].validators.some(validator => validator.severity === 'error' && validator.valid === false);
|
|
5471
5496
|
}
|
|
5472
5497
|
return states;
|
|
5473
5498
|
}
|
|
5474
|
-
describeFieldValidators(field, visible, required) {
|
|
5499
|
+
describeFieldValidators(field, visible, required, fieldErrors) {
|
|
5475
5500
|
const validators = [];
|
|
5476
5501
|
const value = this.engine?.getValue(field.name);
|
|
5477
5502
|
const hasValue = !this.isValidationEmpty(value);
|
|
5503
|
+
const ruleOutcomes = this.getRuleOutcomes(field);
|
|
5504
|
+
const requiredSeverity = ruleOutcomes.some(outcome => outcome.rule.severity === 'error' && outcome.nextAction === 'required');
|
|
5478
5505
|
if (this.hasRequiredValidation(field) || required) {
|
|
5506
|
+
const message = 'This field is required.';
|
|
5479
5507
|
validators.push({
|
|
5480
5508
|
name: 'required',
|
|
5481
5509
|
source: 'required',
|
|
5482
5510
|
active: visible && required,
|
|
5483
|
-
|
|
5511
|
+
valid: !fieldErrors.includes(message),
|
|
5512
|
+
message,
|
|
5513
|
+
...(requiredSeverity ? { severity: 'error' } : {})
|
|
5484
5514
|
});
|
|
5485
5515
|
}
|
|
5486
5516
|
if (field.html5?.minLength !== undefined) {
|
|
5517
|
+
const message = `Minimum length is ${field.html5.minLength}.`;
|
|
5487
5518
|
validators.push({
|
|
5488
5519
|
name: 'minLength',
|
|
5489
5520
|
source: 'html5',
|
|
5490
5521
|
active: visible && hasValue,
|
|
5491
|
-
|
|
5522
|
+
valid: !fieldErrors.includes(message),
|
|
5523
|
+
value: field.html5.minLength,
|
|
5524
|
+
message
|
|
5492
5525
|
});
|
|
5493
5526
|
}
|
|
5494
5527
|
if (field.html5?.maxLength !== undefined) {
|
|
5528
|
+
const message = `Maximum length is ${field.html5.maxLength}.`;
|
|
5495
5529
|
validators.push({
|
|
5496
5530
|
name: 'maxLength',
|
|
5497
5531
|
source: 'html5',
|
|
5498
5532
|
active: visible && hasValue,
|
|
5499
|
-
|
|
5533
|
+
valid: !fieldErrors.includes(message),
|
|
5534
|
+
value: field.html5.maxLength,
|
|
5535
|
+
message
|
|
5500
5536
|
});
|
|
5501
5537
|
}
|
|
5502
5538
|
if (field.html5?.min !== undefined) {
|
|
5539
|
+
const message = `Minimum value is ${field.html5.min}.`;
|
|
5503
5540
|
validators.push({
|
|
5504
5541
|
name: 'min',
|
|
5505
5542
|
source: 'html5',
|
|
5506
5543
|
active: visible && hasValue,
|
|
5507
|
-
|
|
5544
|
+
valid: !fieldErrors.includes(message),
|
|
5545
|
+
value: field.html5.min,
|
|
5546
|
+
message
|
|
5508
5547
|
});
|
|
5509
5548
|
}
|
|
5510
5549
|
if (field.html5?.max !== undefined) {
|
|
5550
|
+
const message = `Maximum value is ${field.html5.max}.`;
|
|
5511
5551
|
validators.push({
|
|
5512
5552
|
name: 'max',
|
|
5513
5553
|
source: 'html5',
|
|
5514
5554
|
active: visible && hasValue,
|
|
5515
|
-
|
|
5555
|
+
valid: !fieldErrors.includes(message),
|
|
5556
|
+
value: field.html5.max,
|
|
5557
|
+
message
|
|
5516
5558
|
});
|
|
5517
5559
|
}
|
|
5518
5560
|
if (field.html5?.pattern) {
|
|
5561
|
+
const message = 'Invalid format.';
|
|
5519
5562
|
validators.push({
|
|
5520
5563
|
name: 'pattern',
|
|
5521
5564
|
source: 'html5',
|
|
5522
5565
|
active: visible && hasValue,
|
|
5523
|
-
|
|
5566
|
+
valid: !fieldErrors.includes(message),
|
|
5567
|
+
value: field.html5.pattern,
|
|
5568
|
+
message
|
|
5524
5569
|
});
|
|
5525
5570
|
}
|
|
5526
|
-
for (const
|
|
5571
|
+
for (const outcome of ruleOutcomes) {
|
|
5572
|
+
const message = this.getRuleValidationMessage(outcome.rule);
|
|
5527
5573
|
validators.push({
|
|
5528
|
-
name: rule.
|
|
5529
|
-
source: '
|
|
5530
|
-
active:
|
|
5531
|
-
|
|
5532
|
-
|
|
5574
|
+
name: outcome.rule.name?.trim() || this.describeRuleName(outcome.rule),
|
|
5575
|
+
source: 'rule',
|
|
5576
|
+
active: true,
|
|
5577
|
+
valid: outcome.conditionMet || outcome.nextAction !== undefined,
|
|
5578
|
+
value: {
|
|
5579
|
+
action: outcome.rule.action,
|
|
5580
|
+
elseAction: outcome.rule.elseAction
|
|
5581
|
+
},
|
|
5582
|
+
message,
|
|
5583
|
+
...(outcome.rule.severity ? { severity: outcome.rule.severity } : {})
|
|
5533
5584
|
});
|
|
5534
5585
|
}
|
|
5535
5586
|
return validators;
|
|
@@ -5548,16 +5599,30 @@ class JsonFormRendererComponent {
|
|
|
5548
5599
|
}
|
|
5549
5600
|
return false;
|
|
5550
5601
|
}
|
|
5551
|
-
|
|
5552
|
-
if (!
|
|
5553
|
-
return
|
|
5554
|
-
try {
|
|
5555
|
-
const checkFn = new Function('form', `return ${rule.when}`);
|
|
5556
|
-
return checkFn(this.engine?.getValues() ?? {});
|
|
5602
|
+
getRuleOutcomes(field) {
|
|
5603
|
+
if (!field.rules?.length) {
|
|
5604
|
+
return [];
|
|
5557
5605
|
}
|
|
5558
|
-
|
|
5559
|
-
|
|
5606
|
+
const schema = this.engine?.getSchema() ?? this.schema;
|
|
5607
|
+
const formValues = this.engine?.getValues() ?? {};
|
|
5608
|
+
return field.rules.map(rule => {
|
|
5609
|
+
const conditionMet = this.ruleEvaluationService.evaluateRule(rule, formValues, schema?.fields ?? []);
|
|
5610
|
+
return {
|
|
5611
|
+
rule,
|
|
5612
|
+
conditionMet,
|
|
5613
|
+
nextAction: conditionMet ? rule.action : rule.elseAction
|
|
5614
|
+
};
|
|
5615
|
+
});
|
|
5616
|
+
}
|
|
5617
|
+
describeRuleName(rule) {
|
|
5618
|
+
return rule.action.charAt(0).toUpperCase() + rule.action.slice(1);
|
|
5619
|
+
}
|
|
5620
|
+
getRuleValidationMessage(rule) {
|
|
5621
|
+
const name = rule.name?.trim();
|
|
5622
|
+
if (name) {
|
|
5623
|
+
return name;
|
|
5560
5624
|
}
|
|
5625
|
+
return `Rule "${rule.action}" failed.`;
|
|
5561
5626
|
}
|
|
5562
5627
|
isValidationEmpty(value) {
|
|
5563
5628
|
return value === null
|
|
@@ -5689,13 +5754,14 @@ class JsonFormRendererComponent {
|
|
|
5689
5754
|
continue;
|
|
5690
5755
|
}
|
|
5691
5756
|
if (field.type === 'file') {
|
|
5757
|
+
const normalizeFileFieldsForSubmit = options.normalizeFileFieldsForSubmit === true;
|
|
5692
5758
|
const fileValue = {
|
|
5693
5759
|
fieldName: field.name,
|
|
5694
|
-
fieldValue:
|
|
5695
|
-
? this.
|
|
5760
|
+
fieldValue: normalizeFileFieldsForSubmit
|
|
5761
|
+
? await this.buildFileSubmitValueEntries(rawValue)
|
|
5696
5762
|
: rawValue,
|
|
5697
|
-
...(
|
|
5698
|
-
...(await this.buildFileFieldMetadata(rawValue))
|
|
5763
|
+
...(normalizeFileFieldsForSubmit ? { fieldType: field.type } : {}),
|
|
5764
|
+
...(!normalizeFileFieldsForSubmit ? await this.buildFileFieldMetadata(rawValue) : {})
|
|
5699
5765
|
};
|
|
5700
5766
|
mapped[field.id] = fileValue;
|
|
5701
5767
|
continue;
|
|
@@ -5782,7 +5848,12 @@ class JsonFormRendererComponent {
|
|
|
5782
5848
|
return undefined;
|
|
5783
5849
|
return values.length === 1 ? values[0] : values;
|
|
5784
5850
|
}
|
|
5785
|
-
|
|
5851
|
+
async buildFileSubmitValueEntries(value) {
|
|
5852
|
+
const rawEntries = this.normalizeFileFieldEntries(value);
|
|
5853
|
+
const normalizedEntries = await Promise.all(rawEntries.map(entry => this.normalizeSingleFileFieldEntry(entry)));
|
|
5854
|
+
return normalizedEntries.filter((entry) => entry !== null);
|
|
5855
|
+
}
|
|
5856
|
+
normalizeFileFieldEntries(value) {
|
|
5786
5857
|
if (this.isFileList(value)) {
|
|
5787
5858
|
return Array.from(value);
|
|
5788
5859
|
}
|
|
@@ -5794,6 +5865,23 @@ class JsonFormRendererComponent {
|
|
|
5794
5865
|
}
|
|
5795
5866
|
return [value];
|
|
5796
5867
|
}
|
|
5868
|
+
async normalizeSingleFileFieldEntry(value) {
|
|
5869
|
+
if (this.isFile(value)) {
|
|
5870
|
+
return this.buildPendingSubmitFileValue(value);
|
|
5871
|
+
}
|
|
5872
|
+
if (this.isUploadedFileRef(value)) {
|
|
5873
|
+
return { ...value };
|
|
5874
|
+
}
|
|
5875
|
+
return null;
|
|
5876
|
+
}
|
|
5877
|
+
async buildPendingSubmitFileValue(file) {
|
|
5878
|
+
return {
|
|
5879
|
+
name: file.name || undefined,
|
|
5880
|
+
size: Number.isFinite(file.size) ? file.size : undefined,
|
|
5881
|
+
type: file.type || undefined,
|
|
5882
|
+
data: await this.readFileBase64(file)
|
|
5883
|
+
};
|
|
5884
|
+
}
|
|
5797
5885
|
getUploadedFileRefs(value) {
|
|
5798
5886
|
if (this.isUploadedFileRef(value))
|
|
5799
5887
|
return [value];
|
|
@@ -5808,26 +5896,6 @@ class JsonFormRendererComponent {
|
|
|
5808
5896
|
: undefined;
|
|
5809
5897
|
return fieldLabel === undefined ? {} : { fieldLabel };
|
|
5810
5898
|
}
|
|
5811
|
-
mergeFileMetadata(target, source) {
|
|
5812
|
-
const merged = { ...target };
|
|
5813
|
-
for (const fieldId of Object.keys(source)) {
|
|
5814
|
-
const sourceValue = source[fieldId];
|
|
5815
|
-
const targetValue = merged[fieldId];
|
|
5816
|
-
if (!sourceValue || !targetValue)
|
|
5817
|
-
continue;
|
|
5818
|
-
if (sourceValue.fileType === undefined && sourceValue.data === undefined)
|
|
5819
|
-
continue;
|
|
5820
|
-
const nextValue = { ...targetValue };
|
|
5821
|
-
if (sourceValue.fileType !== undefined) {
|
|
5822
|
-
nextValue.fileType = sourceValue.fileType;
|
|
5823
|
-
}
|
|
5824
|
-
if (sourceValue.data !== undefined) {
|
|
5825
|
-
nextValue.data = sourceValue.data;
|
|
5826
|
-
}
|
|
5827
|
-
merged[fieldId] = nextValue;
|
|
5828
|
-
}
|
|
5829
|
-
return merged;
|
|
5830
|
-
}
|
|
5831
5899
|
buildGroupedValues(values) {
|
|
5832
5900
|
const grouped = {};
|
|
5833
5901
|
const schema = this.engine?.getSchema();
|
|
@@ -10274,13 +10342,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
|
|
|
10274
10342
|
class DynamicPropertiesComponent {
|
|
10275
10343
|
onPropertyChange;
|
|
10276
10344
|
designerCtx = inject(DesignerContext);
|
|
10277
|
-
validatorTypeOptions = [
|
|
10278
|
-
{ label: 'Built-in', value: 'builtin' },
|
|
10279
|
-
{ label: 'Expression', value: 'expression' }
|
|
10280
|
-
];
|
|
10281
|
-
builtinValidatorOptions = [
|
|
10282
|
-
{ label: 'Email', value: 'email' }
|
|
10283
|
-
];
|
|
10284
10345
|
get properties() {
|
|
10285
10346
|
if (!this.config)
|
|
10286
10347
|
return [];
|
|
@@ -10612,68 +10673,6 @@ class DynamicPropertiesComponent {
|
|
|
10612
10673
|
this.setValue(path, options);
|
|
10613
10674
|
}
|
|
10614
10675
|
}
|
|
10615
|
-
// Validators editor methods
|
|
10616
|
-
addValidator(path) {
|
|
10617
|
-
if (this.readOnly)
|
|
10618
|
-
return;
|
|
10619
|
-
const validators = [...(this.getValue(path) || [])];
|
|
10620
|
-
validators.push(this.createDefaultValidationRule());
|
|
10621
|
-
this.setValue(path, validators);
|
|
10622
|
-
this.handleFieldChange();
|
|
10623
|
-
}
|
|
10624
|
-
removeValidator(path, index) {
|
|
10625
|
-
if (this.readOnly)
|
|
10626
|
-
return;
|
|
10627
|
-
const validators = [...(this.getValue(path) || [])];
|
|
10628
|
-
validators.splice(index, 1);
|
|
10629
|
-
this.setValue(path, validators);
|
|
10630
|
-
this.handleFieldChange();
|
|
10631
|
-
}
|
|
10632
|
-
updateValidator(path, index, field, value) {
|
|
10633
|
-
if (this.readOnly)
|
|
10634
|
-
return;
|
|
10635
|
-
const validators = [...(this.getValue(path) || [])];
|
|
10636
|
-
const currentRule = validators[index];
|
|
10637
|
-
if (!currentRule) {
|
|
10638
|
-
return;
|
|
10639
|
-
}
|
|
10640
|
-
let nextRule = { ...currentRule };
|
|
10641
|
-
if (field === 'type') {
|
|
10642
|
-
nextRule = value === 'expression'
|
|
10643
|
-
? {
|
|
10644
|
-
type: 'expression',
|
|
10645
|
-
expression: 'return true;',
|
|
10646
|
-
message: 'Validation failed.'
|
|
10647
|
-
}
|
|
10648
|
-
: this.createDefaultValidationRule();
|
|
10649
|
-
}
|
|
10650
|
-
else if (field === 'name') {
|
|
10651
|
-
nextRule.name = String(value);
|
|
10652
|
-
nextRule.message = this.defaultValidationMessage(nextRule);
|
|
10653
|
-
}
|
|
10654
|
-
else if (field === 'expression') {
|
|
10655
|
-
nextRule.expression = String(value);
|
|
10656
|
-
}
|
|
10657
|
-
else if (field === 'message') {
|
|
10658
|
-
nextRule.message = String(value);
|
|
10659
|
-
}
|
|
10660
|
-
validators[index] = nextRule;
|
|
10661
|
-
this.setValue(path, validators);
|
|
10662
|
-
this.handleFieldChange();
|
|
10663
|
-
}
|
|
10664
|
-
createDefaultValidationRule() {
|
|
10665
|
-
return {
|
|
10666
|
-
type: 'builtin',
|
|
10667
|
-
name: 'email',
|
|
10668
|
-
message: 'Enter a valid email address.'
|
|
10669
|
-
};
|
|
10670
|
-
}
|
|
10671
|
-
defaultValidationMessage(rule) {
|
|
10672
|
-
if (rule.type === 'builtin' && rule.name === 'email') {
|
|
10673
|
-
return 'Enter a valid email address.';
|
|
10674
|
-
}
|
|
10675
|
-
return 'Validation failed.';
|
|
10676
|
-
}
|
|
10677
10676
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: DynamicPropertiesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
10678
10677
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.17", type: DynamicPropertiesComponent, isStandalone: true, selector: "app-dynamic-properties", inputs: { onPropertyChange: "onPropertyChange", config: "config", readOnly: "readOnly", includeSections: "includeSections", excludeSections: "excludeSections", allFields: "allFields" }, outputs: { configChange: "configChange" }, usesOnChanges: true, ngImport: i0, template: `
|
|
10679
10678
|
<div class="dynamic-properties flex flex-col font-sans text-sm">
|
|
@@ -10816,51 +10815,6 @@ class DynamicPropertiesComponent {
|
|
|
10816
10815
|
</div>
|
|
10817
10816
|
</ui-field-wrapper>
|
|
10818
10817
|
|
|
10819
|
-
<!-- Validators Editor -->
|
|
10820
|
-
<ui-field-wrapper *ngIf="field.type === 'validators-editor'" [label]="field.label || ''" [helpText]="field.helpText || ''">
|
|
10821
|
-
<div class="w-full border border-gray-200 rounded-lg p-3 bg-gray-50">
|
|
10822
|
-
<div class="flex items-center justify-between mb-3">
|
|
10823
|
-
<span class="text-xs font-semibold text-gray-600 uppercase">{{field.label}}</span>
|
|
10824
|
-
<button type="button"
|
|
10825
|
-
(click)="addValidator(field.key)"
|
|
10826
|
-
class="text-xs px-2 py-1 bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors">
|
|
10827
|
-
+
|
|
10828
|
-
</button>
|
|
10829
|
-
</div>
|
|
10830
|
-
<div class="space-y-2">
|
|
10831
|
-
<div *ngFor="let val of getValue(field.key) || []; let i = index" class="flex items-center gap-2 p-2 bg-white rounded border border-gray-200">
|
|
10832
|
-
<select [ngModel]="val.type || 'builtin'"
|
|
10833
|
-
(ngModelChange)="updateValidator(field.key, i, 'type', $event)"
|
|
10834
|
-
class="flex-1 h-8 px-2 text-sm rounded border border-gray-300 bg-white focus:border-blue-500 focus:ring-1 focus:ring-blue-500 outline-none">
|
|
10835
|
-
<option *ngFor="let option of validatorTypeOptions" [value]="option.value">{{ option.label }}</option>
|
|
10836
|
-
</select>
|
|
10837
|
-
<select *ngIf="(val.type || 'builtin') === 'builtin'"
|
|
10838
|
-
[ngModel]="val.name || 'email'"
|
|
10839
|
-
(ngModelChange)="updateValidator(field.key, i, 'name', $event)"
|
|
10840
|
-
class="flex-1 h-8 px-2 text-sm rounded border border-gray-300 bg-white focus:border-blue-500 focus:ring-1 focus:ring-blue-500 outline-none">
|
|
10841
|
-
<option *ngFor="let option of builtinValidatorOptions" [value]="option.value">{{ option.label }}</option>
|
|
10842
|
-
</select>
|
|
10843
|
-
<input *ngIf="val.type === 'expression'"
|
|
10844
|
-
type="text"
|
|
10845
|
-
[ngModel]="val.expression || ''"
|
|
10846
|
-
(ngModelChange)="updateValidator(field.key, i, 'expression', $event)"
|
|
10847
|
-
placeholder="return true;"
|
|
10848
|
-
class="flex-1 h-8 px-2 text-sm rounded border border-gray-300 bg-white focus:border-blue-500 focus:ring-1 focus:ring-blue-500 outline-none">
|
|
10849
|
-
<input type="text"
|
|
10850
|
-
[ngModel]="val.message || ''"
|
|
10851
|
-
(ngModelChange)="updateValidator(field.key, i, 'message', $event)"
|
|
10852
|
-
placeholder="Validation message"
|
|
10853
|
-
class="flex-1 h-8 px-2 text-sm rounded border border-gray-300 bg-white focus:border-blue-500 focus:ring-1 focus:ring-blue-500 outline-none">
|
|
10854
|
-
<button type="button"
|
|
10855
|
-
(click)="removeValidator(field.key, i)"
|
|
10856
|
-
class="w-8 h-8 flex items-center justify-center text-red-600 hover:bg-red-50 rounded transition-colors">
|
|
10857
|
-
<lucide-icon name="x" class="w-4 h-4"></lucide-icon>
|
|
10858
|
-
</button>
|
|
10859
|
-
</div>
|
|
10860
|
-
</div>
|
|
10861
|
-
</div>
|
|
10862
|
-
</ui-field-wrapper>
|
|
10863
|
-
|
|
10864
10818
|
<!-- Field Reference -->
|
|
10865
10819
|
<ui-field-wrapper *ngIf="field.type === 'field-reference'" [label]="field.label || ''" [helpText]="field.helpText || ''">
|
|
10866
10820
|
<select [ngModel]="getValue(field.key) || ''"
|
|
@@ -11109,51 +11063,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
|
|
|
11109
11063
|
</div>
|
|
11110
11064
|
</ui-field-wrapper>
|
|
11111
11065
|
|
|
11112
|
-
<!-- Validators Editor -->
|
|
11113
|
-
<ui-field-wrapper *ngIf="field.type === 'validators-editor'" [label]="field.label || ''" [helpText]="field.helpText || ''">
|
|
11114
|
-
<div class="w-full border border-gray-200 rounded-lg p-3 bg-gray-50">
|
|
11115
|
-
<div class="flex items-center justify-between mb-3">
|
|
11116
|
-
<span class="text-xs font-semibold text-gray-600 uppercase">{{field.label}}</span>
|
|
11117
|
-
<button type="button"
|
|
11118
|
-
(click)="addValidator(field.key)"
|
|
11119
|
-
class="text-xs px-2 py-1 bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors">
|
|
11120
|
-
+
|
|
11121
|
-
</button>
|
|
11122
|
-
</div>
|
|
11123
|
-
<div class="space-y-2">
|
|
11124
|
-
<div *ngFor="let val of getValue(field.key) || []; let i = index" class="flex items-center gap-2 p-2 bg-white rounded border border-gray-200">
|
|
11125
|
-
<select [ngModel]="val.type || 'builtin'"
|
|
11126
|
-
(ngModelChange)="updateValidator(field.key, i, 'type', $event)"
|
|
11127
|
-
class="flex-1 h-8 px-2 text-sm rounded border border-gray-300 bg-white focus:border-blue-500 focus:ring-1 focus:ring-blue-500 outline-none">
|
|
11128
|
-
<option *ngFor="let option of validatorTypeOptions" [value]="option.value">{{ option.label }}</option>
|
|
11129
|
-
</select>
|
|
11130
|
-
<select *ngIf="(val.type || 'builtin') === 'builtin'"
|
|
11131
|
-
[ngModel]="val.name || 'email'"
|
|
11132
|
-
(ngModelChange)="updateValidator(field.key, i, 'name', $event)"
|
|
11133
|
-
class="flex-1 h-8 px-2 text-sm rounded border border-gray-300 bg-white focus:border-blue-500 focus:ring-1 focus:ring-blue-500 outline-none">
|
|
11134
|
-
<option *ngFor="let option of builtinValidatorOptions" [value]="option.value">{{ option.label }}</option>
|
|
11135
|
-
</select>
|
|
11136
|
-
<input *ngIf="val.type === 'expression'"
|
|
11137
|
-
type="text"
|
|
11138
|
-
[ngModel]="val.expression || ''"
|
|
11139
|
-
(ngModelChange)="updateValidator(field.key, i, 'expression', $event)"
|
|
11140
|
-
placeholder="return true;"
|
|
11141
|
-
class="flex-1 h-8 px-2 text-sm rounded border border-gray-300 bg-white focus:border-blue-500 focus:ring-1 focus:ring-blue-500 outline-none">
|
|
11142
|
-
<input type="text"
|
|
11143
|
-
[ngModel]="val.message || ''"
|
|
11144
|
-
(ngModelChange)="updateValidator(field.key, i, 'message', $event)"
|
|
11145
|
-
placeholder="Validation message"
|
|
11146
|
-
class="flex-1 h-8 px-2 text-sm rounded border border-gray-300 bg-white focus:border-blue-500 focus:ring-1 focus:ring-blue-500 outline-none">
|
|
11147
|
-
<button type="button"
|
|
11148
|
-
(click)="removeValidator(field.key, i)"
|
|
11149
|
-
class="w-8 h-8 flex items-center justify-center text-red-600 hover:bg-red-50 rounded transition-colors">
|
|
11150
|
-
<lucide-icon name="x" class="w-4 h-4"></lucide-icon>
|
|
11151
|
-
</button>
|
|
11152
|
-
</div>
|
|
11153
|
-
</div>
|
|
11154
|
-
</div>
|
|
11155
|
-
</ui-field-wrapper>
|
|
11156
|
-
|
|
11157
11066
|
<!-- Field Reference -->
|
|
11158
11067
|
<ui-field-wrapper *ngIf="field.type === 'field-reference'" [label]="field.label || ''" [helpText]="field.helpText || ''">
|
|
11159
11068
|
<select [ngModel]="getValue(field.key) || ''"
|
|
@@ -15264,7 +15173,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
|
|
|
15264
15173
|
type: Output
|
|
15265
15174
|
}] } });
|
|
15266
15175
|
|
|
15267
|
-
function parsePathSegments$
|
|
15176
|
+
function parsePathSegments$3(path) {
|
|
15268
15177
|
const segments = [];
|
|
15269
15178
|
const matcher = /([^[.\]]+)|\[(\d+)\]/g;
|
|
15270
15179
|
let match;
|
|
@@ -15280,14 +15189,14 @@ function parsePathSegments$2(path) {
|
|
|
15280
15189
|
}
|
|
15281
15190
|
return segments;
|
|
15282
15191
|
}
|
|
15283
|
-
function resolvePathValue$
|
|
15192
|
+
function resolvePathValue$2(value, path) {
|
|
15284
15193
|
if (!path)
|
|
15285
15194
|
return value;
|
|
15286
15195
|
const normalized = path.trim();
|
|
15287
15196
|
if (!normalized)
|
|
15288
15197
|
return value;
|
|
15289
15198
|
let current = value;
|
|
15290
|
-
for (const segment of parsePathSegments$
|
|
15199
|
+
for (const segment of parsePathSegments$3(normalized)) {
|
|
15291
15200
|
if (current === null || current === undefined)
|
|
15292
15201
|
return undefined;
|
|
15293
15202
|
if (Array.isArray(current)) {
|
|
@@ -15304,7 +15213,7 @@ function resolvePathValue$1(value, path) {
|
|
|
15304
15213
|
return current;
|
|
15305
15214
|
}
|
|
15306
15215
|
function assignPathValue(target, path, value) {
|
|
15307
|
-
const segments = parsePathSegments$
|
|
15216
|
+
const segments = parsePathSegments$3(path);
|
|
15308
15217
|
if (!segments.length) {
|
|
15309
15218
|
return;
|
|
15310
15219
|
}
|
|
@@ -15440,7 +15349,6 @@ class DataPanelComponent {
|
|
|
15440
15349
|
selectionFieldId;
|
|
15441
15350
|
selectionMatchPath;
|
|
15442
15351
|
childRowsPath;
|
|
15443
|
-
formatNumericOptionLabels = false;
|
|
15444
15352
|
optionLabelPrefixPath;
|
|
15445
15353
|
rootPathOptions = [];
|
|
15446
15354
|
rowPathOptions = [];
|
|
@@ -15682,7 +15590,6 @@ class DataPanelComponent {
|
|
|
15682
15590
|
this.selectionFieldId = undefined;
|
|
15683
15591
|
this.selectionMatchPath = undefined;
|
|
15684
15592
|
this.childRowsPath = undefined;
|
|
15685
|
-
this.formatNumericOptionLabels = false;
|
|
15686
15593
|
this.optionLabelPrefixPath = undefined;
|
|
15687
15594
|
this.rootPathOptions = [];
|
|
15688
15595
|
this.rowPathOptions = [];
|
|
@@ -15724,7 +15631,6 @@ class DataPanelComponent {
|
|
|
15724
15631
|
this.selectionFieldId = d.selectionFieldId;
|
|
15725
15632
|
this.selectionMatchPath = d.selectionMatchPath;
|
|
15726
15633
|
this.childRowsPath = d.childRowsPath;
|
|
15727
|
-
this.formatNumericOptionLabels = d.formatNumericOptionLabels === true;
|
|
15728
15634
|
this.optionLabelPrefixPath = d.optionLabelPrefixPath;
|
|
15729
15635
|
// Search
|
|
15730
15636
|
this.searchEnabled = !!d.searchEnabled;
|
|
@@ -15777,10 +15683,7 @@ class DataPanelComponent {
|
|
|
15777
15683
|
labelKey: this.sourceType === 'source' ? this.labelKey : undefined,
|
|
15778
15684
|
valueKey: this.sourceType === 'source' ? this.valueKey : undefined,
|
|
15779
15685
|
rowsPath: this.sourceType === 'source' ? this.normalizedRowsPath() : undefined,
|
|
15780
|
-
|
|
15781
|
-
? this.formatNumericOptionLabels
|
|
15782
|
-
: undefined,
|
|
15783
|
-
optionLabelPrefixPath: this.shouldPersistOptionLabelFormatting()
|
|
15686
|
+
optionLabelPrefixPath: this.shouldPersistOptionLabelPrefix()
|
|
15784
15687
|
? this.optionLabelPrefixPath
|
|
15785
15688
|
: undefined,
|
|
15786
15689
|
rowSelectionMode: this.sourceType === 'source' && this.bindingShape === 'scalar' && this.rowSelectionMode === 'selected'
|
|
@@ -15891,8 +15794,25 @@ class DataPanelComponent {
|
|
|
15891
15794
|
showOptionMappingControls() {
|
|
15892
15795
|
return this.sourceType === 'source' && this.widgetType !== 'table' && this.usesOptionMapping();
|
|
15893
15796
|
}
|
|
15894
|
-
|
|
15895
|
-
|
|
15797
|
+
showDisplayFormattingControls() {
|
|
15798
|
+
if (this.widgetType === 'select' && this.usesOptionMapping()) {
|
|
15799
|
+
return true;
|
|
15800
|
+
}
|
|
15801
|
+
return this.sourceType === 'source'
|
|
15802
|
+
&& this.bindingShape === 'scalar'
|
|
15803
|
+
&& (this.widgetType === 'text' || this.widgetType === 'number');
|
|
15804
|
+
}
|
|
15805
|
+
displayFormattingTitle() {
|
|
15806
|
+
return this.widgetType === 'select' ? 'Amount Display' : 'Field Display';
|
|
15807
|
+
}
|
|
15808
|
+
displayFormattingDescription() {
|
|
15809
|
+
if (this.widgetType === 'select') {
|
|
15810
|
+
return 'Format the visible dropdown label without changing the stored option value.';
|
|
15811
|
+
}
|
|
15812
|
+
if (this.widgetType === 'number') {
|
|
15813
|
+
return 'Show a fixed prefix in the visible field value without changing the stored number.';
|
|
15814
|
+
}
|
|
15815
|
+
return 'Show a fixed prefix beside the editable value without changing the stored field value.';
|
|
15896
15816
|
}
|
|
15897
15817
|
showStaticOptionsEditor() {
|
|
15898
15818
|
return this.sourceType === 'static' && this.widgetType !== 'table' && this.usesOptionMapping();
|
|
@@ -15922,12 +15842,12 @@ class DataPanelComponent {
|
|
|
15922
15842
|
}
|
|
15923
15843
|
getPreviewLabel(row) {
|
|
15924
15844
|
const key = this.labelKey || 'label';
|
|
15925
|
-
const value = resolvePathValue$
|
|
15845
|
+
const value = resolvePathValue$2(row, key);
|
|
15926
15846
|
return value === undefined || value === null || value === '' ? '(no label)' : String(value);
|
|
15927
15847
|
}
|
|
15928
15848
|
getPreviewValue(row) {
|
|
15929
15849
|
const key = this.valueKey || 'value';
|
|
15930
|
-
const value = resolvePathValue$
|
|
15850
|
+
const value = resolvePathValue$2(row, key);
|
|
15931
15851
|
return value === undefined || value === null ? '' : String(value);
|
|
15932
15852
|
}
|
|
15933
15853
|
availableRootPaths() {
|
|
@@ -15944,8 +15864,13 @@ class DataPanelComponent {
|
|
|
15944
15864
|
const sample = this.extractPreviewRows(this.previewRows, this.effectiveRowsPath())[0];
|
|
15945
15865
|
return sample ? collectArrayPaths(sample) : [];
|
|
15946
15866
|
}
|
|
15947
|
-
|
|
15948
|
-
|
|
15867
|
+
shouldPersistOptionLabelPrefix() {
|
|
15868
|
+
if (this.widgetType === 'select' && this.usesOptionMapping()) {
|
|
15869
|
+
return true;
|
|
15870
|
+
}
|
|
15871
|
+
return this.sourceType === 'source'
|
|
15872
|
+
&& this.bindingShape === 'scalar'
|
|
15873
|
+
&& (this.widgetType === 'text' || this.widgetType === 'number');
|
|
15949
15874
|
}
|
|
15950
15875
|
usesOptionMapping() {
|
|
15951
15876
|
return this.bindingShape === 'list' || this.widgetType === 'search';
|
|
@@ -15955,7 +15880,7 @@ class DataPanelComponent {
|
|
|
15955
15880
|
return normalized ? normalized : 'defaultValue';
|
|
15956
15881
|
}
|
|
15957
15882
|
readScalarTargetValue() {
|
|
15958
|
-
const resolved = resolvePathValue$
|
|
15883
|
+
const resolved = resolvePathValue$2(this.config, this.scalarTargetPath());
|
|
15959
15884
|
if (resolved !== undefined) {
|
|
15960
15885
|
return resolved;
|
|
15961
15886
|
}
|
|
@@ -15978,7 +15903,7 @@ class DataPanelComponent {
|
|
|
15978
15903
|
}
|
|
15979
15904
|
const flattened = [];
|
|
15980
15905
|
for (const row of rows) {
|
|
15981
|
-
const resolved = resolvePathValue$
|
|
15906
|
+
const resolved = resolvePathValue$2(row, normalizedPath);
|
|
15982
15907
|
if (Array.isArray(resolved)) {
|
|
15983
15908
|
flattened.push(...resolved);
|
|
15984
15909
|
continue;
|
|
@@ -16266,18 +16191,9 @@ class DataPanelComponent {
|
|
|
16266
16191
|
</div>
|
|
16267
16192
|
</div>
|
|
16268
16193
|
|
|
16269
|
-
<div class="rounded-lg border border-gray-200 bg-white p-3" *ngIf="
|
|
16270
|
-
<div class="text-xs font-semibold uppercase tracking-wide text-gray-500">
|
|
16271
|
-
<div class="mt-1 text-[11px] text-gray-500">
|
|
16272
|
-
|
|
16273
|
-
<label class="mt-3 flex items-center gap-2 text-sm text-gray-700">
|
|
16274
|
-
<input
|
|
16275
|
-
type="checkbox"
|
|
16276
|
-
[checked]="formatNumericOptionLabels"
|
|
16277
|
-
(change)="formatNumericOptionLabels = $any($event.target).checked; emitChange()"
|
|
16278
|
-
class="rounded border-gray-300 text-blue-600 focus:ring-blue-500">
|
|
16279
|
-
<span>Show thousand separators for numeric labels</span>
|
|
16280
|
-
</label>
|
|
16194
|
+
<div class="rounded-lg border border-gray-200 bg-white p-3" *ngIf="showDisplayFormattingControls()">
|
|
16195
|
+
<div class="text-xs font-semibold uppercase tracking-wide text-gray-500">{{ displayFormattingTitle() }}</div>
|
|
16196
|
+
<div class="mt-1 text-[11px] text-gray-500">{{ displayFormattingDescription() }}</div>
|
|
16281
16197
|
|
|
16282
16198
|
<div class="mt-3 flex flex-col gap-1">
|
|
16283
16199
|
<label class="text-xs font-medium text-gray-500">Prefix Key</label>
|
|
@@ -16885,18 +16801,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
|
|
|
16885
16801
|
</div>
|
|
16886
16802
|
</div>
|
|
16887
16803
|
|
|
16888
|
-
<div class="rounded-lg border border-gray-200 bg-white p-3" *ngIf="
|
|
16889
|
-
<div class="text-xs font-semibold uppercase tracking-wide text-gray-500">
|
|
16890
|
-
<div class="mt-1 text-[11px] text-gray-500">
|
|
16891
|
-
|
|
16892
|
-
<label class="mt-3 flex items-center gap-2 text-sm text-gray-700">
|
|
16893
|
-
<input
|
|
16894
|
-
type="checkbox"
|
|
16895
|
-
[checked]="formatNumericOptionLabels"
|
|
16896
|
-
(change)="formatNumericOptionLabels = $any($event.target).checked; emitChange()"
|
|
16897
|
-
class="rounded border-gray-300 text-blue-600 focus:ring-blue-500">
|
|
16898
|
-
<span>Show thousand separators for numeric labels</span>
|
|
16899
|
-
</label>
|
|
16804
|
+
<div class="rounded-lg border border-gray-200 bg-white p-3" *ngIf="showDisplayFormattingControls()">
|
|
16805
|
+
<div class="text-xs font-semibold uppercase tracking-wide text-gray-500">{{ displayFormattingTitle() }}</div>
|
|
16806
|
+
<div class="mt-1 text-[11px] text-gray-500">{{ displayFormattingDescription() }}</div>
|
|
16900
16807
|
|
|
16901
16808
|
<div class="mt-3 flex flex-col gap-1">
|
|
16902
16809
|
<label class="text-xs font-medium text-gray-500">Prefix Key</label>
|
|
@@ -17674,11 +17581,18 @@ class RulesPanelComponent {
|
|
|
17674
17581
|
ruleActionOptions = [
|
|
17675
17582
|
{ label: 'Visible', value: 'visible' },
|
|
17676
17583
|
{ label: 'Hidden', value: 'hidden' },
|
|
17677
|
-
{ label: 'Enabled', value: 'enable' },
|
|
17678
17584
|
{ label: 'Disabled', value: 'disable' },
|
|
17679
17585
|
{ label: 'Required', value: 'required' },
|
|
17680
17586
|
{ label: 'Optional', value: 'optional' }
|
|
17681
17587
|
];
|
|
17588
|
+
actionLabels = {
|
|
17589
|
+
visible: 'Visible',
|
|
17590
|
+
hidden: 'Hidden',
|
|
17591
|
+
enable: 'Enabled',
|
|
17592
|
+
disable: 'Disabled',
|
|
17593
|
+
required: 'Required',
|
|
17594
|
+
optional: 'Optional'
|
|
17595
|
+
};
|
|
17682
17596
|
severityOptions = [
|
|
17683
17597
|
{ label: 'Warn', value: 'warn' },
|
|
17684
17598
|
{ label: 'Error', value: 'error' }
|
|
@@ -17730,7 +17644,7 @@ class RulesPanelComponent {
|
|
|
17730
17644
|
return `${primary} / else ${this.getActionLabel(rule.elseAction)}`;
|
|
17731
17645
|
}
|
|
17732
17646
|
getActionLabel(action) {
|
|
17733
|
-
return this.
|
|
17647
|
+
return this.actionLabels[action] ?? action;
|
|
17734
17648
|
}
|
|
17735
17649
|
getActionColor(action) {
|
|
17736
17650
|
switch (action) {
|
|
@@ -17749,7 +17663,7 @@ class RulesPanelComponent {
|
|
|
17749
17663
|
<div class="flex items-center justify-between mb-2">
|
|
17750
17664
|
<div class="flex flex-col">
|
|
17751
17665
|
<span class="font-semibold text-gray-700">Rules</span>
|
|
17752
|
-
<span class="text-xs text-gray-500">Rules can override visibility,
|
|
17666
|
+
<span class="text-xs text-gray-500">Rules can override visibility, disabled, and required state set elsewhere.</span>
|
|
17753
17667
|
</div>
|
|
17754
17668
|
<button (click)="addRule()"
|
|
17755
17669
|
[disabled]="readOnly"
|
|
@@ -17832,7 +17746,7 @@ class RulesPanelComponent {
|
|
|
17832
17746
|
<div class="flex flex-col gap-2">
|
|
17833
17747
|
<div class="flex items-center gap-2 bg-amber-50 p-2 rounded-md border border-amber-100">
|
|
17834
17748
|
<span class="text-xs font-semibold text-amber-700 uppercase">Severity</span>
|
|
17835
|
-
<span class="text-xs text-amber-800 italic">
|
|
17749
|
+
<span class="text-xs text-amber-800 italic">Error severity is emitted in runtime validation; warn stays informational.</span>
|
|
17836
17750
|
</div>
|
|
17837
17751
|
|
|
17838
17752
|
<div class="flex items-center gap-2">
|
|
@@ -17871,7 +17785,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
|
|
|
17871
17785
|
<div class="flex items-center justify-between mb-2">
|
|
17872
17786
|
<div class="flex flex-col">
|
|
17873
17787
|
<span class="font-semibold text-gray-700">Rules</span>
|
|
17874
|
-
<span class="text-xs text-gray-500">Rules can override visibility,
|
|
17788
|
+
<span class="text-xs text-gray-500">Rules can override visibility, disabled, and required state set elsewhere.</span>
|
|
17875
17789
|
</div>
|
|
17876
17790
|
<button (click)="addRule()"
|
|
17877
17791
|
[disabled]="readOnly"
|
|
@@ -17954,7 +17868,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
|
|
|
17954
17868
|
<div class="flex flex-col gap-2">
|
|
17955
17869
|
<div class="flex items-center gap-2 bg-amber-50 p-2 rounded-md border border-amber-100">
|
|
17956
17870
|
<span class="text-xs font-semibold text-amber-700 uppercase">Severity</span>
|
|
17957
|
-
<span class="text-xs text-amber-800 italic">
|
|
17871
|
+
<span class="text-xs text-amber-800 italic">Error severity is emitted in runtime validation; warn stays informational.</span>
|
|
17958
17872
|
</div>
|
|
17959
17873
|
|
|
17960
17874
|
<div class="flex items-center gap-2">
|
|
@@ -19546,34 +19460,35 @@ class FormPreviewComponent {
|
|
|
19546
19460
|
copyData() {
|
|
19547
19461
|
navigator.clipboard.writeText(JSON.stringify(this.previewData(), null, 2));
|
|
19548
19462
|
}
|
|
19549
|
-
sanitizePreviewData(value) {
|
|
19463
|
+
sanitizePreviewData(value, withinFileField = false) {
|
|
19550
19464
|
if (Array.isArray(value)) {
|
|
19551
|
-
return value.map(item => this.sanitizePreviewData(item));
|
|
19465
|
+
return value.map(item => this.sanitizePreviewData(item, withinFileField));
|
|
19552
19466
|
}
|
|
19553
19467
|
if (!this.isObjectRecord(value)) {
|
|
19554
19468
|
return value;
|
|
19555
19469
|
}
|
|
19470
|
+
const nextWithinFileField = withinFileField || this.isFileFieldRecord(value);
|
|
19556
19471
|
const sanitized = {};
|
|
19557
19472
|
for (const [key, entryValue] of Object.entries(value)) {
|
|
19558
|
-
if (key === 'data' && this.shouldHideFileData(
|
|
19473
|
+
if (key === 'data' && this.shouldHideFileData(nextWithinFileField, entryValue)) {
|
|
19559
19474
|
continue;
|
|
19560
19475
|
}
|
|
19561
|
-
sanitized[key] = this.sanitizePreviewData(entryValue);
|
|
19476
|
+
sanitized[key] = this.sanitizePreviewData(entryValue, nextWithinFileField);
|
|
19562
19477
|
}
|
|
19563
19478
|
return sanitized;
|
|
19564
19479
|
}
|
|
19565
19480
|
isObjectRecord(value) {
|
|
19566
19481
|
return !!value && typeof value === 'object';
|
|
19567
19482
|
}
|
|
19568
|
-
shouldHideFileData(
|
|
19569
|
-
if (!
|
|
19483
|
+
shouldHideFileData(withinFileField, value) {
|
|
19484
|
+
if (!withinFileField)
|
|
19570
19485
|
return false;
|
|
19571
19486
|
return this.isBytePayload(value) || this.isBase64Payload(value);
|
|
19572
19487
|
}
|
|
19573
19488
|
isFileFieldRecord(value) {
|
|
19574
19489
|
return typeof value['fieldName'] === 'string'
|
|
19575
19490
|
&& Object.hasOwn(value, 'fieldValue')
|
|
19576
|
-
&& Object.hasOwn(value, 'fileType');
|
|
19491
|
+
&& (value['fieldType'] === 'file' || Object.hasOwn(value, 'fileType'));
|
|
19577
19492
|
}
|
|
19578
19493
|
isBytePayload(value) {
|
|
19579
19494
|
if (value instanceof Uint8Array)
|
|
@@ -20220,13 +20135,13 @@ async function updateFieldSettings(state, args, widgetDefs = []) {
|
|
|
20220
20135
|
updates[key] = value;
|
|
20221
20136
|
}
|
|
20222
20137
|
}
|
|
20138
|
+
const html5Patch = {};
|
|
20223
20139
|
if (typeof a['disabled'] === 'boolean') {
|
|
20224
|
-
|
|
20140
|
+
html5Patch['disabled'] = a['disabled'];
|
|
20225
20141
|
}
|
|
20226
20142
|
if (typeof a['readonly'] === 'boolean') {
|
|
20227
|
-
|
|
20143
|
+
html5Patch['readonly'] = a['readonly'];
|
|
20228
20144
|
}
|
|
20229
|
-
const html5Patch = {};
|
|
20230
20145
|
const html5Keys = ['required', 'min', 'max', 'step', 'minLength', 'maxLength', 'pattern'];
|
|
20231
20146
|
for (const key of html5Keys) {
|
|
20232
20147
|
if (typeof a[key] !== 'undefined') {
|
|
@@ -22036,7 +21951,7 @@ const DATA_SOURCES_TEMPLATE = {
|
|
|
22036
21951
|
"type": "text",
|
|
22037
21952
|
"label": "Selected country code",
|
|
22038
21953
|
"placeholder": "Auto-filled",
|
|
22039
|
-
"readonly": true,
|
|
21954
|
+
"html5": { "readonly": true },
|
|
22040
21955
|
"helpText": "Updated by an event binding on the Country field."
|
|
22041
21956
|
},
|
|
22042
21957
|
{
|
|
@@ -22442,8 +22357,8 @@ const TRANSACTION_KYC_REVIEW_TEMPLATE = {
|
|
|
22442
22357
|
"name": "clientDisplay",
|
|
22443
22358
|
"type": "text",
|
|
22444
22359
|
"label": "Client",
|
|
22445
|
-
"readonly": true,
|
|
22446
22360
|
"html5": {
|
|
22361
|
+
"readonly": true,
|
|
22447
22362
|
"required": false
|
|
22448
22363
|
},
|
|
22449
22364
|
"rules": [
|
|
@@ -22489,7 +22404,7 @@ const TRANSACTION_KYC_REVIEW_TEMPLATE = {
|
|
|
22489
22404
|
"type": "text",
|
|
22490
22405
|
"label": "Balance",
|
|
22491
22406
|
"defaultValue": "USD 24,580.00",
|
|
22492
|
-
"readonly": true,
|
|
22407
|
+
"html5": { "readonly": true },
|
|
22493
22408
|
"rules": [
|
|
22494
22409
|
{
|
|
22495
22410
|
"id": "rule_balance_visible",
|
|
@@ -23257,7 +23172,7 @@ const JOURNEY_BRANCHING_TEMPLATE_STEP_TWO = {
|
|
|
23257
23172
|
"name": "summaryCountryCode",
|
|
23258
23173
|
"type": "text",
|
|
23259
23174
|
"label": "Country Code",
|
|
23260
|
-
"readonly": true,
|
|
23175
|
+
"html5": { "readonly": true },
|
|
23261
23176
|
"dataConfig": {
|
|
23262
23177
|
"type": "source",
|
|
23263
23178
|
"datasourceId": "journey_branch_ds_country_profile",
|
|
@@ -23462,7 +23377,7 @@ const JOURNEY_BRANCHING_TEMPLATE_STEP_THREE = {
|
|
|
23462
23377
|
"name": "summaryCurrency",
|
|
23463
23378
|
"type": "text",
|
|
23464
23379
|
"label": "Currency",
|
|
23465
|
-
"readonly": true,
|
|
23380
|
+
"html5": { "readonly": true },
|
|
23466
23381
|
"dataConfig": {
|
|
23467
23382
|
"type": "source",
|
|
23468
23383
|
"datasourceId": "journey_branch_ds_country_profile",
|
|
@@ -23475,7 +23390,7 @@ const JOURNEY_BRANCHING_TEMPLATE_STEP_THREE = {
|
|
|
23475
23390
|
"name": "summaryTimezone",
|
|
23476
23391
|
"type": "text",
|
|
23477
23392
|
"label": "Timezone",
|
|
23478
|
-
"readonly": true,
|
|
23393
|
+
"html5": { "readonly": true },
|
|
23479
23394
|
"dataConfig": {
|
|
23480
23395
|
"type": "source",
|
|
23481
23396
|
"datasourceId": "journey_branch_ds_country_profile",
|
|
@@ -31707,7 +31622,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
|
|
|
31707
31622
|
}]
|
|
31708
31623
|
}] });
|
|
31709
31624
|
|
|
31710
|
-
function parsePathSegments$
|
|
31625
|
+
function parsePathSegments$2(path) {
|
|
31711
31626
|
const segments = [];
|
|
31712
31627
|
const matcher = /([^[.\]]+)|\[(\d+)\]/g;
|
|
31713
31628
|
let match;
|
|
@@ -31723,14 +31638,14 @@ function parsePathSegments$1(path) {
|
|
|
31723
31638
|
}
|
|
31724
31639
|
return segments;
|
|
31725
31640
|
}
|
|
31726
|
-
function resolvePathValue(value, path) {
|
|
31641
|
+
function resolvePathValue$1(value, path) {
|
|
31727
31642
|
if (!path)
|
|
31728
31643
|
return value;
|
|
31729
31644
|
const normalizedPath = path.trim();
|
|
31730
31645
|
if (!normalizedPath)
|
|
31731
31646
|
return value;
|
|
31732
31647
|
let current = value;
|
|
31733
|
-
for (const segment of parsePathSegments$
|
|
31648
|
+
for (const segment of parsePathSegments$2(normalizedPath)) {
|
|
31734
31649
|
if (current === null || current === undefined) {
|
|
31735
31650
|
return undefined;
|
|
31736
31651
|
}
|
|
@@ -31754,7 +31669,7 @@ function hasPathSyntax(path) {
|
|
|
31754
31669
|
return false;
|
|
31755
31670
|
return path.includes('.') || path.includes('[');
|
|
31756
31671
|
}
|
|
31757
|
-
function valuesMatch(left, right) {
|
|
31672
|
+
function valuesMatch$1(left, right) {
|
|
31758
31673
|
if (Object.is(left, right))
|
|
31759
31674
|
return true;
|
|
31760
31675
|
if (left === undefined || left === null || right === undefined || right === null)
|
|
@@ -31774,7 +31689,20 @@ function compareSortableValues(left, right) {
|
|
|
31774
31689
|
}
|
|
31775
31690
|
return String(left ?? '').localeCompare(String(right ?? ''));
|
|
31776
31691
|
}
|
|
31692
|
+
function toDisplayText(value) {
|
|
31693
|
+
if (typeof value === 'string') {
|
|
31694
|
+
const trimmed = value.trim();
|
|
31695
|
+
return trimmed.length > 0 ? trimmed : undefined;
|
|
31696
|
+
}
|
|
31697
|
+
if (typeof value === 'number' || typeof value === 'boolean') {
|
|
31698
|
+
return String(value);
|
|
31699
|
+
}
|
|
31700
|
+
return undefined;
|
|
31701
|
+
}
|
|
31777
31702
|
class DataProvider {
|
|
31703
|
+
async getValueDisplayPrefix(_field, _engine) {
|
|
31704
|
+
return '';
|
|
31705
|
+
}
|
|
31778
31706
|
// Non-abstract with default implementation for backward compatibility
|
|
31779
31707
|
async queryOptions(field, query, engine) {
|
|
31780
31708
|
const options = await this.getOptions(field, engine);
|
|
@@ -31797,8 +31725,8 @@ class DataProvider {
|
|
|
31797
31725
|
if (query.sort && query.sort.length > 0) {
|
|
31798
31726
|
rows = [...rows].sort((a, b) => {
|
|
31799
31727
|
for (const s of query.sort) {
|
|
31800
|
-
const valA = resolvePathValue(a, s.column);
|
|
31801
|
-
const valB = resolvePathValue(b, s.column);
|
|
31728
|
+
const valA = resolvePathValue$1(a, s.column);
|
|
31729
|
+
const valB = resolvePathValue$1(b, s.column);
|
|
31802
31730
|
if (valA === valB)
|
|
31803
31731
|
continue;
|
|
31804
31732
|
const result = compareSortableValues(valA, valB);
|
|
@@ -31952,27 +31880,42 @@ class DefaultDataProvider extends DataProvider {
|
|
|
31952
31880
|
return cfg.staticValue;
|
|
31953
31881
|
return currentValue !== undefined ? currentValue : field.defaultValue;
|
|
31954
31882
|
}
|
|
31955
|
-
|
|
31956
|
-
|
|
31957
|
-
rows = this.applyRowFilters(rows, cfg.filters, engine);
|
|
31958
|
-
if (!rows || rows.length === 0) {
|
|
31959
|
-
return currentValue !== undefined ? currentValue : field.defaultValue;
|
|
31960
|
-
}
|
|
31961
|
-
const selectedRow = this.selectScalarRow(rows, cfg, engine);
|
|
31962
|
-
if (cfg.rowSelectionMode === 'selected' && !selectedRow) {
|
|
31883
|
+
const context = await this.getScalarValueContext(cfg, field, engine);
|
|
31884
|
+
if (!context) {
|
|
31963
31885
|
return currentValue !== undefined ? currentValue : field.defaultValue;
|
|
31964
31886
|
}
|
|
31965
|
-
const row =
|
|
31887
|
+
const row = context.row;
|
|
31966
31888
|
const resolvedPath = cfg.valueKey;
|
|
31967
|
-
const resolvedValue = resolvePathValue(row, resolvedPath);
|
|
31889
|
+
const resolvedValue = resolvePathValue$1(row, resolvedPath);
|
|
31968
31890
|
if (resolvedPath && resolvedValue !== undefined) {
|
|
31969
31891
|
return resolvedValue;
|
|
31970
31892
|
}
|
|
31971
|
-
if (resolvePathValue(row, 'value') !== undefined) {
|
|
31972
|
-
return resolvePathValue(row, 'value');
|
|
31893
|
+
if (resolvePathValue$1(row, 'value') !== undefined) {
|
|
31894
|
+
return resolvePathValue$1(row, 'value');
|
|
31973
31895
|
}
|
|
31974
31896
|
return row;
|
|
31975
31897
|
}
|
|
31898
|
+
async getValueDisplayPrefix(field, engine) {
|
|
31899
|
+
const cfg = getEffectiveDataConfig(field);
|
|
31900
|
+
const prefixPath = cfg.optionLabelPrefixPath?.trim();
|
|
31901
|
+
if (!prefixPath) {
|
|
31902
|
+
return '';
|
|
31903
|
+
}
|
|
31904
|
+
const context = await this.getScalarValueContext(cfg, field, engine);
|
|
31905
|
+
if (!context) {
|
|
31906
|
+
return '';
|
|
31907
|
+
}
|
|
31908
|
+
for (const candidate of [context.row, context.parentRow, context.sourceRow]) {
|
|
31909
|
+
if (!candidate)
|
|
31910
|
+
continue;
|
|
31911
|
+
const resolved = resolvePathValue$1(candidate, prefixPath);
|
|
31912
|
+
const value = toDisplayText(resolved);
|
|
31913
|
+
if (value) {
|
|
31914
|
+
return value;
|
|
31915
|
+
}
|
|
31916
|
+
}
|
|
31917
|
+
return '';
|
|
31918
|
+
}
|
|
31976
31919
|
async resolveValue(field, value) {
|
|
31977
31920
|
return String(value);
|
|
31978
31921
|
}
|
|
@@ -32020,6 +31963,18 @@ class DefaultDataProvider extends DataProvider {
|
|
|
32020
31963
|
const rows = await this.getRawRows(cfg, field, engine);
|
|
32021
31964
|
return this.resolveCollectionRowContexts(rows, cfg, engine);
|
|
32022
31965
|
}
|
|
31966
|
+
async getScalarValueContext(cfg, field, engine) {
|
|
31967
|
+
const contexts = await this.getOptionRowContexts(cfg, field, engine);
|
|
31968
|
+
const filteredContexts = this.applyOptionRowFilters(contexts, cfg.filters, engine);
|
|
31969
|
+
if (filteredContexts.length === 0) {
|
|
31970
|
+
return undefined;
|
|
31971
|
+
}
|
|
31972
|
+
const selectedContext = this.selectOptionContext(filteredContexts, cfg, engine);
|
|
31973
|
+
if (cfg.rowSelectionMode === 'selected' && !selectedContext) {
|
|
31974
|
+
return undefined;
|
|
31975
|
+
}
|
|
31976
|
+
return selectedContext ?? filteredContexts[0];
|
|
31977
|
+
}
|
|
32023
31978
|
resolveCollectionRowContexts(rows, cfg, engine) {
|
|
32024
31979
|
const parentContexts = this.extractRowContexts(rows, cfg.rowsPath);
|
|
32025
31980
|
if (cfg.rowSelectionMode === 'selected' && cfg.childRowsPath) {
|
|
@@ -32056,7 +32011,7 @@ class DefaultDataProvider extends DataProvider {
|
|
|
32056
32011
|
}
|
|
32057
32012
|
const flattened = [];
|
|
32058
32013
|
for (const row of rows) {
|
|
32059
|
-
const resolved = resolvePathValue(row, normalizedPath);
|
|
32014
|
+
const resolved = resolvePathValue$1(row, normalizedPath);
|
|
32060
32015
|
if (Array.isArray(resolved)) {
|
|
32061
32016
|
for (const entry of resolved) {
|
|
32062
32017
|
flattened.push({
|
|
@@ -32084,7 +32039,7 @@ class DefaultDataProvider extends DataProvider {
|
|
|
32084
32039
|
}
|
|
32085
32040
|
const flattened = [];
|
|
32086
32041
|
for (const row of rows) {
|
|
32087
|
-
const resolved = resolvePathValue(row, normalizedPath);
|
|
32042
|
+
const resolved = resolvePathValue$1(row, normalizedPath);
|
|
32088
32043
|
if (Array.isArray(resolved)) {
|
|
32089
32044
|
for (const entry of resolved) {
|
|
32090
32045
|
flattened.push(this.toRowRecord(entry));
|
|
@@ -32112,7 +32067,7 @@ class DefaultDataProvider extends DataProvider {
|
|
|
32112
32067
|
if (selectorValue === undefined || selectorValue === null || selectorValue === '') {
|
|
32113
32068
|
return undefined;
|
|
32114
32069
|
}
|
|
32115
|
-
return rows.find(row => valuesMatch(resolvePathValue(row, cfg.selectionMatchPath), selectorValue));
|
|
32070
|
+
return rows.find(row => valuesMatch$1(resolvePathValue$1(row, cfg.selectionMatchPath), selectorValue));
|
|
32116
32071
|
}
|
|
32117
32072
|
selectOptionContext(contexts, cfg, engine) {
|
|
32118
32073
|
if (contexts.length === 0)
|
|
@@ -32129,7 +32084,7 @@ class DefaultDataProvider extends DataProvider {
|
|
|
32129
32084
|
if (selectorValue === undefined || selectorValue === null || selectorValue === '') {
|
|
32130
32085
|
return undefined;
|
|
32131
32086
|
}
|
|
32132
|
-
return contexts.find(context => valuesMatch(resolvePathValue(context.row, cfg.selectionMatchPath), selectorValue));
|
|
32087
|
+
return contexts.find(context => valuesMatch$1(resolvePathValue$1(context.row, cfg.selectionMatchPath), selectorValue));
|
|
32133
32088
|
}
|
|
32134
32089
|
applyRowFilters(rows, filters, engine) {
|
|
32135
32090
|
if (!filters || filters.length === 0)
|
|
@@ -32146,7 +32101,7 @@ class DefaultDataProvider extends DataProvider {
|
|
|
32146
32101
|
const expected = this.resolveFilterValue(filter, engine);
|
|
32147
32102
|
if (expected === undefined)
|
|
32148
32103
|
return true;
|
|
32149
|
-
const actual = resolvePathValue(row, filter.column);
|
|
32104
|
+
const actual = resolvePathValue$1(row, filter.column);
|
|
32150
32105
|
const val = expected;
|
|
32151
32106
|
switch (filter.op) {
|
|
32152
32107
|
case 'eq': return actual === val;
|
|
@@ -32218,17 +32173,16 @@ class DefaultDataProvider extends DataProvider {
|
|
|
32218
32173
|
}
|
|
32219
32174
|
mapRowToOption(row, labelKey, valueKey) {
|
|
32220
32175
|
return {
|
|
32221
|
-
label: String(resolvePathValue(row, labelKey) ?? ''),
|
|
32222
|
-
value: this.toOptionValue(resolvePathValue(row, valueKey))
|
|
32176
|
+
label: String(resolvePathValue$1(row, labelKey) ?? ''),
|
|
32177
|
+
value: this.toOptionValue(resolvePathValue$1(row, valueKey))
|
|
32223
32178
|
};
|
|
32224
32179
|
}
|
|
32225
32180
|
mapContextToOption(context, labelKey, valueKey, cfg) {
|
|
32226
|
-
const rawLabel = String(resolvePathValue(context.row, labelKey) ?? '');
|
|
32227
32181
|
const prefix = this.resolveOptionLabelPrefix(context, cfg);
|
|
32228
|
-
const label = this.formatOptionLabel(rawLabel, cfg);
|
|
32229
32182
|
return {
|
|
32230
|
-
label:
|
|
32231
|
-
|
|
32183
|
+
label: String(resolvePathValue$1(context.row, labelKey) ?? ''),
|
|
32184
|
+
displayPrefix: prefix || undefined,
|
|
32185
|
+
value: this.toOptionValue(resolvePathValue$1(context.row, valueKey))
|
|
32232
32186
|
};
|
|
32233
32187
|
}
|
|
32234
32188
|
resolveOptionLabelPrefix(context, cfg) {
|
|
@@ -32239,39 +32193,14 @@ class DefaultDataProvider extends DataProvider {
|
|
|
32239
32193
|
for (const candidate of [context.row, context.parentRow, context.sourceRow]) {
|
|
32240
32194
|
if (!candidate)
|
|
32241
32195
|
continue;
|
|
32242
|
-
const resolved = resolvePathValue(candidate, prefixPath);
|
|
32243
|
-
|
|
32244
|
-
|
|
32245
|
-
const value = String(resolved).trim();
|
|
32246
|
-
if (value.length > 0) {
|
|
32196
|
+
const resolved = resolvePathValue$1(candidate, prefixPath);
|
|
32197
|
+
const value = toDisplayText(resolved);
|
|
32198
|
+
if (value) {
|
|
32247
32199
|
return value;
|
|
32248
32200
|
}
|
|
32249
32201
|
}
|
|
32250
32202
|
return '';
|
|
32251
32203
|
}
|
|
32252
|
-
formatOptionLabel(label, cfg) {
|
|
32253
|
-
if (!cfg.formatNumericOptionLabels) {
|
|
32254
|
-
return label;
|
|
32255
|
-
}
|
|
32256
|
-
const trimmed = label.trim();
|
|
32257
|
-
if (!trimmed) {
|
|
32258
|
-
return label;
|
|
32259
|
-
}
|
|
32260
|
-
const normalized = trimmed.replace(/,/g, '');
|
|
32261
|
-
if (!/^-?\d+(\.\d+)?$/.test(normalized)) {
|
|
32262
|
-
return label;
|
|
32263
|
-
}
|
|
32264
|
-
const numericValue = Number(normalized);
|
|
32265
|
-
if (!Number.isFinite(numericValue)) {
|
|
32266
|
-
return label;
|
|
32267
|
-
}
|
|
32268
|
-
const fractionPart = normalized.split('.')[1];
|
|
32269
|
-
return new Intl.NumberFormat(undefined, {
|
|
32270
|
-
useGrouping: true,
|
|
32271
|
-
minimumFractionDigits: fractionPart?.length ?? 0,
|
|
32272
|
-
maximumFractionDigits: fractionPart?.length ?? 0
|
|
32273
|
-
}).format(numericValue);
|
|
32274
|
-
}
|
|
32275
32204
|
async getRuntimeOptions(field, engine) {
|
|
32276
32205
|
if (!engine)
|
|
32277
32206
|
return undefined;
|
|
@@ -32430,12 +32359,68 @@ function getHeadingClass(level) {
|
|
|
32430
32359
|
}
|
|
32431
32360
|
}
|
|
32432
32361
|
|
|
32362
|
+
function parsePathSegments$1(path) {
|
|
32363
|
+
const segments = [];
|
|
32364
|
+
const matcher = /([^[.\]]+)|\[(\d+)\]/g;
|
|
32365
|
+
let match;
|
|
32366
|
+
while ((match = matcher.exec(path)) !== null) {
|
|
32367
|
+
const [, property, index] = match;
|
|
32368
|
+
if (property) {
|
|
32369
|
+
segments.push(property);
|
|
32370
|
+
continue;
|
|
32371
|
+
}
|
|
32372
|
+
if (index !== undefined) {
|
|
32373
|
+
segments.push(index);
|
|
32374
|
+
}
|
|
32375
|
+
}
|
|
32376
|
+
return segments;
|
|
32377
|
+
}
|
|
32378
|
+
function resolvePathValue(value, path) {
|
|
32379
|
+
if (!path)
|
|
32380
|
+
return value;
|
|
32381
|
+
const normalizedPath = path.trim();
|
|
32382
|
+
if (!normalizedPath)
|
|
32383
|
+
return value;
|
|
32384
|
+
let current = value;
|
|
32385
|
+
for (const segment of parsePathSegments$1(normalizedPath)) {
|
|
32386
|
+
if (current === null || current === undefined) {
|
|
32387
|
+
return undefined;
|
|
32388
|
+
}
|
|
32389
|
+
if (Array.isArray(current)) {
|
|
32390
|
+
const index = Number(segment);
|
|
32391
|
+
if (!Number.isInteger(index)) {
|
|
32392
|
+
return undefined;
|
|
32393
|
+
}
|
|
32394
|
+
current = current[index];
|
|
32395
|
+
continue;
|
|
32396
|
+
}
|
|
32397
|
+
if (typeof current !== 'object') {
|
|
32398
|
+
return undefined;
|
|
32399
|
+
}
|
|
32400
|
+
current = current[segment];
|
|
32401
|
+
}
|
|
32402
|
+
return current;
|
|
32403
|
+
}
|
|
32404
|
+
function valuesMatch(left, right) {
|
|
32405
|
+
if (Object.is(left, right))
|
|
32406
|
+
return true;
|
|
32407
|
+
if (left === undefined || left === null || right === undefined || right === null)
|
|
32408
|
+
return false;
|
|
32409
|
+
const leftIsPrimitive = typeof left === 'string' || typeof left === 'number' || typeof left === 'boolean';
|
|
32410
|
+
const rightIsPrimitive = typeof right === 'string' || typeof right === 'number' || typeof right === 'boolean';
|
|
32411
|
+
if (leftIsPrimitive && rightIsPrimitive) {
|
|
32412
|
+
return String(left) === String(right);
|
|
32413
|
+
}
|
|
32414
|
+
return false;
|
|
32415
|
+
}
|
|
32433
32416
|
class TextFieldWidgetComponent {
|
|
32434
32417
|
_config;
|
|
32435
32418
|
hasReceivedConfig = false;
|
|
32436
32419
|
dependencyValueSnapshot = new Map();
|
|
32437
32420
|
isControlFocused = false;
|
|
32438
32421
|
isControlHovered = false;
|
|
32422
|
+
displayPrefix = '';
|
|
32423
|
+
formattedNumberValue = '';
|
|
32439
32424
|
set config(value) {
|
|
32440
32425
|
const previousSignature = this.getDataConfigSignature(this._config);
|
|
32441
32426
|
this._config = value;
|
|
@@ -32450,7 +32435,10 @@ class TextFieldWidgetComponent {
|
|
|
32450
32435
|
if (this.dataProvider && this._config?.dataConfig) {
|
|
32451
32436
|
this.seedDependencySnapshotFromEngine();
|
|
32452
32437
|
void this.refreshValueFromDataSource();
|
|
32438
|
+
return;
|
|
32453
32439
|
}
|
|
32440
|
+
this.displayPrefix = '';
|
|
32441
|
+
this.syncFormattedNumberValue();
|
|
32454
32442
|
}
|
|
32455
32443
|
get config() {
|
|
32456
32444
|
return this._config;
|
|
@@ -32473,6 +32461,12 @@ class TextFieldWidgetComponent {
|
|
|
32473
32461
|
isColorField() {
|
|
32474
32462
|
return this.config?.type === 'color';
|
|
32475
32463
|
}
|
|
32464
|
+
usesFormattedNumberInput() {
|
|
32465
|
+
return this.config?.type === 'number' && usesFieldThousandSeparator(this.config);
|
|
32466
|
+
}
|
|
32467
|
+
hasDisplayPrefix() {
|
|
32468
|
+
return !this.isTextarea() && !this.isColorField() && this.displayPrefix.trim().length > 0;
|
|
32469
|
+
}
|
|
32476
32470
|
getControlClass(multiline = false) {
|
|
32477
32471
|
return getTextControlClass({
|
|
32478
32472
|
invalid: !!this.error,
|
|
@@ -32510,6 +32504,9 @@ class TextFieldWidgetComponent {
|
|
|
32510
32504
|
if (this.dataProvider && this.config.dataConfig) {
|
|
32511
32505
|
void this.refreshValueFromDataSource();
|
|
32512
32506
|
}
|
|
32507
|
+
else {
|
|
32508
|
+
this.syncFormattedNumberValue();
|
|
32509
|
+
}
|
|
32513
32510
|
// Sync enabled state based on config + rules
|
|
32514
32511
|
this.syncEnabledState();
|
|
32515
32512
|
if (this.engine) {
|
|
@@ -32522,7 +32519,7 @@ class TextFieldWidgetComponent {
|
|
|
32522
32519
|
const datasourceId = this.config?.dataConfig?.datasourceId;
|
|
32523
32520
|
if (!datasourceId || update.datasourceId !== datasourceId)
|
|
32524
32521
|
return;
|
|
32525
|
-
void this.refreshValueFromDataSource();
|
|
32522
|
+
void this.refreshValueFromDataSource(true);
|
|
32526
32523
|
});
|
|
32527
32524
|
}
|
|
32528
32525
|
this.engine.valueChanges$
|
|
@@ -32530,7 +32527,7 @@ class TextFieldWidgetComponent {
|
|
|
32530
32527
|
.subscribe(values => {
|
|
32531
32528
|
this.syncEnabledState();
|
|
32532
32529
|
if (this.haveDependencyValuesChanged(values)) {
|
|
32533
|
-
void this.refreshValueFromDataSource();
|
|
32530
|
+
void this.refreshValueFromDataSource(true);
|
|
32534
32531
|
}
|
|
32535
32532
|
});
|
|
32536
32533
|
// Listen for submit attempts to show validation errors
|
|
@@ -32545,6 +32542,9 @@ class TextFieldWidgetComponent {
|
|
|
32545
32542
|
this.control.valueChanges
|
|
32546
32543
|
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
32547
32544
|
.subscribe(val => {
|
|
32545
|
+
if (this.usesFormattedNumberInput() && !this.isControlFocused) {
|
|
32546
|
+
this.syncFormattedNumberValue();
|
|
32547
|
+
}
|
|
32548
32548
|
if (this.engine) {
|
|
32549
32549
|
this.engine.setValue(this.config.name, val);
|
|
32550
32550
|
this.engine.emitUiEvent({ fieldId: this.config.id, fieldName: this.config.name, type: 'change', value: val });
|
|
@@ -32556,6 +32556,7 @@ class TextFieldWidgetComponent {
|
|
|
32556
32556
|
}
|
|
32557
32557
|
onFocus() {
|
|
32558
32558
|
this.isControlFocused = true;
|
|
32559
|
+
this.syncFormattedNumberValue();
|
|
32559
32560
|
if (this.engine)
|
|
32560
32561
|
this.engine.emitUiEvent({ fieldId: this.config.id, fieldName: this.config.name, type: 'focus' });
|
|
32561
32562
|
}
|
|
@@ -32565,6 +32566,8 @@ class TextFieldWidgetComponent {
|
|
|
32565
32566
|
}
|
|
32566
32567
|
onBlur() {
|
|
32567
32568
|
this.isControlFocused = false;
|
|
32569
|
+
this.control.markAsTouched();
|
|
32570
|
+
this.syncFormattedNumberValue();
|
|
32568
32571
|
if (this.engine) {
|
|
32569
32572
|
this.engine.emitUiEvent({ fieldId: this.config.id, fieldName: this.config.name, type: 'blur' });
|
|
32570
32573
|
if (this.control.touched) {
|
|
@@ -32612,6 +32615,15 @@ class TextFieldWidgetComponent {
|
|
|
32612
32615
|
invalid: !!this.error
|
|
32613
32616
|
}), splitControlSurfaceStyles(this.config.style).controlStyles);
|
|
32614
32617
|
}
|
|
32618
|
+
getSingleLineControlStyles() {
|
|
32619
|
+
const styles = this.getControlStyles();
|
|
32620
|
+
if (!this.hasDisplayPrefix()) {
|
|
32621
|
+
return styles;
|
|
32622
|
+
}
|
|
32623
|
+
return mergeAndNormalize(styles, {
|
|
32624
|
+
paddingLeft: `calc(20px + ${Math.max(this.displayPrefix.length, 1)}ch)`
|
|
32625
|
+
});
|
|
32626
|
+
}
|
|
32615
32627
|
hasWrapperFrame() {
|
|
32616
32628
|
return hasWrapperSurfaceStyles(this.config.style);
|
|
32617
32629
|
}
|
|
@@ -32619,7 +32631,7 @@ class TextFieldWidgetComponent {
|
|
|
32619
32631
|
return this.engine ? this.engine.isFieldVisible(this.config.id) : true;
|
|
32620
32632
|
}
|
|
32621
32633
|
get enabled() {
|
|
32622
|
-
if (this.config
|
|
32634
|
+
if (isFieldDisabled(this.config))
|
|
32623
32635
|
return false;
|
|
32624
32636
|
return this.engine ? this.engine.isFieldEnabled(this.config.id) : true;
|
|
32625
32637
|
}
|
|
@@ -32645,14 +32657,25 @@ class TextFieldWidgetComponent {
|
|
|
32645
32657
|
this.control.disable({ emitEvent: false });
|
|
32646
32658
|
}
|
|
32647
32659
|
}
|
|
32648
|
-
async refreshValueFromDataSource() {
|
|
32660
|
+
async refreshValueFromDataSource(clearWhenMissing = false) {
|
|
32649
32661
|
if (!this.dataProvider || !this.config.dataConfig)
|
|
32650
32662
|
return;
|
|
32651
32663
|
try {
|
|
32664
|
+
if (clearWhenMissing && !(await this.hasSelectedRowMatch())) {
|
|
32665
|
+
this.clearResolvedValue();
|
|
32666
|
+
return;
|
|
32667
|
+
}
|
|
32652
32668
|
const val = await this.dataProvider.getValue(this.config, this.engine);
|
|
32653
|
-
|
|
32669
|
+
this.displayPrefix = await this.dataProvider.getValueDisplayPrefix(this.config, this.engine);
|
|
32670
|
+
if (val === undefined || val === null) {
|
|
32671
|
+
if (!clearWhenMissing) {
|
|
32672
|
+
return;
|
|
32673
|
+
}
|
|
32674
|
+
this.clearResolvedValue();
|
|
32654
32675
|
return;
|
|
32676
|
+
}
|
|
32655
32677
|
this.control.setValue(val, { emitEvent: false });
|
|
32678
|
+
this.syncFormattedNumberValue();
|
|
32656
32679
|
if (this.engine) {
|
|
32657
32680
|
this.engine.setValue(this.config.name, val);
|
|
32658
32681
|
}
|
|
@@ -32661,12 +32684,48 @@ class TextFieldWidgetComponent {
|
|
|
32661
32684
|
// Ignore failed datasource refreshes; field remains editable.
|
|
32662
32685
|
}
|
|
32663
32686
|
}
|
|
32687
|
+
clearResolvedValue() {
|
|
32688
|
+
this.displayPrefix = '';
|
|
32689
|
+
this.control.setValue(null, { emitEvent: false });
|
|
32690
|
+
this.syncFormattedNumberValue();
|
|
32691
|
+
if (this.engine) {
|
|
32692
|
+
this.engine.setValue(this.config.name, null);
|
|
32693
|
+
}
|
|
32694
|
+
}
|
|
32695
|
+
async hasSelectedRowMatch() {
|
|
32696
|
+
const cfg = this.config.dataConfig;
|
|
32697
|
+
if (!cfg
|
|
32698
|
+
|| cfg.rowSelectionMode !== 'selected'
|
|
32699
|
+
|| !cfg.selectionFieldId
|
|
32700
|
+
|| !cfg.selectionMatchPath
|
|
32701
|
+
|| !this.engine) {
|
|
32702
|
+
return true;
|
|
32703
|
+
}
|
|
32704
|
+
const selectorField = this.engine.getSchema().fields.find(field => field.id === cfg.selectionFieldId);
|
|
32705
|
+
if (!selectorField) {
|
|
32706
|
+
return false;
|
|
32707
|
+
}
|
|
32708
|
+
const selectorValue = this.engine.getValue(selectorField.name);
|
|
32709
|
+
if (selectorValue === undefined || selectorValue === null || selectorValue === '') {
|
|
32710
|
+
return false;
|
|
32711
|
+
}
|
|
32712
|
+
const rows = await this.dataProvider.getList(this.config, this.engine);
|
|
32713
|
+
return rows.some(row => valuesMatch(resolvePathValue(row, cfg.selectionMatchPath), selectorValue));
|
|
32714
|
+
}
|
|
32664
32715
|
getDataConfigSignature(config) {
|
|
32665
32716
|
if (!config)
|
|
32666
32717
|
return '';
|
|
32667
32718
|
const dataConfig = config.dataConfig;
|
|
32668
32719
|
if (!dataConfig) {
|
|
32669
|
-
return
|
|
32720
|
+
return [
|
|
32721
|
+
config.id,
|
|
32722
|
+
config.name,
|
|
32723
|
+
config.type,
|
|
32724
|
+
String(config.html5?.readonly ?? ''),
|
|
32725
|
+
String(config.html5?.disabled ?? ''),
|
|
32726
|
+
String(config.useThousandSeparator ?? ''),
|
|
32727
|
+
'no-data-config'
|
|
32728
|
+
].join('::');
|
|
32670
32729
|
}
|
|
32671
32730
|
const sourceKey = dataConfig.type === 'source' || dataConfig.type === 'global' || dataConfig.type === 'api'
|
|
32672
32731
|
? String(dataConfig.datasourceId ?? '')
|
|
@@ -32674,13 +32733,18 @@ class TextFieldWidgetComponent {
|
|
|
32674
32733
|
return [
|
|
32675
32734
|
config.id,
|
|
32676
32735
|
config.name,
|
|
32736
|
+
String(config.html5?.readonly ?? ''),
|
|
32737
|
+
String(config.html5?.disabled ?? ''),
|
|
32677
32738
|
dataConfig.type ?? '',
|
|
32678
32739
|
sourceKey,
|
|
32679
32740
|
String(dataConfig.valueKey ?? ''),
|
|
32680
32741
|
String(dataConfig.rowsPath ?? ''),
|
|
32742
|
+
String(dataConfig.optionLabelPrefixPath ?? ''),
|
|
32743
|
+
String(dataConfig.optionLabelPrefixFieldId ?? ''),
|
|
32681
32744
|
String(dataConfig.rowSelectionMode ?? ''),
|
|
32682
32745
|
String(dataConfig.selectionFieldId ?? ''),
|
|
32683
32746
|
String(dataConfig.selectionMatchPath ?? ''),
|
|
32747
|
+
String(config.useThousandSeparator ?? ''),
|
|
32684
32748
|
(dataConfig.filters ?? []).map(filter => `${filter.column}:${filter.valueFrom ?? ''}:${filter.fieldId ?? ''}`).join('|')
|
|
32685
32749
|
].join('::');
|
|
32686
32750
|
}
|
|
@@ -32733,6 +32797,59 @@ class TextFieldWidgetComponent {
|
|
|
32733
32797
|
.filter(field => dependencyIds.has(field.id))
|
|
32734
32798
|
.map(field => field.name);
|
|
32735
32799
|
}
|
|
32800
|
+
onFormattedNumberInput(event) {
|
|
32801
|
+
const input = event.target;
|
|
32802
|
+
this.formattedNumberValue = input.value;
|
|
32803
|
+
if (this.control.pristine) {
|
|
32804
|
+
this.control.markAsDirty();
|
|
32805
|
+
}
|
|
32806
|
+
const normalized = input.value.replace(/,/g, '').trim();
|
|
32807
|
+
if (!normalized) {
|
|
32808
|
+
this.control.setValue(null);
|
|
32809
|
+
return;
|
|
32810
|
+
}
|
|
32811
|
+
const parsed = Number(normalized);
|
|
32812
|
+
this.control.setValue(Number.isFinite(parsed) ? parsed : null);
|
|
32813
|
+
}
|
|
32814
|
+
syncFormattedNumberValue() {
|
|
32815
|
+
if (!this.usesFormattedNumberInput()) {
|
|
32816
|
+
return;
|
|
32817
|
+
}
|
|
32818
|
+
const rawValue = this.control.value;
|
|
32819
|
+
if (rawValue === undefined || rawValue === null || rawValue === '') {
|
|
32820
|
+
this.formattedNumberValue = '';
|
|
32821
|
+
return;
|
|
32822
|
+
}
|
|
32823
|
+
if (typeof rawValue !== 'string' && typeof rawValue !== 'number') {
|
|
32824
|
+
this.formattedNumberValue = '';
|
|
32825
|
+
return;
|
|
32826
|
+
}
|
|
32827
|
+
const normalized = String(rawValue).replace(/,/g, '').trim();
|
|
32828
|
+
if (!normalized) {
|
|
32829
|
+
this.formattedNumberValue = '';
|
|
32830
|
+
return;
|
|
32831
|
+
}
|
|
32832
|
+
if (this.isControlFocused) {
|
|
32833
|
+
this.formattedNumberValue = normalized;
|
|
32834
|
+
return;
|
|
32835
|
+
}
|
|
32836
|
+
this.formattedNumberValue = this.formatNumericValue(normalized);
|
|
32837
|
+
}
|
|
32838
|
+
formatNumericValue(value) {
|
|
32839
|
+
if (!/^-?\d+(\.\d+)?$/.test(value)) {
|
|
32840
|
+
return value;
|
|
32841
|
+
}
|
|
32842
|
+
const numericValue = Number(value);
|
|
32843
|
+
if (!Number.isFinite(numericValue)) {
|
|
32844
|
+
return value;
|
|
32845
|
+
}
|
|
32846
|
+
const fractionPart = value.split('.')[1];
|
|
32847
|
+
return new Intl.NumberFormat(undefined, {
|
|
32848
|
+
useGrouping: true,
|
|
32849
|
+
minimumFractionDigits: fractionPart?.length ?? 0,
|
|
32850
|
+
maximumFractionDigits: fractionPart?.length ?? 0
|
|
32851
|
+
}).format(numericValue);
|
|
32852
|
+
}
|
|
32736
32853
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TextFieldWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
32737
32854
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: TextFieldWidgetComponent, isStandalone: true, selector: "app-text-field-widget", inputs: { config: "config", engine: "engine", control: "control" }, ngImport: i0, template: `
|
|
32738
32855
|
<div [class]="fieldContainerClass"
|
|
@@ -32762,7 +32879,7 @@ class TextFieldWidgetComponent {
|
|
|
32762
32879
|
(blur)="onBlur()"
|
|
32763
32880
|
(mouseenter)="onMouseEnter()"
|
|
32764
32881
|
(mouseleave)="onMouseLeave()"
|
|
32765
|
-
[readonly]="config.readonly"
|
|
32882
|
+
[readonly]="config.html5?.readonly"
|
|
32766
32883
|
[attr.aria-required]="required"
|
|
32767
32884
|
[attr.aria-invalid]="!!error"
|
|
32768
32885
|
[attr.aria-describedby]="getAriaDescribedBy()"
|
|
@@ -32783,7 +32900,7 @@ class TextFieldWidgetComponent {
|
|
|
32783
32900
|
(blur)="onBlur()"
|
|
32784
32901
|
(mouseenter)="onMouseEnter()"
|
|
32785
32902
|
(mouseleave)="onMouseLeave()"
|
|
32786
|
-
[readonly]="config.readonly"
|
|
32903
|
+
[readonly]="config.html5?.readonly"
|
|
32787
32904
|
[attr.aria-required]="required"
|
|
32788
32905
|
[attr.aria-invalid]="!!error"
|
|
32789
32906
|
[attr.aria-describedby]="getAriaDescribedBy()"
|
|
@@ -32795,9 +32912,48 @@ class TextFieldWidgetComponent {
|
|
|
32795
32912
|
[cpAlphaChannel]="'disabled'"
|
|
32796
32913
|
[cpOutputFormat]="'hex'"
|
|
32797
32914
|
[cpFallbackColor]="'#000000'"
|
|
32798
|
-
[cpDisabled]="config.readonly || !enabled"
|
|
32915
|
+
[cpDisabled]="config.html5?.readonly || !enabled"
|
|
32799
32916
|
(colorPickerChange)="onColorPickerChange($event)">
|
|
32917
|
+
} @else if (usesFormattedNumberInput()) {
|
|
32918
|
+
@if (hasDisplayPrefix()) {
|
|
32919
|
+
<span
|
|
32920
|
+
class="pointer-events-none absolute left-3 top-1/2 z-[1] -translate-y-1/2 text-sm text-slate-500"
|
|
32921
|
+
data-fd-field-prefix>
|
|
32922
|
+
{{ displayPrefix }}
|
|
32923
|
+
</span>
|
|
32924
|
+
}
|
|
32925
|
+
<input
|
|
32926
|
+
[id]="fieldId"
|
|
32927
|
+
type="text"
|
|
32928
|
+
inputmode="decimal"
|
|
32929
|
+
[placeholder]="config.placeholder || ''"
|
|
32930
|
+
[value]="formattedNumberValue"
|
|
32931
|
+
(input)="onFormattedNumberInput($event)"
|
|
32932
|
+
(click)="onClick()"
|
|
32933
|
+
(focus)="onFocus()"
|
|
32934
|
+
(blur)="onBlur()"
|
|
32935
|
+
(mouseenter)="onMouseEnter()"
|
|
32936
|
+
(mouseleave)="onMouseLeave()"
|
|
32937
|
+
[readonly]="config.html5?.readonly"
|
|
32938
|
+
[disabled]="control.disabled"
|
|
32939
|
+
[attr.aria-required]="required"
|
|
32940
|
+
[attr.aria-invalid]="!!error"
|
|
32941
|
+
[attr.aria-describedby]="getAriaDescribedBy()"
|
|
32942
|
+
[attr.aria-label]="getAccessibleLabel()"
|
|
32943
|
+
[class]="getControlClass()"
|
|
32944
|
+
[ngStyle]="getSingleLineControlStyles()"
|
|
32945
|
+
data-fd="field-control"
|
|
32946
|
+
[attr.min]="config.html5?.min"
|
|
32947
|
+
[attr.max]="config.html5?.max"
|
|
32948
|
+
[attr.step]="config.html5?.step">
|
|
32800
32949
|
} @else {
|
|
32950
|
+
@if (hasDisplayPrefix()) {
|
|
32951
|
+
<span
|
|
32952
|
+
class="pointer-events-none absolute left-3 top-1/2 z-[1] -translate-y-1/2 text-sm text-slate-500"
|
|
32953
|
+
data-fd-field-prefix>
|
|
32954
|
+
{{ displayPrefix }}
|
|
32955
|
+
</span>
|
|
32956
|
+
}
|
|
32801
32957
|
<input
|
|
32802
32958
|
[id]="fieldId"
|
|
32803
32959
|
[type]="config.type"
|
|
@@ -32808,13 +32964,13 @@ class TextFieldWidgetComponent {
|
|
|
32808
32964
|
(blur)="onBlur()"
|
|
32809
32965
|
(mouseenter)="onMouseEnter()"
|
|
32810
32966
|
(mouseleave)="onMouseLeave()"
|
|
32811
|
-
[readonly]="config.readonly"
|
|
32967
|
+
[readonly]="config.html5?.readonly"
|
|
32812
32968
|
[attr.aria-required]="required"
|
|
32813
32969
|
[attr.aria-invalid]="!!error"
|
|
32814
32970
|
[attr.aria-describedby]="getAriaDescribedBy()"
|
|
32815
32971
|
[attr.aria-label]="getAccessibleLabel()"
|
|
32816
32972
|
[class]="getControlClass()"
|
|
32817
|
-
[ngStyle]="
|
|
32973
|
+
[ngStyle]="getSingleLineControlStyles()"
|
|
32818
32974
|
data-fd="field-control"
|
|
32819
32975
|
[attr.min]="config.html5?.min"
|
|
32820
32976
|
[attr.max]="config.html5?.max"
|
|
@@ -32866,7 +33022,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
|
|
|
32866
33022
|
(blur)="onBlur()"
|
|
32867
33023
|
(mouseenter)="onMouseEnter()"
|
|
32868
33024
|
(mouseleave)="onMouseLeave()"
|
|
32869
|
-
[readonly]="config.readonly"
|
|
33025
|
+
[readonly]="config.html5?.readonly"
|
|
32870
33026
|
[attr.aria-required]="required"
|
|
32871
33027
|
[attr.aria-invalid]="!!error"
|
|
32872
33028
|
[attr.aria-describedby]="getAriaDescribedBy()"
|
|
@@ -32887,7 +33043,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
|
|
|
32887
33043
|
(blur)="onBlur()"
|
|
32888
33044
|
(mouseenter)="onMouseEnter()"
|
|
32889
33045
|
(mouseleave)="onMouseLeave()"
|
|
32890
|
-
[readonly]="config.readonly"
|
|
33046
|
+
[readonly]="config.html5?.readonly"
|
|
32891
33047
|
[attr.aria-required]="required"
|
|
32892
33048
|
[attr.aria-invalid]="!!error"
|
|
32893
33049
|
[attr.aria-describedby]="getAriaDescribedBy()"
|
|
@@ -32899,9 +33055,48 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
|
|
|
32899
33055
|
[cpAlphaChannel]="'disabled'"
|
|
32900
33056
|
[cpOutputFormat]="'hex'"
|
|
32901
33057
|
[cpFallbackColor]="'#000000'"
|
|
32902
|
-
[cpDisabled]="config.readonly || !enabled"
|
|
33058
|
+
[cpDisabled]="config.html5?.readonly || !enabled"
|
|
32903
33059
|
(colorPickerChange)="onColorPickerChange($event)">
|
|
33060
|
+
} @else if (usesFormattedNumberInput()) {
|
|
33061
|
+
@if (hasDisplayPrefix()) {
|
|
33062
|
+
<span
|
|
33063
|
+
class="pointer-events-none absolute left-3 top-1/2 z-[1] -translate-y-1/2 text-sm text-slate-500"
|
|
33064
|
+
data-fd-field-prefix>
|
|
33065
|
+
{{ displayPrefix }}
|
|
33066
|
+
</span>
|
|
33067
|
+
}
|
|
33068
|
+
<input
|
|
33069
|
+
[id]="fieldId"
|
|
33070
|
+
type="text"
|
|
33071
|
+
inputmode="decimal"
|
|
33072
|
+
[placeholder]="config.placeholder || ''"
|
|
33073
|
+
[value]="formattedNumberValue"
|
|
33074
|
+
(input)="onFormattedNumberInput($event)"
|
|
33075
|
+
(click)="onClick()"
|
|
33076
|
+
(focus)="onFocus()"
|
|
33077
|
+
(blur)="onBlur()"
|
|
33078
|
+
(mouseenter)="onMouseEnter()"
|
|
33079
|
+
(mouseleave)="onMouseLeave()"
|
|
33080
|
+
[readonly]="config.html5?.readonly"
|
|
33081
|
+
[disabled]="control.disabled"
|
|
33082
|
+
[attr.aria-required]="required"
|
|
33083
|
+
[attr.aria-invalid]="!!error"
|
|
33084
|
+
[attr.aria-describedby]="getAriaDescribedBy()"
|
|
33085
|
+
[attr.aria-label]="getAccessibleLabel()"
|
|
33086
|
+
[class]="getControlClass()"
|
|
33087
|
+
[ngStyle]="getSingleLineControlStyles()"
|
|
33088
|
+
data-fd="field-control"
|
|
33089
|
+
[attr.min]="config.html5?.min"
|
|
33090
|
+
[attr.max]="config.html5?.max"
|
|
33091
|
+
[attr.step]="config.html5?.step">
|
|
32904
33092
|
} @else {
|
|
33093
|
+
@if (hasDisplayPrefix()) {
|
|
33094
|
+
<span
|
|
33095
|
+
class="pointer-events-none absolute left-3 top-1/2 z-[1] -translate-y-1/2 text-sm text-slate-500"
|
|
33096
|
+
data-fd-field-prefix>
|
|
33097
|
+
{{ displayPrefix }}
|
|
33098
|
+
</span>
|
|
33099
|
+
}
|
|
32905
33100
|
<input
|
|
32906
33101
|
[id]="fieldId"
|
|
32907
33102
|
[type]="config.type"
|
|
@@ -32912,13 +33107,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
|
|
|
32912
33107
|
(blur)="onBlur()"
|
|
32913
33108
|
(mouseenter)="onMouseEnter()"
|
|
32914
33109
|
(mouseleave)="onMouseLeave()"
|
|
32915
|
-
[readonly]="config.readonly"
|
|
33110
|
+
[readonly]="config.html5?.readonly"
|
|
32916
33111
|
[attr.aria-required]="required"
|
|
32917
33112
|
[attr.aria-invalid]="!!error"
|
|
32918
33113
|
[attr.aria-describedby]="getAriaDescribedBy()"
|
|
32919
33114
|
[attr.aria-label]="getAccessibleLabel()"
|
|
32920
33115
|
[class]="getControlClass()"
|
|
32921
|
-
[ngStyle]="
|
|
33116
|
+
[ngStyle]="getSingleLineControlStyles()"
|
|
32922
33117
|
data-fd="field-control"
|
|
32923
33118
|
[attr.min]="config.html5?.min"
|
|
32924
33119
|
[attr.max]="config.html5?.max"
|
|
@@ -33025,12 +33220,12 @@ class FileUploadWidgetComponent {
|
|
|
33025
33220
|
return this.engine ? this.engine.isFieldVisible(this.config.id) : true;
|
|
33026
33221
|
}
|
|
33027
33222
|
get enabled() {
|
|
33028
|
-
if (this.config
|
|
33223
|
+
if (isFieldDisabled(this.config))
|
|
33029
33224
|
return false;
|
|
33030
33225
|
return this.engine ? this.engine.isFieldEnabled(this.config.id) : true;
|
|
33031
33226
|
}
|
|
33032
33227
|
get isDisabled() {
|
|
33033
|
-
return !this.enabled ||
|
|
33228
|
+
return !this.enabled || isFieldReadonly(this.config);
|
|
33034
33229
|
}
|
|
33035
33230
|
get required() {
|
|
33036
33231
|
return this.engine ? this.engine.isFieldRequired(this.config.id) : !!this.config?.html5?.required;
|
|
@@ -33521,7 +33716,7 @@ class SelectWidgetComponent {
|
|
|
33521
33716
|
this.runtimeOptionsLoaded = false;
|
|
33522
33717
|
this.currentSearchTerm = '';
|
|
33523
33718
|
this.setOptionsFromRaw([]);
|
|
33524
|
-
void this.loadOptions(this.currentSearchTerm);
|
|
33719
|
+
void this.loadOptions(this.currentSearchTerm, false, true);
|
|
33525
33720
|
});
|
|
33526
33721
|
}
|
|
33527
33722
|
}
|
|
@@ -33664,7 +33859,7 @@ class SelectWidgetComponent {
|
|
|
33664
33859
|
return this.engine ? this.engine.isFieldVisible(this.config.id) : true;
|
|
33665
33860
|
}
|
|
33666
33861
|
get enabled() {
|
|
33667
|
-
if (this.config
|
|
33862
|
+
if (isFieldDisabled(this.config))
|
|
33668
33863
|
return false;
|
|
33669
33864
|
return this.engine ? this.engine.isFieldEnabled(this.config.id) : true;
|
|
33670
33865
|
}
|
|
@@ -33721,7 +33916,7 @@ class SelectWidgetComponent {
|
|
|
33721
33916
|
event.preventDefault();
|
|
33722
33917
|
}
|
|
33723
33918
|
onPillClick() {
|
|
33724
|
-
if (this.config
|
|
33919
|
+
if (isFieldReadonly(this.config)) {
|
|
33725
33920
|
return;
|
|
33726
33921
|
}
|
|
33727
33922
|
this.onClick();
|
|
@@ -33788,7 +33983,7 @@ class SelectWidgetComponent {
|
|
|
33788
33983
|
assign('--fd-select-icon-color', controlStyles['iconColor'] ?? controlStyles['color']);
|
|
33789
33984
|
return vars;
|
|
33790
33985
|
}
|
|
33791
|
-
async loadOptions(term = '', isSearch = false) {
|
|
33986
|
+
async loadOptions(term = '', isSearch = false, clearStaleSelection = false) {
|
|
33792
33987
|
if (!this.config)
|
|
33793
33988
|
return;
|
|
33794
33989
|
const reqId = ++this.requestId;
|
|
@@ -33806,8 +34001,17 @@ class SelectWidgetComponent {
|
|
|
33806
34001
|
opts = await this.dataProvider.getOptions(this.config, this.engine);
|
|
33807
34002
|
}
|
|
33808
34003
|
if (this.requestId === reqId) {
|
|
33809
|
-
this.
|
|
33810
|
-
|
|
34004
|
+
const selectedValue = this.resolveSelectedValueForFallback();
|
|
34005
|
+
const shouldClearStaleSelection = clearStaleSelection
|
|
34006
|
+
&& this.hasMeaningfulValue(selectedValue)
|
|
34007
|
+
&& !this.hasOptionValue(opts, this.toComparableOptionValue(selectedValue));
|
|
34008
|
+
this.setOptionsFromRaw(shouldClearStaleSelection ? opts : this.withSelectedValueFallbackOptions(opts));
|
|
34009
|
+
if (shouldClearStaleSelection) {
|
|
34010
|
+
this.control.setValue(null);
|
|
34011
|
+
}
|
|
34012
|
+
else {
|
|
34013
|
+
this.syncStoredFieldLabel(this.control.value);
|
|
34014
|
+
}
|
|
33811
34015
|
this.loading = false;
|
|
33812
34016
|
this.loadError = null;
|
|
33813
34017
|
this.cdr.markForCheck();
|
|
@@ -33914,6 +34118,9 @@ class SelectWidgetComponent {
|
|
|
33914
34118
|
config.id,
|
|
33915
34119
|
config.name,
|
|
33916
34120
|
config.type,
|
|
34121
|
+
String(config.html5?.readonly ?? ''),
|
|
34122
|
+
String(config.html5?.disabled ?? ''),
|
|
34123
|
+
String(config.useThousandSeparator ?? ''),
|
|
33917
34124
|
'no-data-config',
|
|
33918
34125
|
fieldStaticOptions
|
|
33919
34126
|
].join('::');
|
|
@@ -33926,11 +34133,13 @@ class SelectWidgetComponent {
|
|
|
33926
34133
|
config.id,
|
|
33927
34134
|
config.name,
|
|
33928
34135
|
config.type,
|
|
34136
|
+
String(config.html5?.readonly ?? ''),
|
|
34137
|
+
String(config.html5?.disabled ?? ''),
|
|
33929
34138
|
dataConfig.type ?? '',
|
|
33930
34139
|
String(dataConfig.datasourceId ?? ''),
|
|
33931
34140
|
String(dataConfig.labelKey ?? ''),
|
|
33932
34141
|
String(dataConfig.valueKey ?? ''),
|
|
33933
|
-
String(
|
|
34142
|
+
String(config.useThousandSeparator ?? ''),
|
|
33934
34143
|
String(dataConfig.optionLabelPrefixFieldId ?? ''),
|
|
33935
34144
|
String(dataConfig.searchEnabled ?? ''),
|
|
33936
34145
|
String(dataConfig.optionsLimit ?? ''),
|
|
@@ -33983,15 +34192,18 @@ class SelectWidgetComponent {
|
|
|
33983
34192
|
applyDisplayFormatting() {
|
|
33984
34193
|
this.options = this.rawOptions.map(option => ({
|
|
33985
34194
|
...option,
|
|
33986
|
-
label: this.formatOptionLabel(option
|
|
34195
|
+
label: this.formatOptionLabel(option)
|
|
33987
34196
|
}));
|
|
33988
34197
|
}
|
|
33989
|
-
formatOptionLabel(
|
|
33990
|
-
const
|
|
34198
|
+
formatOptionLabel(option) {
|
|
34199
|
+
const label = option.label;
|
|
34200
|
+
const formattedLabel = usesFieldThousandSeparator(this.config)
|
|
33991
34201
|
? this.formatNumericLabel(label)
|
|
33992
34202
|
: label;
|
|
33993
|
-
const
|
|
33994
|
-
|
|
34203
|
+
const prefixParts = [option.displayPrefix, this.resolveOptionLabelPrefix()]
|
|
34204
|
+
.map(value => value?.trim())
|
|
34205
|
+
.filter((value) => !!value);
|
|
34206
|
+
return prefixParts.length > 0 ? `${prefixParts.join(' ')} ${formattedLabel}` : formattedLabel;
|
|
33995
34207
|
}
|
|
33996
34208
|
resolveOptionLabelPrefix() {
|
|
33997
34209
|
const prefixFieldId = this.config.dataConfig?.optionLabelPrefixFieldId;
|
|
@@ -34074,6 +34286,12 @@ class SelectWidgetComponent {
|
|
|
34074
34286
|
hasOptionValue(options, value) {
|
|
34075
34287
|
return options.some(option => Object.is(option.value, value) || String(option.value) === String(value));
|
|
34076
34288
|
}
|
|
34289
|
+
toComparableOptionValue(value) {
|
|
34290
|
+
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
34291
|
+
return value;
|
|
34292
|
+
}
|
|
34293
|
+
return String(value ?? '');
|
|
34294
|
+
}
|
|
34077
34295
|
resolveSelectedValueForFallback() {
|
|
34078
34296
|
const controlValue = this.control.value;
|
|
34079
34297
|
if (this.hasMeaningfulValue(controlValue)) {
|
|
@@ -34118,7 +34336,7 @@ class SelectWidgetComponent {
|
|
|
34118
34336
|
if (this.config.dataConfig?.optionLabelPrefixFieldId) {
|
|
34119
34337
|
return this.resolveOptionLabelPrefix().length === 0;
|
|
34120
34338
|
}
|
|
34121
|
-
return this.config
|
|
34339
|
+
return !usesFieldThousandSeparator(this.config);
|
|
34122
34340
|
}
|
|
34123
34341
|
setStoredFieldLabel(label) {
|
|
34124
34342
|
if (!this.engine || typeof this.engine.setFieldLabel !== 'function') {
|
|
@@ -34156,8 +34374,8 @@ class SelectWidgetComponent {
|
|
|
34156
34374
|
[loadingText]="'Loading options...'"
|
|
34157
34375
|
[notFoundText]="loadError || 'No options found'"
|
|
34158
34376
|
[searchable]="isSearchable()"
|
|
34159
|
-
[clearable]="!required && !config.readonly && !hasPillLabel()"
|
|
34160
|
-
[readonly]="config.readonly"
|
|
34377
|
+
[clearable]="!required && !config.html5?.readonly && !hasPillLabel()"
|
|
34378
|
+
[readonly]="config.html5?.readonly"
|
|
34161
34379
|
[labelForId]="fieldId"
|
|
34162
34380
|
[inputAttrs]="getInputAttributes()"
|
|
34163
34381
|
[typeahead]="searchTerms$"
|
|
@@ -34183,7 +34401,7 @@ class SelectWidgetComponent {
|
|
|
34183
34401
|
class="fd-select-pill"
|
|
34184
34402
|
[ngStyle]="getPillStyles()"
|
|
34185
34403
|
data-fd-select-pill
|
|
34186
|
-
[disabled]="config.readonly"
|
|
34404
|
+
[disabled]="config.html5?.readonly"
|
|
34187
34405
|
(mousedown)="onPillMouseDown($event)"
|
|
34188
34406
|
(click)="onPillClick()">
|
|
34189
34407
|
<span class="fd-select-pill__label">{{ pillLabel() }}</span>
|
|
@@ -34236,8 +34454,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
|
|
|
34236
34454
|
[loadingText]="'Loading options...'"
|
|
34237
34455
|
[notFoundText]="loadError || 'No options found'"
|
|
34238
34456
|
[searchable]="isSearchable()"
|
|
34239
|
-
[clearable]="!required && !config.readonly && !hasPillLabel()"
|
|
34240
|
-
[readonly]="config.readonly"
|
|
34457
|
+
[clearable]="!required && !config.html5?.readonly && !hasPillLabel()"
|
|
34458
|
+
[readonly]="config.html5?.readonly"
|
|
34241
34459
|
[labelForId]="fieldId"
|
|
34242
34460
|
[inputAttrs]="getInputAttributes()"
|
|
34243
34461
|
[typeahead]="searchTerms$"
|
|
@@ -34263,7 +34481,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
|
|
|
34263
34481
|
class="fd-select-pill"
|
|
34264
34482
|
[ngStyle]="getPillStyles()"
|
|
34265
34483
|
data-fd-select-pill
|
|
34266
|
-
[disabled]="config.readonly"
|
|
34484
|
+
[disabled]="config.html5?.readonly"
|
|
34267
34485
|
(mousedown)="onPillMouseDown($event)"
|
|
34268
34486
|
(click)="onPillClick()">
|
|
34269
34487
|
<span class="fd-select-pill__label">{{ pillLabel() }}</span>
|
|
@@ -34358,7 +34576,7 @@ class SearchWidgetComponent {
|
|
|
34358
34576
|
return this.engine ? this.engine.isFieldVisible(this.config.id) : true;
|
|
34359
34577
|
}
|
|
34360
34578
|
get enabled() {
|
|
34361
|
-
if (this.config
|
|
34579
|
+
if (isFieldDisabled(this.config))
|
|
34362
34580
|
return false;
|
|
34363
34581
|
return this.engine ? this.engine.isFieldEnabled(this.config.id) : true;
|
|
34364
34582
|
}
|
|
@@ -34421,7 +34639,7 @@ class SearchWidgetComponent {
|
|
|
34421
34639
|
const datasourceId = this.config?.dataConfig?.datasourceId;
|
|
34422
34640
|
if (!datasourceId || update.datasourceId !== datasourceId)
|
|
34423
34641
|
return;
|
|
34424
|
-
void this.refreshForCurrentQuery();
|
|
34642
|
+
void this.refreshForCurrentQuery(true);
|
|
34425
34643
|
});
|
|
34426
34644
|
}
|
|
34427
34645
|
this.engine.valueChanges$
|
|
@@ -34565,7 +34783,7 @@ class SearchWidgetComponent {
|
|
|
34565
34783
|
this.queryControl.disable({ emitEvent: false });
|
|
34566
34784
|
}
|
|
34567
34785
|
}
|
|
34568
|
-
async refreshForCurrentQuery() {
|
|
34786
|
+
async refreshForCurrentQuery(clearStaleSelection = false) {
|
|
34569
34787
|
const query = this.queryControl.value ?? '';
|
|
34570
34788
|
if (!this.shouldQuery(query)) {
|
|
34571
34789
|
this.options = [];
|
|
@@ -34575,7 +34793,7 @@ class SearchWidgetComponent {
|
|
|
34575
34793
|
this.cdr.markForCheck();
|
|
34576
34794
|
return;
|
|
34577
34795
|
}
|
|
34578
|
-
await this.loadOptions(query);
|
|
34796
|
+
await this.loadOptions(query, clearStaleSelection);
|
|
34579
34797
|
}
|
|
34580
34798
|
async handleQueryChange(query) {
|
|
34581
34799
|
if (this.selectingOption) {
|
|
@@ -34595,7 +34813,7 @@ class SearchWidgetComponent {
|
|
|
34595
34813
|
}
|
|
34596
34814
|
await this.loadOptions(normalizedQuery);
|
|
34597
34815
|
}
|
|
34598
|
-
async loadOptions(term) {
|
|
34816
|
+
async loadOptions(term, clearStaleSelection = false) {
|
|
34599
34817
|
const requestId = ++this.requestId;
|
|
34600
34818
|
this.loading = true;
|
|
34601
34819
|
this.loadError = null;
|
|
@@ -34609,6 +34827,15 @@ class SearchWidgetComponent {
|
|
|
34609
34827
|
return;
|
|
34610
34828
|
}
|
|
34611
34829
|
this.options = this.normalizeOptions(options);
|
|
34830
|
+
if (clearStaleSelection && this.isSelectedOptionState() && !this.hasOptionValue(this.options, this.control.value)) {
|
|
34831
|
+
this.queryControl.setValue('', { emitEvent: false });
|
|
34832
|
+
this.control.setValue(null);
|
|
34833
|
+
this.loading = false;
|
|
34834
|
+
this.loadError = null;
|
|
34835
|
+
this.activeOptionIndex = -1;
|
|
34836
|
+
this.cdr.markForCheck();
|
|
34837
|
+
return;
|
|
34838
|
+
}
|
|
34612
34839
|
this.activeOptionIndex = this.options.length > 0 ? 0 : -1;
|
|
34613
34840
|
this.loading = false;
|
|
34614
34841
|
this.loadError = null;
|
|
@@ -34640,6 +34867,31 @@ class SearchWidgetComponent {
|
|
|
34640
34867
|
const minChars = this.getMinChars();
|
|
34641
34868
|
return (query ?? '').trim().length >= minChars;
|
|
34642
34869
|
}
|
|
34870
|
+
isSelectedOptionState() {
|
|
34871
|
+
if (!this.hasMeaningfulValue(this.control.value)) {
|
|
34872
|
+
return false;
|
|
34873
|
+
}
|
|
34874
|
+
const storedLabel = this.getStoredFieldLabel();
|
|
34875
|
+
if (typeof storedLabel === 'string' && storedLabel.length > 0) {
|
|
34876
|
+
return true;
|
|
34877
|
+
}
|
|
34878
|
+
return String(this.control.value ?? '') !== String(this.queryControl.value ?? '');
|
|
34879
|
+
}
|
|
34880
|
+
hasOptionValue(options, value) {
|
|
34881
|
+
if (!this.hasMeaningfulValue(value)) {
|
|
34882
|
+
return false;
|
|
34883
|
+
}
|
|
34884
|
+
return options.some(option => Object.is(option.value, value) || String(option.value) === String(value));
|
|
34885
|
+
}
|
|
34886
|
+
hasMeaningfulValue(value) {
|
|
34887
|
+
if (value === undefined || value === null)
|
|
34888
|
+
return false;
|
|
34889
|
+
if (typeof value === 'string')
|
|
34890
|
+
return value.length > 0;
|
|
34891
|
+
if (Array.isArray(value))
|
|
34892
|
+
return value.length > 0;
|
|
34893
|
+
return true;
|
|
34894
|
+
}
|
|
34643
34895
|
getMinChars() {
|
|
34644
34896
|
return this.toSafeNonNegativeInt(this.config?.['searchMinChars'], 1);
|
|
34645
34897
|
}
|
|
@@ -34707,7 +34959,7 @@ class SearchWidgetComponent {
|
|
|
34707
34959
|
type="search"
|
|
34708
34960
|
[placeholder]="config.placeholder || 'Search...'"
|
|
34709
34961
|
[formControl]="queryControl"
|
|
34710
|
-
[readonly]="config.readonly"
|
|
34962
|
+
[readonly]="config.html5?.readonly"
|
|
34711
34963
|
[attr.aria-required]="required"
|
|
34712
34964
|
[attr.aria-invalid]="!!error"
|
|
34713
34965
|
[attr.aria-describedby]="getAriaDescribedBy()"
|
|
@@ -34786,7 +35038,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
|
|
|
34786
35038
|
type="search"
|
|
34787
35039
|
[placeholder]="config.placeholder || 'Search...'"
|
|
34788
35040
|
[formControl]="queryControl"
|
|
34789
|
-
[readonly]="config.readonly"
|
|
35041
|
+
[readonly]="config.html5?.readonly"
|
|
34790
35042
|
[attr.aria-required]="required"
|
|
34791
35043
|
[attr.aria-invalid]="!!error"
|
|
34792
35044
|
[attr.aria-describedby]="getAriaDescribedBy()"
|
|
@@ -35073,7 +35325,7 @@ class TreeSelectWidgetComponent {
|
|
|
35073
35325
|
expandRecursive(filtered);
|
|
35074
35326
|
}
|
|
35075
35327
|
toggleDropdown(e) {
|
|
35076
|
-
if (this.config
|
|
35328
|
+
if (isFieldDisabled(this.config) || isFieldReadonly(this.config))
|
|
35077
35329
|
return;
|
|
35078
35330
|
this.engine?.emitUiEvent({ fieldId: this.config.id, fieldName: this.config.name, type: 'click' });
|
|
35079
35331
|
if (this.isOpen) {
|
|
@@ -35185,8 +35437,8 @@ class TreeSelectWidgetComponent {
|
|
|
35185
35437
|
<!-- Dropdown Trigger -->
|
|
35186
35438
|
<div class="relative group" (click)="toggleDropdown($event)">
|
|
35187
35439
|
<div class="flex items-center justify-between w-full rounded-md border text-sm px-3 py-2 cursor-pointer transition-colors"
|
|
35188
|
-
[class.bg-gray-50]="config.disabled"
|
|
35189
|
-
[class.cursor-not-allowed]="config.disabled"
|
|
35440
|
+
[class.bg-gray-50]="config.html5?.disabled"
|
|
35441
|
+
[class.cursor-not-allowed]="config.html5?.disabled"
|
|
35190
35442
|
[class.border-gray-300]="!isInvalid && !isOpen"
|
|
35191
35443
|
[class.border-blue-500]="isOpen"
|
|
35192
35444
|
[class.ring-2]="isOpen"
|
|
@@ -35289,8 +35541,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
|
|
|
35289
35541
|
<!-- Dropdown Trigger -->
|
|
35290
35542
|
<div class="relative group" (click)="toggleDropdown($event)">
|
|
35291
35543
|
<div class="flex items-center justify-between w-full rounded-md border text-sm px-3 py-2 cursor-pointer transition-colors"
|
|
35292
|
-
[class.bg-gray-50]="config.disabled"
|
|
35293
|
-
[class.cursor-not-allowed]="config.disabled"
|
|
35544
|
+
[class.bg-gray-50]="config.html5?.disabled"
|
|
35545
|
+
[class.cursor-not-allowed]="config.html5?.disabled"
|
|
35294
35546
|
[class.border-gray-300]="!isInvalid && !isOpen"
|
|
35295
35547
|
[class.border-blue-500]="isOpen"
|
|
35296
35548
|
[class.ring-2]="isOpen"
|
|
@@ -35540,7 +35792,7 @@ class RadioWidgetComponent {
|
|
|
35540
35792
|
return this.engine ? this.engine.isFieldVisible(this.config.id) : true;
|
|
35541
35793
|
}
|
|
35542
35794
|
get enabled() {
|
|
35543
|
-
if (this.config
|
|
35795
|
+
if (isFieldDisabled(this.config))
|
|
35544
35796
|
return false;
|
|
35545
35797
|
return this.engine ? this.engine.isFieldEnabled(this.config.id) : true;
|
|
35546
35798
|
}
|
|
@@ -35856,7 +36108,7 @@ class CheckboxGroupWidgetComponent {
|
|
|
35856
36108
|
return this.engine ? this.engine.isFieldVisible(this.config.id) : true;
|
|
35857
36109
|
}
|
|
35858
36110
|
get enabled() {
|
|
35859
|
-
if (this.config
|
|
36111
|
+
if (isFieldDisabled(this.config))
|
|
35860
36112
|
return false;
|
|
35861
36113
|
return this.engine ? this.engine.isFieldEnabled(this.config.id) : true;
|
|
35862
36114
|
}
|
|
@@ -36092,7 +36344,7 @@ class CheckboxWidgetComponent {
|
|
|
36092
36344
|
return this.engine ? this.engine.isFieldVisible(this.config.id) : true;
|
|
36093
36345
|
}
|
|
36094
36346
|
get enabled() {
|
|
36095
|
-
if (this.config
|
|
36347
|
+
if (isFieldDisabled(this.config))
|
|
36096
36348
|
return false;
|
|
36097
36349
|
return this.engine ? this.engine.isFieldEnabled(this.config.id) : true;
|
|
36098
36350
|
}
|
|
@@ -36326,7 +36578,7 @@ class RepeatableGroupWidgetComponent {
|
|
|
36326
36578
|
return this.engine ? this.engine.isFieldVisible(this.config.id) : true;
|
|
36327
36579
|
}
|
|
36328
36580
|
get enabled() {
|
|
36329
|
-
if (this.config
|
|
36581
|
+
if (isFieldDisabled(this.config))
|
|
36330
36582
|
return false;
|
|
36331
36583
|
return this.engine ? this.engine.isFieldEnabled(this.config.id) : true;
|
|
36332
36584
|
}
|
|
@@ -37660,6 +37912,10 @@ function generateId$2() {
|
|
|
37660
37912
|
const COMMON_GROUP_FIELDS = [
|
|
37661
37913
|
{ key: 'groupKey', type: 'text', label: 'Group Key', placeholder: 'documents', helpText: 'Group fields into one object on submit/preview (uses the field key inside the group).' }
|
|
37662
37914
|
];
|
|
37915
|
+
const COMMON_INTERACTIVITY_FIELDS = [
|
|
37916
|
+
{ key: 'html5.readonly', type: 'checkbox', label: 'Read Only' },
|
|
37917
|
+
{ key: 'html5.disabled', type: 'checkbox', label: 'Disabled' }
|
|
37918
|
+
];
|
|
37663
37919
|
const COMMON_BASIC_FIELDS = [
|
|
37664
37920
|
{ key: 'name', type: 'text', label: 'Field Key (Name)' },
|
|
37665
37921
|
{ key: 'label', type: 'text', label: 'Label' },
|
|
@@ -37667,6 +37923,7 @@ const COMMON_BASIC_FIELDS = [
|
|
|
37667
37923
|
{ key: 'placeholder', type: 'text', label: 'Placeholder' },
|
|
37668
37924
|
{ key: 'helpText', type: 'text', label: 'Help Text' }, // Hint
|
|
37669
37925
|
{ key: 'tooltip', type: 'text', label: 'Tooltip' },
|
|
37926
|
+
...COMMON_INTERACTIVITY_FIELDS,
|
|
37670
37927
|
...COMMON_GROUP_FIELDS
|
|
37671
37928
|
];
|
|
37672
37929
|
const FILE_BASIC_FIELDS = [
|
|
@@ -37675,6 +37932,7 @@ const FILE_BASIC_FIELDS = [
|
|
|
37675
37932
|
{ key: 'showLabel', type: 'checkbox', label: 'Show Native Label' },
|
|
37676
37933
|
{ key: 'helpText', type: 'text', label: 'Help Text' },
|
|
37677
37934
|
{ key: 'tooltip', type: 'text', label: 'Tooltip' },
|
|
37935
|
+
...COMMON_INTERACTIVITY_FIELDS,
|
|
37678
37936
|
...COMMON_GROUP_FIELDS
|
|
37679
37937
|
];
|
|
37680
37938
|
const COMMON_APPEARANCE_FIELDS = [
|
|
@@ -37699,9 +37957,7 @@ const COMMON_APPEARANCE_FIELDS = [
|
|
|
37699
37957
|
{ label: 'Third Width (33%)', value: '33.33%' },
|
|
37700
37958
|
{ label: 'Quarter Width (25%)', value: '25%' }
|
|
37701
37959
|
]
|
|
37702
|
-
}
|
|
37703
|
-
{ key: 'readonly', type: 'checkbox', label: 'Read Only' },
|
|
37704
|
-
{ key: 'disabled', type: 'checkbox', label: 'Disabled' }
|
|
37960
|
+
}
|
|
37705
37961
|
];
|
|
37706
37962
|
const COMMON_STYLE_SECTIONS = [
|
|
37707
37963
|
STYLE_LAYOUT_SECTION,
|
|
@@ -37718,16 +37974,10 @@ const BASE_REQUIRED_FIELD = {
|
|
|
37718
37974
|
label: 'Required',
|
|
37719
37975
|
helpText: 'Base required state; Rules can override this dynamically.'
|
|
37720
37976
|
};
|
|
37721
|
-
const CUSTOM_VALIDATION_RULES_FIELD = {
|
|
37722
|
-
key: 'validation',
|
|
37723
|
-
type: 'validators-editor',
|
|
37724
|
-
label: 'Custom Validation Rules',
|
|
37725
|
-
helpText: 'Use these for field-level validation checks. Use the Rules tab for conditional behaviour.'
|
|
37726
|
-
};
|
|
37727
37977
|
function createValidationSection(...fields) {
|
|
37728
37978
|
return {
|
|
37729
37979
|
label: 'Validation',
|
|
37730
|
-
fields
|
|
37980
|
+
fields
|
|
37731
37981
|
};
|
|
37732
37982
|
}
|
|
37733
37983
|
const TEXT_VALIDATION_SECTION = createValidationSection(BASE_REQUIRED_FIELD, { key: 'html5.minLength', type: 'number', label: 'Min Length' }, { key: 'html5.maxLength', type: 'number', label: 'Max Length' }, { key: 'html5.pattern', type: 'text', label: 'Pattern (regex)' });
|
|
@@ -37737,6 +37987,28 @@ const TIME_VALIDATION_SECTION = createValidationSection(BASE_REQUIRED_FIELD, { k
|
|
|
37737
37987
|
const DATETIME_VALIDATION_SECTION = createValidationSection(BASE_REQUIRED_FIELD, { key: 'html5.min', type: 'text', label: 'Earliest (YYYY-MM-DDTHH:MM)' }, { key: 'html5.max', type: 'text', label: 'Latest (YYYY-MM-DDTHH:MM)' });
|
|
37738
37988
|
const SELECT_VALIDATION_SECTION = createValidationSection(BASE_REQUIRED_FIELD);
|
|
37739
37989
|
const FILE_VALIDATION_SECTION = createValidationSection(BASE_REQUIRED_FIELD);
|
|
37990
|
+
const NUMBER_DISPLAY_SECTION = {
|
|
37991
|
+
label: 'Display',
|
|
37992
|
+
fields: [
|
|
37993
|
+
{
|
|
37994
|
+
key: 'useThousandSeparator',
|
|
37995
|
+
type: 'checkbox',
|
|
37996
|
+
label: 'Show thousand separators',
|
|
37997
|
+
helpText: 'Formats grouped digits in the visible field value without changing the stored number.'
|
|
37998
|
+
}
|
|
37999
|
+
]
|
|
38000
|
+
};
|
|
38001
|
+
const SELECT_DISPLAY_SECTION = {
|
|
38002
|
+
label: 'Display',
|
|
38003
|
+
fields: [
|
|
38004
|
+
{
|
|
38005
|
+
key: 'useThousandSeparator',
|
|
38006
|
+
type: 'checkbox',
|
|
38007
|
+
label: 'Show thousand separators for numeric labels',
|
|
38008
|
+
helpText: 'Formats numeric option labels without changing the stored option value.'
|
|
38009
|
+
}
|
|
38010
|
+
]
|
|
38011
|
+
};
|
|
37740
38012
|
const BUTTON_VARIANT_OPTIONS = [
|
|
37741
38013
|
{ label: 'Primary (Blue)', value: 'primary' },
|
|
37742
38014
|
{ label: 'Secondary (Outline)', value: 'secondary' }
|
|
@@ -37752,6 +38024,7 @@ const BUTTON_PROPERTIES = [
|
|
|
37752
38024
|
label: 'Style',
|
|
37753
38025
|
fields: [
|
|
37754
38026
|
{ key: 'variant', type: 'select', label: 'Variant', options: BUTTON_VARIANT_OPTIONS },
|
|
38027
|
+
...COMMON_INTERACTIVITY_FIELDS,
|
|
37755
38028
|
...COMMON_APPEARANCE_FIELDS
|
|
37756
38029
|
]
|
|
37757
38030
|
},
|
|
@@ -37770,6 +38043,7 @@ const IMAGE_BUTTON_PROPERTIES = [
|
|
|
37770
38043
|
label: 'Style',
|
|
37771
38044
|
fields: [
|
|
37772
38045
|
{ key: 'variant', type: 'select', label: 'Variant', options: BUTTON_VARIANT_OPTIONS },
|
|
38046
|
+
...COMMON_INTERACTIVITY_FIELDS,
|
|
37773
38047
|
...COMMON_APPEARANCE_FIELDS
|
|
37774
38048
|
]
|
|
37775
38049
|
},
|
|
@@ -37819,6 +38093,7 @@ const REPEATABLE_WIDGET_PROPERTIES = [
|
|
|
37819
38093
|
{ key: 'showLabel', type: 'checkbox', label: 'Show Native Label' },
|
|
37820
38094
|
{ key: 'helpText', type: 'text', label: 'Help Text' },
|
|
37821
38095
|
{ key: 'tooltip', type: 'text', label: 'Tooltip' },
|
|
38096
|
+
...COMMON_INTERACTIVITY_FIELDS,
|
|
37822
38097
|
...COMMON_GROUP_FIELDS
|
|
37823
38098
|
]
|
|
37824
38099
|
},
|
|
@@ -37942,6 +38217,7 @@ const FIELD_WIDGETS = [
|
|
|
37942
38217
|
]
|
|
37943
38218
|
},
|
|
37944
38219
|
NUMBER_VALIDATION_SECTION,
|
|
38220
|
+
NUMBER_DISPLAY_SECTION,
|
|
37945
38221
|
{ label: 'Appearance', fields: COMMON_APPEARANCE_FIELDS },
|
|
37946
38222
|
...COMMON_STYLE_SECTIONS
|
|
37947
38223
|
]
|
|
@@ -38403,6 +38679,7 @@ const FIELD_WIDGETS = [
|
|
|
38403
38679
|
},
|
|
38404
38680
|
// Options are now handled in Data Tab
|
|
38405
38681
|
SELECT_VALIDATION_SECTION,
|
|
38682
|
+
SELECT_DISPLAY_SECTION,
|
|
38406
38683
|
{ label: 'Appearance', fields: COMMON_APPEARANCE_FIELDS },
|
|
38407
38684
|
...COMMON_STYLE_SECTIONS
|
|
38408
38685
|
]
|
|
@@ -41218,5 +41495,5 @@ function provideHttpDataSourceClient(config) {
|
|
|
41218
41495
|
* Generated bundle index. Do not edit.
|
|
41219
41496
|
*/
|
|
41220
41497
|
|
|
41221
|
-
export { APPEARANCE_FIELDS, AiToolRegistryService, CONTENT_TEXT_CLASS, CONTENT_TEXT_MUTED_CLASS, CORE_DESIGNER_PLUGINS, CURRENT_SCHEMA_VERSION, DATA_PROVIDER, DATA_SOURCE_CLIENT, DEFAULT_TEMPLATE_LIBRARY, DEFAULT_WEBSITE_SECTIONS, DEFAULT_WIDGET_PACKS, DESIGNER_PLUGINS, DESIGNER_SECTIONS, DataCatalog, DataPanelComponent, DataProvider, DefaultDataProvider, DefaultDataSourceClient, DefaultFileUploadClient, DesignerContext, DesignerStateService, DynamicPropertiesComponent, EFFECTS_FIELDS, EMAIL_SAFE_STYLE_SECTIONS, EMAIL_WIDGETS, EmailRendererComponent, EventsPanelComponent, EventsWorkspaceComponent, FIELD_CHOICE_LABEL_CLASS, FIELD_CHOICE_SURFACE_CLASS, FIELD_CONTAINER_CLASS, FIELD_ERROR_CLASS, FIELD_HELP_CLASS, FIELD_LABEL_CLASS, FIELD_OPTION_CLASS, FIELD_REQUIRED_CLASS, FIELD_RESULTS_PANEL_CLASS, FIELD_WIDGETS, FILE_UPLOAD_CARD_CLASS, FILE_UPLOAD_CLIENT, FORM_DESIGNER_AI_TOOL_PLUGIN, FULL_WEB_STYLE_SECTIONS, FieldPaletteComponent, FormDesignerAiFeatureStateService, FormDesignerShellComponent, FormEngine, FormJourneyStateService, FormJourneyViewerComponent, FormViewerComponent, GlobalDataManagerComponent, HTTP_DATA_SOURCE_CLIENT_CONFIG, HttpDataSourceClient, InMemoryDataCatalogService, InspectorAdvancedSectionComponent, InspectorBackgroundsSectionComponent, InspectorBordersSectionComponent, InspectorEffectsSectionComponent, InspectorLayoutSectionComponent, InspectorPositionSectionComponent, InspectorSizeSectionComponent, InspectorSpacingSectionComponent, InspectorSpinInputComponent, InspectorTypographySectionComponent, JsonFormDesignerComponent, JsonFormRendererComponent, LAYOUT_FIELDS, LayoutCanvasComponent, LayoutNodeComponent, OUTLINED_FIELD_BORDER_WIDTH, OUTLINED_FIELD_IDLE_BORDER_COLOR, OUTLINED_FIELD_INTERACTIVE_BORDER_COLOR, OUTLINED_FIELD_INVALID_BORDER_COLOR, PAGE_WIDGETS, PropertiesPanelComponent, RulesPanelComponent, RuntimeFieldDataAccessRegistryService, SELECT_THEME_HOOKS, SELECT_THEME_TOKENS, SPACING_BOX_MODEL_FIELD, SPACING_MARGIN_FIELDS, SPACING_PADDING_FIELDS, STANDARD_FORM_STYLE_SECTIONS, STYLE_APPEARANCE_SECTION, STYLE_EFFECTS_SECTION, STYLE_LAYOUT_SECTION, STYLE_SECTIONS, STYLE_SPACING_SECTION, STYLE_TRANSFORM_SECTION, STYLE_TYPOGRAPHY_SECTION, TABLE_CELL_CLASS, TABLE_EMPTY_CLASS, TABLE_GRID_CLASS, TABLE_HEAD_CELL_CLASS, TABLE_HEAD_CLASS, TABLE_ICON_BUTTON_CLASS, TABLE_ROOT_CLASS, TABLE_ROW_CLASS, TABLE_TOOLBAR_CLASS, TRANSFORM_FIELDS, TYPOGRAPHY_FIELDS, ThemeService, UiAccordionComponent, UiBoxModelComponent, UiColorSwatchComponent, UiDimensionComponent, UiEdgeBoxComponent, UiFieldWrapperComponent, UiInputComponent, UiRangeNumberComponent, UiSelectIconComponent, UiTabComponent, UiTabsComponent, WIDGET_DEFINITIONS, WIDGET_ID_SEPARATOR, WebsiteBrickStudioComponent, WebsiteDesignerShellComponent, WebsitePreviewShellComponent, WebsiteProjectService, WidgetDefinitionResolverService, WidgetInspectorComponent, appendSectionToSchema, buildWidgetId, checkSchemaForApiOnlySources, createDefaultWebsiteBrick, createDefaultWebsiteBricks, createDefaultWebsiteTheme, createEmptySchema, createFormEngine, createFormJourneyPage, createFormJourneyProject, createPluginContext, createWebsiteBrick, createWebsitePage, createWebsiteProject, defineWidget, flattenPluginWidgets, getButtonClass, getChoiceControlClass, getEffectiveDataConfig, getFileInputClass, getFileUploadShellClass, getHeadingClass, getOutlinedFieldInlineStyle, getTextControlClass, getWidgetsForFlavor, hasWrapperSurfaceStyles, inferSchema, isFormJourneyProject, isWidgetVisibleInPalette, mergeAndNormalize, normalizeRuntimeOptions, normalizeStyle$1 as normalizeStyle, normalizeToJourney, parseCsv, parseJsonArray, parseSchema, provideDesignerPlugins, provideFormDesignerAngaiFeature, provideHttpDataSourceClient, serializeSchema, slugifyId, splitControlSurfaceStyles, stripEmbeddedSourceData, unwrapSinglePageJourney };
|
|
41498
|
+
export { APPEARANCE_FIELDS, AiToolRegistryService, CONTENT_TEXT_CLASS, CONTENT_TEXT_MUTED_CLASS, CORE_DESIGNER_PLUGINS, CURRENT_SCHEMA_VERSION, DATA_PROVIDER, DATA_SOURCE_CLIENT, DEFAULT_TEMPLATE_LIBRARY, DEFAULT_WEBSITE_SECTIONS, DEFAULT_WIDGET_PACKS, DESIGNER_PLUGINS, DESIGNER_SECTIONS, DataCatalog, DataPanelComponent, DataProvider, DefaultDataProvider, DefaultDataSourceClient, DefaultFileUploadClient, DesignerContext, DesignerStateService, DynamicPropertiesComponent, EFFECTS_FIELDS, EMAIL_SAFE_STYLE_SECTIONS, EMAIL_WIDGETS, EmailRendererComponent, EventsPanelComponent, EventsWorkspaceComponent, FIELD_CHOICE_LABEL_CLASS, FIELD_CHOICE_SURFACE_CLASS, FIELD_CONTAINER_CLASS, FIELD_ERROR_CLASS, FIELD_HELP_CLASS, FIELD_LABEL_CLASS, FIELD_OPTION_CLASS, FIELD_REQUIRED_CLASS, FIELD_RESULTS_PANEL_CLASS, FIELD_WIDGETS, FILE_UPLOAD_CARD_CLASS, FILE_UPLOAD_CLIENT, FORM_DESIGNER_AI_TOOL_PLUGIN, FULL_WEB_STYLE_SECTIONS, FieldPaletteComponent, FormDesignerAiFeatureStateService, FormDesignerShellComponent, FormEngine, FormJourneyStateService, FormJourneyViewerComponent, FormViewerComponent, GlobalDataManagerComponent, HTTP_DATA_SOURCE_CLIENT_CONFIG, HttpDataSourceClient, InMemoryDataCatalogService, InspectorAdvancedSectionComponent, InspectorBackgroundsSectionComponent, InspectorBordersSectionComponent, InspectorEffectsSectionComponent, InspectorLayoutSectionComponent, InspectorPositionSectionComponent, InspectorSizeSectionComponent, InspectorSpacingSectionComponent, InspectorSpinInputComponent, InspectorTypographySectionComponent, JsonFormDesignerComponent, JsonFormRendererComponent, LAYOUT_FIELDS, LayoutCanvasComponent, LayoutNodeComponent, OUTLINED_FIELD_BORDER_WIDTH, OUTLINED_FIELD_IDLE_BORDER_COLOR, OUTLINED_FIELD_INTERACTIVE_BORDER_COLOR, OUTLINED_FIELD_INVALID_BORDER_COLOR, PAGE_WIDGETS, PropertiesPanelComponent, RulesPanelComponent, RuntimeFieldDataAccessRegistryService, SELECT_THEME_HOOKS, SELECT_THEME_TOKENS, SPACING_BOX_MODEL_FIELD, SPACING_MARGIN_FIELDS, SPACING_PADDING_FIELDS, STANDARD_FORM_STYLE_SECTIONS, STYLE_APPEARANCE_SECTION, STYLE_EFFECTS_SECTION, STYLE_LAYOUT_SECTION, STYLE_SECTIONS, STYLE_SPACING_SECTION, STYLE_TRANSFORM_SECTION, STYLE_TYPOGRAPHY_SECTION, TABLE_CELL_CLASS, TABLE_EMPTY_CLASS, TABLE_GRID_CLASS, TABLE_HEAD_CELL_CLASS, TABLE_HEAD_CLASS, TABLE_ICON_BUTTON_CLASS, TABLE_ROOT_CLASS, TABLE_ROW_CLASS, TABLE_TOOLBAR_CLASS, TRANSFORM_FIELDS, TYPOGRAPHY_FIELDS, ThemeService, UiAccordionComponent, UiBoxModelComponent, UiColorSwatchComponent, UiDimensionComponent, UiEdgeBoxComponent, UiFieldWrapperComponent, UiInputComponent, UiRangeNumberComponent, UiSelectIconComponent, UiTabComponent, UiTabsComponent, WIDGET_DEFINITIONS, WIDGET_ID_SEPARATOR, WebsiteBrickStudioComponent, WebsiteDesignerShellComponent, WebsitePreviewShellComponent, WebsiteProjectService, WidgetDefinitionResolverService, WidgetInspectorComponent, appendSectionToSchema, buildWidgetId, checkSchemaForApiOnlySources, createDefaultWebsiteBrick, createDefaultWebsiteBricks, createDefaultWebsiteTheme, createEmptySchema, createFormEngine, createFormJourneyPage, createFormJourneyProject, createPluginContext, createWebsiteBrick, createWebsitePage, createWebsiteProject, defineWidget, flattenPluginWidgets, getButtonClass, getChoiceControlClass, getEffectiveDataConfig, getFileInputClass, getFileUploadShellClass, getHeadingClass, getOutlinedFieldInlineStyle, getTextControlClass, getWidgetsForFlavor, hasWrapperSurfaceStyles, inferSchema, isFieldDisabled, isFieldReadonly, isFormJourneyProject, isWidgetVisibleInPalette, mergeAndNormalize, normalizeRuntimeOptions, normalizeStyle$1 as normalizeStyle, normalizeToJourney, parseCsv, parseJsonArray, parseSchema, provideDesignerPlugins, provideFormDesignerAngaiFeature, provideHttpDataSourceClient, serializeSchema, slugifyId, splitControlSurfaceStyles, stripEmbeddedSourceData, unwrapSinglePageJourney, usesFieldThousandSeparator };
|
|
41222
41499
|
//# sourceMappingURL=uch-web-ngx-form-designer.mjs.map
|