feat(tahuantinsuyu): fase 12 — Control::ChartPicker para Synastry
Cualquier carta del DB se puede elegir como partner de sinastría
(no solo hermanas del contacto actual). El módulo SynastryModule
declara un Control::ChartPicker; el panel renderea un dropdown que
abre un popup con todas las cartas; el shell inyecta las opciones y
resuelve el partner desde la selección persistida.
- modules: nueva variante Control::ChartPicker { key, label } sin
default — las opciones las inyecta el host. SynastryModule.controls()
agrega un picker con key="partner_chart_id".
- store: list_all_charts() — query sin filtros, ordenada por label
case-insensitive. Pensada para selectores cross-contact.
- panel:
- ChartOption struct público (id + label).
- chart_options Vec + chart_picker_value HashMap + chart_picker_open
Option (solo uno abierto a la vez).
- APIs públicas set_chart_options / set_chart_picker para sync.
- set_active_kind inicializa picker_value a None ("automático").
- render_chart_picker: botón "▾ label" en bg_button; al click toggle
un popup absolute con (automático) + separador + cada chart_option
clickable. select_picker emite ControlChanged con Value::String(id)
o Value::Null.
- shell:
- new() llama refresh_chart_options al final para popular el panel
desde el boot.
- refresh_chart_options() builds Vec<ChartOption> desde
list_all_charts (label + birth_brief "YYYY-MM-DD · Lugar"). Lo
llamamos también desde TreeEvent::HierarchyChanged para que el
dropdown refleje altas/bajas.
- resolve_synastry_partner reemplaza find_synastry_partner: 1) lee
module_configs["synastry"]["partner_chart_id"] y resuelve el chart;
2) fallback al automático (primera hermana). El fallback significa
que el módulo sigue funcionando sin elegir manualmente.
- sync_panel_from_configs ahora maneja Value::String / Value::Null
→ set_chart_picker, así el picker se restaura al cargar una carta.
Persistencia: el partner_chart_id va al config_json (fase 11), así
que cada carta recuerda con quién hizo sinastría la última vez.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -293,6 +293,24 @@ impl Store {
|
||||
.and_then(|v| v.into_iter().collect::<StoreResult<Vec<_>>>())
|
||||
}
|
||||
|
||||
/// Lista todas las cartas del DB ordenadas por label (case-insensitive).
|
||||
/// Pensado para pickers / selectores cross-contact (ej. elegir un
|
||||
/// partner de sinastría desde cualquier contacto).
|
||||
pub fn list_all_charts(&self) -> StoreResult<Vec<Chart>> {
|
||||
let conn = self.conn.lock().unwrap();
|
||||
let mut stmt = conn.prepare(
|
||||
"SELECT id, contact_id, kind, label, birth_data_json, config_json, \
|
||||
related_chart_id, created_at_ms \
|
||||
FROM charts ORDER BY label COLLATE NOCASE ASC",
|
||||
)?;
|
||||
let rows = stmt.query_map([], row_to_chart)?;
|
||||
let mut out = Vec::new();
|
||||
for r in rows {
|
||||
out.push(r??);
|
||||
}
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
pub fn get_chart(&self, id: ChartId) -> StoreResult<Chart> {
|
||||
let conn = self.conn.lock().unwrap();
|
||||
let mut stmt = conn.prepare(
|
||||
|
||||
Reference in New Issue
Block a user