Skip to content

Commit 50a6201

Browse files
authored
Merge pull request #67 from holg/refactor_table_content
Issue 66 fixed keeping track of the query params in the way the frontend…
2 parents cc55cec + 18aba6f commit 50a6201

1 file changed

Lines changed: 55 additions & 38 deletions

File tree

src/components/table_content.rs

Lines changed: 55 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// leptos-struct-table/src/components/table_content.rs
2+
13
#![allow(clippy::await_holding_refcell_ref)]
24

35
use crate::components::renderer_fn::renderer_fn;
@@ -167,7 +169,7 @@ pub fn TableContent<Row, DataP, Err, ClsP, ScrollEl, ScrollM>(
167169
/// Can be one of
168170
/// - `Virtualization`
169171
/// - `InfiniteScroll`
170-
/// - `Pagination`
172+
/// - `Pagination`
171173
///
172174
/// Please check [`DisplayStrategy`] to see explanations of all available options.
173175
#[prop(optional)]
@@ -394,63 +396,74 @@ where
394396
);
395397

396398
Effect::new(move || {
397-
let first_visible_row_index = first_visible_row_index.get();
398-
let visible_row_count = visible_row_count.get().min(MAX_DISPLAY_ROW_COUNT);
399-
400399
// with this a reload triggers this effect
401400
reload_count.track();
402401

403-
if visible_row_count == 0 {
404-
return;
405-
}
406-
407-
let mut start = first_visible_row_index.saturating_sub(visible_row_count * 2);
408-
409-
let mut end = start + visible_row_count * 5;
402+
// 1. Get all values *atomically* within a single .with() call
403+
let (first_visible, visible_count, row_count_opt) = loaded_rows.with(|_| {
404+
(
405+
first_visible_row_index.get(),
406+
visible_row_count.get(),
407+
row_count.get(),
408+
)
409+
});
410410

411-
if let Some(chunk_size) = DataP::CHUNK_SIZE {
412-
start /= chunk_size;
413-
start *= chunk_size;
411+
let visible_count = visible_count.min(MAX_DISPLAY_ROW_COUNT);
414412

415-
end /= chunk_size;
416-
end += 1;
417-
end *= chunk_size;
413+
if visible_count == 0 {
414+
return;
418415
}
419416

420-
if let Some(row_count) = row_count.get() {
417+
let mut start = first_visible.saturating_sub(visible_count * 2);
418+
let mut end = start + visible_count * 5;
419+
420+
if let Some(row_count) = row_count_opt {
421+
// Clamp end to row_count if we know it
421422
end = end.min(row_count);
422-
}
423423

424-
if !matches!(display_strategy, DisplayStrategy::Pagination { .. }) {
425-
end = end.min(start + MAX_DISPLAY_ROW_COUNT);
424+
// Ensure start is within valid bounds *after* clamping end
425+
start = start.min(end); // Crucial: prevent start > end
426+
} else {
427+
//If total number of rows is unknown, we don't clamp,
428+
// but limit to MAX_DISPLAY_ROW_COUNT
429+
if !matches!(display_strategy, DisplayStrategy::Pagination { .. }) {
430+
end = end.min(start + MAX_DISPLAY_ROW_COUNT);
431+
}
426432
}
427433

428-
loaded_rows.update_untracked(|loaded_rows| {
429-
if end > loaded_rows.len() {
430-
loaded_rows.resize(end);
431-
}
432-
});
434+
if let Some(chunk_size) = DataP::CHUNK_SIZE {
435+
start = (start / chunk_size) * chunk_size;
436+
end = ((end + chunk_size - 1) / chunk_size) * chunk_size; // Round end *up* to nearest chunk size
437+
}
433438

434439
let range = start..end;
435440

436441
set_display_range.set(match display_strategy {
437442
DisplayStrategy::Virtualization | DisplayStrategy::InfiniteScroll => range.clone(),
438443
DisplayStrategy::Pagination { row_count, .. } => {
439-
first_visible_row_index..(first_visible_row_index + row_count).min(end)
444+
first_visible..(first_visible + row_count).min(end)
445+
}
446+
});
447+
448+
loaded_rows.update_untracked(|loaded_rows| {
449+
if end > loaded_rows.len() {
450+
loaded_rows.resize(end);
440451
}
441452
});
442453

443454
let missing_range =
444455
loaded_rows.with_untracked(|loaded_rows| loaded_rows.missing_range(range.clone()));
445456

446457
if let Some(missing_range) = missing_range {
447-
let mut end = missing_range.end;
448-
if let Some(row_count) = row_count.get() {
449-
end = end.min(row_count);
458+
// Ensure missing_range is valid *after* all calculations
459+
let missing_start = missing_range.start.min(missing_range.end);
460+
let missing_end = missing_range.end; // Already correct
450461

451-
if end <= missing_range.start {
452-
return;
453-
}
462+
let missing_range = missing_start..missing_end;
463+
464+
if missing_range.is_empty() {
465+
// Don't proceed with empty ranges
466+
return;
454467
}
455468

456469
loaded_rows.write().write_loading(missing_range.clone());
@@ -497,12 +510,16 @@ where
497510

498511
if let Ok((_, loaded_range)) = &result {
499512
if loaded_range.end < missing_range.end {
500-
if let Some(row_count) = row_count.get_untracked() {
501-
if loaded_range.end < row_count {
513+
match row_count_opt { // Use pre-fetched value!
514+
Some(row_count) => {
515+
if loaded_range.end < row_count {
516+
set_known_row_count(loaded_range.end);
517+
}
518+
},
519+
None => {
502520
set_known_row_count(loaded_range.end);
503-
}
504-
} else {
505-
set_known_row_count(loaded_range.end);
521+
},
522+
506523
}
507524
}
508525
}

0 commit comments

Comments
 (0)