Doc + formatting
This commit is contained in:
parent
9ed5a04e22
commit
995f77d1ef
9 changed files with 39 additions and 30 deletions
8
TODO.md
8
TODO.md
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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(
|
||||||
panic!(
|
|error| {
|
||||||
"Failed to write default configuration file {}: {}",
|
panic!(
|
||||||
consts::FILE_CONF,
|
"Failed to write default configuration file {}: {}",
|
||||||
error
|
consts::FILE_CONF,
|
||||||
)
|
error
|
||||||
});
|
)
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
default_config
|
default_config
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,13 +845,14 @@ 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(user_id)
|
.bind(recipe_id)
|
||||||
.bind(insert_result.last_insert_rowid())
|
.bind(user_id)
|
||||||
.bind(servings)
|
.bind(insert_result.last_insert_rowid())
|
||||||
.execute(&mut *tx)
|
.bind(servings)
|
||||||
.await?;
|
.execute(&mut *tx)
|
||||||
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
tx.commit().await?;
|
tx.commit().await?;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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"] }
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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());
|
||||||
|
|
|
||||||
|
|
@ -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| {
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue