use std::collections::HashMap;
use leptos::prelude::*;
use orbital_data::{DataRecord, DataValue};
use super::DataTableColumnDef;
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum EditMode {
#[default]
Cell,
Row,
}
#[derive(Clone)]
pub struct EditFieldDraft {
pub field: String,
pub original: DataValue,
pub draft: RwSignal<String>,
pub error: RwSignal<Option<String>>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum EditSession {
Idle,
Editing {
row_id: String,
mode: EditMode,
active_field: Option<String>,
},
Committing {
row_id: String,
},
}
#[derive(Clone, Copy)]
pub struct EditSessionStore {
pub session: RwSignal<EditSession>,
pub drafts: StoredValue<HashMap<String, EditFieldDraft>>,
}
impl Default for EditSessionStore {
fn default() -> Self {
Self::new()
}
}
impl EditSessionStore {
pub fn new() -> Self {
Self {
session: RwSignal::new(EditSession::Idle),
drafts: StoredValue::new(HashMap::new()),
}
}
pub fn is_editing_row(&self, row_id: &str) -> bool {
matches!(
self.session.get(),
EditSession::Editing { row_id: id, .. } | EditSession::Committing { row_id: id }
if id == row_id
)
}
pub fn is_editing_field(&self, row_id: &str, field: &str) -> bool {
match self.session.get() {
EditSession::Editing {
row_id: id,
mode,
active_field,
} if id == row_id => match mode {
EditMode::Row => self.drafts.with_value(|d| d.contains_key(field)),
EditMode::Cell => active_field.as_deref() == Some(field),
},
EditSession::Committing { row_id: id } if id == row_id => {
self.drafts.with_value(|d| d.contains_key(field))
}
_ => false,
}
}
pub fn clear(&self) {
self.drafts.set_value(HashMap::new());
self.session.set(EditSession::Idle);
}
}
pub struct EditCellProps {
pub row: DataRecord,
pub column: DataTableColumnDef,
pub draft: RwSignal<String>,
pub error: RwSignal<Option<String>>,
pub on_commit: Callback<(), ()>,
pub on_cancel: Callback<(), ()>,
}