TableController constructor

TableController({
  1. required TableConfig config,
  2. required List<Map<String, dynamic>> data,
})

Create controller from config and data

Implementation

factory TableController({
  required TableConfig config,
  required List<Map<String, dynamic>> data,
}) {
  // Process data: separate totals from regular rows
  final processedData = _processTableData(data, config.totals);

  // Detect if this is tree data
  final isTreeData = _isTreeData(processedData.regularRows);

  // Split columns into fixed/data sections
  final allColumns = config.allColumns;
  final fixedCount = config.fixedColumns;

  final fixedColumns = allColumns.take(fixedCount).toList();
  final dataColumns = allColumns.skip(fixedCount).toList();

  // Extract column groups
  final columnGroups = _extractColumnGroups(
    fixedColumns: fixedColumns,
    dataColumns: dataColumns,
  );

  // Initialize separate width arrays
  final fixedColumnWidths = fixedColumns.map((col) => col.width).toList();
  final dataColumnWidths = dataColumns.map((col) => col.width).toList();

  // Initialize column widths from config (keep for backward compatibility)
  final columnWidths = allColumns.map((col) => col.width).toList();

  // Create tree manager instance
  final treeManager = TreeManager();

  // Get expandable row IDs if tree data
  final expandableIds = isTreeData
      ? treeManager.getAllExpandableIds(processedData.regularRows)
      : <String>{};

  // Determine initial expanded state
  final initialExpanded = config.dataTreeStartExpanded ? expandableIds : <String>{};

  // Flatten tree if needed
  // Include totalRows as leaf TreeRows at top of tree
  final totalTreeRows = processedData.totalRows.asMap().entries.map((entry) {
    return TreeRow(
      data: entry.value,
      depth: 0,
      hasChildren: false,
      id: '_total_${entry.key}',
    );
  }).toList();

  final flattenedRegular = isTreeData
      ? treeManager.flattenTree(
          rows: processedData.regularRows,
          expandedIds: initialExpanded,
        )
      : <TreeRow>[];

  final treeRows = isTreeData
      ? [...totalTreeRows, ...flattenedRegular]
      : <TreeRow>[];

  // Initial visible rows
  final visibleRows = [...processedData.totalRows, ...processedData.regularRows];

  // Create initial state
  final state = TableState(
    config: config,
    columns: allColumns,
    fixedColumns: fixedColumns,
    dataColumns: dataColumns,
    fixedColumnWidths: fixedColumnWidths,
    dataColumnWidths: dataColumnWidths,
    columnGroups: columnGroups,
    originalRows: data,
    totalRows: processedData.totalRows,
    regularRows: processedData.regularRows,
    visibleRows: visibleRows,
    totalRowCount: visibleRows.length,
    sortField: config.sortColumn,
    sortAscending: config.initialSortAscending,
    columnWidths: columnWidths,
    isTreeData: isTreeData,
    expandedRowIds: initialExpanded,
    treeRows: treeRows,
    allExpanded: config.dataTreeStartExpanded && expandableIds.isNotEmpty,
    loadedRowCount: 50, // Progressive loading: initial 50 rows
  );

  return TableController._(state);
}