Doc + formatting

This commit is contained in:
Greg Burri 2025-03-18 20:03:25 +01:00
parent 9ed5a04e22
commit 995f77d1ef
9 changed files with 39 additions and 30 deletions

View file

@ -1,5 +1,9 @@
* Finish all local storage API (remove scheduled, add ingredient, etc..)
* Find an elegant/global way to adapt the quantities to servings (e.g. shopping list)
* FIX: when the event blur is triggered when changing page, the async process doesn't finish all the time * FIX: when the event blur is triggered when changing page, the async process doesn't finish all the time
* User can change default_servings in profile * User can change default_servings in profile
* Add a way to retrieve a backup of the database (only if admin)
* Maybe make a dev-page with logs and other tools/information
* Can choose servings number in recipe view * Can choose servings number in recipe view
* Default number is the user setting user.default_servings * Default number is the user setting user.default_servings
* A symbol show the native recipe servings number * A symbol show the native recipe servings number
@ -7,8 +11,10 @@
* Define the UI (mockups). * Define the UI (mockups).
* Two CSS: one for desktop and one for mobile * Two CSS: one for desktop and one for mobile
* Use CSS flex/grid to define a good design/layout * Use CSS flex/grid to define a good design/layout
* CSS for dark mode + autodetect
* CSS for toast and modal dialog * CSS for toast and modal dialog
* Calendar: Choose the first day of the week * Calendar: Choose the first day of the week
* i18n: prefix uri with the language: /fr/recipe/view/2
* Make a search page * Make a search page
Use FTS5: Use FTS5:
https://sqlite.org/fts5.html https://sqlite.org/fts5.html

View file

