@xlabs-store/core 0.0.2 → 0.0.3
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/components/index.js +1 -1
- package/components/p-CQ2VND9-.js +1 -0
- package/components/p-CQQI-pRu.js +1 -0
- package/components/p-CkwLFDlS.js +1 -0
- package/components/p-CzHtwC1k.js +1 -0
- package/components/{p-BlvrLhyv.js → p-DqayamUz.js} +1 -1
- package/components/x-form-builder.js +1 -1
- package/components/x-icon-picker-dropdown-content.js +1 -1
- package/components/x-input-icon.js +1 -1
- package/components/x-login.js +1 -1
- package/components/x-table.js +1 -1
- package/dist/cjs/icons-BfHE2jcr.js +19261 -0
- package/dist/cjs/index.cjs.js +2 -2
- package/dist/cjs/{schema-builder-BKX4QdTc.js → schema-builder-DAwDwgIM.js} +98 -14
- package/dist/cjs/x-address_51.cjs.entry.js +115 -11
- package/dist/cjs/x-icon-picker-dropdown-content.cjs.entry.js +1 -1
- package/dist/collection/components/x-form-builder/services/schema/condition-builder.js +48 -6
- package/dist/collection/components/x-form-builder/services/schema/form-mapping.js +2 -2
- package/dist/collection/components/x-form-builder/utils/condition-engine.js +48 -6
- package/dist/collection/components/x-form-builder/x-form-builder.js +96 -6
- package/dist/collection/components/x-icon/icons.js +11462 -11492
- package/dist/collection/components/x-table/x-table.js +18 -4
- package/dist/esm/icons-CQ2VND9-.js +19259 -0
- package/dist/esm/index.js +2 -2
- package/dist/esm/{schema-builder-DlGEzg5B.js → schema-builder-CekbhOnD.js} +98 -14
- package/dist/esm/x-address_51.entry.js +115 -11
- package/dist/esm/x-icon-picker-dropdown-content.entry.js +1 -1
- package/dist/types/components/x-form-builder/types/common/field-types-enum.d.ts +1 -1
- package/dist/types/components/x-form-builder/types/fields/advanced-fields.d.ts +1 -0
- package/dist/types/components/x-form-builder/types/fields/form-field-union.d.ts +2 -2
- package/dist/types/components/x-form-builder/types/fields/layout-fields.d.ts +10 -1
- package/dist/types/components/x-form-builder/types/fields/special-input-fields.d.ts +3 -0
- package/dist/types/components/x-form-builder/x-form-builder.d.ts +2 -0
- package/dist/xlabs/index.esm.js +1 -1
- package/dist/xlabs/{p-45fda37b.entry.js → p-99c568fd.entry.js} +1 -1
- package/dist/xlabs/p-CQ2VND9-.js +1 -0
- package/dist/xlabs/p-CkwLFDlS.js +1 -0
- package/dist/xlabs/p-a4995e36.entry.js +1 -0
- package/dist/xlabs/xlabs.esm.js +1 -1
- package/package.json +1 -1
- package/components/p-BGNOiTqa.js +0 -1
- package/components/p-BgCjF74f.js +0 -1
- package/components/p-xf66Fag-.js +0 -1
- package/components/p-xzKm-BQN.js +0 -1
- package/dist/cjs/icons-DJ-kuboh.js +0 -19291
- package/dist/esm/icons-BgCjF74f.js +0 -19289
- package/dist/xlabs/p-239cf367.entry.js +0 -1
- package/dist/xlabs/p-BgCjF74f.js +0 -1
- package/dist/xlabs/p-xf66Fag-.js +0 -1
|
@@ -51,12 +51,26 @@ export function evaluateCondition(condition, formValues, context) {
|
|
|
51
51
|
const result = (() => {
|
|
52
52
|
switch (operator) {
|
|
53
53
|
case 'equals':
|
|
54
|
+
if ((typeof actualValue === 'string' && typeof expectedValue === 'number') ||
|
|
55
|
+
(typeof actualValue === 'number' && typeof expectedValue === 'string')) {
|
|
56
|
+
return String(actualValue) === String(expectedValue);
|
|
57
|
+
}
|
|
54
58
|
return actualValue === expectedValue;
|
|
55
59
|
case 'notEquals':
|
|
60
|
+
if ((typeof actualValue === 'string' && typeof expectedValue === 'number') ||
|
|
61
|
+
(typeof actualValue === 'number' && typeof expectedValue === 'string')) {
|
|
62
|
+
return String(actualValue) !== String(expectedValue);
|
|
63
|
+
}
|
|
56
64
|
return actualValue !== expectedValue;
|
|
57
65
|
case 'contains':
|
|
58
66
|
if (Array.isArray(actualValue)) {
|
|
59
|
-
return actualValue.
|
|
67
|
+
return actualValue.some(item => {
|
|
68
|
+
if ((typeof item === 'string' && typeof expectedValue === 'number') ||
|
|
69
|
+
(typeof item === 'number' && typeof expectedValue === 'string')) {
|
|
70
|
+
return String(item) === String(expectedValue);
|
|
71
|
+
}
|
|
72
|
+
return item === expectedValue;
|
|
73
|
+
});
|
|
60
74
|
}
|
|
61
75
|
if (typeof actualValue === 'string') {
|
|
62
76
|
return actualValue.includes(String(expectedValue));
|
|
@@ -64,7 +78,13 @@ export function evaluateCondition(condition, formValues, context) {
|
|
|
64
78
|
return false;
|
|
65
79
|
case 'notContains':
|
|
66
80
|
if (Array.isArray(actualValue)) {
|
|
67
|
-
return !actualValue.
|
|
81
|
+
return !actualValue.some(item => {
|
|
82
|
+
if ((typeof item === 'string' && typeof expectedValue === 'number') ||
|
|
83
|
+
(typeof item === 'number' && typeof expectedValue === 'string')) {
|
|
84
|
+
return String(item) === String(expectedValue);
|
|
85
|
+
}
|
|
86
|
+
return item === expectedValue;
|
|
87
|
+
});
|
|
68
88
|
}
|
|
69
89
|
if (typeof actualValue === 'string') {
|
|
70
90
|
return !actualValue.includes(String(expectedValue));
|
|
@@ -90,24 +110,46 @@ export function evaluateCondition(condition, formValues, context) {
|
|
|
90
110
|
return String(actualValue).endsWith(String(expectedValue));
|
|
91
111
|
case 'in':
|
|
92
112
|
if (Array.isArray(expectedValue)) {
|
|
93
|
-
return expectedValue.
|
|
113
|
+
return expectedValue.some(item => {
|
|
114
|
+
if ((typeof item === 'string' && typeof actualValue === 'number') ||
|
|
115
|
+
(typeof item === 'number' && typeof actualValue === 'string')) {
|
|
116
|
+
return String(item) === String(actualValue);
|
|
117
|
+
}
|
|
118
|
+
return item === actualValue;
|
|
119
|
+
});
|
|
94
120
|
}
|
|
95
121
|
if (typeof expectedValue === 'string') {
|
|
96
122
|
return expectedValue
|
|
97
123
|
.split(',')
|
|
98
124
|
.map(v => v.trim())
|
|
99
|
-
.
|
|
125
|
+
.some(item => {
|
|
126
|
+
if (typeof actualValue === 'number') {
|
|
127
|
+
return item === String(actualValue);
|
|
128
|
+
}
|
|
129
|
+
return item === actualValue;
|
|
130
|
+
});
|
|
100
131
|
}
|
|
101
132
|
return false;
|
|
102
133
|
case 'notIn':
|
|
103
134
|
if (Array.isArray(expectedValue)) {
|
|
104
|
-
return !expectedValue.
|
|
135
|
+
return !expectedValue.some(item => {
|
|
136
|
+
if ((typeof item === 'string' && typeof actualValue === 'number') ||
|
|
137
|
+
(typeof item === 'number' && typeof actualValue === 'string')) {
|
|
138
|
+
return String(item) === String(actualValue);
|
|
139
|
+
}
|
|
140
|
+
return item === actualValue;
|
|
141
|
+
});
|
|
105
142
|
}
|
|
106
143
|
if (typeof expectedValue === 'string') {
|
|
107
144
|
return !expectedValue
|
|
108
145
|
.split(',')
|
|
109
146
|
.map(v => v.trim())
|
|
110
|
-
.
|
|
147
|
+
.some(item => {
|
|
148
|
+
if (typeof actualValue === 'number') {
|
|
149
|
+
return item === String(actualValue);
|
|
150
|
+
}
|
|
151
|
+
return item === actualValue;
|
|
152
|
+
});
|
|
111
153
|
}
|
|
112
154
|
return true;
|
|
113
155
|
default:
|
|
@@ -191,6 +191,15 @@ export class XFormBuilder {
|
|
|
191
191
|
gridTemplateColumns: `repeat(${field.columns || 12}, minmax(0, 1fr))`,
|
|
192
192
|
gap: `${field.gap || 15}px`,
|
|
193
193
|
} }, 'elements' in field && field.elements ? this.bind(field.elements, field) : null));
|
|
194
|
+
const ColumnsCallback = (field) => {
|
|
195
|
+
const items = field.items || [];
|
|
196
|
+
return (h("div", { style: {
|
|
197
|
+
display: 'grid',
|
|
198
|
+
gridTemplateColumns: `repeat(12, minmax(0, 1fr))`,
|
|
199
|
+
gap: `${field.gap || 15}px`,
|
|
200
|
+
width: '100%',
|
|
201
|
+
} }, items.map((item) => (h("div", { style: { gridColumn: `span ${item.span || 12}` }, key: item.key }, item.elements ? this.bind(item.elements, field) : null)))));
|
|
202
|
+
};
|
|
194
203
|
const MapsCallback = (field) => {
|
|
195
204
|
const width = field.width || '100%';
|
|
196
205
|
const height = field.height || 400;
|
|
@@ -455,7 +464,16 @@ export class XFormBuilder {
|
|
|
455
464
|
dataIndex: col.dataIndex || col.key,
|
|
456
465
|
slot: col.actions ? col.slot || col.key || 'action' : col.slot,
|
|
457
466
|
}));
|
|
458
|
-
|
|
467
|
+
const controlVal = field.control?.value;
|
|
468
|
+
const isValArrayOfObjects = Array.isArray(controlVal) && controlVal.length > 0 && typeof controlVal[0] === 'object';
|
|
469
|
+
const dataSource = isValArrayOfObjects ? controlVal : (f.dataSource || []);
|
|
470
|
+
const rowSelection = f.rowSelection
|
|
471
|
+
? {
|
|
472
|
+
...f.rowSelection,
|
|
473
|
+
selectedRowKeys: Array.isArray(controlVal) && !isValArrayOfObjects ? controlVal : [],
|
|
474
|
+
}
|
|
475
|
+
: undefined;
|
|
476
|
+
return (h("x-table", { ...commonProps, columns: columns, dataSource: dataSource, rowKey: f.rowKey || 'id', tableTitle: f.tableTitle, pagination: f.pagination, tableScroll: f.tableScroll, rowSelection: rowSelection, size: f.size, bordered: f.bordered, loading: f.loading, showHeader: f.showHeader, emptyText: f.emptyText, resizableColumns: f.resizableColumns, draggableColumns: f.draggableColumns, draggableRows: f.draggableRows, sticky: f.sticky, onXSelectionChange: ev => {
|
|
459
477
|
if (f.rowSelection) {
|
|
460
478
|
onChange(ev.detail.selectedRowKeys);
|
|
461
479
|
}
|
|
@@ -463,7 +481,7 @@ export class XFormBuilder {
|
|
|
463
481
|
console.log('x-form-builder: Table changed:', ev.detail);
|
|
464
482
|
} }, columns
|
|
465
483
|
.filter(col => col.actions)
|
|
466
|
-
.map(col => (
|
|
484
|
+
.map(col => (dataSource || []).map((record, index) => (h("div", { slot: `${col.slot}-${index}`, style: { display: 'flex', gap: '8px' } }, (col.actions || []).map(action => {
|
|
467
485
|
const button = (h("x-button", { type: action.type === 'button' ? 'primary' : 'link', size: "small", danger: action.danger, onClick: e => {
|
|
468
486
|
e.stopPropagation();
|
|
469
487
|
this.xTableAction.emit({
|
|
@@ -517,6 +535,29 @@ export class XFormBuilder {
|
|
|
517
535
|
}
|
|
518
536
|
return (h("x-tabs", { activeKey: activeKey, tabPlacement: f.tabPlacement || 'top', type: tabsType, editable: allowRename, hideAdd: !allowAdd, onXTabRename: onRename, onXEdit: onEdit }, items.map(item => (h("x-tab-pane", { key: item.key, paneKey: item.key, tab: item.label, disabled: item.disabled, icon: item.icon, closable: allowRemove && item.closable !== false }, this.bind(item.elements, field))))));
|
|
519
537
|
};
|
|
538
|
+
const DynamicCallback = (field) => {
|
|
539
|
+
const slotName = field.meta?.slot || field.metadata?.slot || field.name;
|
|
540
|
+
return (h("div", { class: "x-dynamic-field-container", ...{
|
|
541
|
+
onXChange: (e) => {
|
|
542
|
+
if (field.control && e.detail && 'value' in e.detail) {
|
|
543
|
+
field.control.setValue(e.detail.value, { emitEvent: false });
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
} }, h("slot", { name: slotName }, h("div", { style: {
|
|
547
|
+
height: '300px',
|
|
548
|
+
width: '100%',
|
|
549
|
+
border: '1px dashed #d1d5db',
|
|
550
|
+
borderRadius: '8px',
|
|
551
|
+
backgroundColor: '#f9fafb',
|
|
552
|
+
display: 'flex',
|
|
553
|
+
flexDirection: 'column',
|
|
554
|
+
alignItems: 'center',
|
|
555
|
+
justifyContent: 'center',
|
|
556
|
+
color: '#9ca3af',
|
|
557
|
+
fontSize: '13px',
|
|
558
|
+
gap: '8px'
|
|
559
|
+
} }, h("span", { style: { fontSize: '24px' } }, "\uD83E\uDDE9"), h("span", null, "Dynamic slot \"", slotName, "\" is empty or not configured")))));
|
|
560
|
+
};
|
|
520
561
|
return {
|
|
521
562
|
'text': InputCallback,
|
|
522
563
|
'input': InputCallback,
|
|
@@ -556,6 +597,9 @@ export class XFormBuilder {
|
|
|
556
597
|
'button': ButtonCallback,
|
|
557
598
|
'href': HrefCallback,
|
|
558
599
|
'grid': GridCallback,
|
|
600
|
+
'columns': ColumnsCallback,
|
|
601
|
+
'columns-3': ColumnsCallback,
|
|
602
|
+
'columns-4': ColumnsCallback,
|
|
559
603
|
'table': TableCallback,
|
|
560
604
|
'maps': MapsCallback,
|
|
561
605
|
'panel': PanelCallback,
|
|
@@ -564,9 +608,50 @@ export class XFormBuilder {
|
|
|
564
608
|
'qr-code': QRCodeCallback,
|
|
565
609
|
'tabs': TabsCallback,
|
|
566
610
|
'range-picker': DateRangeCallback,
|
|
611
|
+
'dynamic': DynamicCallback,
|
|
567
612
|
};
|
|
568
613
|
}
|
|
569
614
|
async submit(event, field) {
|
|
615
|
+
// Gather values from dynamic slots first
|
|
616
|
+
let dynamicValues = {};
|
|
617
|
+
let allDynamicValid = true;
|
|
618
|
+
let dynamicErrors = {};
|
|
619
|
+
if (this.builder && this.builder.form) {
|
|
620
|
+
const dynamicFields = Array.from(this.builder.form.mapping.values()).filter(f => f.type === 'dynamic');
|
|
621
|
+
for (const dField of dynamicFields) {
|
|
622
|
+
const slotName = dField.meta?.slot || dField.metadata?.slot || dField.name;
|
|
623
|
+
// Search for slotted elements in light DOM (children of this.el)
|
|
624
|
+
const slottedElement = Array.from(this.el.children).find(child => child.getAttribute('slot') === slotName);
|
|
625
|
+
if (slottedElement) {
|
|
626
|
+
let val = slottedElement.value;
|
|
627
|
+
if (val === undefined && dField.control) {
|
|
628
|
+
val = dField.control.value;
|
|
629
|
+
}
|
|
630
|
+
// Update internal control so built-in validators (like required) pass
|
|
631
|
+
if (dField.control && val !== undefined) {
|
|
632
|
+
dField.control.setValue(val, { emitEvent: false });
|
|
633
|
+
}
|
|
634
|
+
// Check if it has a validate method
|
|
635
|
+
if (typeof slottedElement.validate === 'function') {
|
|
636
|
+
const res = await slottedElement.validate(val);
|
|
637
|
+
if (res) {
|
|
638
|
+
allDynamicValid = false;
|
|
639
|
+
dynamicErrors[dField.name] = res;
|
|
640
|
+
slottedElement.validationState = {
|
|
641
|
+
status: 'invalid',
|
|
642
|
+
errorMessage: typeof res === 'object' ? Object.values(res)[0] : 'Invalid',
|
|
643
|
+
errors: res
|
|
644
|
+
};
|
|
645
|
+
}
|
|
646
|
+
else {
|
|
647
|
+
slottedElement.validationState = { status: 'valid', errors: null, errorMessage: '' };
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
// Merge value
|
|
651
|
+
dynamicValues[dField.name] = val;
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
}
|
|
570
655
|
// Validate all mapped controls (both sync and async) first to ensure errors are updated
|
|
571
656
|
if (this.builder && this.builder.form) {
|
|
572
657
|
for (const [_key, fld] of Array.from(this.builder.form.mapping.entries())) {
|
|
@@ -591,9 +676,9 @@ export class XFormBuilder {
|
|
|
591
676
|
}
|
|
592
677
|
}
|
|
593
678
|
}
|
|
594
|
-
if (this.builder.form.valid && allCaptchaValid) {
|
|
679
|
+
if (this.builder.form.valid && allCaptchaValid && allDynamicValid) {
|
|
595
680
|
this.formSubmit.emit({
|
|
596
|
-
value: this.builder.form.value,
|
|
681
|
+
value: { ...this.builder.form.value, ...dynamicValues },
|
|
597
682
|
builder: this.builder,
|
|
598
683
|
event: event,
|
|
599
684
|
field,
|
|
@@ -615,7 +700,7 @@ export class XFormBuilder {
|
|
|
615
700
|
this.formError.emit({
|
|
616
701
|
builder: this.builder,
|
|
617
702
|
event: event,
|
|
618
|
-
errors: this.builder.form.errors,
|
|
703
|
+
errors: { ...this.builder.form.errors, ...dynamicErrors },
|
|
619
704
|
});
|
|
620
705
|
}
|
|
621
706
|
}
|
|
@@ -678,7 +763,8 @@ export class XFormBuilder {
|
|
|
678
763
|
const control = field.control;
|
|
679
764
|
if (control && this.builder && control.touched) {
|
|
680
765
|
commonProps.status = undefined;
|
|
681
|
-
|
|
766
|
+
// Bỏ qua hiển thị lỗi nội bộ của x-form-builder cho các trường dynamic vì client tự quản lý
|
|
767
|
+
if (control.invalid && field.type !== 'dynamic') {
|
|
682
768
|
commonProps.status = 'error';
|
|
683
769
|
const errors = control.errors ?? {};
|
|
684
770
|
const messages = this.getMessageValidator(field, errors);
|
|
@@ -727,6 +813,10 @@ export class XFormBuilder {
|
|
|
727
813
|
componentWillLoad() {
|
|
728
814
|
this.asyncBuilderForm(true);
|
|
729
815
|
}
|
|
816
|
+
componentDidUpdate() {
|
|
817
|
+
}
|
|
818
|
+
disconnectedCallback() {
|
|
819
|
+
}
|
|
730
820
|
handleValueChange() {
|
|
731
821
|
if (this._isInternalChange)
|
|
732
822
|
return;
|