diff --git a/alembic/versions/2022-06-01-11.12.06_ab0bae02578f_add_use_abbreviation_column_to_.py b/alembic/versions/2022-06-01-11.12.06_ab0bae02578f_add_use_abbreviation_column_to_.py
new file mode 100644
index 000000000000..3f39ef0ddcba
--- /dev/null
+++ b/alembic/versions/2022-06-01-11.12.06_ab0bae02578f_add_use_abbreviation_column_to_.py
@@ -0,0 +1,30 @@
+"""Add use_abbreviation column to ingredients
+
+Revision ID: ab0bae02578f
+Revises: 09dfc897ad62
+Create Date: 2022-06-01 11:12:06.748383
+
+"""
+import sqlalchemy as sa
+
+from alembic import op
+
+# revision identifiers, used by Alembic.
+revision = "ab0bae02578f"
+down_revision = "09dfc897ad62"
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+ # ### commands auto generated by Alembic - please adjust! ###
+ op.add_column("ingredient_units", sa.Column("use_abbreviation", sa.Boolean(), nullable=True))
+
+ op.execute("UPDATE ingredient_units SET use_abbreviation = FALSE WHERE use_abbreviation IS NULL")
+ # ### end Alembic commands ###
+
+
+def downgrade():
+ # ### commands auto generated by Alembic - please adjust! ###
+ op.drop_column("ingredient_units", "use_abbreviation")
+ # ### end Alembic commands ###
diff --git a/frontend/composables/recipes/use-recipe-ingredients.ts b/frontend/composables/recipes/use-recipe-ingredients.ts
index 9d2bd06d65c3..f3600548720e 100644
--- a/frontend/composables/recipes/use-recipe-ingredients.ts
+++ b/frontend/composables/recipes/use-recipe-ingredients.ts
@@ -19,6 +19,8 @@ export function parseIngredientText(ingredient: RecipeIngredient, disableAmount:
let returnQty = "";
+ let unitDisplay = unit?.name;
+
// casting to number is required as sometimes quantity is a string
if (quantity && Number(quantity) !== 0) {
console.log("Using Quantity", quantity, typeof quantity);
@@ -34,8 +36,12 @@ export function parseIngredientText(ingredient: RecipeIngredient, disableAmount:
} else {
returnQty = (quantity * scale).toString();
}
+
+ if (unit?.useAbbreviation && unit.abbreviation) {
+ unitDisplay = unit.abbreviation;
+ }
}
- const text = `${returnQty} ${unit?.name || " "} ${food?.name || " "} ${note || " "}`.replace(/ {2,}/g, " ");
+ const text = `${returnQty} ${unitDisplay || " "} ${food?.name || " "} ${note || " "}`.replace(/ {2,}/g, " ");
return sanitizeIngredientHTML(text);
}
diff --git a/frontend/pages/group/data/units.vue b/frontend/pages/group/data/units.vue
index b48d0b5937f4..37a99fa83d23 100644
--- a/frontend/pages/group/data/units.vue
+++ b/frontend/pages/group/data/units.vue
@@ -36,6 +36,7 @@
+
@@ -106,6 +107,11 @@
Combine
+
+
+ {{ item.useAbbreviation ? $globals.icons.check : $globals.icons.close }}
+
+
{{ item.fraction ? $globals.icons.check : $globals.icons.close }}
@@ -153,10 +159,15 @@ export default defineComponent({
value: "abbreviation",
show: true,
},
+ {
+ text: "Use Abbv.",
+ value: "useAbbreviation",
+ show: true,
+ },
{
text: "Description",
value: "description",
- show: true,
+ show: false,
},
{
text: "Fraction",
diff --git a/frontend/types/api-types/admin.ts b/frontend/types/api-types/admin.ts
index 106646efea2a..034db6b6b5b0 100644
--- a/frontend/types/api-types/admin.ts
+++ b/frontend/types/api-types/admin.ts
@@ -133,6 +133,7 @@ export interface IngredientUnit {
description?: string;
fraction?: boolean;
abbreviation?: string;
+ useAbbreviation?: boolean;
id: string;
}
export interface CreateIngredientUnit {
@@ -140,6 +141,7 @@ export interface CreateIngredientUnit {
description?: string;
fraction?: boolean;
abbreviation?: string;
+ useAbbreviation?: boolean;
}
export interface IngredientFood {
name: string;
diff --git a/frontend/types/api-types/cookbook.ts b/frontend/types/api-types/cookbook.ts
index a6fa7ff84e90..91965f039eb0 100644
--- a/frontend/types/api-types/cookbook.ts
+++ b/frontend/types/api-types/cookbook.ts
@@ -112,6 +112,7 @@ export interface IngredientUnit {
description?: string;
fraction?: boolean;
abbreviation?: string;
+ useAbbreviation?: boolean;
id: string;
}
export interface CreateIngredientUnit {
@@ -119,6 +120,7 @@ export interface CreateIngredientUnit {
description?: string;
fraction?: boolean;
abbreviation?: string;
+ useAbbreviation?: boolean;
}
export interface IngredientFood {
name: string;
diff --git a/frontend/types/api-types/group.ts b/frontend/types/api-types/group.ts
index a65627053718..9a7ba50aea52 100644
--- a/frontend/types/api-types/group.ts
+++ b/frontend/types/api-types/group.ts
@@ -207,6 +207,7 @@ export interface IngredientUnit {
description?: string;
fraction?: boolean;
abbreviation?: string;
+ useAbbreviation?: boolean;
id: string;
}
export interface ReadGroupPreferences {
@@ -287,6 +288,7 @@ export interface CreateIngredientUnit {
description?: string;
fraction?: boolean;
abbreviation?: string;
+ useAbbreviation?: boolean;
}
export interface CreateIngredientFood {
name: string;
diff --git a/frontend/types/api-types/meal-plan.ts b/frontend/types/api-types/meal-plan.ts
index a16f0551bf37..df387e5b9a07 100644
--- a/frontend/types/api-types/meal-plan.ts
+++ b/frontend/types/api-types/meal-plan.ts
@@ -148,6 +148,7 @@ export interface IngredientUnit {
description?: string;
fraction?: boolean;
abbreviation?: string;
+ useAbbreviation?: boolean;
id: string;
}
export interface CreateIngredientUnit {
@@ -155,6 +156,7 @@ export interface CreateIngredientUnit {
description?: string;
fraction?: boolean;
abbreviation?: string;
+ useAbbreviation?: boolean;
}
export interface IngredientFood {
name: string;
diff --git a/frontend/types/api-types/recipe.ts b/frontend/types/api-types/recipe.ts
index 038d748b941a..ae23040f9e19 100644
--- a/frontend/types/api-types/recipe.ts
+++ b/frontend/types/api-types/recipe.ts
@@ -49,6 +49,7 @@ export interface CreateIngredientUnit {
description?: string;
fraction?: boolean;
abbreviation?: string;
+ useAbbreviation?: boolean;
}
export interface CreateRecipe {
name: string;
@@ -117,6 +118,7 @@ export interface IngredientUnit {
description?: string;
fraction?: boolean;
abbreviation?: string;
+ useAbbreviation?: boolean;
id: string;
}
export interface IngredientsRequest {
@@ -340,6 +342,7 @@ export interface SaveIngredientUnit {
description?: string;
fraction?: boolean;
abbreviation?: string;
+ useAbbreviation?: boolean;
groupId: string;
}
export interface ScrapeRecipe {
diff --git a/frontend/types/api-types/user.ts b/frontend/types/api-types/user.ts
index af9ec82671b9..c72d2bf83a48 100644
--- a/frontend/types/api-types/user.ts
+++ b/frontend/types/api-types/user.ts
@@ -164,6 +164,7 @@ export interface IngredientUnit {
description?: string;
fraction?: boolean;
abbreviation?: string;
+ useAbbreviation?: boolean;
id: string;
}
export interface CreateIngredientUnit {
@@ -171,6 +172,7 @@ export interface CreateIngredientUnit {
description?: string;
fraction?: boolean;
abbreviation?: string;
+ useAbbreviation?: boolean;
}
export interface IngredientFood {
name: string;
diff --git a/mealie/db/models/recipe/ingredient.py b/mealie/db/models/recipe/ingredient.py
index 83118caf32ac..3b3e4896c7e6 100644
--- a/mealie/db/models/recipe/ingredient.py
+++ b/mealie/db/models/recipe/ingredient.py
@@ -18,6 +18,7 @@ class IngredientUnitModel(SqlAlchemyBase, BaseMixins):
name = Column(String)
description = Column(String)
abbreviation = Column(String)
+ use_abbreviation = Column(Boolean, default=False)
fraction = Column(Boolean, default=True)
ingredients = orm.relationship("RecipeIngredient", back_populates="unit")
diff --git a/mealie/schema/recipe/recipe_ingredient.py b/mealie/schema/recipe/recipe_ingredient.py
index 2803603acb2e..61cac7db838f 100644
--- a/mealie/schema/recipe/recipe_ingredient.py
+++ b/mealie/schema/recipe/recipe_ingredient.py
@@ -34,6 +34,7 @@ class IngredientFood(CreateIngredientFood):
class CreateIngredientUnit(UnitFoodBase):
fraction: bool = True
abbreviation: str = ""
+ use_abbreviation: bool = False
class SaveIngredientUnit(CreateIngredientUnit):
diff --git a/tests/integration_tests/user_recipe_tests/test_recipe_units.py b/tests/integration_tests/user_recipe_tests/test_recipe_units.py
index b6708171b3b3..be102a6df32c 100644
--- a/tests/integration_tests/user_recipe_tests/test_recipe_units.py
+++ b/tests/integration_tests/user_recipe_tests/test_recipe_units.py
@@ -9,17 +9,19 @@ from tests.utils.fixture_schemas import TestUser
class Routes:
base = "/api/units"
+ @staticmethod
def item(item_id: int) -> str:
return f"{Routes.base}/{item_id}"
@pytest.fixture(scope="function")
-def unit(api_client: TestClient, unique_user: TestUser) -> dict:
+def unit(api_client: TestClient, unique_user: TestUser):
data = CreateIngredientUnit(
name=random_string(10),
description=random_string(10),
fraction=random_bool(),
- abbreviation=random_string(3) + ".",
+ abbreviation=f"{random_string(3)}.",
+ use_abbreviation=random_bool(),
).dict(by_alias=True)
response = api_client.post(Routes.base, json=data, headers=unique_user.token)
@@ -52,6 +54,7 @@ def test_read_unit(api_client: TestClient, unit: dict, unique_user: TestUser):
assert as_json["description"] == unit["description"]
assert as_json["fraction"] == unit["fraction"]
assert as_json["abbreviation"] == unit["abbreviation"]
+ assert as_json["useAbbreviation"] == unit["useAbbreviation"]
def test_update_unit(api_client: TestClient, unit: dict, unique_user: TestUser):
@@ -60,8 +63,10 @@ def test_update_unit(api_client: TestClient, unit: dict, unique_user: TestUser):
"name": random_string(10),
"description": random_string(10),
"fraction": not unit["fraction"],
- "abbreviation": random_string(3) + ".",
+ "abbreviation": f"{random_string(3)}.",
+ "useAbbreviation": not unit["useAbbreviation"],
}
+
response = api_client.put(Routes.item(unit["id"]), json=update_data, headers=unique_user.token)
assert response.status_code == 200
as_json = response.json()
@@ -71,14 +76,15 @@ def test_update_unit(api_client: TestClient, unit: dict, unique_user: TestUser):
assert as_json["description"] == update_data["description"]
assert as_json["fraction"] == update_data["fraction"]
assert as_json["abbreviation"] == update_data["abbreviation"]
+ assert as_json["useAbbreviation"] == update_data["useAbbreviation"]
def test_delete_unit(api_client: TestClient, unit: dict, unique_user: TestUser):
- id = unit["id"]
+ item_id = unit["id"]
- response = api_client.delete(Routes.item(id), headers=unique_user.token)
+ response = api_client.delete(Routes.item(item_id), headers=unique_user.token)
assert response.status_code == 200
- response = api_client.get(Routes.item(id), headers=unique_user.token)
+ response = api_client.get(Routes.item(item_id), headers=unique_user.token)
assert response.status_code == 404
diff --git a/tests/unit_tests/services_tests/backup_v2_tests/test_alchemy_exporter.py b/tests/unit_tests/services_tests/backup_v2_tests/test_alchemy_exporter.py
index 2f0bc5a71fb3..4df4ee682a8f 100644
--- a/tests/unit_tests/services_tests/backup_v2_tests/test_alchemy_exporter.py
+++ b/tests/unit_tests/services_tests/backup_v2_tests/test_alchemy_exporter.py
@@ -4,7 +4,7 @@ from mealie.core.config import get_app_settings
from mealie.services.backups_v2.alchemy_exporter import AlchemyExporter
ALEMBIC_VERSIONS = [
- {"version_num": "09dfc897ad62"},
+ {"version_num": "ab0bae02578f"},
]