Ingredients can now be remove from shopping list when a recipe is unscheduled.
This commit is contained in:
parent
a3f2b4a86a
commit
da5ea57787
7 changed files with 92 additions and 36 deletions
|
|
@ -795,7 +795,7 @@ VALUES ($1, $2)
|
||||||
recipe_id: i64,
|
recipe_id: i64,
|
||||||
date: NaiveDate,
|
date: NaiveDate,
|
||||||
servings: u32,
|
servings: u32,
|
||||||
add_ingredients_element: bool,
|
add_ingredients_to_shopping_list: bool,
|
||||||
) -> Result<AddScheduledRecipeResult> {
|
) -> Result<AddScheduledRecipeResult> {
|
||||||
let mut tx = self.tx().await?;
|
let mut tx = self.tx().await?;
|
||||||
|
|
||||||
|
|
@ -823,7 +823,7 @@ VALUES ($1, $2, $3, $4)
|
||||||
}
|
}
|
||||||
Ok(insert_result) => {
|
Ok(insert_result) => {
|
||||||
|
|
||||||
if add_ingredients_element {
|
if add_ingredients_to_shopping_list {
|
||||||
sqlx::query(
|
sqlx::query(
|
||||||
r#"
|
r#"
|
||||||
INSERT INTO [ShoppingEntry] ([ingredient_id], [user_id], [recipe_scheduled_id], [servings])
|
INSERT INTO [ShoppingEntry] ([ingredient_id], [user_id], [recipe_scheduled_id], [servings])
|
||||||
|
|
@ -853,7 +853,27 @@ INSERT INTO [ShoppingEntry] ([ingredient_id], [user_id], [recipe_scheduled_id],
|
||||||
user_id: i64,
|
user_id: i64,
|
||||||
recipe_id: i64,
|
recipe_id: i64,
|
||||||
date: NaiveDate,
|
date: NaiveDate,
|
||||||
|
remove_ingredients_from_shopping_list: bool,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
let mut tx = self.tx().await?;
|
||||||
|
|
||||||
|
if remove_ingredients_from_shopping_list {
|
||||||
|
sqlx::query(
|
||||||
|
r#"
|
||||||
|
DELETE FROM [ShoppingEntry]
|
||||||
|
WHERE [recipe_scheduled_id] IN (
|
||||||
|
SELECT [id] FROM [RecipeScheduled]
|
||||||
|
WHERE [user_id] = $1 AND [recipe_id] = $2 AND [date] = $3
|
||||||
|
)
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.bind(user_id)
|
||||||
|
.bind(recipe_id)
|
||||||
|
.bind(date)
|
||||||
|
.execute(&mut *tx)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
|
||||||
sqlx::query(
|
sqlx::query(
|
||||||
r#"
|
r#"
|
||||||
DELETE FROM [RecipeScheduled]
|
DELETE FROM [RecipeScheduled]
|
||||||
|
|
@ -863,10 +883,12 @@ INSERT INTO [ShoppingEntry] ([ingredient_id], [user_id], [recipe_scheduled_id],
|
||||||
.bind(user_id)
|
.bind(user_id)
|
||||||
.bind(recipe_id)
|
.bind(recipe_id)
|
||||||
.bind(date)
|
.bind(date)
|
||||||
.execute(&self.pool)
|
.execute(&mut *tx)
|
||||||
.await
|
.await?;
|
||||||
.map(|_| ())
|
|
||||||
.map_err(DBError::from)
|
tx.commit().await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_scheduled_recipes(
|
pub async fn get_scheduled_recipes(
|
||||||
|
|
|
||||||
|
|
@ -681,12 +681,17 @@ pub async fn schedule_recipe(
|
||||||
pub async fn rm_scheduled_recipe(
|
pub async fn rm_scheduled_recipe(
|
||||||
State(connection): State<db::Connection>,
|
State(connection): State<db::Connection>,
|
||||||
Extension(user): Extension<Option<model::User>>,
|
Extension(user): Extension<Option<model::User>>,
|
||||||
ExtractRon(ron): ExtractRon<common::ron_api::ScheduledRecipe>,
|
ExtractRon(ron): ExtractRon<common::ron_api::RemoveScheduledRecipe>,
|
||||||
) -> Result<impl IntoResponse> {
|
) -> Result<impl IntoResponse> {
|
||||||
check_user_rights_recipe(&connection, &user, ron.recipe_id).await?;
|
check_user_rights_recipe(&connection, &user, ron.recipe_id).await?;
|
||||||
if let Some(user) = user {
|
if let Some(user) = user {
|
||||||
connection
|
connection
|
||||||
.rm_scheduled_recipe(user.id, ron.recipe_id, ron.date)
|
.rm_scheduled_recipe(
|
||||||
|
user.id,
|
||||||
|
ron.recipe_id,
|
||||||
|
ron.date,
|
||||||
|
ron.remove_ingredients_from_shopping_list,
|
||||||
|
)
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
Ok(StatusCode::OK)
|
Ok(StatusCode::OK)
|
||||||
|
|
|
||||||
|
|
@ -146,6 +146,7 @@ pub enum Sentence {
|
||||||
CalendarAddToPlannerAlreadyExists,
|
CalendarAddToPlannerAlreadyExists,
|
||||||
CalendarDateFormat, // See https://docs.rs/chrono/latest/chrono/format/strftime/index.html.
|
CalendarDateFormat, // See https://docs.rs/chrono/latest/chrono/format/strftime/index.html.
|
||||||
CalendarAddIngredientsToShoppingList,
|
CalendarAddIngredientsToShoppingList,
|
||||||
|
CalendarRemoveIngredientsFromShoppingList,
|
||||||
CalendarUnscheduleConfirmation,
|
CalendarUnscheduleConfirmation,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,18 @@
|
||||||
<div class="scheduled-recipe-with-link-and-remove"><a></a><span class="remove-scheduled-recipe">X</span></div>
|
<div class="scheduled-recipe-with-link-and-remove"><a></a><span class="remove-scheduled-recipe">X</span></div>
|
||||||
<div class="scheduled-recipe"></div>
|
<div class="scheduled-recipe"></div>
|
||||||
|
|
||||||
<span class="unschedule-confirmation">{{ tr.t(Sentence::CalendarUnscheduleConfirmation) }}</span>
|
<div class="unschedule-confirmation">
|
||||||
|
<div>{{ tr.t(Sentence::CalendarUnscheduleConfirmation) }}</div>
|
||||||
|
<input
|
||||||
|
id="input-remove-ingredients-from-shopping-list"
|
||||||
|
type="checkbox"
|
||||||
|
checked
|
||||||
|
/>
|
||||||
|
<label for="input-remove-ingredients-from-shopping-list">
|
||||||
|
{{ tr.t(Sentence::CalendarRemoveIngredientsFromShoppingList) }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
<span class="calendar-date-format">{{ tr.t(Sentence::CalendarDateFormat) }}</span>
|
<span class="calendar-date-format">{{ tr.t(Sentence::CalendarDateFormat) }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -130,6 +130,7 @@
|
||||||
(CalendarAddToPlannerAlreadyExists, "Recipe {title} has already been scheduled for {date}"),
|
(CalendarAddToPlannerAlreadyExists, "Recipe {title} has already been scheduled for {date}"),
|
||||||
(CalendarDateFormat, "%A, %-d %B, %C%y"), // See https://docs.rs/chrono/latest/chrono/format/strftime/index.html.
|
(CalendarDateFormat, "%A, %-d %B, %C%y"), // See https://docs.rs/chrono/latest/chrono/format/strftime/index.html.
|
||||||
(CalendarAddIngredientsToShoppingList, "Add ingredients to shopping list"),
|
(CalendarAddIngredientsToShoppingList, "Add ingredients to shopping list"),
|
||||||
|
(CalendarRemoveIngredientsFromShoppingList, "Remove ingredients from shopping list"),
|
||||||
(CalendarUnscheduleConfirmation, "Are you sure to remove {title} on {date}"),
|
(CalendarUnscheduleConfirmation, "Are you sure to remove {title} on {date}"),
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
|
|
@ -264,6 +265,7 @@
|
||||||
(CalendarAddToPlannerAlreadyExists, "La recette {title} a été déjà été agendée pour le {date}"),
|
(CalendarAddToPlannerAlreadyExists, "La recette {title} a été déjà été agendée pour le {date}"),
|
||||||
(CalendarDateFormat, "%A %-d %B %C%y"), // See https://docs.rs/chrono/latest/chrono/format/strftime/index.html.
|
(CalendarDateFormat, "%A %-d %B %C%y"), // See https://docs.rs/chrono/latest/chrono/format/strftime/index.html.
|
||||||
(CalendarAddIngredientsToShoppingList, "Ajouter les ingrédients à la liste de course"),
|
(CalendarAddIngredientsToShoppingList, "Ajouter les ingrédients à la liste de course"),
|
||||||
|
(CalendarRemoveIngredientsFromShoppingList, "Enlever les ingrédients de la liste de course"),
|
||||||
(CalendarUnscheduleConfirmation, "Êtes-vous sûr de vouloir enlever {title} du {date}"),
|
(CalendarUnscheduleConfirmation, "Êtes-vous sûr de vouloir enlever {title} du {date}"),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -204,9 +204,10 @@ pub enum ScheduleRecipeResult {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
pub struct ScheduledRecipe {
|
pub struct RemoveScheduledRecipe {
|
||||||
pub recipe_id: i64,
|
pub recipe_id: i64,
|
||||||
pub date: NaiveDate,
|
pub date: NaiveDate,
|
||||||
|
pub remove_ingredients_from_shopping_list: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** Shopping list ***/
|
/*** Shopping list ***/
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,15 @@ use std::{cell::RefCell, rc::Rc};
|
||||||
|
|
||||||
use chrono::{offset::Local, Datelike, Days, Months, NaiveDate, Weekday};
|
use chrono::{offset::Local, Datelike, Days, Months, NaiveDate, Weekday};
|
||||||
use common::{ron_api, utils::substitute_with_names};
|
use common::{ron_api, utils::substitute_with_names};
|
||||||
use gloo::{console::log, events::EventListener, utils::document};
|
use gloo::{
|
||||||
|
console::log,
|
||||||
|
events::EventListener,
|
||||||
|
utils::{document, window},
|
||||||
|
};
|
||||||
use scanf::sscanf;
|
use scanf::sscanf;
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
use wasm_bindgen_futures::spawn_local;
|
use wasm_bindgen_futures::spawn_local;
|
||||||
use web_sys::Element;
|
use web_sys::{Element, HtmlInputElement};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
modal_dialog,
|
modal_dialog,
|
||||||
|
|
@ -140,11 +144,13 @@ pub fn setup(
|
||||||
|
|
||||||
let title = target.previous_element_sibling().unwrap().inner_html();
|
let title = target.previous_element_sibling().unwrap().inner_html();
|
||||||
|
|
||||||
if modal_dialog::show_and_initialize(
|
if let Some(remove_ingredients_from_shopping_list) =
|
||||||
|
modal_dialog::show_and_initialize_with_ok(
|
||||||
"#hidden-templates-calendar .unschedule-confirmation",
|
"#hidden-templates-calendar .unschedule-confirmation",
|
||||||
async |element| {
|
async |element| {
|
||||||
let date_format =
|
let date_format = selector::<Element>(
|
||||||
selector::<Element>("#hidden-templates-calendar .calendar-date-format")
|
"#hidden-templates-calendar .calendar-date-format",
|
||||||
|
)
|
||||||
.inner_html();
|
.inner_html();
|
||||||
element.set_inner_html(&substitute_with_names(
|
element.set_inner_html(&substitute_with_names(
|
||||||
&element.inner_html(),
|
&element.inner_html(),
|
||||||
|
|
@ -157,14 +163,22 @@ pub fn setup(
|
||||||
],
|
],
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
|
|element, _| {
|
||||||
|
let remove_ingredients_element: HtmlInputElement =
|
||||||
|
element.selector("#input-remove-ingredients-from-shopping-list");
|
||||||
|
remove_ingredients_element.checked()
|
||||||
|
},
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.is_some()
|
|
||||||
{
|
{
|
||||||
let body = ron_api::ScheduledRecipe { recipe_id, date };
|
let body = ron_api::RemoveScheduledRecipe {
|
||||||
|
recipe_id,
|
||||||
|
date,
|
||||||
|
remove_ingredients_from_shopping_list,
|
||||||
|
};
|
||||||
let _ =
|
let _ =
|
||||||
request::delete::<(), _>("calendar/remove_scheduled_recipe", body).await;
|
request::delete::<(), _>("calendar/remove_scheduled_recipe", body).await;
|
||||||
target.parent_element().unwrap().remove();
|
window().location().reload().unwrap();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue