1use std::rc::Rc;
2use std::collections::HashMap;
3
4use dioxus::prelude::Callback;
5use dioxus::prelude::Element;
6use dioxus_signals::{Memo, ReadSignal, Signal};
7use indexmap::IndexMap;
8
9use hyle::{Blueprint, Field, FieldType, HyleDataState, MutateInput, Outcome, Primitive, PurifyError, Query, Source, Value};
10use serde_json::Value as JsonValue;
11
12pub(crate) const FORMA_MODEL: &str = "forma";
14pub type HyleFilterField = hyle::HyleFilterField<Rc<dyn Fn(HyleFilterFieldProps) -> Element>>;
19
20pub type DioxusFieldChangeFn = Rc<dyn Fn(&Field) -> Option<hyle::FieldChange<Rc<dyn Fn(HyleFilterFieldProps) -> Element>>>>;
22
23pub type DioxusFieldChangeMap = HashMap<String, DioxusFieldChangeFn>;
25
26#[derive(Default)]
30pub struct UseFiltersOptions {
31 pub initial_committed: IndexMap<String, String>,
32 pub change: Option<DioxusFieldChangeMap>,
34}
35
36#[derive(Default)]
38pub struct UseFormOptions {
39 pub initial_committed: IndexMap<String, String>,
40 pub change: Option<DioxusFieldChangeMap>,
42}
43
44impl UseFormOptions {
45 pub fn with_change(
51 mut self,
52 key: &str,
53 f: impl Fn(&hyle::Field) -> Option<hyle::FieldChange> + 'static,
54 ) -> Self {
55 self.change
56 .get_or_insert_with(HashMap::new)
57 .insert(
58 key.to_owned(),
59 Rc::new(move |field: &hyle::Field| {
60 f(field).map(|fc| hyle::FieldChange {
61 field: fc.field,
62 render: None,
63 })
64 }),
65 );
66 self
67 }
68}
69
70#[derive(Clone, PartialEq)]
74pub enum HyleSourceState {
75 Loading,
76 Ready(Source),
77 Error(String),
78}
79
80pub type UseSource = ReadSignal<HyleSourceState>;
82
83#[derive(Clone, Copy, PartialEq)]
89pub struct HyleAdapter {
90 pub source: UseSource,
91 pub create: HyleMutation,
92 pub update: HyleMutation,
93 pub delete: HyleMutation,
94}
95
96#[derive(Clone, Copy, PartialEq)]
100pub struct HyleListState {
101 pub data: Memo<HyleDataState>,
102 pub query: Memo<Query>,
103 pub page: Signal<usize>,
104 pub per_page: Signal<usize>,
105 pub sort_field: Signal<Option<String>>,
106 pub sort_ascending: Signal<bool>,
107}
108
109#[derive(Clone)]
113pub struct HyleFilterFieldProps {
114 pub key: String,
115 pub label: String,
116 pub field: Field,
117 pub options: Option<Vec<(String, String)>>,
118 pub value: String,
119 pub set: Callback<String>,
120}
121
122#[derive(Clone, Copy, PartialEq)]
126pub struct HyleMutation {
127 pub mutate: Callback<MutateInput>,
128 pub reset: Callback<()>,
129 pub is_pending: Signal<bool>,
130 pub is_success: Signal<bool>,
131 pub error: Signal<Option<String>>,
132}
133
134#[derive(Clone, Default)]
138pub struct BoundMutateInput {
139 pub id: Option<JsonValue>,
140 pub data: IndexMap<String, String>,
141}
142
143#[derive(Clone, Copy)]
145pub struct BoundMutation {
146 pub mutate: Callback<BoundMutateInput>,
147 pub is_pending: Signal<bool>,
148 pub is_success: Signal<bool>,
149 pub error: Signal<Option<String>>,
150}
151
152#[derive(Clone, Copy)]
154pub struct BoundMutations {
155 pub create: BoundMutation,
156 pub update: BoundMutation,
157 pub delete: BoundMutation,
158}
159
160#[derive(Clone, Copy, PartialEq)]
164pub struct HyleFiltersState {
165 pub query: Memo<Query>,
166 pub fields: Memo<Vec<HyleFilterField>>,
167 pub form_data: Signal<IndexMap<String, String>>,
168 pub set_field: Callback<(String, String)>,
169 pub filter_apply: Callback<()>,
170 pub filter_clear: Callback<()>,
171 pub filter_reset_key: Signal<u32>,
172 pub validate: Callback<()>,
173 pub purify_errors: Signal<Option<Vec<PurifyError>>>,
174}
175
176#[derive(Clone)]
180pub struct HyleValueProps {
181 pub key: String,
182 pub field: Field,
183 pub value: Value,
184 pub outcome: Outcome,
185 pub model_name: String,
186 pub blueprint: Blueprint,
187 pub components: Option<HyleComponents>,
188}
189
190#[derive(Clone, Default)]
192pub struct HyleComponents {
193 pub values: indexmap::IndexMap<String, fn(HyleValueProps) -> Element>,
194 pub filters: indexmap::IndexMap<String, fn(HyleFilterFieldProps) -> Element>,
195}
196
197pub fn field_type_key(field_type: &FieldType) -> &'static str {
199 match field_type {
200 FieldType::Primitive { primitive } => match primitive {
201 Primitive::String => "string",
202 Primitive::Number => "number",
203 Primitive::Boolean => "boolean",
204 Primitive::File => "file",
205 },
206 FieldType::Reference { .. } => "reference",
207 FieldType::Array { .. } => "array",
208 FieldType::Shape { .. } => "shape",
209 }
210}
211
212#[derive(Clone, Copy, PartialEq)]
216pub struct HyleFormState {
217 pub filters: HyleFiltersState,
218 pub is_edit: bool,
219 pub is_valid: bool,
220 pub on_submit: Callback<()>,
221 pub mutation: HyleMutation,
222}