feat(layout): supporte la création de layouts plugins (customPluginLayout)
Étend le flux de création de layout backend (DTO, usecases, store) et le frontend (sélecteur, adaptateurs, LayoutTabs/LayoutGrid) pour permettre d'ouvrir un layout déclaré par un plugin installé (ex. Android Health), sans passer par le message bloquant "extension backend pas encore livrée". Ticket #141 — QA vert. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@ -603,6 +603,38 @@ impl LayoutTree {
|
||||
Ok(tree)
|
||||
}
|
||||
|
||||
/// Replaces the opaque state of a plugin-provided custom layout leaf.
|
||||
///
|
||||
/// Pure: returns a new validated tree.
|
||||
///
|
||||
/// # Errors
|
||||
/// - [`LayoutError::NodeNotFound`] if `target` is not a custom plugin layout
|
||||
/// leaf in the tree.
|
||||
pub fn set_plugin_layout_state(
|
||||
&self,
|
||||
target: NodeId,
|
||||
state: serde_json::Value,
|
||||
) -> Result<Self, LayoutError> {
|
||||
let mut found = false;
|
||||
let root = map_node(&self.root, &mut |node| {
|
||||
if let LayoutNode::CustomPluginLayout(cell) = node {
|
||||
if cell.id == target {
|
||||
found = true;
|
||||
let mut cell = cell.clone();
|
||||
cell.state = state.clone();
|
||||
return LayoutNode::CustomPluginLayout(cell);
|
||||
}
|
||||
}
|
||||
node.clone()
|
||||
});
|
||||
if !found {
|
||||
return Err(LayoutError::NodeNotFound(target));
|
||||
}
|
||||
let tree = Self { root };
|
||||
tree.validate()?;
|
||||
Ok(tree)
|
||||
}
|
||||
|
||||
/// Sets (or, with `None`, clears) the **engine session id** cache
|
||||
/// ([`LeafCell::engine_session_id`]) on the leaf `target` — the resumable id of
|
||||
/// the current provider (id Claude `--resume`, UUID minté pour `--session-id`).
|
||||
|
||||
Reference in New Issue
Block a user