Add DAST, graph modules, toast notifications, and dashboard enhancements
Add DAST scanning and code knowledge graph features across the stack: - compliance-dast and compliance-graph workspace crates - Agent API handlers and routes for DAST targets/scans and graph builds - Core models and traits for DAST and graph domains - Dashboard pages for DAST targets/findings/overview and graph explorer/impact - Toast notification system with auto-dismiss for async action feedback - Button click animations and disabled states for better UX Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
86
compliance-dashboard/src/components/toast.rs
Normal file
86
compliance-dashboard/src/components/toast.rs
Normal file
@@ -0,0 +1,86 @@
|
||||
use dioxus::prelude::*;
|
||||
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub enum ToastType {
|
||||
Success,
|
||||
Error,
|
||||
Info,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub struct ToastMessage {
|
||||
pub id: usize,
|
||||
pub message: String,
|
||||
pub toast_type: ToastType,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Toasts {
|
||||
items: Signal<Vec<ToastMessage>>,
|
||||
next_id: Signal<usize>,
|
||||
}
|
||||
|
||||
impl Toasts {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
items: Signal::new(vec![]),
|
||||
next_id: Signal::new(0),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn push(&mut self, toast_type: ToastType, message: impl Into<String>) {
|
||||
let id = *self.next_id.read();
|
||||
*self.next_id.write() = id + 1;
|
||||
self.items.write().push(ToastMessage {
|
||||
id,
|
||||
message: message.into(),
|
||||
toast_type,
|
||||
});
|
||||
|
||||
#[cfg(feature = "web")]
|
||||
{
|
||||
let mut items = self.items;
|
||||
spawn(async move {
|
||||
gloo_timers::future::TimeoutFuture::new(4_000).await;
|
||||
items.write().retain(|t| t.id != id);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, id: usize) {
|
||||
self.items.write().retain(|t| t.id != id);
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn ToastContainer() -> Element {
|
||||
let mut toasts = use_context::<Toasts>();
|
||||
let items = toasts.items.read();
|
||||
|
||||
rsx! {
|
||||
div { class: "toast-container",
|
||||
for toast in items.iter() {
|
||||
{
|
||||
let toast_id = toast.id;
|
||||
let type_class = match toast.toast_type {
|
||||
ToastType::Success => "toast-success",
|
||||
ToastType::Error => "toast-error",
|
||||
ToastType::Info => "toast-info",
|
||||
};
|
||||
rsx! {
|
||||
div {
|
||||
key: "{toast_id}",
|
||||
class: "toast {type_class}",
|
||||
span { "{toast.message}" }
|
||||
button {
|
||||
class: "toast-dismiss",
|
||||
onclick: move |_| toasts.remove(toast_id),
|
||||
"\u{00d7}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user