df-ae-forms-package 1.1.5 → 1.1.6
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/index.esm.js +236 -36
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +236 -36
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -820,7 +820,6 @@ const DfFormInput = ({ id, properties, validationErrors = {}, formValue = '', in
|
|
|
820
820
|
// Update ref if ID changes (shouldn't happen, but safety check)
|
|
821
821
|
React.useEffect(() => {
|
|
822
822
|
if (id !== componentIdRef.current) {
|
|
823
|
-
console.warn(`[DfFormInput] Component ID changed from ${componentIdRef.current} to ${id}`);
|
|
824
823
|
componentIdRef.current = id;
|
|
825
824
|
}
|
|
826
825
|
}, [id]);
|
|
@@ -2998,8 +2997,6 @@ const DfFormLocation = ({ id, properties, validationErrors = {}, formValue = nul
|
|
|
2998
2997
|
}
|
|
2999
2998
|
}
|
|
3000
2999
|
catch (error) {
|
|
3001
|
-
// Capacitor not properly initialized, fall through to web geolocation
|
|
3002
|
-
console.warn('Capacitor Geolocation not available, falling back to web geolocation');
|
|
3003
3000
|
}
|
|
3004
3001
|
}
|
|
3005
3002
|
// Fallback to standard web geolocation API (for browsers)
|
|
@@ -3713,7 +3710,6 @@ const AttachmentThumbnails = ({ attachments, onRemove }) => {
|
|
|
3713
3710
|
newUrls.set(index, url);
|
|
3714
3711
|
}
|
|
3715
3712
|
catch (e) {
|
|
3716
|
-
console.warn('Failed to create object URL for attachment:', e);
|
|
3717
3713
|
}
|
|
3718
3714
|
}
|
|
3719
3715
|
else if (file && file.url && file.type && file.type.startsWith('image/')) {
|
|
@@ -4624,7 +4620,6 @@ formTemplateId, onThresholdActionCompletion, onThresholdIssueRaised, onNotesChan
|
|
|
4624
4620
|
zIndex: 5
|
|
4625
4621
|
}, children: jsxRuntime.jsxs("button", { onClick: (e) => {
|
|
4626
4622
|
e.stopPropagation();
|
|
4627
|
-
console.log('[TableView] Add Entry button clicked (grid view)', 'entries:', dataEntries.length, 'max:', maxEntries);
|
|
4628
4623
|
onAddEntry();
|
|
4629
4624
|
}, disabled: dataEntries.length >= maxEntries, style: {
|
|
4630
4625
|
padding: '8px 16px',
|
|
@@ -4750,7 +4745,6 @@ formTemplateId, onThresholdActionCompletion, onThresholdIssueRaised, onNotesChan
|
|
|
4750
4745
|
justifyContent: 'center'
|
|
4751
4746
|
}, children: jsxRuntime.jsxs("button", { onClick: (e) => {
|
|
4752
4747
|
e.stopPropagation();
|
|
4753
|
-
console.log('[TableView] Add Entry button clicked (list view)', 'entries:', dataEntries.length, 'max:', maxEntries);
|
|
4754
4748
|
onAddEntry();
|
|
4755
4749
|
}, disabled: dataEntries.length >= maxEntries, style: {
|
|
4756
4750
|
padding: '8px 16px',
|
|
@@ -5003,12 +4997,8 @@ const DfFormDataGrid = ({ id, properties, mode = 'edit', formData = {}, onValueC
|
|
|
5003
4997
|
// In edit/preview modes, don't handle value changes as components are read-only
|
|
5004
4998
|
}, [mode, onValueChange]);
|
|
5005
4999
|
const handleAddEntry = React.useCallback(() => {
|
|
5006
|
-
console.log('[DfFormDataGrid] handleAddEntry called - Component ID:', id);
|
|
5007
5000
|
// Safety check: ensure we have entries array
|
|
5008
5001
|
const currentEntries = Array.isArray(properties.entries) ? properties.entries : [];
|
|
5009
|
-
console.log('[DfFormDataGrid] gridComponents:', gridComponents.length);
|
|
5010
|
-
console.log('[DfFormDataGrid] current entries count:', currentEntries.length);
|
|
5011
|
-
console.log('[DfFormDataGrid] onValueChange exists:', !!onValueChange);
|
|
5012
5002
|
// Use timestamp and random string to ensure uniqueness even if entries are deleted
|
|
5013
5003
|
const uniqueSuffix = `${Date.now()}-${Math.random().toString(36).substr(2, 5)}`;
|
|
5014
5004
|
const newEntryId = `entry-${uniqueSuffix}`;
|
|
@@ -5030,11 +5020,8 @@ const DfFormDataGrid = ({ id, properties, mode = 'edit', formData = {}, onValueC
|
|
|
5030
5020
|
}),
|
|
5031
5021
|
styles: {}
|
|
5032
5022
|
};
|
|
5033
|
-
console.log('[DfFormDataGrid] newEntry created:', newEntry.id, 'with', newEntry.components.length, 'components');
|
|
5034
5023
|
const updatedEntries = [...currentEntries, newEntry];
|
|
5035
|
-
console.log('[DfFormDataGrid] updatedEntries count:', updatedEntries.length);
|
|
5036
5024
|
if (onValueChange) {
|
|
5037
|
-
console.log('[DfFormDataGrid] calling onValueChange with updated datagrid structure - Entries:', updatedEntries.length);
|
|
5038
5025
|
onValueChange({
|
|
5039
5026
|
id: gridId, // Use sanitized gridId
|
|
5040
5027
|
value: {
|
|
@@ -5044,13 +5031,9 @@ const DfFormDataGrid = ({ id, properties, mode = 'edit', formData = {}, onValueC
|
|
|
5044
5031
|
});
|
|
5045
5032
|
// Notify parent if callback provided
|
|
5046
5033
|
if (onEntryAdd) {
|
|
5047
|
-
console.log('[DfFormDataGrid] calling onEntryAdd callback');
|
|
5048
5034
|
onEntryAdd();
|
|
5049
5035
|
}
|
|
5050
5036
|
}
|
|
5051
|
-
else {
|
|
5052
|
-
console.warn('[DfFormDataGrid] Cannot add entry: onValueChange is missing');
|
|
5053
|
-
}
|
|
5054
5037
|
}, [onValueChange, properties, gridId, gridComponents, onEntryAdd]);
|
|
5055
5038
|
const handleRemoveEntry = React.useCallback((entryIndex) => {
|
|
5056
5039
|
// Safety check: ensure we have entries array
|
|
@@ -5059,7 +5042,6 @@ const DfFormDataGrid = ({ id, properties, mode = 'edit', formData = {}, onValueC
|
|
|
5059
5042
|
.filter((_, index) => index !== entryIndex)
|
|
5060
5043
|
.map((entry, index) => ({ ...entry, index })); // Only update index, preserve unique ID
|
|
5061
5044
|
if (onValueChange) {
|
|
5062
|
-
console.log('[DfFormDataGrid] Removing entry at index:', entryIndex, 'New count:', updatedEntries.length);
|
|
5063
5045
|
onValueChange({
|
|
5064
5046
|
id: gridId, // Use sanitized gridId
|
|
5065
5047
|
value: { ...properties, entries: updatedEntries }
|
|
@@ -5447,8 +5429,8 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5447
5429
|
const [validationErrors, setValidationErrors] = React.useState({});
|
|
5448
5430
|
const [formSubmitted, setFormSubmitted] = React.useState(false);
|
|
5449
5431
|
const [touchedFields, setTouchedFields] = React.useState({});
|
|
5450
|
-
//
|
|
5451
|
-
|
|
5432
|
+
// Component visibility state - driven by conditional logic evaluation
|
|
5433
|
+
const [componentVisibility, setComponentVisibility] = React.useState({});
|
|
5452
5434
|
// Track raised issues for threshold conditions (Set of condition IDs)
|
|
5453
5435
|
const [raisedThresholdIssues, setRaisedThresholdIssues] = React.useState(new Set());
|
|
5454
5436
|
// Track threshold action completions: Map<conditionId, { notesCompleted, attachmentsCompleted, emailSent }>
|
|
@@ -5546,6 +5528,11 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5546
5528
|
if (component.children && Array.isArray(component.children)) {
|
|
5547
5529
|
initializeComponentValues(component.children, values);
|
|
5548
5530
|
}
|
|
5531
|
+
// CRITICAL for conditional logic: Also store value under the label key
|
|
5532
|
+
// so condition lookups by label (e.g. "Temperature") work during init
|
|
5533
|
+
if (component.basic?.label && componentId && values[componentId] !== undefined) {
|
|
5534
|
+
values[component.basic.label] = values[componentId];
|
|
5535
|
+
}
|
|
5549
5536
|
});
|
|
5550
5537
|
};
|
|
5551
5538
|
const initializeFormState = React.useCallback(() => {
|
|
@@ -5617,15 +5604,12 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5617
5604
|
const labelPart = safeLabel ? `-${safeLabel}` : '';
|
|
5618
5605
|
validatedComponent.id = `${name}${labelPart}-${index}`;
|
|
5619
5606
|
}
|
|
5620
|
-
console.warn(`[DfFormPreview] Fixed missing/invalid ID: ${validatedComponent.id}`);
|
|
5621
5607
|
}
|
|
5622
5608
|
else {
|
|
5623
5609
|
// ID is a valid string, check for duplicates
|
|
5624
5610
|
if (seenIds.has(validatedComponent.id)) {
|
|
5625
|
-
console.error(`[DfFormPreview] Duplicate component ID detected: ${validatedComponent.id}`);
|
|
5626
5611
|
// Generate a unique ID for duplicate - using index to keep it somewhat stable
|
|
5627
5612
|
validatedComponent.id = `${validatedComponent.id}-dup-${index}`;
|
|
5628
|
-
console.warn(`[DfFormPreview] Generated new unique ID: ${validatedComponent.id}`);
|
|
5629
5613
|
}
|
|
5630
5614
|
}
|
|
5631
5615
|
seenIds.add(validatedComponent.id);
|
|
@@ -5680,7 +5664,6 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5680
5664
|
validatedFormComponents = getValidatedComponents(localFormComponents);
|
|
5681
5665
|
// Synchronize local state if components were mutated (IDs added/fixed)
|
|
5682
5666
|
if (JSON.stringify(validatedFormComponents) !== JSON.stringify(localFormComponents)) {
|
|
5683
|
-
console.log('[DfFormPreview] Synchronizing local components after ID validation');
|
|
5684
5667
|
setLocalFormComponents(validatedFormComponents);
|
|
5685
5668
|
onFormDataChange?.(validatedFormComponents);
|
|
5686
5669
|
}
|
|
@@ -5733,13 +5716,229 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5733
5716
|
// Initialize notes and attachments state
|
|
5734
5717
|
setComponentNotes(prev => ({ ...initialNotes, ...prev }));
|
|
5735
5718
|
setComponentAttachments(prev => ({ ...initialAttachments, ...prev }));
|
|
5736
|
-
//
|
|
5737
|
-
|
|
5719
|
+
// Evaluate conditional logic on initialization
|
|
5720
|
+
evaluateConditionalLogic(initialValues);
|
|
5738
5721
|
}, [initialFormData, localFormComponents]);
|
|
5739
|
-
//
|
|
5740
|
-
|
|
5741
|
-
|
|
5722
|
+
// ======================== CONDITIONAL LOGIC ENGINE ========================
|
|
5723
|
+
// This is a pure visibility layer. It NEVER modifies component data.
|
|
5724
|
+
// It computes a { [componentId]: boolean } map based on each component's
|
|
5725
|
+
// `logic` property and the current form values.
|
|
5726
|
+
// Helper: Flatten all components (including nested) into a flat list
|
|
5727
|
+
const flattenAllComponents = React.useCallback((components) => {
|
|
5728
|
+
const flat = [];
|
|
5729
|
+
const traverse = (items) => {
|
|
5730
|
+
if (!items || !Array.isArray(items))
|
|
5731
|
+
return;
|
|
5732
|
+
for (const item of items) {
|
|
5733
|
+
flat.push(item);
|
|
5734
|
+
if (item.children && Array.isArray(item.children))
|
|
5735
|
+
traverse(item.children);
|
|
5736
|
+
if (item.cells && Array.isArray(item.cells)) {
|
|
5737
|
+
for (const row of item.cells) {
|
|
5738
|
+
const normalizedRow = normalizeTableRow(row);
|
|
5739
|
+
for (const cell of normalizedRow) {
|
|
5740
|
+
if (cell.components)
|
|
5741
|
+
traverse(cell.components);
|
|
5742
|
+
}
|
|
5743
|
+
}
|
|
5744
|
+
}
|
|
5745
|
+
if (item.entries && Array.isArray(item.entries)) {
|
|
5746
|
+
for (const entry of item.entries) {
|
|
5747
|
+
if (entry.components)
|
|
5748
|
+
traverse(entry.components);
|
|
5749
|
+
}
|
|
5750
|
+
}
|
|
5751
|
+
if (item.templateComponents && Array.isArray(item.templateComponents)) {
|
|
5752
|
+
traverse(item.templateComponents);
|
|
5753
|
+
}
|
|
5754
|
+
}
|
|
5755
|
+
};
|
|
5756
|
+
traverse(components);
|
|
5757
|
+
return flat;
|
|
5758
|
+
}, []);
|
|
5759
|
+
// Helper: Get the value of a component referenced by a condition's `when` field.
|
|
5760
|
+
// The `when` field is typically a component LABEL (e.g. "Temperature"), not an ID.
|
|
5761
|
+
const getConditionComponentValue = React.useCallback((conditionWhen, allComponents, currentFormValues) => {
|
|
5762
|
+
// Try to find the component by label, id, or _id
|
|
5763
|
+
const comp = allComponents.find(c => c.basic?.label === conditionWhen ||
|
|
5764
|
+
ensureStringId$1(c.id) === conditionWhen ||
|
|
5765
|
+
ensureStringId$1(c._id) === conditionWhen);
|
|
5766
|
+
if (!comp)
|
|
5767
|
+
return undefined;
|
|
5768
|
+
const compId = ensureStringId$1(comp.id || comp._id);
|
|
5769
|
+
// Check formValues by ID first
|
|
5770
|
+
if (compId && currentFormValues[compId] !== undefined) {
|
|
5771
|
+
return currentFormValues[compId];
|
|
5772
|
+
}
|
|
5773
|
+
// Also check by label (main website stores values by label too)
|
|
5774
|
+
if (comp.basic?.label && currentFormValues[comp.basic.label] !== undefined) {
|
|
5775
|
+
return currentFormValues[comp.basic.label];
|
|
5776
|
+
}
|
|
5777
|
+
// Fall back to component's basic.value or defaultValue
|
|
5778
|
+
if (comp.basic?.value !== undefined && comp.basic?.value !== null && comp.basic?.value !== '') {
|
|
5779
|
+
return comp.basic.value;
|
|
5780
|
+
}
|
|
5781
|
+
if (comp.basic?.defaultValue !== undefined && comp.basic?.defaultValue !== null && comp.basic?.defaultValue !== '') {
|
|
5782
|
+
return comp.basic.defaultValue;
|
|
5783
|
+
}
|
|
5784
|
+
return undefined;
|
|
5742
5785
|
}, []);
|
|
5786
|
+
// Helper: Evaluate a single condition
|
|
5787
|
+
const evaluateSingleCondition = React.useCallback((condition, componentValue) => {
|
|
5788
|
+
const { operator, value } = condition;
|
|
5789
|
+
// isEmpty / isNotEmpty
|
|
5790
|
+
if (operator === 'isEmpty') {
|
|
5791
|
+
if (componentValue == null)
|
|
5792
|
+
return true;
|
|
5793
|
+
if (typeof componentValue === 'string')
|
|
5794
|
+
return componentValue.trim() === '';
|
|
5795
|
+
if (Array.isArray(componentValue))
|
|
5796
|
+
return componentValue.length === 0;
|
|
5797
|
+
return false;
|
|
5798
|
+
}
|
|
5799
|
+
if (operator === 'isNotEmpty') {
|
|
5800
|
+
if (componentValue == null)
|
|
5801
|
+
return false;
|
|
5802
|
+
if (typeof componentValue === 'string')
|
|
5803
|
+
return componentValue.trim() !== '';
|
|
5804
|
+
if (Array.isArray(componentValue))
|
|
5805
|
+
return componentValue.length > 0;
|
|
5806
|
+
return true;
|
|
5807
|
+
}
|
|
5808
|
+
// checked / notChecked (for checkboxes)
|
|
5809
|
+
if (operator === 'checked' || operator === 'notChecked') {
|
|
5810
|
+
let isChecked = false;
|
|
5811
|
+
if (typeof componentValue === 'boolean')
|
|
5812
|
+
isChecked = componentValue;
|
|
5813
|
+
else if (typeof componentValue === 'string')
|
|
5814
|
+
isChecked = componentValue.toLowerCase() === 'true' || componentValue === '1' || componentValue.length > 0;
|
|
5815
|
+
else if (Array.isArray(componentValue))
|
|
5816
|
+
isChecked = componentValue.length > 0;
|
|
5817
|
+
else if (typeof componentValue === 'number')
|
|
5818
|
+
isChecked = componentValue > 0;
|
|
5819
|
+
return operator === 'checked' ? isChecked : !isChecked;
|
|
5820
|
+
}
|
|
5821
|
+
// equals / notEquals
|
|
5822
|
+
if (operator === 'equals' || operator === 'notEquals') {
|
|
5823
|
+
let isEqual = false;
|
|
5824
|
+
// Loose comparison
|
|
5825
|
+
if (componentValue == value)
|
|
5826
|
+
isEqual = true;
|
|
5827
|
+
// String comparison (case-insensitive, trimmed)
|
|
5828
|
+
if (!isEqual && componentValue != null && value != null) {
|
|
5829
|
+
const strA = String(componentValue).trim();
|
|
5830
|
+
const strB = String(value).trim();
|
|
5831
|
+
// Numeric comparison within strings
|
|
5832
|
+
if (strA !== '' && strB !== '' && !isNaN(Number(strA)) && !isNaN(Number(strB))) {
|
|
5833
|
+
isEqual = Number(strA) === Number(strB);
|
|
5834
|
+
}
|
|
5835
|
+
if (!isEqual) {
|
|
5836
|
+
isEqual = strA.toLowerCase() === strB.toLowerCase();
|
|
5837
|
+
}
|
|
5838
|
+
}
|
|
5839
|
+
// Array contains check (for multi-select)
|
|
5840
|
+
if (!isEqual && Array.isArray(componentValue)) {
|
|
5841
|
+
isEqual = componentValue.some(v => String(v).trim().toLowerCase() === String(value).trim().toLowerCase());
|
|
5842
|
+
}
|
|
5843
|
+
return operator === 'equals' ? isEqual : !isEqual;
|
|
5844
|
+
}
|
|
5845
|
+
// contains / notContains
|
|
5846
|
+
if (operator === 'contains' || operator === 'notContains') {
|
|
5847
|
+
let doesContain = false;
|
|
5848
|
+
if (typeof componentValue === 'string' && value != null) {
|
|
5849
|
+
doesContain = componentValue.trim().toLowerCase().includes(String(value).trim().toLowerCase());
|
|
5850
|
+
}
|
|
5851
|
+
else if (Array.isArray(componentValue) && value != null) {
|
|
5852
|
+
doesContain = componentValue.some(v => String(v).trim().toLowerCase() === String(value).trim().toLowerCase());
|
|
5853
|
+
}
|
|
5854
|
+
return operator === 'contains' ? doesContain : !doesContain;
|
|
5855
|
+
}
|
|
5856
|
+
// Numeric comparisons
|
|
5857
|
+
if (['greaterThan', 'lessThan', 'greaterThanOrEqual', 'lessThanOrEqual'].includes(operator)) {
|
|
5858
|
+
const numA = typeof componentValue === 'number' ? componentValue : parseFloat(String(componentValue));
|
|
5859
|
+
const numB = typeof value === 'number' ? value : parseFloat(String(value));
|
|
5860
|
+
if (isNaN(numA) || isNaN(numB))
|
|
5861
|
+
return false;
|
|
5862
|
+
switch (operator) {
|
|
5863
|
+
case 'greaterThan': return numA > numB;
|
|
5864
|
+
case 'lessThan': return numA < numB;
|
|
5865
|
+
case 'greaterThanOrEqual': return numA >= numB;
|
|
5866
|
+
case 'lessThanOrEqual': return numA <= numB;
|
|
5867
|
+
default: return false;
|
|
5868
|
+
}
|
|
5869
|
+
}
|
|
5870
|
+
return false;
|
|
5871
|
+
}, []);
|
|
5872
|
+
// Main conditional logic evaluation function
|
|
5873
|
+
const evaluateConditionalLogic = React.useCallback((explicitValues) => {
|
|
5874
|
+
const currentComponents = localFormComponents;
|
|
5875
|
+
const currentValues = explicitValues || formValues;
|
|
5876
|
+
if (!currentComponents || currentComponents.length === 0)
|
|
5877
|
+
return;
|
|
5878
|
+
const allComponents = flattenAllComponents(currentComponents);
|
|
5879
|
+
const visibility = {};
|
|
5880
|
+
allComponents.forEach(component => {
|
|
5881
|
+
const compId = ensureStringId$1(component.id || component._id);
|
|
5882
|
+
if (!compId)
|
|
5883
|
+
return;
|
|
5884
|
+
// Container components are ALWAYS visible — their children handle their own logic
|
|
5885
|
+
if (['table', 'datagrid', 'section', 'heading', 'instructions'].includes(component.name)) {
|
|
5886
|
+
visibility[compId] = true;
|
|
5887
|
+
return;
|
|
5888
|
+
}
|
|
5889
|
+
// Get the logic property (API sends it as `logic`, builder uses `conditional`)
|
|
5890
|
+
const logic = component.logic || component.conditional;
|
|
5891
|
+
// No logic or action is 'always' → always show
|
|
5892
|
+
if (!logic || logic.action === 'always' || !logic.conditions || logic.conditions.length === 0) {
|
|
5893
|
+
visibility[compId] = true;
|
|
5894
|
+
return;
|
|
5895
|
+
}
|
|
5896
|
+
// Evaluate each condition
|
|
5897
|
+
const conditionResults = logic.conditions.map((condition) => {
|
|
5898
|
+
const componentValue = getConditionComponentValue(condition.when, allComponents, currentValues);
|
|
5899
|
+
return evaluateSingleCondition(condition, componentValue);
|
|
5900
|
+
});
|
|
5901
|
+
// Determine if conditions are met based on 'when' (all/any)
|
|
5902
|
+
let conditionsMet;
|
|
5903
|
+
if (logic.when === 'any') {
|
|
5904
|
+
conditionsMet = conditionResults.some((r) => r);
|
|
5905
|
+
}
|
|
5906
|
+
else {
|
|
5907
|
+
// Default to 'all'
|
|
5908
|
+
conditionsMet = conditionResults.every((r) => r);
|
|
5909
|
+
}
|
|
5910
|
+
// Apply action
|
|
5911
|
+
if (logic.action === 'show') {
|
|
5912
|
+
visibility[compId] = conditionsMet;
|
|
5913
|
+
}
|
|
5914
|
+
else if (logic.action === 'hide') {
|
|
5915
|
+
visibility[compId] = !conditionsMet;
|
|
5916
|
+
}
|
|
5917
|
+
else {
|
|
5918
|
+
visibility[compId] = true;
|
|
5919
|
+
}
|
|
5920
|
+
});
|
|
5921
|
+
// Only update state if visibility actually changed (prevent re-render loops)
|
|
5922
|
+
setComponentVisibility(prev => {
|
|
5923
|
+
const prevStr = JSON.stringify(prev);
|
|
5924
|
+
const newStr = JSON.stringify(visibility);
|
|
5925
|
+
if (prevStr === newStr)
|
|
5926
|
+
return prev;
|
|
5927
|
+
return visibility;
|
|
5928
|
+
});
|
|
5929
|
+
}, [localFormComponents, formValues, flattenAllComponents, getConditionComponentValue, evaluateSingleCondition]);
|
|
5930
|
+
// Re-evaluate conditional logic whenever form values change
|
|
5931
|
+
React.useEffect(() => {
|
|
5932
|
+
evaluateConditionalLogic();
|
|
5933
|
+
}, [formValues, evaluateConditionalLogic]);
|
|
5934
|
+
// Check if a component should be visible
|
|
5935
|
+
const shouldShowComponent = React.useCallback((componentId) => {
|
|
5936
|
+
// In preview mode (read-only submission view), always show everything
|
|
5937
|
+
if (isPreviewMode)
|
|
5938
|
+
return true;
|
|
5939
|
+
// Default to visible if not explicitly set to false
|
|
5940
|
+
return componentVisibility[componentId] !== false;
|
|
5941
|
+
}, [componentVisibility, isPreviewMode]);
|
|
5743
5942
|
// Handle form value changes and re-evaluate conditional logic
|
|
5744
5943
|
const onFormValueChange = React.useCallback((change) => {
|
|
5745
5944
|
// CRITICAL: Validate that change.id is valid and unique
|
|
@@ -5791,6 +5990,13 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5791
5990
|
// Only update formValues for actual value changes, not structure updates
|
|
5792
5991
|
if (!isStructureUpdate) {
|
|
5793
5992
|
newFormValues[change.id] = change.value;
|
|
5993
|
+
// CRITICAL for conditional logic: Also store value under the component's label.
|
|
5994
|
+
// Conditions reference components by label (e.g. "Temperature"), not by ID.
|
|
5995
|
+
const allComponents = flattenAllComponents(localFormComponents);
|
|
5996
|
+
const targetComp = allComponents.find(c => ensureStringId$1(c.id || c._id) === change.id);
|
|
5997
|
+
if (targetComp?.basic?.label) {
|
|
5998
|
+
newFormValues[targetComp.basic.label] = change.value;
|
|
5999
|
+
}
|
|
5794
6000
|
setFormValues(newFormValues);
|
|
5795
6001
|
}
|
|
5796
6002
|
// Clear raised issues for this component when value changes
|
|
@@ -6531,7 +6737,6 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6531
6737
|
componentCounterRef.current += 1;
|
|
6532
6738
|
cachedId = `generated-${name}-${componentCounterRef.current}-${Math.random().toString(36).substr(2, 9)}`;
|
|
6533
6739
|
componentIdCacheRef.current.set(cacheKey, cachedId);
|
|
6534
|
-
console.warn('[DfFormPreview] Generated and cached ID for component:', cachedId, 'key:', cacheKey);
|
|
6535
6740
|
}
|
|
6536
6741
|
finalComponentId = cachedId;
|
|
6537
6742
|
// Create a new component object with the cached ID (don't mutate original)
|
|
@@ -6547,9 +6752,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6547
6752
|
if (formValue !== undefined) {
|
|
6548
6753
|
// Check if this value is being used by multiple components
|
|
6549
6754
|
const componentsWithSameValue = localFormComponents.filter(comp => comp.id !== componentId && formValues[comp.id] === formValue);
|
|
6550
|
-
if (componentsWithSameValue.length > 0)
|
|
6551
|
-
console.warn(`[DfFormPreview] Component ${componentId} shares form value with other components:`, componentsWithSameValue.map(c => c.id));
|
|
6552
|
-
}
|
|
6755
|
+
if (componentsWithSameValue.length > 0) ;
|
|
6553
6756
|
}
|
|
6554
6757
|
const commonProps = {
|
|
6555
6758
|
id: componentId, // Use the validated component ID
|
|
@@ -6762,10 +6965,8 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6762
6965
|
}, onValueChange: (change) => {
|
|
6763
6966
|
const changeId = ensureStringId$1(change.id);
|
|
6764
6967
|
const componentId = ensureStringId$1(component.id);
|
|
6765
|
-
console.log(`[DfFormPreview] datagrid onValueChange - Target: ${changeId}, Component: ${componentId}`);
|
|
6766
6968
|
// Handle datagrid value changes (entries updates)
|
|
6767
6969
|
if (changeId === componentId && change.value && typeof change.value === 'object' && 'entries' in change.value) {
|
|
6768
|
-
console.log('[DfFormPreview] datagrid entries update - entries count:', change.value.entries?.length);
|
|
6769
6970
|
// Update localFormComponents with new entries structure
|
|
6770
6971
|
const updatedComponents = localFormComponents.map(comp => {
|
|
6771
6972
|
const currentCompId = ensureStringId$1(comp.id);
|
|
@@ -6808,7 +7009,6 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6808
7009
|
}
|
|
6809
7010
|
});
|
|
6810
7011
|
if (valuesChanged) {
|
|
6811
|
-
console.log('[DfFormPreview] Initializing form values for new datagrid entries');
|
|
6812
7012
|
setFormValues(newValues);
|
|
6813
7013
|
}
|
|
6814
7014
|
}
|