feat(tahuantinsuyu): editor inline para cartas libres (F2)
Las cartas libres ahora se pueden editar en su totalidad (fecha,
hora, lugar, lat/lon/alt, TZ, label) desde el menú contextual.
La edición es **in-memory** — la carta se queda como libre tras
el cambio; para persistirla hay que usar "Guardar como…".
Tree:
- Nuevo `Modal::EditFreeChart { source_id, form, error }`
paralelo al `Modal::EditChart` existente. Reusa la misma
`ChartForm` (11 TextInputs: name + place + date + time + TZ
+ lat/lon/alt) y la misma función `render_chart_form` para
pintarlo. El title cambia a "Editar carta libre".
- `open_edit_free_chart_modal(source_id, w, cx)`: lee el entry
de `self.free_charts` (que ahora trae `birth_data` además
de id+label), pre-puebla el form, y abre el modal.
- Submit: `build_chart_from_form` parsea + valida; al éxito
emite nuevo evento `TreeEvent::FreeChartEditConfirmed
{ source_id, birth_data, label }`. Al error, conserva el
modal con la pill destructiva.
- City picker funciona como antes — el branch de
`apply_city_preset` se extendió para que reconozca
`Modal::EditFreeChart` además de Create/Edit.
Modelo:
- `FreeChartEntry` ahora incluye `birth_data: StoredBirthData`
además de id+label. El shell se lo pasa al setter; el tree
lo usa para pre-poblar el form sin tener que pedirlo al
shell.
Shell:
- `push_free_charts_to_tree` clona `birth_data` en cada entry.
- Handler `FreeChartEditConfirmed`: actualiza
`free_charts[id]` con los nuevos datos + label, re-publica
al tree, y si la carta editada era la activa, re-renderea
el wheel.
Menú contextual de "Cartas libres" / `<carta libre>` ahora:
- Editar datos…
- Guardar como…
- Borrar (no se ofrece sobre sky-now)
10 tests verdes (sin afectar lo testeado).
Próximo y último: F4 — botón "Guardar como…" en cada módulo
overlay (RS, prog, sa, gr) que captura la carta derivada con
un sufijo automático en el contacto original.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -249,6 +249,7 @@ impl Shell {
|
||||
entries.push(FreeChartEntry {
|
||||
id: FreeChartId::sky_now(),
|
||||
label: c.label.clone(),
|
||||
birth_data: c.birth_data.clone(),
|
||||
});
|
||||
}
|
||||
let mut others: Vec<(&FreeChartId, &Chart)> = self
|
||||
@@ -261,6 +262,7 @@ impl Shell {
|
||||
entries.push(FreeChartEntry {
|
||||
id: id.clone(),
|
||||
label: c.label.clone(),
|
||||
birth_data: c.birth_data.clone(),
|
||||
});
|
||||
}
|
||||
self.tree
|
||||
@@ -502,6 +504,32 @@ impl Shell {
|
||||
);
|
||||
return;
|
||||
}
|
||||
TreeEvent::FreeChartEditConfirmed {
|
||||
source_id,
|
||||
birth_data,
|
||||
label,
|
||||
} => {
|
||||
if let Some(chart) = self.free_charts.get_mut(source_id) {
|
||||
chart.birth_data = birth_data.clone();
|
||||
chart.label = label.clone();
|
||||
}
|
||||
self.push_free_charts_to_tree(cx);
|
||||
// Si la carta editada era la activa, re-render.
|
||||
if let Some(current) = self.current_chart.as_mut() {
|
||||
// Heurística: comparamos por label (ya cambiado al
|
||||
// que pidió el usuario). Si el label de la activa
|
||||
// coincide, era esta carta.
|
||||
if current.label == label.clone()
|
||||
|| current.birth_data.subject_name.as_deref() == Some("Cielo")
|
||||
{
|
||||
if let Some(updated) = self.free_charts.get(source_id) {
|
||||
*current = updated.clone();
|
||||
self.render_current(cx);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
TreeEvent::DeleteFreeChartRequested(id) => {
|
||||
if id.is_sky_now() {
|
||||
return; // no se borra el Cielo
|
||||
|
||||
Reference in New Issue
Block a user