178 lines
4.9 KiB
Rust
178 lines
4.9 KiB
Rust
//! Template List Widget
|
|
//!
|
|
//! Provides a widget for displaying and managing enrolled face templates.
|
|
//! Supports viewing template details and removing templates.
|
|
|
|
use crate::dbus_client::TemplateInfo;
|
|
|
|
/// Template list box containing enrolled templates
|
|
#[derive(Debug, Clone)]
|
|
pub struct TemplateListBox {
|
|
/// List of templates
|
|
templates: Vec<TemplateInfo>,
|
|
}
|
|
|
|
impl TemplateListBox {
|
|
/// Create a new template list box
|
|
pub fn new(templates: Vec<TemplateInfo>) -> Self {
|
|
Self { templates }
|
|
}
|
|
|
|
/// Get the list of templates
|
|
pub fn templates(&self) -> &[TemplateInfo] {
|
|
&self.templates
|
|
}
|
|
|
|
/// Find a template by ID
|
|
pub fn find_by_id(&self, id: &str) -> Option<&TemplateInfo> {
|
|
self.templates.iter().find(|t| t.id == id)
|
|
}
|
|
|
|
/// Find a template by label
|
|
pub fn find_by_label(&self, label: &str) -> Option<&TemplateInfo> {
|
|
self.templates.iter().find(|t| t.label == label)
|
|
}
|
|
|
|
/// Check if any templates are enrolled
|
|
pub fn is_empty(&self) -> bool {
|
|
self.templates.is_empty()
|
|
}
|
|
|
|
/// Get the count of enrolled templates
|
|
pub fn count(&self) -> usize {
|
|
self.templates.len()
|
|
}
|
|
|
|
/// Update the template list
|
|
pub fn update(&mut self, templates: Vec<TemplateInfo>) {
|
|
self.templates = templates;
|
|
}
|
|
}
|
|
|
|
impl Default for TemplateListBox {
|
|
fn default() -> Self {
|
|
Self::new(Vec::new())
|
|
}
|
|
}
|
|
|
|
/// Template display model for UI binding
|
|
#[derive(Debug, Clone)]
|
|
pub struct TemplateDisplayModel {
|
|
/// Template ID
|
|
pub id: String,
|
|
/// Display label
|
|
pub label: String,
|
|
/// Username
|
|
pub username: String,
|
|
/// Formatted creation date
|
|
pub created_date: String,
|
|
/// Formatted last used date
|
|
pub last_used_date: String,
|
|
/// Whether this template has been used recently
|
|
pub recently_used: bool,
|
|
}
|
|
|
|
impl TemplateDisplayModel {
|
|
/// Create a display model from template info
|
|
pub fn from_template(template: &TemplateInfo) -> Self {
|
|
use chrono::{DateTime, Duration, Local, Utc};
|
|
|
|
let created_date = DateTime::<Utc>::from_timestamp(template.created_at, 0)
|
|
.map(|dt| dt.with_timezone(&Local))
|
|
.map(|dt| dt.format("%B %d, %Y").to_string())
|
|
.unwrap_or_else(|| "Unknown".to_string());
|
|
|
|
let (last_used_date, recently_used) = if let Some(ts) = template.last_used {
|
|
let dt = DateTime::<Utc>::from_timestamp(ts, 0).map(|dt| dt.with_timezone(&Local));
|
|
|
|
let date_str = dt
|
|
.as_ref()
|
|
.map(|d| d.format("%B %d, %Y at %H:%M").to_string())
|
|
.unwrap_or_else(|| "Unknown".to_string());
|
|
|
|
// Check if used within the last 24 hours
|
|
let recent = dt
|
|
.map(|d| {
|
|
let now = Local::now();
|
|
now.signed_duration_since(d) < Duration::hours(24)
|
|
})
|
|
.unwrap_or(false);
|
|
|
|
(date_str, recent)
|
|
} else {
|
|
("Never".to_string(), false)
|
|
};
|
|
|
|
Self {
|
|
id: template.id.clone(),
|
|
label: template.label.clone(),
|
|
username: template.username.clone(),
|
|
created_date,
|
|
last_used_date,
|
|
recently_used,
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Template action types
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
pub enum TemplateAction {
|
|
/// View template details
|
|
View,
|
|
/// Remove template
|
|
Remove,
|
|
/// Test authentication with template
|
|
Test,
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
fn create_test_template(id: &str, label: &str) -> TemplateInfo {
|
|
TemplateInfo {
|
|
id: id.to_string(),
|
|
label: label.to_string(),
|
|
username: "testuser".to_string(),
|
|
created_at: 1704067200, // 2024-01-01 00:00:00 UTC
|
|
last_used: Some(1704153600), // 2024-01-02 00:00:00 UTC
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn test_template_list_box() {
|
|
let templates = vec![
|
|
create_test_template("1", "default"),
|
|
create_test_template("2", "backup"),
|
|
];
|
|
|
|
let list = TemplateListBox::new(templates);
|
|
|
|
assert!(!list.is_empty());
|
|
assert_eq!(list.count(), 2);
|
|
assert!(list.find_by_id("1").is_some());
|
|
assert!(list.find_by_label("backup").is_some());
|
|
assert!(list.find_by_id("nonexistent").is_none());
|
|
}
|
|
|
|
#[test]
|
|
fn test_empty_list() {
|
|
let list = TemplateListBox::default();
|
|
|
|
assert!(list.is_empty());
|
|
assert_eq!(list.count(), 0);
|
|
}
|
|
|
|
#[test]
|
|
fn test_template_display_model() {
|
|
let template = create_test_template("test-id", "Test Face");
|
|
let model = TemplateDisplayModel::from_template(&template);
|
|
|
|
assert_eq!(model.id, "test-id");
|
|
assert_eq!(model.label, "Test Face");
|
|
assert_eq!(model.username, "testuser");
|
|
assert!(!model.created_date.is_empty());
|
|
assert_ne!(model.last_used_date, "Never");
|
|
}
|
|
}
|