fret_ui_headless/table/
tanstack_auto_reset.rs1use super::{Table, TableState};
10
11#[derive(Debug, Default, Clone)]
20pub struct TanStackAutoResetQueue {
21 page_index_registered: bool,
22 expanded_registered: bool,
23 pending_page_index_register: bool,
24 pending_expanded_register: bool,
25 pending_page_index_reset: bool,
26 pending_expanded_reset: bool,
27}
28
29impl TanStackAutoResetQueue {
30 pub fn begin_render_pass(&mut self) {
32 self.pending_page_index_register = false;
33 self.pending_expanded_register = false;
34 self.pending_page_index_reset = false;
35 self.pending_expanded_reset = false;
36 }
37
38 pub fn auto_reset_page_index<TData>(&mut self, table: &Table<'_, TData>) {
40 if !self.page_index_registered {
41 self.pending_page_index_register = true;
44 return;
45 }
46 if table.should_auto_reset_page_index() {
47 self.pending_page_index_reset = true;
48 }
49 }
50
51 pub fn auto_reset_expanded<TData>(&mut self, table: &Table<'_, TData>) {
53 if !self.expanded_registered {
54 self.pending_expanded_register = true;
55 return;
56 }
57 if table.should_auto_reset_expanded() {
58 self.pending_expanded_reset = true;
59 }
60 }
61
62 pub fn flush<TData>(&mut self, table: &Table<'_, TData>, state: &mut TableState) {
68 if self.pending_expanded_reset {
69 state.expanding = table.reset_expanded(false);
70 }
71 if self.pending_page_index_reset {
72 state.pagination = table.reset_page_index(false);
73 }
74 if self.pending_expanded_register {
75 self.expanded_registered = true;
76 }
77 if self.pending_page_index_register {
78 self.page_index_registered = true;
79 }
80 self.pending_expanded_register = false;
81 self.pending_page_index_register = false;
82 self.pending_expanded_reset = false;
83 self.pending_page_index_reset = false;
84 }
85
86 pub fn expanded_registered(&self) -> bool {
87 self.expanded_registered
88 }
89
90 pub fn page_index_registered(&self) -> bool {
91 self.page_index_registered
92 }
93
94 pub fn pending_expanded_reset(&self) -> bool {
95 self.pending_expanded_reset
96 }
97
98 pub fn pending_page_index_reset(&self) -> bool {
99 self.pending_page_index_reset
100 }
101}
102
103#[cfg(test)]
104mod tests {
105 use super::*;
106 use crate::table::{
107 ColumnDef, ExpandingState, FilteringFnSpec, PaginationState, RowId, RowKey,
108 };
109
110 #[derive(Debug, Clone)]
111 struct Row {
112 id: u64,
113 cpu: u64,
114 }
115
116 fn build_table(
117 data: &[Row],
118 state: TableState,
119 initial: TableState,
120 manual_pagination: bool,
121 ) -> Table<'_, Row> {
122 let columns: Vec<ColumnDef<Row>> = vec![
123 ColumnDef::<Row>::new("cpu")
124 .sort_value_by(|r: &Row| crate::table::TanStackValue::Number(r.cpu as f64))
125 .sorting_fn_auto()
126 .filtering_fn_auto(),
127 ];
128
129 Table::builder(data)
130 .columns(columns)
131 .get_row_key(|row, _idx, _parent| RowKey(row.id))
132 .get_row_id(|row, _idx, _parent| RowId::new(row.id.to_string()))
133 .state(state)
134 .initial_state(initial)
135 .options(crate::table::TableOptions {
136 manual_pagination,
137 ..Default::default()
138 })
139 .global_filter_fn(FilteringFnSpec::Auto)
140 .build()
141 }
142
143 #[test]
144 fn page_index_register_first_then_reset_coalesces() {
145 let data = vec![Row { id: 1, cpu: 10 }, Row { id: 2, cpu: 20 }];
146
147 let mut state = TableState::default();
148 state.pagination = PaginationState {
149 page_index: 1,
150 page_size: 2,
151 };
152
153 let initial = TableState::default();
154
155 let table = build_table(&data, state.clone(), initial.clone(), false);
156
157 let mut q = TanStackAutoResetQueue::default();
158
159 q.begin_render_pass();
161 q.auto_reset_page_index(&table);
162 q.auto_reset_page_index(&table);
163 q.flush(&table, &mut state);
164 assert!(q.page_index_registered());
165 assert_eq!(state.pagination.page_index, 1);
166
167 q.begin_render_pass();
169 q.auto_reset_page_index(&table);
170 q.auto_reset_page_index(&table);
171 q.auto_reset_page_index(&table);
172 assert!(q.pending_page_index_reset());
173 q.flush(&table, &mut state);
174 assert_eq!(state.pagination.page_index, initial.pagination.page_index);
175 assert!(!q.pending_page_index_reset());
176 }
177
178 #[test]
179 fn manual_pagination_disables_auto_reset_by_default() {
180 let data = vec![Row { id: 1, cpu: 10 }, Row { id: 2, cpu: 20 }];
181
182 let mut state = TableState::default();
183 state.pagination.page_index = 3;
184
185 let initial = TableState::default();
186 let table = build_table(&data, state.clone(), initial.clone(), true);
187
188 let mut q = TanStackAutoResetQueue::default();
189
190 q.begin_render_pass();
192 q.auto_reset_page_index(&table);
193 q.flush(&table, &mut state);
194 assert_eq!(state.pagination.page_index, 3);
195
196 q.begin_render_pass();
198 q.auto_reset_page_index(&table);
199 q.flush(&table, &mut state);
200 assert_eq!(state.pagination.page_index, 3);
201 }
202
203 #[test]
204 fn expanded_register_first_then_reset() {
205 let data = vec![Row { id: 1, cpu: 10 }, Row { id: 2, cpu: 20 }];
206
207 let mut state = TableState::default();
208 state.expanding = ExpandingState::All;
209
210 let mut initial = TableState::default();
211 initial.expanding = ExpandingState::default();
212
213 let table = build_table(&data, state.clone(), initial.clone(), false);
214
215 let mut q = TanStackAutoResetQueue::default();
216
217 q.begin_render_pass();
218 q.auto_reset_expanded(&table);
219 q.flush(&table, &mut state);
220 assert_eq!(state.expanding, ExpandingState::All);
221
222 q.begin_render_pass();
223 q.auto_reset_expanded(&table);
224 q.flush(&table, &mut state);
225 assert_eq!(state.expanding, initial.expanding);
226 }
227}