mirror of
https://github.com/hay-kot/mealie.git
synced 2025-08-22 06:23:34 -07:00
merge kentors changes
This commit is contained in:
parent
874bea7fa4
commit
3cadc3d04b
8 changed files with 102 additions and 9 deletions
|
@ -5,6 +5,9 @@ import settings from "./api/settings";
|
||||||
import themes from "./api/themes";
|
import themes from "./api/themes";
|
||||||
import migration from "./api/migration";
|
import migration from "./api/migration";
|
||||||
import myUtils from "./api/upload";
|
import myUtils from "./api/upload";
|
||||||
|
import category from "./api/category";
|
||||||
|
|
||||||
|
// import api from "../api";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
recipes: recipe,
|
recipes: recipe,
|
||||||
|
@ -14,4 +17,5 @@ export default {
|
||||||
themes: themes,
|
themes: themes,
|
||||||
migrations: migration,
|
migrations: migration,
|
||||||
utils: myUtils,
|
utils: myUtils,
|
||||||
|
categories: category,
|
||||||
};
|
};
|
||||||
|
|
15
frontend/src/api/category.js
Normal file
15
frontend/src/api/category.js
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import { baseURL } from "./api-utils";
|
||||||
|
import { apiReq } from "./api-utils";
|
||||||
|
|
||||||
|
const categoryBase = baseURL + "category/";
|
||||||
|
|
||||||
|
const categoryURLs = {
|
||||||
|
get_all: `${categoryBase}all`,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
async get_all() {
|
||||||
|
let response = await apiReq.get(categoryURLs.get_all);
|
||||||
|
return response;
|
||||||
|
},
|
||||||
|
}
|
|
@ -101,6 +101,10 @@
|
||||||
item-color="secondary"
|
item-color="secondary"
|
||||||
deletable-chips
|
deletable-chips
|
||||||
v-model="value.categories"
|
v-model="value.categories"
|
||||||
|
hide-selected
|
||||||
|
:items="categories"
|
||||||
|
:search-input.sync="categoriesSearchInput"
|
||||||
|
@change="categoriesSearchInput = ''"
|
||||||
>
|
>
|
||||||
<template v-slot:selection="data">
|
<template v-slot:selection="data">
|
||||||
<v-chip
|
<v-chip
|
||||||
|
@ -116,7 +120,17 @@
|
||||||
</v-combobox>
|
</v-combobox>
|
||||||
|
|
||||||
<h2 class="mt-4">{{ $t("recipe.tags") }}</h2>
|
<h2 class="mt-4">{{ $t("recipe.tags") }}</h2>
|
||||||
<v-combobox dense multiple chips deletable-chips v-model="value.tags">
|
<v-combobox
|
||||||
|
dense
|
||||||
|
multiple
|
||||||
|
chips
|
||||||
|
deletable-chips
|
||||||
|
v-model="value.tags"
|
||||||
|
hide-selected
|
||||||
|
:items="tags"
|
||||||
|
:search-input.sync="tagsSearchInput"
|
||||||
|
@change="tagssSearchInput = ''"
|
||||||
|
>
|
||||||
<template v-slot:selection="data">
|
<template v-slot:selection="data">
|
||||||
<v-chip
|
<v-chip
|
||||||
:input-value="data.selected"
|
:input-value="data.selected"
|
||||||
|
@ -234,13 +248,24 @@ export default {
|
||||||
return {
|
return {
|
||||||
fileObject: null,
|
fileObject: null,
|
||||||
rules: {
|
rules: {
|
||||||
required: v => !!v || "Key Name Required",
|
required: (v) => !!v || "Key Name Required",
|
||||||
whiteSpace: v =>
|
whiteSpace: (v) =>
|
||||||
!v || v.split(" ").length <= 1 || "No White Space Allowed",
|
!v || v.split(" ").length <= 1 || "No White Space Allowed",
|
||||||
},
|
},
|
||||||
|
categoriesSearchInput: "",
|
||||||
|
tagsSearchInput: "",
|
||||||
|
categories: [],
|
||||||
|
tags: [],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getCategories();
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
async getCategories() {
|
||||||
|
let response = await api.categories.get_all();
|
||||||
|
this.categories = response.data.map((cat) => cat.name);
|
||||||
|
},
|
||||||
uploadImage() {
|
uploadImage() {
|
||||||
this.$emit("upload", this.fileObject);
|
this.$emit("upload", this.fileObject);
|
||||||
},
|
},
|
||||||
|
@ -286,7 +311,7 @@ export default {
|
||||||
|
|
||||||
appendSteps(steps) {
|
appendSteps(steps) {
|
||||||
let processSteps = [];
|
let processSteps = [];
|
||||||
steps.forEach(element => {
|
steps.forEach((element) => {
|
||||||
processSteps.push({ text: element });
|
processSteps.push({ text: element });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ from routes import (
|
||||||
setting_routes,
|
setting_routes,
|
||||||
static_routes,
|
static_routes,
|
||||||
user_routes,
|
user_routes,
|
||||||
|
category_routes,
|
||||||
)
|
)
|
||||||
|
|
||||||
from utils.api_docs import generate_api_docs
|
from utils.api_docs import generate_api_docs
|
||||||
|
@ -39,6 +40,7 @@ def api_routers():
|
||||||
app.include_router(backup_routes.router)
|
app.include_router(backup_routes.router)
|
||||||
app.include_router(user_routes.router)
|
app.include_router(user_routes.router)
|
||||||
app.include_router(migration_routes.router)
|
app.include_router(migration_routes.router)
|
||||||
|
app.include_router(category_routes.router)
|
||||||
|
|
||||||
|
|
||||||
if PRODUCTION:
|
if PRODUCTION:
|
||||||
|
|
|
@ -23,11 +23,22 @@ class ApiExtras(SqlAlchemyBase):
|
||||||
return {self.key_name: self.value}
|
return {self.key_name: self.value}
|
||||||
|
|
||||||
|
|
||||||
|
recipes2categories = sa.Table("recipes2categories", SqlAlchemyBase.metadata,
|
||||||
|
sa.Column("recipe_id", sa.Integer, sa.ForeignKey("recipes.id")),
|
||||||
|
sa.Column("category_id", sa.Integer, sa.ForeignKey("categories.id")))
|
||||||
|
|
||||||
class Category(SqlAlchemyBase):
|
class Category(SqlAlchemyBase):
|
||||||
__tablename__ = "categories"
|
__tablename__ = "categories"
|
||||||
id = sa.Column(sa.Integer, primary_key=True)
|
id = sa.Column(sa.Integer, primary_key=True)
|
||||||
parent_id = sa.Column(sa.String, sa.ForeignKey("recipes.id"))
|
|
||||||
name = sa.Column(sa.String, index=True)
|
name = sa.Column(sa.String, index=True)
|
||||||
|
recipes = orm.relationship(
|
||||||
|
"RecipeModel",
|
||||||
|
secondary=recipes2categories,
|
||||||
|
back_populates="categories"
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(self, name) -> None:
|
||||||
|
self.name = name
|
||||||
|
|
||||||
def to_str(self):
|
def to_str(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
@ -116,9 +127,10 @@ class RecipeModel(SqlAlchemyBase, BaseMixins):
|
||||||
|
|
||||||
# Mealie Specific
|
# Mealie Specific
|
||||||
slug = sa.Column(sa.String, index=True, unique=True)
|
slug = sa.Column(sa.String, index=True, unique=True)
|
||||||
categories: List[Category] = orm.relationship(
|
categories: List = orm.relationship(
|
||||||
"Category",
|
"Category",
|
||||||
cascade="all, delete",
|
secondary=recipes2categories,
|
||||||
|
back_populates="recipes",
|
||||||
)
|
)
|
||||||
tags: List[Tag] = orm.relationship(
|
tags: List[Tag] = orm.relationship(
|
||||||
"Tag",
|
"Tag",
|
||||||
|
@ -170,7 +182,7 @@ class RecipeModel(SqlAlchemyBase, BaseMixins):
|
||||||
|
|
||||||
# Mealie Specific
|
# Mealie Specific
|
||||||
self.slug = slug
|
self.slug = slug
|
||||||
self.categories = [Category(name=cat) for cat in categories]
|
self.categories = [Category(cat) for cat in categories]
|
||||||
self.tags = [Tag(name=tag) for tag in tags]
|
self.tags = [Tag(name=tag) for tag in tags]
|
||||||
self.dateAdded = dateAdded
|
self.dateAdded = dateAdded
|
||||||
self.notes = [Note(**note) for note in notes]
|
self.notes = [Note(**note) for note in notes]
|
||||||
|
@ -200,7 +212,7 @@ class RecipeModel(SqlAlchemyBase, BaseMixins):
|
||||||
extras: dict = None,
|
extras: dict = None,
|
||||||
):
|
):
|
||||||
"""Updated a database entry by removing nested rows and rebuilds the row through the __init__ functions"""
|
"""Updated a database entry by removing nested rows and rebuilds the row through the __init__ functions"""
|
||||||
list_of_tables = [RecipeIngredient, RecipeInstruction, Category, Tag, ApiExtras]
|
list_of_tables = [RecipeIngredient, RecipeInstruction, Tag, ApiExtras]
|
||||||
RecipeModel._sql_remove_list(session, list_of_tables, self.id)
|
RecipeModel._sql_remove_list(session, list_of_tables, self.id)
|
||||||
|
|
||||||
self.__init__(
|
self.__init__(
|
||||||
|
|
11
mealie/models/category_models.py
Normal file
11
mealie/models/category_models.py
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
from pydantic.main import BaseModel
|
||||||
|
|
||||||
|
class Category(BaseModel):
|
||||||
|
name: str
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
schema_extra = {
|
||||||
|
"example": {
|
||||||
|
"name": "Breakfast"
|
||||||
|
}
|
||||||
|
}
|
14
mealie/routes/category_routes.py
Normal file
14
mealie/routes/category_routes.py
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
from models.category_models import Category
|
||||||
|
from services.category_services import get_all
|
||||||
|
from fastapi import APIRouter, HTTPException
|
||||||
|
from utils.snackbar import SnackResponse
|
||||||
|
|
||||||
|
router = APIRouter(tags=["Category"])
|
||||||
|
|
||||||
|
@router.get("/api/category/all", response_model=List[Category])
|
||||||
|
def get_all_categories():
|
||||||
|
""" Returns a list of all categories """
|
||||||
|
|
||||||
|
return get_all()
|
10
mealie/services/category_services.py
Normal file
10
mealie/services/category_services.py
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
from typing import List
|
||||||
|
from models.category_models import Category
|
||||||
|
from db.database import db
|
||||||
|
|
||||||
|
def get_all() -> List[Category]:
|
||||||
|
categories = db.category.all()
|
||||||
|
print(categories)
|
||||||
|
[print(cat) for cat in categories]
|
||||||
|
return [Category(name=cat) for cat in categories]
|
||||||
|
return [Category(name="Hej"), Category(name="Fra"), Category(name="Serveren")];
|
Loading…
Add table
Add a link
Reference in a new issue