refactor!: unify records and pivot mode cell handling
Refactor records mode to use synthetic CellKeys (_Index, _Dim) for all columns, allowing uniform handling of display values and edits across both pivot and records modes. - Introduce `synthetic_record_info` to extract metadata from synthetic keys. - Update `GridLayout::cell_key` to return synthetic keys in records mode. - Add `GridLayout::resolve_display` to handle value resolution for synthetic keys. - Replace `records_col` and `records_value` in `CmdContext` with a unified `display_value`. - Update `EditOrDrill` and `AddRecordRow` to use synthetic key detection. - Refactor `CommitCellEdit` to use a shared `commit_cell_value` helper. BREAKING CHANGE: CmdContext fields `records_col` and `records_value` are replaced by `display_value` . Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-31B-it-GGUF:UD-Q5_K_XL)
This commit is contained in:
@ -164,28 +164,34 @@ impl App {
|
||||
none_cats: layout.none_cats.clone(),
|
||||
view_back_stack: self.view_back_stack.clone(),
|
||||
view_forward_stack: self.view_forward_stack.clone(),
|
||||
records_col: if layout.is_records_mode() {
|
||||
Some(layout.col_label(sel_col))
|
||||
} else {
|
||||
None
|
||||
display_value: {
|
||||
let key = layout.cell_key(sel_row, sel_col);
|
||||
if let Some(k) = &key {
|
||||
if let Some((idx, dim)) = crate::view::synthetic_record_info(k) {
|
||||
// Synthetic records key: check pending drill edits first
|
||||
self.drill_state.as_ref()
|
||||
.and_then(|s| s.pending_edits.get(&(idx, dim)).cloned())
|
||||
.or_else(|| layout.resolve_display(k))
|
||||
.unwrap_or_default()
|
||||
} else {
|
||||
self.model.get_cell(k)
|
||||
.map(|v| v.to_string())
|
||||
.unwrap_or_default()
|
||||
}
|
||||
} else {
|
||||
String::new()
|
||||
}
|
||||
},
|
||||
records_value: if layout.is_records_mode() {
|
||||
// Check pending edits first, then fall back to original
|
||||
let col_name = layout.col_label(sel_col);
|
||||
let pending = self.drill_state.as_ref().and_then(|s| {
|
||||
s.pending_edits.get(&(sel_row, col_name.clone())).cloned()
|
||||
});
|
||||
pending.or_else(|| layout.records_display(sel_row, sel_col))
|
||||
} else {
|
||||
None
|
||||
},
|
||||
// Approximate visible rows/cols from terminal size.
|
||||
// Approximate visible rows from terminal size.
|
||||
// Chrome: title(1) + border(2) + col_headers(n_col_levels) + separator(1)
|
||||
// + tile_bar(1) + status_bar(1) = ~8 rows of chrome.
|
||||
visible_rows: (self.term_height as usize).saturating_sub(8),
|
||||
// Visible cols depends on column widths — use a rough estimate.
|
||||
// The grid renderer does the precise calculation.
|
||||
visible_cols: ((self.term_width as usize).saturating_sub(30) / 12).max(1),
|
||||
visible_cols: {
|
||||
let (fmt_comma, fmt_decimals) = parse_number_format(&view.number_format);
|
||||
let col_widths = compute_col_widths(&self.model, &layout, fmt_comma, fmt_decimals);
|
||||
let row_header_width = compute_row_header_width(&layout);
|
||||
compute_visible_cols(&col_widths, row_header_width, self.term_width, view.col_offset)
|
||||
},
|
||||
expanded_cats: &self.expanded_cats,
|
||||
key_code: key,
|
||||
}
|
||||
|
||||
@ -97,15 +97,7 @@ pub struct EnterEditAtCursor;
|
||||
impl Effect for EnterEditAtCursor {
|
||||
fn apply(&self, app: &mut App) {
|
||||
let ctx = app.cmd_context(crossterm::event::KeyCode::Null, crossterm::event::KeyModifiers::NONE);
|
||||
let value = if let Some(v) = &ctx.records_value {
|
||||
v.clone()
|
||||
} else {
|
||||
ctx.cell_key
|
||||
.as_ref()
|
||||
.and_then(|k| ctx.model.get_cell(k).cloned())
|
||||
.map(|v| v.to_string())
|
||||
.unwrap_or_default()
|
||||
};
|
||||
let value = ctx.display_value.clone();
|
||||
drop(ctx);
|
||||
app.buffers.insert("edit".to_string(), value);
|
||||
app.mode = AppMode::Editing {
|
||||
|
||||
Reference in New Issue
Block a user