use std::rc::Rc;
use std::collections::HashMap;
use dioxus::prelude::Callback;
use dioxus::prelude::Element;
use dioxus_signals::{Memo, ReadSignal, Signal};
use indexmap::IndexMap;
use hyle::{Blueprint, Field, FieldType, HyleDataState, MutateInput, Outcome, Primitive, PurifyError, Query, Source, Value};
use serde_json::Value as JsonValue;
pub(crate) const FORMA_MODEL: &str = "forma";
pub type HyleFilterField = hyle::HyleFilterField<Rc<dyn Fn(HyleFilterFieldProps) -> Element>>;
pub type DioxusFieldChangeFn = Rc<dyn Fn(&Field) -> Option<hyle::FieldChange<Rc<dyn Fn(HyleFilterFieldProps) -> Element>>>>;
pub type DioxusFieldChangeMap = HashMap<String, DioxusFieldChangeFn>;
#[derive(Default)]
pub struct UseFiltersOptions {
pub initial_committed: IndexMap<String, String>,
pub change: Option<DioxusFieldChangeMap>,
}
#[derive(Default)]
pub struct UseFormOptions {
pub initial_committed: IndexMap<String, String>,
pub change: Option<DioxusFieldChangeMap>,
}
impl UseFormOptions {
pub fn with_change(
mut self,
key: &str,
f: impl Fn(&hyle::Field) -> Option<hyle::FieldChange> + 'static,
) -> Self {
self.change
.get_or_insert_with(HashMap::new)
.insert(
key.to_owned(),
Rc::new(move |field: &hyle::Field| {
f(field).map(|fc| hyle::FieldChange {
field: fc.field,
render: None,
})
}),
);
self
}
}
#[derive(Clone, PartialEq)]
pub enum HyleSourceState {
Loading,
Ready(Source),
Error(String),
}
pub type UseSource = ReadSignal<HyleSourceState>;
#[derive(Clone, Copy, PartialEq)]
pub struct HyleAdapter {
pub source: UseSource,
pub create: HyleMutation,
pub update: HyleMutation,
pub delete: HyleMutation,
}
#[derive(Clone, Copy, PartialEq)]
pub struct HyleListState {
pub data: Memo<HyleDataState>,
pub query: Memo<Query>,
pub page: Signal<usize>,
pub per_page: Signal<usize>,
pub sort_field: Signal<Option<String>>,
pub sort_ascending: Signal<bool>,
}
#[derive(Clone)]
pub struct HyleFilterFieldProps {
pub key: String,
pub label: String,
pub field: Field,
pub options: Option<Vec<(String, String)>>,
pub value: String,
pub set: Callback<String>,
}
#[derive(Clone, Copy, PartialEq)]
pub struct HyleMutation {
pub mutate: Callback<MutateInput>,
pub reset: Callback<()>,
pub is_pending: Signal<bool>,
pub is_success: Signal<bool>,
pub error: Signal<Option<String>>,
}
#[derive(Clone, Default)]
pub struct BoundMutateInput {
pub id: Option<JsonValue>,
pub data: IndexMap<String, String>,
}
#[derive(Clone, Copy)]
pub struct BoundMutation {
pub mutate: Callback<BoundMutateInput>,
pub is_pending: Signal<bool>,
pub is_success: Signal<bool>,
pub error: Signal<Option<String>>,
}
#[derive(Clone, Copy)]
pub struct BoundMutations {
pub create: BoundMutation,
pub update: BoundMutation,
pub delete: BoundMutation,
}
#[derive(Clone, Copy, PartialEq)]
pub struct HyleFiltersState {
pub query: Memo<Query>,
pub fields: Memo<Vec<HyleFilterField>>,
pub form_data: Signal<IndexMap<String, String>>,
pub set_field: Callback<(String, String)>,
pub filter_apply: Callback<()>,
pub filter_clear: Callback<()>,
pub filter_reset_key: Signal<u32>,
pub validate: Callback<()>,
pub purify_errors: Signal<Option<Vec<PurifyError>>>,
}
#[derive(Clone)]
pub struct HyleValueProps {
pub key: String,
pub field: Field,
pub value: Value,
pub outcome: Outcome,
pub model_name: String,
pub blueprint: Blueprint,
pub components: Option<HyleComponents>,
}
#[derive(Clone, Default)]
pub struct HyleComponents {
pub values: indexmap::IndexMap<String, fn(HyleValueProps) -> Element>,
pub filters: indexmap::IndexMap<String, fn(HyleFilterFieldProps) -> Element>,
}
pub fn field_type_key(field_type: &FieldType) -> &'static str {
match field_type {
FieldType::Primitive { primitive } => match primitive {
Primitive::String => "string",
Primitive::Number => "number",
Primitive::Boolean => "boolean",
Primitive::File => "file",
},
FieldType::Reference { .. } => "reference",
FieldType::Array { .. } => "array",
FieldType::Shape { .. } => "shape",
}
}
#[derive(Clone, Copy, PartialEq)]
pub struct HyleFormState {
pub filters: HyleFiltersState,
pub is_edit: bool,
pub is_valid: bool,
pub on_submit: Callback<()>,
pub mutation: HyleMutation,
}