orbital-core-components 0.1.1

Themed Orbital UI components for Leptos applications
Documentation
use std::collections::HashSet;

use super::node::RichTreeNode;
use crate::tree::types::RichTreeData;

#[derive(Clone)]
pub(crate) struct RichTreeCtx<T: Clone + Send + Sync + 'static>(pub RichTreeData<T>);

pub(crate) fn build_nodes<T: Clone + Send + Sync + 'static>(
    data: &RichTreeData<T>,
) -> Vec<RichTreeNode> {
    data.items
        .iter()
        .enumerate()
        .map(|(i, item)| map_item(data, item, i))
        .collect()
}

pub(crate) fn map_item<T: Clone + Send + Sync + 'static>(
    data: &RichTreeData<T>,
    item: &T,
    _order: usize,
) -> RichTreeNode {
    let children = (data.get_children)(item);
    let lazy = data.lazy_fetch.is_some() && children.is_empty();
    RichTreeNode {
        id: (data.get_id)(item),
        label: (data.get_label)(item),
        children: if lazy {
            vec![]
        } else {
            children
                .iter()
                .enumerate()
                .map(|(i, child)| map_item(data, child, i))
                .collect()
        },
        disabled: (data.is_disabled)(item),
        editable: (data.is_editable)(item),
        lazy,
    }
}

pub(crate) fn collect_editable(nodes: &[RichTreeNode]) -> HashSet<String> {
    let mut editable = HashSet::new();
    collect_editable_into(nodes, &mut editable);
    editable
}

fn collect_editable_into(nodes: &[RichTreeNode], editable: &mut HashSet<String>) {
    for node in nodes {
        if node.editable {
            editable.insert(node.id.clone());
        }
        collect_editable_into(&node.children, editable);
    }
}

pub(crate) fn merge_disabled(nodes: &[RichTreeNode], base: &HashSet<String>) -> HashSet<String> {
    let mut disabled = base.clone();
    collect_disabled_into(nodes, &mut disabled);
    disabled
}

fn collect_disabled_into(nodes: &[RichTreeNode], disabled: &mut HashSet<String>) {
    for node in nodes {
        if node.disabled {
            disabled.insert(node.id.clone());
        }
        collect_disabled_into(&node.children, disabled);
    }
}

pub(crate) fn merge_lazy_children(
    roots: &mut [RichTreeNode],
    parent_id: &str,
    children: Vec<RichTreeNode>,
) {
    for node in roots.iter_mut() {
        if node.id == parent_id {
            node.children = children;
            node.lazy = false;
            return;
        }
        merge_lazy_children(&mut node.children, parent_id, children.clone());
    }
}

pub(crate) fn update_node_label(roots: &mut [RichTreeNode], item_id: &str, label: &str) -> bool {
    for node in roots.iter_mut() {
        if node.id == item_id {
            node.label = label.to_string();
            return true;
        }
        if update_node_label(&mut node.children, item_id, label) {
            return true;
        }
    }
    false
}