@unvired/turboforms-embed-sdk 2.0.60 → 2.0.61
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/dist/turboforms.esm.js +8 -8
- package/dist/turboforms.html +149 -41
- package/dist/turboforms.js +8 -8
- package/package.json +1 -1
package/dist/turboforms.html
CHANGED
|
@@ -7168,12 +7168,30 @@
|
|
|
7168
7168
|
min-width: 50px !important;
|
|
7169
7169
|
}
|
|
7170
7170
|
|
|
7171
|
-
/* 7b.
|
|
7172
|
-
.tf-embed-sdk .formio-component-datagrid .
|
|
7173
|
-
|
|
7174
|
-
|
|
7175
|
-
|
|
7176
|
-
|
|
7171
|
+
/* 7b. Hide inner component labels and control-label--hidden inside DataGrid table body cells */
|
|
7172
|
+
.tf-embed-sdk .formio-component-datagrid table tbody td label:not(.form-check-label):not(.custom-control-label),
|
|
7173
|
+
.tf-embed-sdk .formio-component-datagrid table tbody td .col-form-label,
|
|
7174
|
+
.tf-embed-sdk .formio-component-datagrid table tbody td .control-label--hidden,
|
|
7175
|
+
.tf-embed-sdk .formio-component-datagrid table tbody td [ref="label"],
|
|
7176
|
+
.tf-embed-sdk .formio-component-datagrid .formio-component-label-hidden label:not(.form-check-label):not(.custom-control-label),
|
|
7177
|
+
.tf-embed-sdk .formio-component-datagrid .formio-component-label-hidden .col-form-label,
|
|
7178
|
+
.tf-embed-sdk .formio-component-datagrid .formio-component-label-hidden .control-label--hidden {
|
|
7179
|
+
display: none !important;
|
|
7180
|
+
margin: 0 !important;
|
|
7181
|
+
padding: 0 !important;
|
|
7182
|
+
height: 0 !important;
|
|
7183
|
+
min-height: 0 !important;
|
|
7184
|
+
line-height: 0 !important;
|
|
7185
|
+
font-size: 0 !important;
|
|
7186
|
+
border: none !important;
|
|
7187
|
+
visibility: hidden !important;
|
|
7188
|
+
}
|
|
7189
|
+
|
|
7190
|
+
/* Remove component vertical margins inside DataGrid cells for tight layout */
|
|
7191
|
+
.tf-embed-sdk .formio-component-datagrid table tbody td .formio-form-group,
|
|
7192
|
+
.tf-embed-sdk .formio-component-datagrid table tbody td .formio-component {
|
|
7193
|
+
margin-top: 0 !important;
|
|
7194
|
+
margin-bottom: 0 !important;
|
|
7177
7195
|
}
|
|
7178
7196
|
|
|
7179
7197
|
/* 8. Responsive Table Equality and Rescue */
|
|
@@ -7193,17 +7211,6 @@
|
|
|
7193
7211
|
.tf-embed-sdk .table td .formio-component {
|
|
7194
7212
|
width: 100% !important;
|
|
7195
7213
|
max-width: 100% !important;
|
|
7196
|
-
}
|
|
7197
|
-
|
|
7198
|
-
/* Ensure labels inside table cells don't break the responsive horizontal layout */
|
|
7199
|
-
.tf-embed-sdk .table td label:not(.custom-control-label) {
|
|
7200
|
-
max-width: 100% !important;
|
|
7201
|
-
word-break: break-word !important;
|
|
7202
|
-
white-space: normal !important;
|
|
7203
|
-
line-height: 1.1 !important;
|
|
7204
|
-
font-size: 0.75rem !important;
|
|
7205
|
-
margin-bottom: 2px !important;
|
|
7206
|
-
display: block !important;
|
|
7207
7214
|
}</style>
|
|
7208
7215
|
<style>/* TABS RENDERER - UI NORMALIZATION */
|
|
7209
7216
|
|
|
@@ -32372,7 +32379,38 @@ class SmartSelectComponent extends SmartSelectField {
|
|
|
32372
32379
|
isEntireObjectDisplay() {
|
|
32373
32380
|
return this.component.dataSrc === 'resource' && this.valueProperty === 'data';
|
|
32374
32381
|
}
|
|
32382
|
+
findMasterdataItem(val) {
|
|
32383
|
+
if (!this.component.masterdata || val == null) return null;
|
|
32384
|
+
const valStr = String(val);
|
|
32385
|
+
const valProp = this.component.valueProperty || this.valueProperty;
|
|
32386
|
+
return this.component.masterdata.find(item => {
|
|
32387
|
+
if (!item || typeof item !== 'object') return false;
|
|
32388
|
+
if (valProp) {
|
|
32389
|
+
let pVal = _.get(item, valProp);
|
|
32390
|
+
if (pVal !== undefined && pVal !== null && String(pVal) === valStr) return true;
|
|
32391
|
+
if (valProp.startsWith('data.')) {
|
|
32392
|
+
pVal = _.get(item, valProp.replace(/^data\./, ''));
|
|
32393
|
+
if (pVal !== undefined && pVal !== null && String(pVal) === valStr) return true;
|
|
32394
|
+
}
|
|
32395
|
+
if (item[valProp] !== undefined && item[valProp] !== null && String(item[valProp]) === valStr) return true;
|
|
32396
|
+
}
|
|
32397
|
+
const raw = item.data || item;
|
|
32398
|
+
for (const k of Object.keys(raw)) {
|
|
32399
|
+
if (/id$/i.test(k) || k === 'value' || k === '_id' || k === 'id') {
|
|
32400
|
+
if (raw[k] !== undefined && raw[k] !== null && String(raw[k]) === valStr) {
|
|
32401
|
+
return true;
|
|
32402
|
+
}
|
|
32403
|
+
}
|
|
32404
|
+
}
|
|
32405
|
+
return false;
|
|
32406
|
+
});
|
|
32407
|
+
}
|
|
32408
|
+
|
|
32375
32409
|
selectValueAndLabel(data) {
|
|
32410
|
+
if ((typeof data === 'string' || typeof data === 'number') && this.component.dataSrc === 'masterdata' && this.component.masterdata) {
|
|
32411
|
+
const matched = this.findMasterdataItem(data);
|
|
32412
|
+
if (matched) data = matched;
|
|
32413
|
+
}
|
|
32376
32414
|
const value = this.getOptionValue((this.isEntireObjectDisplay() && !this.itemValue(data)) ? data : this.itemValue(data));
|
|
32377
32415
|
return {
|
|
32378
32416
|
value,
|
|
@@ -32385,8 +32423,13 @@ class SmartSelectComponent extends SmartSelectField {
|
|
|
32385
32423
|
return '';
|
|
32386
32424
|
}
|
|
32387
32425
|
|
|
32426
|
+
if ((typeof data === 'string' || typeof data === 'number') && this.component.dataSrc === 'masterdata' && this.component.masterdata) {
|
|
32427
|
+
const matched = this.findMasterdataItem(data);
|
|
32428
|
+
if (matched) data = matched;
|
|
32429
|
+
}
|
|
32430
|
+
|
|
32388
32431
|
// If they wish to show the value in read only mode, then just return the itemValue here.
|
|
32389
|
-
if (this.options.readOnly && this.component.readOnlyValue) {
|
|
32432
|
+
if (this.options.readOnly && this.component.readOnlyValue && !this.component.template && !this.component.labelProperty) {
|
|
32390
32433
|
return this.itemValue(data);
|
|
32391
32434
|
}
|
|
32392
32435
|
// Perform a fast interpretation if we should not use the template.
|
|
@@ -32435,7 +32478,7 @@ class SmartSelectComponent extends SmartSelectField {
|
|
|
32435
32478
|
}
|
|
32436
32479
|
|
|
32437
32480
|
let templateData = data;
|
|
32438
|
-
if (typeof data === 'object' &&
|
|
32481
|
+
if (typeof data === 'object' && data !== null && !data.data) {
|
|
32439
32482
|
templateData = Object.assign({ data: data }, data);
|
|
32440
32483
|
}
|
|
32441
32484
|
|
|
@@ -33085,11 +33128,8 @@ class SmartSelectComponent extends SmartSelectField {
|
|
|
33085
33128
|
case 'masterdata':
|
|
33086
33129
|
logger.info(`[TF_SDK:181] ✅ masterdata case for '${this.key}'. masterdata length:`, this.filteredMasterdata ? this.filteredMasterdata.length : 0);
|
|
33087
33130
|
let safeMasterData = this.filteredMasterdata || [];
|
|
33088
|
-
if (safeMasterData.length > 0
|
|
33089
|
-
|
|
33090
|
-
if (expectsData) {
|
|
33091
|
-
safeMasterData = safeMasterData.map(item => Object.assign({ data: item }, item));
|
|
33092
|
-
}
|
|
33131
|
+
if (safeMasterData.length > 0) {
|
|
33132
|
+
safeMasterData = safeMasterData.map(item => (item && typeof item === 'object' && !item.data) ? Object.assign({ data: item }, item) : item);
|
|
33093
33133
|
}
|
|
33094
33134
|
|
|
33095
33135
|
if (!this.isFromSearch && !this.isScrollLoading && !this.component.dropdownOpened) {
|
|
@@ -34546,6 +34586,21 @@ class SmartSelectComponent extends SmartSelectField {
|
|
|
34546
34586
|
|
|
34547
34587
|
value = convertToString(value);
|
|
34548
34588
|
|
|
34589
|
+
if (this.component.dataSrc === 'masterdata' && this.component.masterdata) {
|
|
34590
|
+
const convertMasterdata = (v) => {
|
|
34591
|
+
if (typeof v === 'string' || typeof v === 'number') {
|
|
34592
|
+
const matched = this.findMasterdataItem(v);
|
|
34593
|
+
return matched || v;
|
|
34594
|
+
}
|
|
34595
|
+
return v;
|
|
34596
|
+
};
|
|
34597
|
+
if (Array.isArray(value)) {
|
|
34598
|
+
value = value.map(convertMasterdata);
|
|
34599
|
+
} else if (value != null) {
|
|
34600
|
+
value = convertMasterdata(value);
|
|
34601
|
+
}
|
|
34602
|
+
}
|
|
34603
|
+
|
|
34549
34604
|
if (['values', 'custom'].includes(this.component.dataSrc) && !this.asyncCustomValues()) {
|
|
34550
34605
|
const {
|
|
34551
34606
|
items,
|
|
@@ -34569,7 +34624,7 @@ class SmartSelectComponent extends SmartSelectField {
|
|
|
34569
34624
|
: value;
|
|
34570
34625
|
}
|
|
34571
34626
|
|
|
34572
|
-
if (_.isString(value)) {
|
|
34627
|
+
if (_.isString(value) && this.component.dataSrc !== 'masterdata') {
|
|
34573
34628
|
return value;
|
|
34574
34629
|
}
|
|
34575
34630
|
const getTemplateValue = (v) => {
|
|
@@ -39377,9 +39432,52 @@ function getValueFromData(data, path) {
|
|
|
39377
39432
|
function isComponentEmpty(inst) {
|
|
39378
39433
|
if (!inst) return true;
|
|
39379
39434
|
const val = inst.getValue ? inst.getValue() : inst.dataValue;
|
|
39380
|
-
|
|
39381
|
-
|
|
39382
|
-
|
|
39435
|
+
if (inst.isEmpty) {
|
|
39436
|
+
return inst.isEmpty(val);
|
|
39437
|
+
}
|
|
39438
|
+
if (val === undefined || val === null || val === "") return true;
|
|
39439
|
+
if (Array.isArray(val) && val.length === 0) return true;
|
|
39440
|
+
if (typeof val === "object" && !Array.isArray(val) && Object.keys(val).length === 0) return true;
|
|
39441
|
+
return false;
|
|
39442
|
+
}
|
|
39443
|
+
|
|
39444
|
+
/**
|
|
39445
|
+
* Helper to retrieve the exact component instance associated with an error,
|
|
39446
|
+
* including specific row instances inside DataGrids/EditGrids.
|
|
39447
|
+
*/
|
|
39448
|
+
function getComponentByError(form, err) {
|
|
39449
|
+
if (!form || !err) return null;
|
|
39450
|
+
|
|
39451
|
+
// 1. Direct component instance reference on error object
|
|
39452
|
+
if (err.component && err.component.element) {
|
|
39453
|
+
return err.component;
|
|
39454
|
+
}
|
|
39455
|
+
|
|
39456
|
+
// 2. Try exact path (e.g., "dataGrid[0].crewLead", "dataGrid.0.crewLead")
|
|
39457
|
+
const path = err.path || err.context?.path || err.context?.hasPath;
|
|
39458
|
+
if (path) {
|
|
39459
|
+
let inst = typeof form.getComponent === "function" ? form.getComponent(path) : null;
|
|
39460
|
+
if (inst && inst.element) return inst;
|
|
39461
|
+
|
|
39462
|
+
// Convert array notation dataGrid[0].crewLead -> dataGrid.0.crewLead
|
|
39463
|
+
const dotPath = String(path).replace(/\[(\d+)\]/g, ".$1");
|
|
39464
|
+
inst = typeof form.getComponent === "function" ? form.getComponent(dotPath) : null;
|
|
39465
|
+
if (inst && inst.element) return inst;
|
|
39466
|
+
|
|
39467
|
+
// Convert dot notation dataGrid.0.crewLead -> dataGrid[0].crewLead
|
|
39468
|
+
const bracketPath = String(path).replace(/\.(\d+)\./g, "[$1].");
|
|
39469
|
+
inst = typeof form.getComponent === "function" ? form.getComponent(bracketPath) : null;
|
|
39470
|
+
if (inst && inst.element) return inst;
|
|
39471
|
+
}
|
|
39472
|
+
|
|
39473
|
+
// 3. Fallback to component key
|
|
39474
|
+
const key = err.context?.component?.key || err.component?.key || (typeof err.context?.component === "string" ? err.context.component : null);
|
|
39475
|
+
if (key && typeof form.getComponent === "function") {
|
|
39476
|
+
const inst = form.getComponent(key);
|
|
39477
|
+
if (inst && inst.element) return inst;
|
|
39478
|
+
}
|
|
39479
|
+
|
|
39480
|
+
return null;
|
|
39383
39481
|
}
|
|
39384
39482
|
|
|
39385
39483
|
/**
|
|
@@ -39597,21 +39695,31 @@ function FormOnComplete() {
|
|
|
39597
39695
|
let isTrulyInvalid = false;
|
|
39598
39696
|
let trueErrors = [];
|
|
39599
39697
|
|
|
39600
|
-
|
|
39601
|
-
|
|
39602
|
-
|
|
39603
|
-
|
|
39604
|
-
|
|
39605
|
-
|
|
39606
|
-
|
|
39607
|
-
|
|
39608
|
-
|
|
39609
|
-
|
|
39610
|
-
|
|
39611
|
-
|
|
39698
|
+
// Combine errors from formObj.errors, error (promise reject), error.errors, error.details
|
|
39699
|
+
let rawErrors = [];
|
|
39700
|
+
if (formObj && Array.isArray(formObj.errors) && formObj.errors.length > 0) {
|
|
39701
|
+
rawErrors = rawErrors.concat(formObj.errors);
|
|
39702
|
+
}
|
|
39703
|
+
if (Array.isArray(error)) {
|
|
39704
|
+
rawErrors = rawErrors.concat(error);
|
|
39705
|
+
} else if (error && Array.isArray(error.errors)) {
|
|
39706
|
+
rawErrors = rawErrors.concat(error.errors);
|
|
39707
|
+
} else if (error && Array.isArray(error.details)) {
|
|
39708
|
+
rawErrors = rawErrors.concat(error.details);
|
|
39709
|
+
} else if (error && typeof error === "object" && (error.message || error.context)) {
|
|
39710
|
+
rawErrors.push(error);
|
|
39711
|
+
}
|
|
39712
|
+
|
|
39713
|
+
if (rawErrors.length > 0) {
|
|
39714
|
+
rawErrors.forEach((err) => {
|
|
39715
|
+
const inst = getComponentByError(formObj, err);
|
|
39716
|
+
if (inst && inst.element) {
|
|
39717
|
+
if (!isComponentEmpty(inst)) {
|
|
39718
|
+
clearComponentErrorUI(inst);
|
|
39612
39719
|
} else {
|
|
39613
39720
|
isTrulyInvalid = true;
|
|
39614
39721
|
trueErrors.push(err);
|
|
39722
|
+
showComponentErrorUI(inst, err);
|
|
39615
39723
|
}
|
|
39616
39724
|
} else {
|
|
39617
39725
|
isTrulyInvalid = true;
|
|
@@ -41474,7 +41582,7 @@ initThemeHook();
|
|
|
41474
41582
|
</div>
|
|
41475
41583
|
|
|
41476
41584
|
<div id="sticky-footer">
|
|
41477
|
-
<div class="build-version">SDK v2.0.
|
|
41585
|
+
<div class="build-version">SDK v2.0.61</div>
|
|
41478
41586
|
|
|
41479
41587
|
<button class="footer-btn footer-btn-secondary" id="prevBtn" style="display:none" onclick="FormOnPrevious()">
|
|
41480
41588
|
<i class="bi bi-chevron-left"></i> Previous
|