feat(virtual_table): Add injection state for Ctrl+N between rows

State fields:
- injected_row_idx: visual index of injected row
- injected_row_id: ID after commit (NEW_ROW_ID until saved)
- injected_committed: true when saved to DB

Result fields:
- injection_committed: panel should INSERT
- injection_row_idx: where it was injected
- needs_reload: table should refetch from DB

Helper methods:
- hasInjection(), startInjection(), clearInjection()
- markInjectionCommitted(), isInjectionVisible()
This commit is contained in:
reugenio 2025-12-28 02:22:06 +01:00
parent c6b9bd080a
commit 712466adc8
2 changed files with 66 additions and 0 deletions

View file

@ -163,6 +163,19 @@ pub const VirtualAdvancedTableState = struct {
/// Buffer para acumular cambios de la fila actual antes de commit
row_edit_buffer: table_core.RowEditBuffer = .{},
// =========================================================================
// Estado de inyección local (Ctrl+N entre líneas)
// =========================================================================
/// Índice visual donde está la fila inyectada (null = sin inyección)
injected_row_idx: ?usize = null,
/// ID de la fila inyectada tras commit (NEW_ROW_ID si aún no guardada)
injected_row_id: i64 = table_core.NEW_ROW_ID,
/// True si la fila inyectada ya fue guardada en BD (tiene ID real)
injected_committed: bool = false,
const Self = @This();
// =========================================================================
@ -715,6 +728,46 @@ pub const VirtualAdvancedTableState = struct {
.h = row_height,
};
}
// =========================================================================
// Métodos de inyección local (Ctrl+N entre líneas)
// =========================================================================
/// Verifica si hay una fila inyectada activa
pub fn hasInjection(self: *const Self) bool {
return self.injected_row_idx != null;
}
/// Inicia una inyección en el índice especificado
pub fn startInjection(self: *Self, visual_idx: usize) void {
self.injected_row_idx = visual_idx;
self.injected_row_id = table_core.NEW_ROW_ID;
self.injected_committed = false;
self.row_edit_buffer.startInjectedEdit(visual_idx);
}
/// Marca la fila inyectada como guardada en BD
pub fn markInjectionCommitted(self: *Self, real_id: i64) void {
self.injected_row_id = real_id;
self.injected_committed = true;
}
/// Limpia el estado de inyección (después de reload)
pub fn clearInjection(self: *Self) void {
self.injected_row_idx = null;
self.injected_row_id = table_core.NEW_ROW_ID;
self.injected_committed = false;
}
/// Verifica si la fila inyectada está visible en la ventana actual
pub fn isInjectionVisible(self: *const Self, visible_rows: usize) bool {
if (self.injected_row_idx) |idx| {
const scroll_start = self.nav.scroll_row;
const scroll_end = scroll_start + visible_rows;
return idx >= scroll_start and idx < scroll_end;
}
return false;
}
};
// =============================================================================

View file

@ -130,6 +130,19 @@ pub const VirtualAdvancedTableResult = struct {
/// Shift estaba presionado con Tab (para tab_out inverso)
tab_shift: bool = false,
// =========================================================================
// Inyección local (Ctrl+N entre líneas)
// =========================================================================
/// Una fila inyectada fue guardada en BD (el panel debe hacer INSERT)
injection_committed: bool = false,
/// Índice visual donde se inyectó la fila
injection_row_idx: ?usize = null,
/// La tabla necesita recargarse desde BD (fila inyectada salió del viewport)
needs_reload: bool = false,
// =========================================================================
// Compatibilidad (DEPRECADO - usar row_committed)
// =========================================================================