@ -2,7 +2,7 @@ use std::{fmt, fs::File};
use ron::{ use ron::{
de::from_reader, de::from_reader,
ser::{to_writer_pretty, PrettyConfig}, ser::{PrettyConfig, to_writer_pretty},
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -49,7 +49,7 @@ pub fn load() -> Config {
) )
}), }),
Err(_) => { Err(_) => {
let file = File::create(consts::FILE_CONF).unwrap_or_else(|error| { let mut file = File::create(consts::FILE_CONF).unwrap_or_else(|error| {
panic!( panic!(
"Failed to create default configuration file {}: {}", "Failed to create default configuration file {}: {}",
consts::FILE_CONF, consts::FILE_CONF,
@ -59,13 +59,15 @@ pub fn load() -> Config {
let default_config = Config::default(); let default_config = Config::default();
to_writer_pretty(file, &default_config, PrettyConfig::new()).unwrap_or_else(|error| { to_writer_pretty(&mut file, &default_config, PrettyConfig::new()).unwrap_or_else(
|error| {
panic!( panic!(
"Failed to write default configuration file {}: {}", "Failed to write default configuration file {}: {}",
consts::FILE_CONF, consts::FILE_CONF,
error error
) )
}); },
);
default_config default_config
} }

View file

@ -829,15 +829,13 @@ VALUES ($1, $2, $3, $4)
{ {
Err(Error::Database(error)) Err(Error::Database(error))
if error.code() == Some(std::borrow::Cow::Borrowed("2067")) if error.code() == Some(std::borrow::Cow::Borrowed("2067"))
&& error.message() == "UNIQUE constraint failed: RecipeScheduled.user_id, RecipeScheduled.recipe_id, RecipeScheduled.date" => && error.message()
== "UNIQUE constraint failed: RecipeScheduled.user_id, RecipeScheduled.recipe_id, RecipeScheduled.date" =>
{ {
Ok(AddScheduledRecipeResult::RecipeAlreadyScheduledAtThisDate) Ok(AddScheduledRecipeResult::RecipeAlreadyScheduledAtThisDate)
} }
Err(error) => { Err(error) => Err(DBError::from(error)),
Err(DBError::from(error))
}
Ok(insert_result) => { Ok(insert_result) => {
if add_ingredients_to_shopping_list { if add_ingredients_to_shopping_list {
sqlx::query( sqlx::query(
r#" r#"
@ -847,7 +845,8 @@ INSERT INTO [ShoppingEntry] ([ingredient_id], [user_id], [recipe_scheduled_id],
INNER JOIN [Group] ON [Group].[id] = [Step].[group_id] INNER JOIN [Group] ON [Group].[id] = [Step].[group_id]
INNER JOIN [Recipe] ON [Recipe].[id] = [Group].[recipe_id] INNER JOIN [Recipe] ON [Recipe].[id] = [Group].[recipe_id]
WHERE [Recipe].[id] = $1 WHERE [Recipe].[id] = $1
"#) "#,
)
.bind(recipe_id) .bind(recipe_id)
.bind(user_id) .bind(user_id)
.bind(insert_result.last_insert_rowid()) .bind(insert_result.last_insert_rowid())

View file

@ -1,4 +1,3 @@
use axum::Error;
use chrono::{Duration, prelude::*}; use chrono::{Duration, prelude::*};
use rand::distr::{Alphanumeric, SampleString}; use rand::distr::{Alphanumeric, SampleString};
use sqlx::Sqlite; use sqlx::Sqlite;

View file

@ -5,6 +5,6 @@ authors = ["Grégory Burri <greg.burri@gmail.com>"]
edition = "2024" edition = "2024"
[dependencies] [dependencies]
ron = "0.8" ron = "0.8" # Can't upgrade to 0.9 because of https://github.com/ron-rs/ron/issues/561.
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
chrono = { version = "0.4", features = ["serde"] } chrono = { version = "0.4", features = ["serde"] }

View file

@ -15,7 +15,7 @@ common = { path = "../common" }
chrono = { version = "0.4", features = ["serde", "unstable-locales"] } chrono = { version = "0.4", features = ["serde", "unstable-locales"] }
ron = "0.8" ron = "0.8" # Can't upgrade to 0.9 because of https://github.com/ron-rs/ron/issues/561.
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_html_form = "0.2" serde_html_form = "0.2"
thiserror = "2" thiserror = "2"

View file

@ -1,6 +1,6 @@
use std::{cell::RefCell, rc::Rc}; use std::{cell::RefCell, rc::Rc};
use chrono::{offset::Local, Datelike, Days, Months, NaiveDate, Weekday}; use chrono::{Datelike, Days, Months, NaiveDate, Weekday, offset::Local};
use common::{ron_api, utils::substitute_with_names}; use common::{ron_api, utils::substitute_with_names};
use gloo::{ use gloo::{
console::log, console::log,
@ -16,7 +16,7 @@ use crate::{
modal_dialog, modal_dialog,
recipe_scheduler::RecipeScheduler, recipe_scheduler::RecipeScheduler,
request, request,
utils::{by_id, get_locale, selector, selector_all, SelectorExt}, utils::{SelectorExt, by_id, get_locale, selector, selector_all},
}; };
struct CalendarStateInternal { struct CalendarStateInternal {
@ -116,7 +116,7 @@ pub fn setup(
EventListener::new(&days, "click", move |event| { EventListener::new(&days, "click", move |event| {
let target: Element = event.target().unwrap().dyn_into().unwrap(); let target: Element = event.target().unwrap().dyn_into().unwrap();
log!(event); // log!(event); // TODO: Remove.
if target.class_name() == "number" && options.can_select_date { if target.class_name() == "number" && options.can_select_date {
let first_day = first_grid_day(state_clone.get_displayed_date()); let first_day = first_grid_day(state_clone.get_displayed_date());

View file

@ -61,6 +61,9 @@ pub fn setup_page(is_user_logged: bool) {
} }
EventListener::new( EventListener::new(
// TODO: Find the right place to move the item based on:
// 1) recipe id, 2) name, 3) shopping entry id
// Se shopping_list.rs@L30
&item_element.selector(".item-is-checked"), &item_element.selector(".item-is-checked"),
"change", "change",
move |event| { move |event| {

View file

@ -1,7 +1,7 @@
use chrono::{Datelike, Days, Months, NaiveDate}; use chrono::{Datelike, Days, Months, NaiveDate};
use common::ron_api; use common::ron_api;
use gloo::storage::{LocalStorage, Storage}; use gloo::storage::{LocalStorage, Storage};
use ron::ser::{to_string_pretty, PrettyConfig}; use ron::ser::{PrettyConfig, to_string_pretty};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use thiserror::Error; use thiserror::Error;
@ -37,7 +37,7 @@ impl ShoppingList {
if self.is_local { if self.is_local {
todo!(); todo!();
} else { } else {
request::put( request::patch(
"shopping_list/set_checked", "shopping_list/set_checked",
ron_api::Value { ron_api::Value {
id: item_id, id: item_id,