fix(virtual_table): RowIdGetter now handles injected rows
Bug: Tab within injected row was triggering immediate row commit. This happened because RowIdGetter.getRowId() returned the REAL row ID for the injected row index, instead of NEW_ROW_ID. Fix: - RowIdGetter now takes injected_idx parameter - Returns NEW_ROW_ID for injected row - Adjusts indices for rows after injection (row-1) - num_rows calculation now accounts for injection (+1) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
4b61c2a119
commit
b3a33ec4f3
2 changed files with 34 additions and 3 deletions
|
|
@ -80,11 +80,13 @@ pub const PagedDataSource = struct {
|
|||
if (row == inj_idx) {
|
||||
// Esta es la fila inyectada - leer del edit buffer
|
||||
if (self.state.row_edit_buffer.getPendingValue(col)) |pending| {
|
||||
std.debug.print("[PDS-DEBUG] injected row={} col={} pending=\"{s}\"\n", .{ row, col, pending });
|
||||
const copy_len = @min(pending.len, buf.len);
|
||||
@memcpy(buf[0..copy_len], pending[0..copy_len]);
|
||||
return buf[0..copy_len];
|
||||
}
|
||||
// Sin valor pendiente - retornar vacío (celda nueva)
|
||||
std.debug.print("[PDS-DEBUG] injected row={} col={} NO pending\n", .{ row, col });
|
||||
return "";
|
||||
} else if (row > inj_idx) {
|
||||
// Fila después de la inyección - ajustar índice (-1)
|
||||
|
|
|
|||
|
|
@ -343,10 +343,19 @@ pub fn virtualAdvancedTableRect(
|
|||
const edited_cell = list_state.getEditingCell().?;
|
||||
const new_value = list_state.getEditText();
|
||||
|
||||
std.debug.print("[VT-DEBUG] editor committed: cell=({},{}) value=\"{s}\" hasChanged={} is_injected={}\n", .{
|
||||
edited_cell.row,
|
||||
edited_cell.col,
|
||||
new_value,
|
||||
list_state.hasValueChanged(),
|
||||
list_state.row_edit_buffer.is_injected,
|
||||
});
|
||||
|
||||
// Añadir cambio al buffer de fila (NO commit inmediato)
|
||||
// El commit real se hace cuando el usuario abandona la fila
|
||||
if (list_state.hasValueChanged()) {
|
||||
list_state.row_edit_buffer.addChange(edited_cell.col, new_value);
|
||||
std.debug.print("[VT-DEBUG] addChange: col={} value=\"{s}\"\n", .{ edited_cell.col, new_value });
|
||||
|
||||
// Compatibilidad: mantener flags antiguos
|
||||
result.cell_committed = true;
|
||||
|
|
@ -435,23 +444,43 @@ pub fn virtualAdvancedTableRect(
|
|||
const is_tab = result.navigate_direction == .next_cell or result.navigate_direction == .prev_cell;
|
||||
if (is_tab) {
|
||||
// Wrapper para DataProvider que implementa getRowId(usize) -> i64
|
||||
// Tiene en cuenta filas inyectadas (Ctrl+N) y ghost row
|
||||
const RowIdGetter = struct {
|
||||
prov: DataProvider,
|
||||
total: usize,
|
||||
injected_idx: ?usize,
|
||||
|
||||
pub fn getRowId(self: @This(), row: usize) i64 {
|
||||
// Ghost row está al final (índice = total)
|
||||
// Fila inyectada siempre retorna NEW_ROW_ID
|
||||
if (self.injected_idx) |inj_idx| {
|
||||
if (row == inj_idx) return table_core.NEW_ROW_ID;
|
||||
// Filas después de inyección: ajustar índice hacia provider
|
||||
if (row > inj_idx) {
|
||||
const adjusted_row = row - 1;
|
||||
if (adjusted_row >= self.total) return table_core.NEW_ROW_ID;
|
||||
return self.prov.getRowId(adjusted_row) orelse table_core.NEW_ROW_ID;
|
||||
}
|
||||
}
|
||||
// Ghost row está al final
|
||||
if (row >= self.total) return table_core.NEW_ROW_ID;
|
||||
return self.prov.getRowId(row) orelse table_core.NEW_ROW_ID;
|
||||
}
|
||||
};
|
||||
|
||||
const getter = RowIdGetter{ .prov = provider, .total = total_rows };
|
||||
const getter = RowIdGetter{
|
||||
.prov = provider,
|
||||
.total = total_rows,
|
||||
.injected_idx = list_state.injected_row_idx,
|
||||
};
|
||||
const current_row = list_state.getSelectedRow() orelse 0;
|
||||
const forward = result.navigate_direction == .next_cell;
|
||||
const num_cols = config.columns.len;
|
||||
// VirtualAdvancedTable siempre tiene ghost row disponible
|
||||
const num_rows = total_rows + 1;
|
||||
// Si hay inyección, sumar 1 extra al conteo visual
|
||||
var num_rows = total_rows + 1; // +1 para ghost row
|
||||
if (list_state.injected_row_idx != null) {
|
||||
num_rows += 1; // +1 para fila inyectada
|
||||
}
|
||||
|
||||
const plan = table_core.planTabNavigation(
|
||||
&list_state.row_edit_buffer,
|
||||
|
|
|
|||
Loading…
Reference in a new issue