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) {
|
if (row == inj_idx) {
|
||||||
// Esta es la fila inyectada - leer del edit buffer
|
// Esta es la fila inyectada - leer del edit buffer
|
||||||
if (self.state.row_edit_buffer.getPendingValue(col)) |pending| {
|
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);
|
const copy_len = @min(pending.len, buf.len);
|
||||||
@memcpy(buf[0..copy_len], pending[0..copy_len]);
|
@memcpy(buf[0..copy_len], pending[0..copy_len]);
|
||||||
return buf[0..copy_len];
|
return buf[0..copy_len];
|
||||||
}
|
}
|
||||||
// Sin valor pendiente - retornar vacío (celda nueva)
|
// Sin valor pendiente - retornar vacío (celda nueva)
|
||||||
|
std.debug.print("[PDS-DEBUG] injected row={} col={} NO pending\n", .{ row, col });
|
||||||
return "";
|
return "";
|
||||||
} else if (row > inj_idx) {
|
} else if (row > inj_idx) {
|
||||||
// Fila después de la inyección - ajustar índice (-1)
|
// Fila después de la inyección - ajustar índice (-1)
|
||||||
|
|
|
||||||
|
|
@ -343,10 +343,19 @@ pub fn virtualAdvancedTableRect(
|
||||||
const edited_cell = list_state.getEditingCell().?;
|
const edited_cell = list_state.getEditingCell().?;
|
||||||
const new_value = list_state.getEditText();
|
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)
|
// Añadir cambio al buffer de fila (NO commit inmediato)
|
||||||
// El commit real se hace cuando el usuario abandona la fila
|
// El commit real se hace cuando el usuario abandona la fila
|
||||||
if (list_state.hasValueChanged()) {
|
if (list_state.hasValueChanged()) {
|
||||||
list_state.row_edit_buffer.addChange(edited_cell.col, new_value);
|
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
|
// Compatibilidad: mantener flags antiguos
|
||||||
result.cell_committed = true;
|
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;
|
const is_tab = result.navigate_direction == .next_cell or result.navigate_direction == .prev_cell;
|
||||||
if (is_tab) {
|
if (is_tab) {
|
||||||
// Wrapper para DataProvider que implementa getRowId(usize) -> i64
|
// Wrapper para DataProvider que implementa getRowId(usize) -> i64
|
||||||
|
// Tiene en cuenta filas inyectadas (Ctrl+N) y ghost row
|
||||||
const RowIdGetter = struct {
|
const RowIdGetter = struct {
|
||||||
prov: DataProvider,
|
prov: DataProvider,
|
||||||
total: usize,
|
total: usize,
|
||||||
|
injected_idx: ?usize,
|
||||||
|
|
||||||
pub fn getRowId(self: @This(), row: usize) i64 {
|
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;
|
if (row >= self.total) return table_core.NEW_ROW_ID;
|
||||||
return self.prov.getRowId(row) orelse 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 current_row = list_state.getSelectedRow() orelse 0;
|
||||||
const forward = result.navigate_direction == .next_cell;
|
const forward = result.navigate_direction == .next_cell;
|
||||||
const num_cols = config.columns.len;
|
const num_cols = config.columns.len;
|
||||||
// VirtualAdvancedTable siempre tiene ghost row disponible
|
// 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(
|
const plan = table_core.planTabNavigation(
|
||||||
&list_state.row_edit_buffer,
|
&list_state.row_edit_buffer,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue