meal filtering feature
This commit is contained in:
+39
-2
@@ -340,6 +340,7 @@ struct AddMealForm {
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct MealPickerQuery {
|
||||
picker: Option<i64>,
|
||||
q: Option<String>,
|
||||
}
|
||||
|
||||
async fn home() -> Redirect {
|
||||
@@ -897,15 +898,50 @@ async fn meals_page(
|
||||
State(state): State<AppState>,
|
||||
user: CurrentUser,
|
||||
Query(query): Query<MealPickerQuery>,
|
||||
headers: HeaderMap,
|
||||
) -> Result<Response, AppError> {
|
||||
let meals = state.meals.list_meals().await?;
|
||||
let q = query.q.clone().unwrap_or_default();
|
||||
let meals = state.meals.list_meals(&q).await?;
|
||||
let meal_categories = state.meals.list_meal_categories().await?;
|
||||
let is_htmx = headers
|
||||
.get("hx-request")
|
||||
.and_then(|value| value.to_str().ok())
|
||||
.is_some_and(|value| value == "true");
|
||||
// A boosted navigation (e.g. the category form's POST redirect) also sends
|
||||
// `HX-Request: true`, but must render the full page, not just the results
|
||||
// fragment. Only a live search (an `hx-get` on the filter box) swaps the
|
||||
// fragment. htmx marks boosted requests with `HX-Boosted: true`.
|
||||
let is_boosted = headers
|
||||
.get("hx-boosted")
|
||||
.and_then(|value| value.to_str().ok())
|
||||
.is_some_and(|value| value == "true");
|
||||
if let Some(list_id) = query.picker {
|
||||
return Ok(html_response(views::meal_picker(
|
||||
if query.q.is_some() {
|
||||
// Live search inside the picker: swap only the grouped rows, keeping
|
||||
// the modal and search box focused. The initial picker load has no
|
||||
// `q`, so it falls through to the full modal below.
|
||||
return Ok(html_response(views::meal_picker_results(
|
||||
&meals,
|
||||
&meal_categories,
|
||||
list_id,
|
||||
&user.session.csrf_token,
|
||||
)));
|
||||
}
|
||||
let picker = views::meal_picker(
|
||||
&meals,
|
||||
&meal_categories,
|
||||
list_id,
|
||||
&user.session.csrf_token,
|
||||
&q,
|
||||
);
|
||||
return Ok(html_response(picker));
|
||||
}
|
||||
if is_htmx && !is_boosted {
|
||||
// Live search on the meals page: swap only the grouped results.
|
||||
return Ok(html_response(views::meal_results(
|
||||
&meals,
|
||||
&meal_categories,
|
||||
&q,
|
||||
)));
|
||||
}
|
||||
Ok(html_response(views::meals_page(
|
||||
@@ -913,6 +949,7 @@ async fn meals_page(
|
||||
&meals,
|
||||
&meal_categories,
|
||||
&user.session.csrf_token,
|
||||
&q,
|
||||
)))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user