#[derive(Debug, Clone, Default)]
pub struct ViewSwitcherState {
pub visible: bool,
pub selected: usize,
pub available_views: Vec<MultiViewType>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MultiViewType {
MultiDiff,
Timeline,
Matrix,
}
impl MultiViewType {
pub const fn label(self) -> &'static str {
match self {
Self::MultiDiff => "Multi-Diff Dashboard",
Self::Timeline => "Timeline View",
Self::Matrix => "Matrix Comparison",
}
}
pub const fn shortcut(self) -> &'static str {
match self {
Self::MultiDiff => "1",
Self::Timeline => "2",
Self::Matrix => "3",
}
}
pub const fn icon(self) -> &'static str {
match self {
Self::MultiDiff => "◆",
Self::Timeline => "◇",
Self::Matrix => "▦",
}
}
}
impl ViewSwitcherState {
pub fn new() -> Self {
Self {
visible: false,
selected: 0,
available_views: vec![
MultiViewType::MultiDiff,
MultiViewType::Timeline,
MultiViewType::Matrix,
],
}
}
pub const fn toggle(&mut self) {
self.visible = !self.visible;
}
pub const fn hide(&mut self) {
self.visible = false;
}
pub fn next(&mut self) {
if !self.available_views.is_empty() {
self.selected = (self.selected + 1) % self.available_views.len();
}
}
pub fn previous(&mut self) {
if !self.available_views.is_empty() {
self.selected = self
.selected
.checked_sub(1)
.unwrap_or(self.available_views.len() - 1);
}
}
pub fn current_view(&self) -> Option<MultiViewType> {
self.available_views.get(self.selected).copied()
}
}
#[derive(Debug, Clone, Default)]
pub struct ComponentDeepDiveState {
pub visible: bool,
pub component_name: String,
pub component_id: Option<String>,
pub active_section: usize,
pub collected_data: ComponentDeepDiveData,
}
#[allow(dead_code)]
#[derive(Debug, Clone, Default)]
pub struct ComponentDeepDiveData {
pub version_history: Vec<ComponentVersionEntry>,
pub target_presence: Vec<ComponentTargetPresence>,
pub similarity_info: Vec<ComponentSimilarityInfo>,
pub vulnerabilities: Vec<ComponentVulnInfo>,
pub dependencies: Vec<String>,
pub dependents: Vec<String>,
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct ComponentVersionEntry {
pub version: String,
pub sbom_label: String,
pub date: Option<String>,
pub change_type: String, }
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct ComponentTargetPresence {
pub target_name: String,
pub version: Option<String>,
pub is_present: bool,
pub deviation_from_baseline: Option<String>,
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct ComponentSimilarityInfo {
pub other_sbom: String,
pub similarity_score: f64,
pub version_in_other: Option<String>,
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct ComponentVulnInfo {
pub vuln_id: String,
pub severity: String,
pub status: String, pub description: Option<String>,
}
impl ComponentDeepDiveState {
pub fn new() -> Self {
Self::default()
}
pub fn open(&mut self, name: String, id: Option<String>) {
self.visible = true;
self.component_name = name;
self.component_id = id;
self.active_section = 0;
self.collected_data = ComponentDeepDiveData::default();
}
pub const fn close(&mut self) {
self.visible = false;
}
pub const fn next_section(&mut self) {
self.active_section = (self.active_section + 1) % 4;
}
pub fn prev_section(&mut self) {
self.active_section = self.active_section.checked_sub(1).unwrap_or(3);
}
pub const fn section_labels() -> [&'static str; 4] {
["Overview", "Versions", "Dependencies", "Vulnerabilities"]
}
}
#[derive(Debug, Clone, Default)]
pub struct ShortcutsOverlayState {
pub visible: bool,
pub context: ShortcutsContext,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub enum ShortcutsContext {
#[default]
Global,
MultiDiff,
Timeline,
Matrix,
Diff,
View,
}
impl ShortcutsOverlayState {
pub fn new() -> Self {
Self::default()
}
pub const fn show(&mut self, context: ShortcutsContext) {
self.visible = true;
self.context = context;
}
pub const fn hide(&mut self) {
self.visible = false;
}
}