mirror of
				https://github.com/mealie-recipes/mealie.git
				synced 2025-10-30 17:53:31 -04:00 
			
		
		
		
	recipe extras
This commit is contained in:
		| @@ -41,10 +41,14 @@ Backend | |||||||
| # Draft Changelog | # Draft Changelog | ||||||
| ## v0.0.2 | ## v0.0.2 | ||||||
|  |  | ||||||
| General | Bug Fixes | ||||||
|  | - Added API Key Extras to Recipe Data | ||||||
| - Fixed opacity issues with marked steps - [mtoohey31](https://github.com/mtoohey31) | - Fixed opacity issues with marked steps - [mtoohey31](https://github.com/mtoohey31) | ||||||
| - Improved documentation |  | ||||||
| - Fixed hot-reloading development environment - [grssmnn](https://github.com/grssmnn) | - Fixed hot-reloading development environment - [grssmnn](https://github.com/grssmnn) | ||||||
| - Added Confirmation component to deleting recipes - [zackbcom](https://github.com/zackbcom) | - Added Confirmation component to deleting recipes - [zackbcom](https://github.com/zackbcom) | ||||||
| - Added Persistent storage to vuex - [zackbcom](https://github.com/zackbcom) | - Added Persistent storage to vuex - [zackbcom](https://github.com/zackbcom) | ||||||
| - Updated Theme backend - [zackbcom](https://github.com/zackbcom) | - Updated Theme backend - [zackbcom](https://github.com/zackbcom) | ||||||
|  |  | ||||||
|  | General Improvements | ||||||
|  | - Improved image rendering (nearly x2 speed) | ||||||
|  | - Improved documentation + API Documentation | ||||||
|   | |||||||
							
								
								
									
										103
									
								
								frontend/src/components/Recipe/RecipeEditor/ExtrasEditor.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								frontend/src/components/Recipe/RecipeEditor/ExtrasEditor.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,103 @@ | |||||||
|  | <template> | ||||||
|  |   <div class="text-center"> | ||||||
|  |     <v-dialog v-model="dialog" width="700"> | ||||||
|  |       <template v-slot:activator="{ on, attrs }"> | ||||||
|  |         <v-btn color="accent" dark v-bind="attrs" v-on="on"> API Extras </v-btn> | ||||||
|  |       </template> | ||||||
|  |  | ||||||
|  |       <v-card> | ||||||
|  |         <v-card-title> API Extras </v-card-title> | ||||||
|  |  | ||||||
|  |         <v-card-text :key="formKey"> | ||||||
|  |           <v-row | ||||||
|  |             align="center" | ||||||
|  |             v-for="(value, key, index) in extras" | ||||||
|  |             :key="index" | ||||||
|  |           > | ||||||
|  |             <v-col cols="12" sm="1"> | ||||||
|  |               <v-btn | ||||||
|  |                 fab | ||||||
|  |                 text | ||||||
|  |                 x-small | ||||||
|  |                 color="white" | ||||||
|  |                 elevation="0" | ||||||
|  |                 @click="removeExtra(key)" | ||||||
|  |               > | ||||||
|  |                 <v-icon color="error">mdi-delete</v-icon> | ||||||
|  |               </v-btn> | ||||||
|  |             </v-col> | ||||||
|  |             <v-col cols="12" md="3" sm="6"> | ||||||
|  |               <v-text-field | ||||||
|  |                 label="Object Key" | ||||||
|  |                 :value="key" | ||||||
|  |                 @input="updateKey(index)" | ||||||
|  |               > | ||||||
|  |               </v-text-field> | ||||||
|  |             </v-col> | ||||||
|  |             <v-col cols="12" md="8" sm="6"> | ||||||
|  |               <v-text-field label="Object Value" v-model="extras[key]"> | ||||||
|  |               </v-text-field> | ||||||
|  |             </v-col> | ||||||
|  |           </v-row> | ||||||
|  |         </v-card-text> | ||||||
|  |  | ||||||
|  |         <v-divider></v-divider> | ||||||
|  |  | ||||||
|  |         <v-card-actions> | ||||||
|  |           <v-form ref="addKey"> | ||||||
|  |             <v-text-field | ||||||
|  |               label="New Key Name" | ||||||
|  |               v-model="newKeyName" | ||||||
|  |               class="pr-4" | ||||||
|  |               :rules="[rules.required, rules.whiteSpace]" | ||||||
|  |             ></v-text-field> | ||||||
|  |           </v-form> | ||||||
|  |           <v-btn color="info" text @click="append"> Add Key</v-btn> | ||||||
|  |  | ||||||
|  |           <v-spacer></v-spacer> | ||||||
|  |  | ||||||
|  |           <v-btn color="success" text @click="save"> I accept </v-btn> | ||||||
|  |         </v-card-actions> | ||||||
|  |       </v-card> | ||||||
|  |     </v-dialog> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | export default { | ||||||
|  |   props: { | ||||||
|  |     extras: Object, | ||||||
|  |   }, | ||||||
|  |   data() { | ||||||
|  |     return { | ||||||
|  |       newKeyName: null, | ||||||
|  |       dialog: false, | ||||||
|  |       formKey: 1, | ||||||
|  |       rules: { | ||||||
|  |         required: (v) => !!v || "Key Name Required", | ||||||
|  |         whiteSpace: (v) => !v || v.split(" ").length <= 1 || "No White Space Allowed", | ||||||
|  |       }, | ||||||
|  |     }; | ||||||
|  |   }, | ||||||
|  |  | ||||||
|  |   methods: { | ||||||
|  |     save() { | ||||||
|  |       this.$emit("save", this.extras); | ||||||
|  |       this.dialog = false; | ||||||
|  |     }, | ||||||
|  |     append() { | ||||||
|  |       if (this.$refs.addKey.validate()) { | ||||||
|  |         this.extras[this.newKeyName] = "value"; | ||||||
|  |         this.formKey += 1; | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     removeExtra(key) { | ||||||
|  |       delete this.extras[key]; | ||||||
|  |       this.formKey += 1; | ||||||
|  |     }, | ||||||
|  |   }, | ||||||
|  | }; | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style> | ||||||
|  | </style> | ||||||
| @@ -129,6 +129,7 @@ | |||||||
|           <v-btn class="mt-1" color="secondary" fab dark small @click="addNote"> |           <v-btn class="mt-1" color="secondary" fab dark small @click="addNote"> | ||||||
|             <v-icon>mdi-plus</v-icon> |             <v-icon>mdi-plus</v-icon> | ||||||
|           </v-btn> |           </v-btn> | ||||||
|  |           <ExtrasEditor :extras="value.extras" @save="saveExtras" /> | ||||||
|         </v-col> |         </v-col> | ||||||
|  |  | ||||||
|         <v-divider class="my-divider" :vertical="true"></v-divider> |         <v-divider class="my-divider" :vertical="true"></v-divider> | ||||||
| @@ -178,9 +179,11 @@ | |||||||
| import api from "../../../api"; | import api from "../../../api"; | ||||||
| import utils from "../../../utils"; | import utils from "../../../utils"; | ||||||
| import BulkAdd from "./BulkAdd"; | import BulkAdd from "./BulkAdd"; | ||||||
|  | import ExtrasEditor from "./ExtrasEditor"; | ||||||
| export default { | export default { | ||||||
|   components: { |   components: { | ||||||
|     BulkAdd, |     BulkAdd, | ||||||
|  |     ExtrasEditor, | ||||||
|   }, |   }, | ||||||
|   props: { |   props: { | ||||||
|     value: Object, |     value: Object, | ||||||
| @@ -188,13 +191,6 @@ export default { | |||||||
|   data() { |   data() { | ||||||
|     return { |     return { | ||||||
|       fileObject: null, |       fileObject: null, | ||||||
|       content: this.value, |  | ||||||
|       disabledSteps: [], |  | ||||||
|       description: String, |  | ||||||
|       ingredients: Array, |  | ||||||
|       instructions: Array, |  | ||||||
|       categories: Array, |  | ||||||
|       tags: Array, |  | ||||||
|     }; |     }; | ||||||
|   }, |   }, | ||||||
|   methods: { |   methods: { | ||||||
| @@ -270,6 +266,9 @@ export default { | |||||||
|     removeTags(index) { |     removeTags(index) { | ||||||
|       this.value.tags.splice(index, 1); |       this.value.tags.splice(index, 1); | ||||||
|     }, |     }, | ||||||
|  |     saveExtras(extras) { | ||||||
|  |       this.value.extras = extras; | ||||||
|  |     }, | ||||||
|   }, |   }, | ||||||
| }; | }; | ||||||
| </script> | </script> | ||||||
|   | |||||||
| @@ -42,7 +42,7 @@ class Recipe(BaseModel): | |||||||
|     rating: Optional[int] |     rating: Optional[int] | ||||||
|     rating: Optional[int] |     rating: Optional[int] | ||||||
|     orgURL: Optional[str] |     orgURL: Optional[str] | ||||||
|     extras: Optional[List[str]] |     extras: Optional[dict] | ||||||
|  |  | ||||||
|     class Config: |     class Config: | ||||||
|         schema_extra = { |         schema_extra = { | ||||||
| @@ -67,6 +67,9 @@ class Recipe(BaseModel): | |||||||
|                 "notes": [{"title": "Watch Out!", "text": "Prep the day before!"}], |                 "notes": [{"title": "Watch Out!", "text": "Prep the day before!"}], | ||||||
|                 "orgURL": "https://www.bonappetit.com/recipe/chicken-and-rice-with-leeks-and-salsa-verde", |                 "orgURL": "https://www.bonappetit.com/recipe/chicken-and-rice-with-leeks-and-salsa-verde", | ||||||
|                 "rating": 3, |                 "rating": 3, | ||||||
|  |                 "extras": { | ||||||
|  |                     "message": "Don't forget to defrost the chicken!" | ||||||
|  |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -101,8 +104,11 @@ class Recipe(BaseModel): | |||||||
|     def save_to_db(self) -> str: |     def save_to_db(self) -> str: | ||||||
|         recipe_dict = self.dict() |         recipe_dict = self.dict() | ||||||
|  |  | ||||||
|         extension = Path(recipe_dict["image"]).suffix |         try: | ||||||
|         recipe_dict["image"] = recipe_dict.get("slug") + extension |             extension = Path(recipe_dict["image"]).suffix | ||||||
|  |             recipe_dict["image"] = recipe_dict.get("slug") + extension | ||||||
|  |         except: | ||||||
|  |             recipe_dict["image"] = "no image" | ||||||
|  |  | ||||||
|         try: |         try: | ||||||
|             total_time = recipe_dict.get("totalTime") |             total_time = recipe_dict.get("totalTime") | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user