use logisheets_base::{BlockId, SheetId};
use crate::block_manager::schema_manager::field_type::{FieldAggregate, PivotColumn};
use crate::block_manager::schema_manager::schema::Schema;
use crate::controller::status::Status;
use crate::edit_action::SchemaFieldSpec;
pub fn propagate_field_renames(
status: &mut Status,
sheet_id: SheetId,
block_id: BlockId,
new_fields: &[SchemaFieldSpec],
) {
let renames = detect_renames(status, sheet_id, block_id, new_fields);
if renames.is_empty() {
return;
}
let apply = |s: &mut String| {
if let Some((_, to)) = renames.iter().find(|(from, _)| from == s) {
*s = to.clone();
}
};
let dependents = status.navigator.analyzed_by(&sheet_id, block_id);
for dep in dependents {
if let Some(nav) = status.navigator.sheet_navs.get_mut(&sheet_id) {
if let Some(place) = nav.data.blocks.get(&dep) {
if let Some(pivot) = &place.pivot {
let mut pivot = pivot.clone();
apply(&mut pivot.row_dim);
apply(&mut pivot.measure);
if let Some(c) = &mut pivot.col_dim {
apply(c);
}
for f in &mut pivot.filters {
apply(&mut f.field);
}
let place = place.clone().with_pivot(Some(pivot));
nav.data.blocks.insert(dep, place);
}
}
}
if let Some(schema) = status
.block_schema_manager
.schemas
.get_mut(&(sheet_id, dep))
{
let fix = |aggregate: &mut Option<FieldAggregate>, column: &mut Option<PivotColumn>| {
if let Some(a) = aggregate {
apply(&mut a.source_field);
}
if let Some(m) = column.as_mut().and_then(|c| c.measure.as_mut()) {
apply(m);
}
};
match schema {
Schema::RowSchema(s) => s
.fields
.iter_mut()
.for_each(|(_, e)| fix(&mut e.aggregate, &mut e.pivot_column)),
Schema::ColSchema(s) => s
.fields
.iter_mut()
.for_each(|(_, e)| fix(&mut e.aggregate, &mut e.pivot_column)),
Schema::RandomSchema(_) => {}
}
}
}
}
fn detect_renames(
status: &Status,
sheet_id: SheetId,
block_id: BlockId,
new_fields: &[SchemaFieldSpec],
) -> Vec<(String, String)> {
let Some(schema) = status
.block_schema_manager
.schemas
.get(&(sheet_id, block_id))
else {
return Vec::new();
};
let old: Vec<(String, String)> = match schema {
Schema::RowSchema(s) => s
.fields
.iter()
.map(|(n, e)| (e.render_id.clone(), n.clone()))
.collect(),
Schema::ColSchema(s) => s
.fields
.iter()
.map(|(n, e)| (e.render_id.clone(), n.clone()))
.collect(),
Schema::RandomSchema(_) => return Vec::new(),
};
new_fields
.iter()
.filter_map(|spec| {
let (_, was) = old.iter().find(|(rid, _)| *rid == spec.render_id)?;
(*was != spec.name).then(|| (was.clone(), spec.name.clone()))
})
.collect()
}