shopping list added to the UI

This commit is contained in:
hay-kot 2021-02-18 21:24:20 -09:00
commit afe4e2b739
7 changed files with 159 additions and 9 deletions

View file

@ -5585,10 +5585,17 @@
"integrity": "sha1-h0v2nG9ATCtdmcSBNBOZ/VWJJjM="
},
"fast-levenshtein": {
"version": "2.0.6",
"resolved": "https://registry.npm.taobao.org/fast-levenshtein/download/fast-levenshtein-2.0.6.tgz",
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
"dev": true
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-3.0.0.tgz",
"integrity": "sha512-hKKNajm46uNmTlhHSyZkmToAc56uZJwYq7yrciZjqOxnlfQwERDQJmHPUp7m1m9wx8vgOe8IaCKZ5Kv2k1DdCQ==",
"requires": {
"fastest-levenshtein": "^1.0.7"
}
},
"fastest-levenshtein": {
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz",
"integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow=="
},
"faye-websocket": {
"version": "0.11.3",
@ -8334,6 +8341,14 @@
"prelude-ls": "~1.1.2",
"type-check": "~0.3.2",
"word-wrap": "~1.2.3"
},
"dependencies": {
"fast-levenshtein": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
"dev": true
}
}
},
"ora": {

View file

@ -13,6 +13,7 @@
"@smartweb/vue-flash-message": "^0.6.10",
"axios": "^0.21.1",
"core-js": "^3.8.2",
"fast-levenshtein": "^3.0.0",
"fuse.js": "^6.4.6",
"qs": "^6.9.6",
"v-jsoneditor": "^1.4.2",

View file

@ -8,9 +8,10 @@ const mealPlanURLs = {
all: `${prefix}all`,
create: `${prefix}create`,
thisWeek: `${prefix}this-week`,
update: (planID) => `${prefix}${planID}`,
delete: (planID) => `${prefix}${planID}`,
update: planID => `${prefix}${planID}`,
delete: planID => `${prefix}${planID}`,
today: `${prefix}today`,
shopping: planID => `${prefix}${planID}/shopping-list`,
};
export default {
@ -43,4 +44,9 @@ export default {
let response = await apiReq.put(mealPlanURLs.update(id), body);
return response;
},
async shoppingList(id) {
let response = await apiReq.get(mealPlanURLs.shopping(id));
return response.data;
},
};

View file

@ -0,0 +1,112 @@
<template>
<div class="text-center">
<v-dialog v-model="dialog" width="650">
<v-card>
<v-card-title class="headline">
Shopping List
<v-spacer></v-spacer>
<v-btn text color="accent" @click="group = !group">
Group (Beta)
</v-btn>
</v-card-title>
<v-divider></v-divider>
<v-card-text v-if="group == false">
<v-list
dense
v-for="(recipe, index) in ingredients"
:key="`${index}-recipe`"
>
<v-subheader>{{ recipe.name }} </v-subheader>
<v-divider></v-divider>
<v-list-item-group color="primary">
<v-list-item
v-for="(item, i) in recipe.recipeIngredient"
:key="i"
>
<v-list-item-content>
<v-list-item-title v-text="item"></v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list-item-group>
</v-list>
</v-card-text>
<v-card-text v-else>
<v-list dense>
<v-list-item-group color="primary">
<v-list-item v-for="(item, i) in rawIngredients" :key="i">
<v-list-item-content>
<v-list-item-title v-text="item"></v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list-item-group>
</v-list>
</v-card-text>
<v-divider></v-divider>
</v-card>
</v-dialog>
</div>
</template>
<script>
import api from "@/api";
const levenshtein = require("fast-levenshtein");
export default {
data() {
return {
dialog: false,
planID: 0,
ingredients: [],
rawIngredients: [],
group: false,
};
},
methods: {
openDialog: function(id) {
this.dialog = true;
this.planID = id;
this.getIngredients();
},
async getIngredients() {
this.ingredients = await api.mealPlans.shoppingList(this.planID);
console.log(this.ingredients);
this.getRawIngredients();
},
getRawIngredients() {
this.ingredients.forEach(element => {
this.rawIngredients.push(element.recipeIngredient);
});
this.rawIngredients = this.rawIngredients.flat();
this.rawIngredients = this.levenshteinFilter(this.rawIngredients);
console.log(this.rawIngredients);
},
levenshteinFilter(source, maximum = 5) {
let _source, matches, x, y;
_source = source.slice();
matches = [];
for (x = _source.length - 1; x >= 0; x--) {
let output = _source.splice(x, 1);
for (y = _source.length - 1; y >= 0; y--) {
if (levenshtein.get(output[0], _source[y]) <= maximum) {
output.push(_source[y]);
_source.splice(y, 1);
x--;
}
}
matches.push(output);
}
return matches.flat();
},
},
};
</script>
<style>
</style>

View file

@ -44,6 +44,7 @@
"sign-up": "Sign up"
},
"meal-plan": {
"shopping-list": "Shopping List",
"dinner-this-week": "Dinner This Week",
"meal-planner": "Meal Planner",
"dinner-today": "Dinner Today",

View file

@ -6,6 +6,7 @@
@updated="planUpdated"
/>
<NewMeal v-else @created="requestMeals" class="mb-5" />
<ShoppingListDialog ref="shoppingList" />
<v-card class="my-2">
<v-card-title class="headline">
@ -49,6 +50,14 @@
</v-list-item-group>
</v-list>
<v-card-actions class="mt-n5">
<v-btn
color="accent lighten-2"
class="mx-0"
text
@click="openShoppingList(mealplan.uid)"
>
{{ $t("meal-plan.shopping-list") }}
</v-btn>
<v-spacer></v-spacer>
<v-btn
color="accent lighten-2"
@ -78,11 +87,13 @@ import api from "@/api";
import utils from "@/utils";
import NewMeal from "../components/MealPlan/MealPlanNew";
import EditPlan from "../components/MealPlan/MealPlanEditor";
import ShoppingListDialog from "../components/MealPlan/ShoppingListDialog";
export default {
components: {
NewMeal,
EditPlan,
ShoppingListDialog,
},
data: () => ({
plannedMeals: [],
@ -122,6 +133,10 @@ export default {
api.mealPlans.delete(id);
this.requestMeals();
},
openShoppingList(id) {
console.log(this.$refs.shoppingList.openDialog);
this.$refs.shoppingList.openDialog(id);
},
},
};
</script>

View file

@ -17,9 +17,9 @@ def get_all_meals(session: Session = Depends(generate_session)):
return MealPlan.get_all(session)
@router.get("/shopping-list/{id}")
@router.get("/{id}/shopping-list")
def get_shopping_list(id: str, session: Session = Depends(generate_session)):
#! Refactor into Single Database Call
mealplan = db.meals.get(session, id)
slugs = [x.get("slug") for x in mealplan.get("meals")]
@ -29,7 +29,7 @@ def get_shopping_list(id: str, session: Session = Depends(generate_session)):
for x in recipes
]
return {"ingredients": ingredients}
return ingredients
@router.post("/create")