feat: first take at M2
This commit is contained in:
126
crates/bds-ui/src/state/navigation.rs
Normal file
126
crates/bds-ui/src/state/navigation.rs
Normal file
@@ -0,0 +1,126 @@
|
||||
use std::fmt;
|
||||
|
||||
/// Which list the sidebar is currently showing.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum SidebarView {
|
||||
Posts,
|
||||
Pages,
|
||||
Media,
|
||||
Scripts,
|
||||
Templates,
|
||||
Tags,
|
||||
Chat,
|
||||
Import,
|
||||
Git,
|
||||
Settings,
|
||||
}
|
||||
|
||||
impl fmt::Display for SidebarView {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let key = self.i18n_key();
|
||||
f.write_str(key)
|
||||
}
|
||||
}
|
||||
|
||||
impl SidebarView {
|
||||
/// Returns the `activity.*` i18n key for this sidebar view.
|
||||
pub fn i18n_key(&self) -> &'static str {
|
||||
match self {
|
||||
Self::Posts => "activity.posts",
|
||||
Self::Pages => "activity.pages",
|
||||
Self::Media => "activity.media",
|
||||
Self::Scripts => "activity.scripts",
|
||||
Self::Templates => "activity.templates",
|
||||
Self::Tags => "activity.tags",
|
||||
Self::Chat => "activity.chat",
|
||||
Self::Import => "activity.import",
|
||||
Self::Git => "activity.git",
|
||||
Self::Settings => "activity.settings",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Which tab is selected in the bottom panel.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum PanelTab {
|
||||
Tasks,
|
||||
Output,
|
||||
}
|
||||
|
||||
/// A snapshot of a running or completed task shown in the panel.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TaskSnapshot {
|
||||
pub id: u64,
|
||||
pub label: String,
|
||||
pub status: String,
|
||||
pub progress: Option<f32>,
|
||||
pub message: Option<String>,
|
||||
}
|
||||
|
||||
/// A single line of output shown in the panel.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct OutputEntry {
|
||||
pub timestamp: i64,
|
||||
pub text: String,
|
||||
}
|
||||
|
||||
/// Determine the next `(SidebarView, sidebar_visible)` after a user clicks
|
||||
/// an activity-bar icon.
|
||||
///
|
||||
/// * Same icon + visible -> toggle sidebar off
|
||||
/// * Same icon + hidden -> toggle sidebar on
|
||||
/// * Different icon -> switch view and ensure visible
|
||||
pub fn handle_activity_click(
|
||||
current_view: SidebarView,
|
||||
sidebar_visible: bool,
|
||||
clicked: SidebarView,
|
||||
) -> (SidebarView, bool) {
|
||||
if clicked == current_view {
|
||||
(current_view, !sidebar_visible)
|
||||
} else {
|
||||
(clicked, true)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn toggle_off_when_same_and_visible() {
|
||||
let (view, visible) =
|
||||
handle_activity_click(SidebarView::Posts, true, SidebarView::Posts);
|
||||
assert_eq!(view, SidebarView::Posts);
|
||||
assert!(!visible);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn toggle_on_when_same_and_hidden() {
|
||||
let (view, visible) =
|
||||
handle_activity_click(SidebarView::Posts, false, SidebarView::Posts);
|
||||
assert_eq!(view, SidebarView::Posts);
|
||||
assert!(visible);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn switch_view_when_different() {
|
||||
let (view, visible) =
|
||||
handle_activity_click(SidebarView::Posts, true, SidebarView::Media);
|
||||
assert_eq!(view, SidebarView::Media);
|
||||
assert!(visible);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn switch_view_when_different_and_hidden() {
|
||||
let (view, visible) =
|
||||
handle_activity_click(SidebarView::Posts, false, SidebarView::Settings);
|
||||
assert_eq!(view, SidebarView::Settings);
|
||||
assert!(visible);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display_returns_i18n_key() {
|
||||
assert_eq!(SidebarView::Posts.to_string(), "activity.posts");
|
||||
assert_eq!(SidebarView::Settings.to_string(), "activity.settings");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user