sidebar_dto.rs 97 lignes · 2559 octets
//! Sidebar DTO for Feature 007
//!
//! Provides data structures for contextual sidebar content.

use serde::{Deserialize, Serialize};

/// Sidebar section containing a title and list of items
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SidebarSection {
    /// Section title
    pub title: String,

    /// List of items in this section
    pub items: Vec<SidebarItem>,
}

impl SidebarSection {
    /// Create a new sidebar section
    pub fn new(title: impl Into<String>) -> Self {
        Self {
            title: title.into(),
            items: Vec::new(),
        }
    }

    /// Add an item to this section
    pub fn with_item(mut self, item: SidebarItem) -> Self {
        self.items.push(item);
        self
    }

    /// Add multiple items to this section
    pub fn with_items(mut self, items: Vec<SidebarItem>) -> Self {
        self.items.extend(items);
        self
    }
}

/// Sidebar item representing a single action or information
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SidebarItem {
    /// Display label
    pub label: String,

    /// Icon identifier (can be CSS class, emoji, or icon name)
    pub icon: String,

    /// URL to navigate to (empty string for informational items)
    pub url: String,

    /// Optional badge text (e.g., "New", "3", etc.) - empty string if no badge
    pub badge: String,

    /// Whether this item is enabled/clickable
    pub enabled: bool,

    /// Whether this item has a URL (is clickable)
    pub has_url: bool,
}

impl SidebarItem {
    /// Create a new enabled sidebar item with URL
    pub fn link(label: impl Into<String>, icon: impl Into<String>, url: impl Into<String>) -> Self {
        Self {
            label: label.into(),
            icon: icon.into(),
            url: url.into(),
            badge: String::new(),
            enabled: true,
            has_url: true,
        }
    }

    /// Create a new informational sidebar item (no URL)
    pub fn info(label: impl Into<String>, icon: impl Into<String>) -> Self {
        Self {
            label: label.into(),
            icon: icon.into(),
            url: String::new(),
            badge: String::new(),
            enabled: false,
            has_url: false,
        }
    }

    /// Add a badge to this item
    pub fn with_badge(mut self, badge: impl Into<String>) -> Self {
        self.badge = badge.into();
        self
    }

    /// Set whether this item is enabled
    pub fn set_enabled(mut self, enabled: bool) -> Self {
        self.enabled = enabled;
        self
    }
}