df-ae-forms-package 1.0.80 → 1.0.82

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.d.ts CHANGED
@@ -785,6 +785,7 @@ interface DfFormTableProps {
785
785
  };
786
786
  onCreateIssue?: (issueData: any, attachments: File[]) => Promise<any>;
787
787
  onUpdateIssue?: (issueId: string, updateData: any) => Promise<void>;
788
+ shouldShowComponent?: (id: string) => boolean;
788
789
  }
789
790
  declare const DfFormTable: React.FC<DfFormTableProps>;
790
791
 
package/dist/index.esm.js CHANGED
@@ -5969,9 +5969,47 @@ const DfFormSection = ({ id, properties, mode = 'edit', formData = {}, onValueCh
5969
5969
 
5970
5970
  // Dynamic imports to avoid circular dependencies
5971
5971
  const DfFormTable$1 = React.lazy(() => Promise.resolve().then(function () { return dfFormTable; }));
5972
- const DfFormPreview = ({ formComponents = [], currentDevice = 'desktop', isPreviewMode = false, initialFormData = [], onSubmit, onFormDataChange, formTitle, formDescription, formTemplateId,
5972
+ const DfFormPreview = ({ formComponents: rawFormComponents = [], currentDevice = 'desktop', isPreviewMode = false, initialFormData = [], onSubmit, onFormDataChange, formTitle, formDescription, formTemplateId,
5973
5973
  // Add component management props for edit mode
5974
5974
  onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, selectedComponent, workOrderNumber, assetNumber, isStandalone, user, onCreateIssue, onUpdateIssue }) => {
5975
+ // Ensure all components have IDs (matching main website approach)
5976
+ const formComponents = useMemo(() => {
5977
+ const ensureIds = (components) => {
5978
+ return components.map(comp => {
5979
+ // Reuse existing ID or generate one
5980
+ const id = comp.id || `generated-${Math.random().toString(36).substr(2, 9)}`;
5981
+ const newComp = { ...comp, id };
5982
+ // Recursively handle nested components
5983
+ if (newComp.children && Array.isArray(newComp.children)) {
5984
+ newComp.children = ensureIds(newComp.children);
5985
+ }
5986
+ if (newComp.cells && Array.isArray(newComp.cells)) {
5987
+ newComp.cells = newComp.cells.map((row) => {
5988
+ if (Array.isArray(row)) {
5989
+ return row.map((cell) => ({
5990
+ ...cell,
5991
+ components: cell.components ? ensureIds(cell.components) : []
5992
+ }));
5993
+ }
5994
+ // Handle flat 1D cell (not wrapped in row array)
5995
+ const cell = row;
5996
+ return {
5997
+ ...cell,
5998
+ components: cell.components ? ensureIds(cell.components) : []
5999
+ };
6000
+ });
6001
+ }
6002
+ if (newComp.entries && Array.isArray(newComp.entries)) {
6003
+ newComp.entries = newComp.entries.map((entry) => ({
6004
+ ...entry,
6005
+ components: entry.components ? ensureIds(entry.components) : []
6006
+ }));
6007
+ }
6008
+ return newComp;
6009
+ });
6010
+ };
6011
+ return ensureIds(rawFormComponents || []);
6012
+ }, [rawFormComponents]);
5975
6013
  // Form state
5976
6014
  const [formValues, setFormValues] = useState({});
5977
6015
  const [validationErrors, setValidationErrors] = useState({});
@@ -6017,24 +6055,16 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
6017
6055
  }
6018
6056
  }
6019
6057
  }
6020
- // Handle nested components in table cells
6058
+ // Handle nested components in table cells (2D array: row → cell → components)
6021
6059
  if (component.cells && Array.isArray(component.cells)) {
6022
- component.cells.forEach((rowOrCell, _rowIndex) => {
6023
- // Handle 2D array (standard)
6024
- if (Array.isArray(rowOrCell)) {
6025
- rowOrCell.forEach((cell, _cellIndex) => {
6060
+ component.cells.forEach((row) => {
6061
+ if (Array.isArray(row)) {
6062
+ row.forEach((cell) => {
6026
6063
  if (cell && cell.components && Array.isArray(cell.components)) {
6027
6064
  initializeComponentValues(cell.components, values);
6028
6065
  }
6029
6066
  });
6030
6067
  }
6031
- // Handle 1D array (flat) structure
6032
- else if (typeof rowOrCell === 'object' && rowOrCell !== null) {
6033
- const cell = rowOrCell;
6034
- if (cell && cell.components && Array.isArray(cell.components)) {
6035
- initializeComponentValues(cell.components, values);
6036
- }
6037
- }
6038
6068
  });
6039
6069
  }
6040
6070
  // Handle nested components in datagrid entries
@@ -6080,7 +6110,6 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
6080
6110
  const initialValues = {};
6081
6111
  const initialNotes = {};
6082
6112
  const initialAttachments = {};
6083
- const seenIds = new Set();
6084
6113
  // Helper to extract notes and attachments recursively
6085
6114
  const extractNotesAndAttachments = (components) => {
6086
6115
  components.forEach(comp => {
@@ -6117,92 +6146,16 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
6117
6146
  });
6118
6147
  });
6119
6148
  };
6120
- // Validate component IDs for uniqueness without mutating original props
6121
- const getValidatedComponents = (components) => {
6122
- return components.map((component, index) => {
6123
- let validatedComponent = { ...component };
6124
- // Ensure component has an ID
6125
- if (!validatedComponent.id || typeof validatedComponent.id !== 'string' || validatedComponent.id.trim() === '') {
6126
- // Determine a base name for the ID
6127
- const name = validatedComponent.name || 'component';
6128
- const label = validatedComponent.basic?.label || '';
6129
- const safeLabel = label.replace(/[^a-zA-Z0-9]/g, '').toLowerCase().substring(0, 10);
6130
- // Generate a unique ID
6131
- validatedComponent.id = `${name}-${safeLabel || 'gen'}-${Date.now()}-${Math.random().toString(36).substr(2, 6)}-${index}`;
6132
- console.warn(`[DfFormPreview] Assigned missing ID: ${validatedComponent.id}`);
6133
- }
6134
- else {
6135
- // Check for duplicates
6136
- if (seenIds.has(validatedComponent.id)) {
6137
- console.error(`[DfFormPreview] Duplicate component ID detected: ${validatedComponent.id}`);
6138
- // Generate a unique ID for duplicate
6139
- validatedComponent.id = `${validatedComponent.id}-duplicate-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
6140
- console.warn(`[DfFormPreview] Generated new unique ID: ${validatedComponent.id}`);
6141
- }
6142
- }
6143
- seenIds.add(validatedComponent.id);
6144
- // Recursively validate nested components
6145
- if (validatedComponent.children && Array.isArray(validatedComponent.children)) {
6146
- validatedComponent.children = getValidatedComponents(validatedComponent.children);
6147
- }
6148
- if (validatedComponent.cells && Array.isArray(validatedComponent.cells)) {
6149
- validatedComponent.cells = validatedComponent.cells.map((rowOrCell) => {
6150
- if (Array.isArray(rowOrCell)) {
6151
- // Standard 2D: rowOrCell is an array of cells
6152
- return rowOrCell.map((cell) => {
6153
- if (cell && cell.components && Array.isArray(cell.components)) {
6154
- return { ...cell, components: getValidatedComponents(cell.components) };
6155
- }
6156
- return cell;
6157
- });
6158
- }
6159
- else if (typeof rowOrCell === 'object' && rowOrCell !== null) {
6160
- // Flat 1D: rowOrCell IS the cell object
6161
- const cell = rowOrCell;
6162
- if (cell.components && Array.isArray(cell.components)) {
6163
- return { ...cell, components: getValidatedComponents(cell.components) };
6164
- }
6165
- return cell;
6166
- }
6167
- return rowOrCell;
6168
- });
6169
- }
6170
- if (validatedComponent.entries && Array.isArray(validatedComponent.entries)) {
6171
- validatedComponent.entries = validatedComponent.entries.map((entry) => {
6172
- if (entry && entry.components && Array.isArray(entry.components)) {
6173
- return {
6174
- ...entry,
6175
- components: getValidatedComponents(entry.components)
6176
- };
6177
- }
6178
- return entry;
6179
- });
6180
- }
6181
- return validatedComponent;
6182
- });
6183
- };
6184
- // Initialize validated components
6185
- let validatedFormComponents = formComponents;
6186
- if (formComponents && formComponents.length > 0) {
6187
- validatedFormComponents = getValidatedComponents(formComponents);
6188
- // Notifying parent of changed components if they were mutated (IDs added/fixed)
6189
- if (JSON.stringify(validatedFormComponents) !== JSON.stringify(formComponents)) {
6190
- onFormDataChange?.(validatedFormComponents);
6191
- }
6192
- }
6193
- let validatedInitialFormData = initialFormData;
6194
- if (initialFormData && initialFormData.length > 0) {
6195
- validatedInitialFormData = getValidatedComponents(initialFormData);
6196
- }
6149
+ // IDs are already ensured by the useMemo at the top - no need for getValidatedComponents
6197
6150
  // Initialize form values from initial data
6198
- if (validatedInitialFormData && validatedInitialFormData.length > 0) {
6199
- initializeComponentValues(validatedInitialFormData, initialValues);
6151
+ if (initialFormData && initialFormData.length > 0) {
6152
+ initializeComponentValues(initialFormData, initialValues);
6200
6153
  }
6201
6154
  // Initialize form values from form components (for submitted data or pre-filled forms)
6202
6155
  // CRITICAL: This must run AFTER initialFormData to pick up any values embedded in the components themselves
6203
- if (validatedFormComponents && validatedFormComponents.length > 0) {
6204
- initializeComponentValues(validatedFormComponents, initialValues);
6205
- extractNotesAndAttachments(validatedFormComponents);
6156
+ if (formComponents && formComponents.length > 0) {
6157
+ initializeComponentValues(formComponents, initialValues);
6158
+ extractNotesAndAttachments(formComponents);
6206
6159
  }
6207
6160
  // Set the state
6208
6161
  setFormValues(prev => {
@@ -6245,21 +6198,20 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
6245
6198
  visibility[component.basic.label] = true;
6246
6199
  }
6247
6200
  }
6248
- // Handle nested components in table cells
6201
+ // Handle nested components in table cells (2D: row → cell → components)
6249
6202
  if (component.cells && Array.isArray(component.cells)) {
6250
- component.cells.forEach((rowOrCell) => {
6251
- // Handle 2D array (standard)
6252
- if (Array.isArray(rowOrCell)) {
6253
- rowOrCell.forEach((cell) => {
6254
- if (cell.components && Array.isArray(cell.components)) {
6203
+ component.cells.forEach((row) => {
6204
+ if (Array.isArray(row)) {
6205
+ row.forEach((cell) => {
6206
+ if (cell && cell.components && Array.isArray(cell.components)) {
6255
6207
  evaluateComponentConditionalLogic(cell.components, visibility, currentFormValues, fullSchema);
6256
6208
  }
6257
6209
  });
6258
6210
  }
6259
- // Handle 1D array (flat) structure
6260
- else if (typeof rowOrCell === 'object' && rowOrCell !== null) {
6261
- const cell = rowOrCell;
6262
- if (cell.components && Array.isArray(cell.components)) {
6211
+ else {
6212
+ // Handle flat 1D cell
6213
+ const cell = row;
6214
+ if (cell && cell.components && Array.isArray(cell.components)) {
6263
6215
  evaluateComponentConditionalLogic(cell.components, visibility, currentFormValues, fullSchema);
6264
6216
  }
6265
6217
  }
@@ -6386,13 +6338,24 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
6386
6338
  if (component.name === 'table' && component.cells) {
6387
6339
  return {
6388
6340
  ...component,
6389
- cells: component.cells.map((row) => row.map((cell) => {
6341
+ cells: component.cells.map((row) => {
6342
+ if (Array.isArray(row)) {
6343
+ return row.map((cell) => {
6344
+ const updatedCell = { ...cell };
6345
+ if (updatedCell.components) {
6346
+ updatedCell.components = updateComponentValue(updatedCell.components);
6347
+ }
6348
+ return updatedCell;
6349
+ });
6350
+ }
6351
+ // Handle flat 1D cell
6352
+ const cell = row;
6390
6353
  const updatedCell = { ...cell };
6391
6354
  if (updatedCell.components) {
6392
6355
  updatedCell.components = updateComponentValue(updatedCell.components);
6393
6356
  }
6394
6357
  return updatedCell;
6395
- }))
6358
+ })
6396
6359
  };
6397
6360
  }
6398
6361
  if (component.name === 'datagrid' && component.entries) {
@@ -6464,8 +6427,19 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
6464
6427
  // Check nested components in table cells
6465
6428
  if (comp.name === 'table' && comp.cells) {
6466
6429
  for (const row of comp.cells) {
6467
- for (const cell of row) {
6468
- if (cell.components) {
6430
+ if (Array.isArray(row)) {
6431
+ for (const cell of row) {
6432
+ if (cell && cell.components) {
6433
+ const found = findComponentById(cell.components, fieldId);
6434
+ if (found)
6435
+ return found;
6436
+ }
6437
+ }
6438
+ }
6439
+ else {
6440
+ // Handle flat 1D cell
6441
+ const cell = row;
6442
+ if (cell && cell.components) {
6469
6443
  const found = findComponentById(cell.components, fieldId);
6470
6444
  if (found)
6471
6445
  return found;
@@ -7192,86 +7166,48 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
7192
7166
  } }));
7193
7167
  case 'table':
7194
7168
  return (jsx(React.Suspense, { fallback: jsx("div", { children: "Loading table..." }), children: jsx(DfFormTable$1, { ...commonProps, properties: component, formData: formValues, formTemplateId: formTemplateId, mode: commonProps.mode, validationErrors: validationErrors, touchedFields: touchedFields, formSubmitted: formSubmitted, onThresholdActionCompletion: handleThresholdActionCompletion, onThresholdIssueRaised: handleThresholdIssueRaised, workOrderNumber: workOrderNumber, assetNumber: assetNumber, onCreateIssue: onCreateIssue, onUpdateIssue: onUpdateIssue, onNotesChange: (componentId, notes) => {
7195
- // Handle notes change for table cell components
7196
7169
  const updatedComponents = formComponents.map(comp => {
7197
7170
  if (comp.id === component.id && comp.cells) {
7198
- const updatedCells = comp.cells.map((rowOrCell) => {
7199
- if (Array.isArray(rowOrCell)) {
7200
- return rowOrCell.map((cell) => {
7201
- if (cell.components) {
7202
- const updatedCellComponents = cell.components.map((cellComp) => {
7203
- if (cellComp.id === componentId) {
7204
- return { ...cellComp, basic: { ...cellComp.basic, notes } };
7205
- }
7206
- return cellComp;
7207
- });
7208
- return { ...cell, components: updatedCellComponents };
7209
- }
7210
- return cell;
7211
- });
7212
- }
7213
- else {
7214
- const cell = rowOrCell;
7215
- if (cell.components) {
7216
- const updatedCellComponents = cell.components.map((cellComp) => {
7217
- if (cellComp.id === componentId) {
7218
- return { ...cellComp, basic: { ...cellComp.basic, notes } };
7219
- }
7220
- return cellComp;
7221
- });
7222
- return { ...cell, components: updatedCellComponents };
7223
- }
7224
- return cell;
7171
+ const updateCell = (cell) => {
7172
+ if (cell.components) {
7173
+ return {
7174
+ ...cell,
7175
+ components: cell.components.map((cellComp) => cellComp.id === componentId
7176
+ ? { ...cellComp, basic: { ...cellComp.basic, notes } }
7177
+ : cellComp)
7178
+ };
7225
7179
  }
7226
- });
7180
+ return cell;
7181
+ };
7182
+ const updatedCells = comp.cells.map((row) => Array.isArray(row) ? row.map(updateCell) : updateCell(row));
7227
7183
  return { ...comp, cells: updatedCells };
7228
7184
  }
7229
7185
  return comp;
7230
7186
  });
7231
7187
  onFormDataChange?.(updatedComponents);
7232
7188
  }, onAttachmentChange: (componentId, attachments) => {
7233
- // Handle attachment change for table cell components
7234
7189
  const updatedComponents = formComponents.map(comp => {
7235
7190
  if (comp.id === component.id && comp.cells) {
7236
- const updatedCells = comp.cells.map((rowOrCell) => {
7237
- if (Array.isArray(rowOrCell)) {
7238
- return rowOrCell.map((cell) => {
7239
- if (cell.components) {
7240
- const updatedCellComponents = cell.components.map((cellComp) => {
7241
- if (cellComp.id === componentId) {
7242
- return { ...cellComp, basic: { ...cellComp.basic, attachments: attachments || [] } };
7243
- }
7244
- return cellComp;
7245
- });
7246
- return { ...cell, components: updatedCellComponents };
7247
- }
7248
- return cell;
7249
- });
7250
- }
7251
- else {
7252
- const cell = rowOrCell;
7253
- if (cell.components) {
7254
- const updatedCellComponents = cell.components.map((cellComp) => {
7255
- if (cellComp.id === componentId) {
7256
- return { ...cellComp, basic: { ...cellComp.basic, attachments: attachments || [] } };
7257
- }
7258
- return cellComp;
7259
- });
7260
- return { ...cell, components: updatedCellComponents };
7261
- }
7262
- return cell;
7191
+ const updateCell = (cell) => {
7192
+ if (cell.components) {
7193
+ return {
7194
+ ...cell,
7195
+ components: cell.components.map((cellComp) => cellComp.id === componentId
7196
+ ? { ...cellComp, basic: { ...cellComp.basic, attachments: attachments || [] } }
7197
+ : cellComp)
7198
+ };
7263
7199
  }
7264
- });
7200
+ return cell;
7201
+ };
7202
+ const updatedCells = comp.cells.map((row) => Array.isArray(row) ? row.map(updateCell) : updateCell(row));
7265
7203
  return { ...comp, cells: updatedCells };
7266
7204
  }
7267
7205
  return comp;
7268
7206
  });
7269
7207
  onFormDataChange?.(updatedComponents);
7270
7208
  }, renderFormComponent: (field) => {
7271
- // CRITICAL: Pass the field to renderFormComponent which has access to latest formValues
7272
- // renderFormComponent uses formValues[field.id] internally, so it will get the correct value
7273
7209
  return renderFormComponent(field);
7274
- } }) }));
7210
+ }, shouldShowComponent: shouldShowComponent }) }));
7275
7211
  case 'datagrid':
7276
7212
  return (jsx(DfFormDataGrid, { ...commonProps, properties: component, formData: formValues, formTemplateId: formTemplateId, mode: commonProps.mode, onThresholdActionCompletion: handleThresholdActionCompletion, onThresholdIssueRaised: handleThresholdIssueRaised, onNotesChange: (componentId, notes) => {
7277
7213
  handleComponentNotesChange(componentId, notes);
@@ -7581,12 +7517,13 @@ const ensureComponentHasId = (component) => {
7581
7517
  }
7582
7518
  return component;
7583
7519
  };
7584
- const SimpleTableComponent = ({ component, mode, renderFormComponent, formData = {}, formTemplateId, onThresholdActionCompletion, onThresholdIssueRaised, onNotesChange, onAttachmentChange, workOrderNumber, assetNumber, user, onCreateIssue, onUpdateIssue }) => {
7520
+ const SimpleTableComponent = ({ component, mode, renderFormComponent, formData = {}, formTemplateId, onThresholdActionCompletion, onThresholdIssueRaised, onNotesChange, onAttachmentChange, workOrderNumber, assetNumber, user, onCreateIssue, onUpdateIssue, shouldShowComponent }) => {
7585
7521
  const formValue = formData[component.id];
7522
+ const isVisible = shouldShowComponent ? shouldShowComponent(component.id) : true;
7586
7523
  // Check if component has notes or attachments for submission view
7587
7524
  const hasSubmissionData = mode === 'preview' && ((component.basic?.notes && component.basic.notes.trim().length > 0) ||
7588
7525
  (component.basic?.attachments && Array.isArray(component.basic.attachments) && component.basic.attachments.length > 0));
7589
- return (jsxs("div", { className: "simple-table-component", children: [renderFormComponent(component), !['section', 'table', 'heading', 'file', 'instructions', 'signature', 'location', 'datagrid'].includes(component.name) && (jsx(ComponentActionFeatures, { component: component, mode: "test", formTemplateId: formTemplateId, formValue: formValue, formData: formData, onThresholdActionCompletion: onThresholdActionCompletion, onThresholdIssueRaised: onThresholdIssueRaised, onNotesChange: onNotesChange ? (notes) => onNotesChange(component.id, notes) : undefined, onAttachmentChange: onAttachmentChange ? (attachments) => onAttachmentChange(component.id, attachments) : undefined, workOrderNumber: workOrderNumber, assetNumber: assetNumber, user: user, onCreateIssue: onCreateIssue, onUpdateIssue: onUpdateIssue })), hasSubmissionData && (jsx(ComponentSubmissionActions, { component: component }))] }));
7526
+ return (jsxs("div", { className: `simple-table-component ${(!isVisible && mode !== 'edit') ? 'conditionally-hidden' : ''}`, style: { display: (isVisible || mode === 'edit') ? undefined : 'none' }, children: [renderFormComponent(component), mode === 'test' && !['section', 'table', 'heading', 'file', 'instructions', 'signature', 'location', 'datagrid'].includes(component.name) && (jsx(ComponentActionFeatures, { component: component, mode: "test", formTemplateId: formTemplateId, formValue: formValue, formData: formData, onThresholdActionCompletion: onThresholdActionCompletion, onThresholdIssueRaised: onThresholdIssueRaised, onNotesChange: onNotesChange ? (notes) => onNotesChange(component.id, notes) : undefined, onAttachmentChange: onAttachmentChange ? (attachments) => onAttachmentChange(component.id, attachments) : undefined, workOrderNumber: workOrderNumber, assetNumber: assetNumber, user: user, onCreateIssue: onCreateIssue, onUpdateIssue: onUpdateIssue })), hasSubmissionData && (jsx(ComponentSubmissionActions, { component: component }))] }));
7590
7527
  };
7591
7528
  const DraggableTableComponent = ({ component, selectedComponent, mode, onComponentSelect, onComponentDelete, onComponentEdit, renderFormComponent, isOverlay = false, }) => {
7592
7529
  const { attributes, listeners, setNodeRef, transform, transition, isDragging, isSorting, } = useSortable({
@@ -7607,7 +7544,7 @@ const DraggableTableComponent = ({ component, selectedComponent, mode, onCompone
7607
7544
  onComponentDelete(component, e);
7608
7545
  }, type: "button", title: "Delete Component", children: jsx(Trash2, { size: 12 }) })] }))] }));
7609
7546
  };
7610
- const TableCellComponent = ({ cell, mode, onComponentSelect, onComponentDelete, onComponentEdit, selectedComponent, renderFormComponent, formData = {}, formTemplateId, onThresholdActionCompletion, onThresholdIssueRaised, tableId, onNotesChange, onAttachmentChange, workOrderNumber, assetNumber, user, onCreateIssue, onUpdateIssue }) => {
7547
+ const TableCellComponent = ({ cell, mode, onComponentSelect, onComponentDelete, onComponentEdit, selectedComponent, renderFormComponent, formData = {}, formTemplateId, onThresholdActionCompletion, onThresholdIssueRaised, tableId, onNotesChange, onAttachmentChange, workOrderNumber, assetNumber, user, onCreateIssue, onUpdateIssue, shouldShowComponent }) => {
7611
7548
  const dropZoneId = `table-cell-${tableId}-${cell.row}-${cell.column}`;
7612
7549
  const { setNodeRef, isOver } = useDroppable({
7613
7550
  id: dropZoneId,
@@ -7642,7 +7579,7 @@ const TableCellComponent = ({ cell, mode, onComponentSelect, onComponentDelete,
7642
7579
  cell.components.map((component) => {
7643
7580
  // Only ensure ID if it's truly missing - don't regenerate existing IDs
7644
7581
  const componentWithId = component.id ? component : ensureComponentHasId(component);
7645
- return (jsx(SimpleTableComponent, { component: componentWithId, mode: mode, renderFormComponent: renderFormComponent, formData: formData, formTemplateId: formTemplateId, onThresholdActionCompletion: onThresholdActionCompletion, onThresholdIssueRaised: onThresholdIssueRaised, onNotesChange: onNotesChange, onAttachmentChange: onAttachmentChange, workOrderNumber: workOrderNumber, assetNumber: assetNumber, user: user, onCreateIssue: onCreateIssue, onUpdateIssue: onUpdateIssue }, componentWithId.id));
7582
+ return (jsx(SimpleTableComponent, { component: componentWithId, mode: mode, renderFormComponent: renderFormComponent, formData: formData, formTemplateId: formTemplateId, onThresholdActionCompletion: onThresholdActionCompletion, onThresholdIssueRaised: onThresholdIssueRaised, onNotesChange: onNotesChange, onAttachmentChange: onAttachmentChange, workOrderNumber: workOrderNumber, assetNumber: assetNumber, user: user, onCreateIssue: onCreateIssue, onUpdateIssue: onUpdateIssue, shouldShowComponent: shouldShowComponent }, componentWithId.id));
7646
7583
  }))) : (
7647
7584
  // Only show drop zone content in edit mode
7648
7585
  mode === 'edit' ? (jsx("div", { className: "empty-cell-placeholder", children: jsxs("div", { className: "cell-info", children: [jsx("span", { className: "drop-zone-text", children: "Drag and Drop a form component" }), jsxs("span", { className: "cell-coordinates", children: ["Cell (", cell.row + 1, ", ", cell.column + 1, ")"] })] }) })) : (
@@ -7653,44 +7590,19 @@ const TableCellComponent = ({ cell, mode, onComponentSelect, onComponentDelete,
7653
7590
  visibility: 'hidden' // Hide content but maintain space
7654
7591
  }, children: "\u00A0" }))) }) }));
7655
7592
  };
7656
- const DfFormTable = ({ id, properties, mode = 'edit', formData = {}, validationErrors = {}, touchedFields = {}, formSubmitted = false, onValueChange, onSelect, isSelected = false, className = '', onTableSelect, onComponentSelect, onComponentDelete, onComponentEdit, selectedComponent, renderFormComponent, formTemplateId, onThresholdActionCompletion, onThresholdIssueRaised, onNotesChange, onAttachmentChange, workOrderNumber, assetNumber, user, onCreateIssue, onUpdateIssue }) => {
7657
- const [isCollapsed, setIsCollapsed] = useState(false); // Always start expanded to show drop zones
7658
- // Normalize cells: API may return a flat 1D array of cells (each with .row/.column)
7659
- // or a proper 2D array of rows. Always convert to 2D for consistent rendering.
7660
- const normalizedCells = useMemo(() => {
7661
- const raw = properties.cells;
7662
- if (!raw || !Array.isArray(raw) || raw.length === 0)
7663
- return [];
7664
- // DEBUG: Log cell structure to understand API format
7665
- console.log('[DfFormTable] raw cells (first item):', JSON.stringify(raw[0], null, 2));
7666
- console.log('[DfFormTable] is first item array?', Array.isArray(raw[0]));
7667
- console.log('[DfFormTable] total cells:', raw.length);
7668
- // Check if it's already a 2D array (first element is an array)
7669
- if (Array.isArray(raw[0])) {
7670
- console.log('[DfFormTable] Using 2D array format');
7671
- return raw;
7672
- }
7673
- // It's a flat 1D array — reconstruct 2D using each cell's row/column
7674
- console.log('[DfFormTable] Using 1D flat format, reconstructing 2D grid');
7675
- const grid = [];
7676
- raw.forEach((cell) => {
7677
- const r = typeof cell.row === 'number' ? cell.row : 0;
7678
- const c = typeof cell.column === 'number' ? cell.column : 0;
7679
- console.log(`[DfFormTable] Cell at row=${r} col=${c}, components count:`, cell.components?.length ?? 0);
7680
- if (!grid[r])
7681
- grid[r] = [];
7682
- grid[r][c] = cell;
7683
- });
7684
- return grid;
7685
- }, [properties.cells]);
7593
+ const DfFormTable = ({ id, properties, mode = 'edit', formData = {}, validationErrors = {}, touchedFields = {}, formSubmitted = false, onValueChange, onSelect, isSelected = false, className = '', onTableSelect, onComponentSelect, onComponentDelete, onComponentEdit, selectedComponent, renderFormComponent, formTemplateId, onThresholdActionCompletion, onThresholdIssueRaised, onNotesChange, onAttachmentChange, workOrderNumber, assetNumber, user, onCreateIssue, onUpdateIssue, shouldShowComponent }) => {
7594
+ const [isCollapsed, setIsCollapsed] = useState(false);
7595
+ // Cells may be 2D (row arrays) or 1D (flat cells) depending on API format.
7596
+ // The useMemo in DfFormPreview ensures IDs, but structure may still vary.
7686
7597
  // Check if table has any components in any cells
7687
- const hasAnyComponents = normalizedCells.some(row => Array.isArray(row) && row.some(cell => cell && cell.components && cell.components.length > 0)) || false;
7688
- // Initialize and update table cells when rows/columns change
7689
- // CRITICAL: Skip cell initialization updates to prevent flickering when user types
7690
- useEffect(() => {
7691
- // Skip updates to prevent flickering - cells are already initialized
7692
- return;
7693
- }, [properties.table?.rows, properties.table?.columns, properties.basic?.rows, properties.basic?.columns, properties.cells, id, onValueChange]); // Watch for rows/columns changes
7598
+ const hasAnyComponents = properties.cells?.some((row) => {
7599
+ if (Array.isArray(row)) {
7600
+ return row.some((cell) => cell && cell.components && cell.components.length > 0);
7601
+ }
7602
+ // Handle flat 1D cell
7603
+ const cell = row;
7604
+ return cell && cell.components && cell.components.length > 0;
7605
+ }) || false;
7694
7606
  const handleTableClick = useCallback((event) => {
7695
7607
  event.stopPropagation();
7696
7608
  onSelect?.();
@@ -7706,54 +7618,46 @@ const DfFormTable = ({ id, properties, mode = 'edit', formData = {}, validationE
7706
7618
  };
7707
7619
  const handleComponentDelete = useCallback((component, event) => {
7708
7620
  event.stopPropagation();
7709
- // Find and remove the component from the table cell
7710
- const updatedCells = normalizedCells.map(row => (Array.isArray(row) ? row : []).map(cell => {
7621
+ const updatedCells = properties.cells.map((row) => {
7622
+ if (Array.isArray(row)) {
7623
+ return row.map((cell) => {
7624
+ if (cell && cell.components && cell.components.some((comp) => comp.id === component.id)) {
7625
+ return { ...cell, components: cell.components.filter((comp) => comp.id !== component.id) };
7626
+ }
7627
+ return cell;
7628
+ });
7629
+ }
7630
+ // Handle flat 1D cell
7631
+ const cell = row;
7711
7632
  if (cell && cell.components && cell.components.some((comp) => comp.id === component.id)) {
7712
- const filteredComponents = cell.components.filter((comp) => comp.id !== component.id);
7713
- return {
7714
- ...cell,
7715
- components: filteredComponents
7716
- };
7633
+ return { ...cell, components: cell.components.filter((comp) => comp.id !== component.id) };
7717
7634
  }
7718
7635
  return cell;
7719
- }));
7720
- // Update the table with the modified cells
7721
- if (onValueChange) {
7722
- onValueChange({
7723
- id,
7724
- value: { ...properties, cells: updatedCells }
7725
- });
7726
- }
7727
- // Don't call parent delete handler for table cell components
7728
- // The parent delete handler is for deleting entire fields, not components within table cells
7636
+ });
7637
+ onValueChange?.({ id, value: { ...properties, cells: updatedCells } });
7729
7638
  }, [onComponentDelete, properties, onValueChange, id]);
7730
- // CRITICAL FIX: Ensure all table cell components have proper IDs with table and cell position
7731
- // Use useMemo to prevent ID regeneration on every render
7732
- // Uses normalizedCells so it works whether API returns 1D or 2D cell arrays
7733
- const cellsWithIds = useMemo(() => {
7734
- if (!normalizedCells || normalizedCells.length === 0)
7735
- return [];
7736
- return normalizedCells.map((row, rowIndex) => (Array.isArray(row) ? row : []).map((cell, cellIndex) => ({
7737
- ...cell,
7738
- components: (cell && cell.components && Array.isArray(cell.components))
7739
- ? cell.components.map((comp, compIndex) => {
7740
- // CRITICAL: Only generate ID if it's missing - never regenerate existing IDs
7741
- // This prevents component remounting and losing input state
7742
- if (comp.id && typeof comp.id === 'string' && comp.id.trim() !== '') {
7743
- // ID already exists - keep it as is
7744
- return comp;
7745
- }
7746
- // Generate unique ID that includes table ID, row, cell, and component index
7747
- // This ensures no conflicts with other components
7748
- const uniqueId = `${comp.name || 'component'}-table-${id}-row-${rowIndex}-cell-${cellIndex}-comp-${compIndex}`;
7749
- return {
7750
- ...comp,
7751
- id: uniqueId
7752
- };
7753
- })
7754
- : []
7755
- })));
7756
- }, [normalizedCells, id]); // Only recalculate if cells or table ID changes
7639
+ // Ensure all table cell components have IDs (matching website ensureTableCellComponentsHaveIds)
7640
+ const ensureCellComponentIds = (cell) => ({
7641
+ ...cell,
7642
+ components: (cell?.components || []).map((comp) => {
7643
+ if (!comp.id || comp.id.trim() === '') {
7644
+ return { ...comp, id: `table-cell-${comp.name}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}` };
7645
+ }
7646
+ return comp;
7647
+ })
7648
+ });
7649
+ const ensureTableCellComponentsHaveIds = (cells) => {
7650
+ return cells.map((row) => {
7651
+ if (Array.isArray(row)) {
7652
+ return row.map(ensureCellComponentIds);
7653
+ }
7654
+ // Handle flat 1D cell
7655
+ return ensureCellComponentIds(row);
7656
+ });
7657
+ };
7658
+ const cellsWithIds = properties.cells && properties.cells.length > 0
7659
+ ? ensureTableCellComponentsHaveIds(properties.cells)
7660
+ : [];
7757
7661
  // CRITICAL FIX: Update the parent component with the cells that have proper IDs
7758
7662
  // Skip this in package to prevent flickering - cells are managed by parent
7759
7663
  // useEffect(() => {
@@ -7881,7 +7785,7 @@ const DfFormTable = ({ id, properties, mode = 'edit', formData = {}, validationE
7881
7785
  fontSize: '14px',
7882
7786
  textAlign: 'center'
7883
7787
  }, children: columnName }, `header-${colIndex}`));
7884
- }) }) })), jsx("tbody", { children: cellsWithIds.filter(row => Array.isArray(row) && row.length > 0).map((row, rowIndex) => (jsx("tr", { className: "table-row", children: row.filter(cell => cell != null).map((cell) => (jsx(TableCellComponent, { cell: cell, mode: mode, onComponentSelect: onComponentSelect || (() => { }), onComponentDelete: handleComponentDelete, onComponentEdit: onComponentEdit, selectedComponent: selectedComponent || null, renderFormComponent: renderComponent, formData: formData, formTemplateId: formTemplateId, onThresholdActionCompletion: onThresholdActionCompletion, onThresholdIssueRaised: onThresholdIssueRaised, tableId: id, onNotesChange: onNotesChange, onAttachmentChange: onAttachmentChange, workOrderNumber: workOrderNumber, assetNumber: assetNumber, user: user, onCreateIssue: onCreateIssue, onUpdateIssue: onUpdateIssue }, cell.id))) }, rowIndex))) })] })] }))] }));
7788
+ }) }) })), jsx("tbody", { children: cellsWithIds.filter((row) => Array.isArray(row) && row.length > 0).map((row, rowIndex) => (jsx("tr", { className: "table-row", children: row.filter((cell) => cell != null).map((cell) => (jsx(TableCellComponent, { cell: cell, mode: mode, onComponentSelect: onComponentSelect || (() => { }), onComponentDelete: handleComponentDelete, onComponentEdit: onComponentEdit, selectedComponent: selectedComponent || null, renderFormComponent: renderComponent, formData: formData, formTemplateId: formTemplateId, onThresholdActionCompletion: onThresholdActionCompletion, onThresholdIssueRaised: onThresholdIssueRaised, tableId: id, onNotesChange: onNotesChange, onAttachmentChange: onAttachmentChange, workOrderNumber: workOrderNumber, assetNumber: assetNumber, user: user, onCreateIssue: onCreateIssue, onUpdateIssue: onUpdateIssue, shouldShowComponent: shouldShowComponent }, cell.id))) }, rowIndex))) })] })] }))] }));
7885
7789
  };
7886
7790
 
7887
7791
  var dfFormTable = /*#__PURE__*/Object.freeze({