Rename 'published' to 'public' (for recipe)
This commit is contained in:
parent
eaef6dc77e
commit
4f739593b8
20 changed files with 92 additions and 91 deletions
|
|
@ -27,7 +27,7 @@ clap = { version = "4", features = ["derive"] }
|
|||
|
||||
sqlx = { version = "0.8", features = ["sqlite", "runtime-tokio", "chrono"] }
|
||||
|
||||
askama = "=0.13.0-pre.0"
|
||||
askama = "0.13"
|
||||
|
||||
argon2 = { version = "0.5", features = ["default", "std"] }
|
||||
rand_core = { version = "0.9", features = ["std"] }
|
||||
|
|
|
|||
|
|
@ -21,16 +21,16 @@ VALUES (
|
|||
NULL
|
||||
);
|
||||
|
||||
INSERT INTO [Recipe] ([id], [user_id], [title], [is_published], [creation_datetime])
|
||||
INSERT INTO [Recipe] ([id], [user_id], [title], [is_public], [creation_datetime])
|
||||
VALUES (1, 1, 'Croissant au jambon', true, '2025-01-07T10:41:05.697884837+00:00');
|
||||
|
||||
INSERT INTO [Recipe] ([id], [user_id], [title], [is_published], [creation_datetime], [servings], [estimated_time], [difficulty])
|
||||
INSERT INTO [Recipe] ([id], [user_id], [title], [is_public], [creation_datetime], [servings], [estimated_time], [difficulty])
|
||||
VALUES (2, 1, 'Gratin de thon aux olives', true, '2025-01-07T10:41:05.697884837+00:00', 4, 40, 1);
|
||||
|
||||
INSERT INTO [Recipe] ([id], [user_id], [title], [is_published], [creation_datetime])
|
||||
INSERT INTO [Recipe] ([id], [user_id], [title], [is_public], [creation_datetime])
|
||||
VALUES (3, 1, 'Saumon en croute', true, '2025-01-07T10:41:05.697884837+00:00');
|
||||
|
||||
INSERT INTO [Recipe] ([id], [user_id], [title], [is_published], [creation_datetime])
|
||||
INSERT INTO [Recipe] ([id], [user_id], [title], [is_public], [creation_datetime])
|
||||
VALUES (4, 2, 'Ouiche lorraine', true, '2025-01-07T10:41:05.697884837+00:00');
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ CREATE TABLE [Recipe] (
|
|||
-- 0: Unknown, 1: Easy, 2: Medium, 4: Hard.
|
||||
[difficulty] INTEGER NOT NULL DEFAULT 0,
|
||||
[servings] INTEGER DEFAULT 4,
|
||||
[is_published] INTEGER NOT NULL DEFAULT FALSE,
|
||||
[is_public] INTEGER NOT NULL DEFAULT FALSE,
|
||||
[creation_datetime] TEXT NOT NULL,
|
||||
|
||||
FOREIGN KEY([user_id]) REFERENCES [User]([id]) ON DELETE SET NULL
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ pub enum AddScheduledRecipeResult {
|
|||
impl Connection {
|
||||
/// Returns all the recipe titles where recipe is written in the given language.
|
||||
/// If a user_id is given, the language constraint is ignored for recipes owned by user_id.
|
||||
pub async fn get_all_published_recipe_titles(
|
||||
pub async fn get_all_public_recipe_titles(
|
||||
&self,
|
||||
lang: &str,
|
||||
user_id: Option<i64>,
|
||||
|
|
@ -24,7 +24,7 @@ impl Connection {
|
|||
r#"
|
||||
SELECT [id], [title]
|
||||
FROM [Recipe]
|
||||
WHERE [is_published] = true AND ([lang] = $1 OR [user_id] = $2)
|
||||
WHERE [is_public] = true AND ([lang] = $1 OR [user_id] = $2)
|
||||
ORDER BY [title] COLLATE NOCASE
|
||||
"#,
|
||||
)
|
||||
|
|
@ -35,7 +35,7 @@ ORDER BY [title] COLLATE NOCASE
|
|||
r#"
|
||||
SELECT [id], [title]
|
||||
FROM [Recipe]
|
||||
WHERE [is_published] = true AND [lang] = $1
|
||||
WHERE [is_public] = true AND [lang] = $1
|
||||
ORDER BY [title] COLLATE NOCASE
|
||||
"#,
|
||||
)
|
||||
|
|
@ -46,15 +46,12 @@ ORDER BY [title] COLLATE NOCASE
|
|||
.map_err(DBError::from)
|
||||
}
|
||||
|
||||
pub async fn get_all_unpublished_recipe_titles(
|
||||
&self,
|
||||
owned_by: i64,
|
||||
) -> Result<Vec<(i64, String)>> {
|
||||
pub async fn get_all_private_recipe_titles(&self, owned_by: i64) -> Result<Vec<(i64, String)>> {
|
||||
sqlx::query_as(
|
||||
r#"
|
||||
SELECT [id], [title]
|
||||
FROM [Recipe]
|
||||
WHERE [is_published] = false AND [user_id] = $1
|
||||
WHERE [is_public] = false AND [user_id] = $1
|
||||
ORDER BY [title]
|
||||
"#,
|
||||
)
|
||||
|
|
@ -264,8 +261,7 @@ WHERE [id] = $1 AND ([user_id] = $2 OR (SELECT [is_admin] FROM [User] WHERE [id]
|
|||
r#"
|
||||
SELECT
|
||||
[id], [user_id], [title], [lang],
|
||||
[estimated_time], [description], [difficulty], [servings],
|
||||
[is_published]
|
||||
[estimated_time], [description], [difficulty], [servings], [is_public]
|
||||
FROM [Recipe] WHERE [id] = $1
|
||||
"#,
|
||||
)
|
||||
|
|
@ -520,10 +516,10 @@ WHERE [id] = $1 AND [id] NOT IN (
|
|||
.map_err(DBError::from)
|
||||
}
|
||||
|
||||
pub async fn set_recipe_is_published(&self, recipe_id: i64, is_published: bool) -> Result<()> {
|
||||
sqlx::query("UPDATE [Recipe] SET [is_published] = $2 WHERE [id] = $1")
|
||||
pub async fn set_recipe_is_public(&self, recipe_id: i64, is_public: bool) -> Result<()> {
|
||||
sqlx::query("UPDATE [Recipe] SET [is_public] = $2 WHERE [id] = $1")
|
||||
.bind(recipe_id)
|
||||
.bind(is_published)
|
||||
.bind(is_public)
|
||||
.execute(&self.pool)
|
||||
.await
|
||||
.map(|_| ())
|
||||
|
|
@ -966,7 +962,7 @@ mod tests {
|
|||
.set_recipe_difficulty(recipe_id, Difficulty::Medium)
|
||||
.await?;
|
||||
connection.set_recipe_language(recipe_id, "fr").await?;
|
||||
connection.set_recipe_is_published(recipe_id, true).await?;
|
||||
connection.set_recipe_is_public(recipe_id, true).await?;
|
||||
|
||||
let recipe = connection.get_recipe(recipe_id, false).await?.unwrap();
|
||||
|
||||
|
|
@ -976,7 +972,7 @@ mod tests {
|
|||
assert_eq!(recipe.estimated_time, Some(420));
|
||||
assert_eq!(recipe.difficulty, Difficulty::Medium);
|
||||
assert_eq!(recipe.lang, "fr");
|
||||
assert!(recipe.is_published);
|
||||
assert!(recipe.is_public);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ pub struct Recipe {
|
|||
pub difficulty: Difficulty,
|
||||
|
||||
pub servings: Option<u32>,
|
||||
pub is_published: bool,
|
||||
pub is_public: bool,
|
||||
|
||||
#[sqlx(skip)]
|
||||
pub tags: Vec<String>,
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ use crate::{
|
|||
};
|
||||
|
||||
pub struct Recipes {
|
||||
pub published: Vec<(i64, String)>,
|
||||
pub unpublished: Vec<(i64, String)>,
|
||||
pub public: Vec<(i64, String)>,
|
||||
pub private: Vec<(i64, String)>,
|
||||
pub current_id: Option<i64>,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -162,8 +162,8 @@ async fn main() {
|
|||
patch(services::ron::recipe::set_language),
|
||||
)
|
||||
.route(
|
||||
"/recipe/is_published",
|
||||
patch(services::ron::recipe::set_is_published),
|
||||
"/recipe/is_public",
|
||||
patch(services::ron::recipe::set_is_public),
|
||||
)
|
||||
.route("/recipe", delete(services::ron::recipe::rm))
|
||||
.route("/recipe/groups", get(services::ron::recipe::get_groups))
|
||||
|
|
|
|||
|
|
@ -21,16 +21,14 @@ pub async fn recipes_list_fragments(
|
|||
Extension(context): Extension<Context>,
|
||||
) -> Result<impl IntoResponse> {
|
||||
let recipes = Recipes {
|
||||
published: connection
|
||||
.get_all_published_recipe_titles(
|
||||
public: connection
|
||||
.get_all_public_recipe_titles(
|
||||
context.tr.current_lang_code(),
|
||||
context.user.as_ref().map(|u| u.id),
|
||||
)
|
||||
.await?,
|
||||
unpublished: if let Some(user) = context.user.as_ref() {
|
||||
connection
|
||||
.get_all_unpublished_recipe_titles(user.id)
|
||||
.await?
|
||||
private: if let Some(user) = context.user.as_ref() {
|
||||
connection.get_all_private_recipe_titles(user.id).await?
|
||||
} else {
|
||||
vec![]
|
||||
},
|
||||
|
|
|
|||
|
|
@ -51,16 +51,14 @@ pub async fn home_page(
|
|||
Extension(context): Extension<Context>,
|
||||
) -> Result<impl IntoResponse> {
|
||||
let recipes = Recipes {
|
||||
published: connection
|
||||
.get_all_published_recipe_titles(
|
||||
public: connection
|
||||
.get_all_public_recipe_titles(
|
||||
context.tr.current_lang_code(),
|
||||
context.user.as_ref().map(|u| u.id),
|
||||
)
|
||||
.await?,
|
||||
unpublished: if let Some(user) = context.user.as_ref() {
|
||||
connection
|
||||
.get_all_unpublished_recipe_titles(user.id)
|
||||
.await?
|
||||
private: if let Some(user) = context.user.as_ref() {
|
||||
connection.get_all_private_recipe_titles(user.id).await?
|
||||
} else {
|
||||
vec![]
|
||||
},
|
||||
|
|
|
|||
|
|
@ -44,14 +44,11 @@ pub async fn edit(
|
|||
if let Some(recipe) = connection.get_recipe(recipe_id, false).await? {
|
||||
if model::can_user_edit_recipe(user, &recipe) {
|
||||
let recipes = Recipes {
|
||||
published: connection
|
||||
.get_all_published_recipe_titles(
|
||||
context.tr.current_lang_code(),
|
||||
Some(user.id),
|
||||
)
|
||||
public: connection
|
||||
.get_all_public_recipe_titles(context.tr.current_lang_code(), Some(user.id))
|
||||
.await?,
|
||||
unpublished: connection
|
||||
.get_all_unpublished_recipe_titles(user.id)
|
||||
private: connection
|
||||
.get_all_private_recipe_titles(user.id)
|
||||
.await?,
|
||||
current_id: Some(recipe_id),
|
||||
};
|
||||
|
|
@ -98,7 +95,7 @@ pub async fn view(
|
|||
) -> Result<Response> {
|
||||
match connection.get_recipe(recipe_id, true).await? {
|
||||
Some(recipe) => {
|
||||
if !recipe.is_published
|
||||
if !recipe.is_public
|
||||
&& (context.user.is_none() || recipe.user_id != context.user.as_ref().unwrap().id)
|
||||
{
|
||||
return Ok(Html(
|
||||
|
|
@ -115,15 +112,15 @@ pub async fn view(
|
|||
}
|
||||
|
||||
let recipes = Recipes {
|
||||
published: connection
|
||||
.get_all_published_recipe_titles(
|
||||
public: connection
|
||||
.get_all_public_recipe_titles(
|
||||
context.tr.current_lang_code(),
|
||||
context.user.as_ref().map(|u| u.id),
|
||||
)
|
||||
.await?,
|
||||
unpublished: if let Some(user) = context.user.as_ref() {
|
||||
private: if let Some(user) = context.user.as_ref() {
|
||||
connection
|
||||
.get_all_unpublished_recipe_titles(user.id)
|
||||
.get_all_private_recipe_titles(user.id)
|
||||
.await?
|
||||
} else {
|
||||
vec![]
|
||||
|
|
|
|||
|
|
@ -152,14 +152,14 @@ pub async fn set_language(
|
|||
}
|
||||
|
||||
#[debug_handler]
|
||||
pub async fn set_is_published(
|
||||
pub async fn set_is_public(
|
||||
State(connection): State<db::Connection>,
|
||||
Extension(context): Extension<Context>,
|
||||
ExtractRon(ron): ExtractRon<ron_api::SetIsPublished>,
|
||||
ExtractRon(ron): ExtractRon<ron_api::SetIsPublic>,
|
||||
) -> Result<StatusCode> {
|
||||
check_user_rights_recipe(&connection, &context.user, ron.recipe_id).await?;
|
||||
connection
|
||||
.set_recipe_is_published(ron.recipe_id, ron.is_published)
|
||||
.set_recipe_is_public(ron.recipe_id, ron.is_public)
|
||||
.await?;
|
||||
Ok(StatusCode::OK)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ use crate::consts;
|
|||
pub enum Sentence {
|
||||
MainTitle = 0,
|
||||
CreateNewRecipe,
|
||||
UnpublishedRecipes,
|
||||
PrivateRecipes,
|
||||
UntitledRecipe,
|
||||
|
||||
Name,
|
||||
|
|
@ -100,7 +100,7 @@ pub enum Sentence {
|
|||
RecipeDifficultyHard,
|
||||
RecipeTags,
|
||||
RecipeLanguage,
|
||||
RecipeIsPublished,
|
||||
RecipeIsPublic,
|
||||
RecipeDelete,
|
||||
RecipeAddAGroup,
|
||||
RecipeRemoveGroup,
|
||||
|
|
|
|||
|
|
@ -69,13 +69,13 @@
|
|||
</select>
|
||||
|
||||
<input
|
||||
id="input-is-published"
|
||||
id="input-is-public"
|
||||
type="checkbox"
|
||||
{%~ if recipe.is_published %}
|
||||
{%~ if recipe.is_public %}
|
||||
checked
|
||||
{% endif %}
|
||||
>
|
||||
<label for="input-is-published">{{ context.tr.t(Sentence::RecipeIsPublished) }}</label>
|
||||
<label for="input-is-public">{{ context.tr.t(Sentence::RecipeIsPublic) }}</label>
|
||||
|
||||
<input id="input-delete" type="button" value="{{ context.tr.t(Sentence::RecipeDelete) }}">
|
||||
|
||||
|
|
|
|||
|
|
@ -15,25 +15,25 @@
|
|||
{% endmacro %}
|
||||
|
||||
<div id="recipes-list">
|
||||
{% if !recipes.unpublished.is_empty() %}
|
||||
{{ context.tr.t(Sentence::UnpublishedRecipes) }}
|
||||
{% if !recipes.private.is_empty() %}
|
||||
{{ context.tr.t(Sentence::PrivateRecipes) }}
|
||||
{% endif %}
|
||||
|
||||
<nav class="recipes-list-unpublished">
|
||||
<nav class="recipes-list-private">
|
||||
<ul>
|
||||
{% for (id, title) in recipes.unpublished %}
|
||||
{% for (id, title) in recipes.private %}
|
||||
{% call recipe_item(id, title, recipes.is_current(id)) %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
{% if !recipes.unpublished.is_empty() %}
|
||||
{% if !recipes.private.is_empty() %}
|
||||
<hr>
|
||||
{% endif %}
|
||||
|
||||
<nav class="recipes-list-published">
|
||||
<nav class="recipes-list-public">
|
||||
<ul>
|
||||
{% for (id, title) in recipes.published %}
|
||||
{% for (id, title) in recipes.public %}
|
||||
{% call recipe_item(id, title, recipes.is_current(id)) %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
translation: [
|
||||
(MainTitle, "Cooking Recipes"),
|
||||
(CreateNewRecipe, "Create a new recipe"),
|
||||
(UnpublishedRecipes, "Unpublished recipes"),
|
||||
(PrivateRecipes, "Private recipes"),
|
||||
(UntitledRecipe, "Untitled recipe"),
|
||||
|
||||
(Name, "Name"),
|
||||
|
|
@ -86,7 +86,7 @@
|
|||
(RecipeDifficultyHard, "Hard"),
|
||||
(RecipeTags, "Tags"),
|
||||
(RecipeLanguage, "Language"),
|
||||
(RecipeIsPublished, "Is published"),
|
||||
(RecipeIsPublic, "Is public"),
|
||||
(RecipeDelete, "Delete recipe"),
|
||||
(RecipeAddAGroup, "Add a group"),
|
||||
(RecipeRemoveGroup, "Remove group"),
|
||||
|
|
@ -145,7 +145,7 @@
|
|||
translation: [
|
||||
(MainTitle, "Recettes de Cuisine"),
|
||||
(CreateNewRecipe, "Créer une nouvelle recette"),
|
||||
(UnpublishedRecipes, "Recettes non-publiés"),
|
||||
(PrivateRecipes, "Recettes privées"),
|
||||
(UntitledRecipe, "Recette sans nom"),
|
||||
|
||||
(Name, "Nom"),
|
||||
|
|
@ -225,7 +225,7 @@
|
|||
(RecipeDifficultyHard, "Difficile"),
|
||||
(RecipeTags, "Tags"),
|
||||
(RecipeLanguage, "Langue"),
|
||||
(RecipeIsPublished, "Est publiée"),
|
||||
(RecipeIsPublic, "Est public"),
|
||||
(RecipeDelete, "Supprimer la recette"),
|
||||
(RecipeAddAGroup, "Ajouter un groupe"),
|
||||
(RecipeRemoveGroup, "Supprimer le groupe"),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue