@@ -2,6 +2,8 @@ import { Node, Attribute } from '@core/index.js';
22import { callOrGet } from '@core/utilities/callOrGet.js' ;
33import { getExtensionConfigField } from '@core/helpers/getExtensionConfigField.js' ;
44import { /* TableView */ createTableView } from './TableView.js' ;
5+ import { findParentNodeClosestToPos } from '@helpers/index.js' ;
6+ import { Fragment } from "prosemirror-model" ;
57import { createTable } from './tableHelpers/createTable.js' ;
68import { createColGroup } from './tableHelpers/createColGroup.js' ;
79import { deleteTableWhenSelected } from './tableHelpers/deleteTableWhenSelected.js' ;
@@ -10,6 +12,7 @@ import { createTableBorders } from './tableHelpers/createTableBorders.js';
1012import { createCellBorders } from '../table-cell/helpers/createCellBorders.js' ;
1113import { findParentNode } from '@helpers/findParentNode.js' ;
1214import { TextSelection } from 'prosemirror-state' ;
15+ import { getFieldAttrs } from '@helpers/annotator.js' ;
1316import {
1417 addColumnBefore ,
1518 addColumnAfter ,
@@ -295,6 +298,76 @@ export const Table = Node.create({
295298
296299 return true ;
297300 } ,
301+
302+ generateTable : ( annotation , matchingAnnotation , fieldData ) => {
303+ return ( { tr, editor } ) => {
304+ const seenTableRowAnnotationIds = [ ] ;
305+ const { state : { doc, schema } } = editor ;
306+ const { tableRow : RowType , tableCell : CellType , fieldAnnotation : FieldType , paragraph : ParaType } = schema . nodes ;
307+
308+ // Locate the parent row node containing the annotation
309+ const position = doc . resolve ( annotation . pos ) ;
310+ const rowInfo = findParentNodeClosestToPos ( position , ( node ) => node . type === RowType ) ;
311+ if ( ! rowInfo ) return ;
312+
313+ // Get all annotations in the row
314+ rowInfo . node . descendants ( ( node , pos ) => {
315+ if ( node . type . name === 'fieldAnnotation' ) {
316+ seenTableRowAnnotationIds . push ( node . attrs . fieldId ) ;
317+ }
318+ } ) ;
319+
320+ if ( ! seenTableRowAnnotationIds . includes ( annotation . node . attrs . fieldId ) ) return [ ] ;
321+
322+ // Figure out the position where we will start inserting new rows
323+ const { pos : rowStartPos , node : rowNode } = rowInfo ;
324+ let insertPos = rowStartPos + rowNode . nodeSize ;
325+
326+ // Helper: rebuild a single cell for a given row index
327+ const rebuildCell = ( cellNode , rowIndex ) => {
328+ const updatedBlocks = cellNode . content . content . map ( ( blockNode ) => {
329+ if ( blockNode . type !== ParaType ) return blockNode ;
330+
331+ // Rebuild paragraphs by mapping inline nodes
332+ const updatedInlines = blockNode . content . content . map ( ( inlineNode ) => {
333+ if ( inlineNode . type !== FieldType ) return inlineNode ;
334+
335+ // Find the matching field data and compute new attributes
336+ const fieldRecord = fieldData . find ( ( f ) => f . input_id === inlineNode . attrs . fieldId ) ;
337+ const value = fieldRecord ?. input_value [ rowIndex ] ;
338+
339+ // Different field types require different annotation handling
340+ // We use the helper here to get the correct attributes
341+ // Since generated tables contain annotated fields
342+ const extraAttrs = getFieldAttrs ( inlineNode , value ) ;
343+ return FieldType . create (
344+ { ...inlineNode . attrs , ...extraAttrs } ,
345+ inlineNode . content ,
346+ inlineNode . marks
347+ ) ;
348+ } ) ;
349+
350+ return ParaType . create ( blockNode . attrs , Fragment . from ( updatedInlines ) , blockNode . marks ) ;
351+ } ) ;
352+
353+ return CellType . create ( cellNode . attrs , Fragment . from ( updatedBlocks ) , cellNode . marks ) ;
354+ } ;
355+
356+ // Iterate over each row value and build+insert a new row
357+ matchingAnnotation . input_value . forEach ( ( _ , rowIndex ) => {
358+ // Build all cells for the new row
359+ const newCells = rowNode . content . content . map ( ( cellNode ) => rebuildCell ( cellNode , rowIndex ) ) ;
360+ const newRow = RowType . create ( rowNode . attrs , Fragment . from ( newCells ) , rowNode . marks ) ;
361+
362+ tr . insert ( insertPos , Fragment . from ( newRow ) ) ;
363+ insertPos += newRow . nodeSize ;
364+ } ) ;
365+
366+ // Remove the original (placeholder) row
367+ tr . delete ( rowStartPos , rowStartPos + rowNode . nodeSize ) ;
368+ return seenTableRowAnnotationIds ;
369+ } ;
370+ } ,
298371 } ;
299372 } ,
300373
0 commit comments