mirror of
				https://github.com/mealie-recipes/mealie.git
				synced 2025-10-31 02:03:35 -04:00 
			
		
		
		
	Refactor/composables-folder (#787)
* move api clients and rename * organize recipes composables * rewrite useRecipeContext * refactor(frontend): ♻️ abstract common ingredient functionality. * feat(frontend): ✨ add scale, and back to recipe button + hide ingredients if none * update regex to mach 11. instead of just 1. * minor UX improvements Co-authored-by: Hayden K <hay-kot@pm.me>
This commit is contained in:
		| @@ -71,7 +71,7 @@ | |||||||
| </template> | </template> | ||||||
|  |  | ||||||
| <script> | <script> | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
| export default { | export default { | ||||||
|   props: { |   props: { | ||||||
|     slug: { |     slug: { | ||||||
| @@ -88,7 +88,7 @@ export default { | |||||||
|     }, |     }, | ||||||
|   }, |   }, | ||||||
|   setup() { |   setup() { | ||||||
|     const api = useApiSingleton(); |     const api = useUserApi(); | ||||||
|  |  | ||||||
|     return { api }; |     return { api }; | ||||||
|   }, |   }, | ||||||
|   | |||||||
| @@ -18,8 +18,7 @@ | |||||||
| </template> | </template> | ||||||
|  |  | ||||||
| <script> | <script> | ||||||
| import { useStaticRoutes } from "~/composables/api"; | import { useStaticRoutes, useUserApi } from "~/composables/api"; | ||||||
| import { useApiSingleton } from "~/composables/use-api"; |  | ||||||
| export default { | export default { | ||||||
|   props: { |   props: { | ||||||
|     tiny: { |     tiny: { | ||||||
| @@ -52,7 +51,7 @@ export default { | |||||||
|     }, |     }, | ||||||
|   }, |   }, | ||||||
|   setup() { |   setup() { | ||||||
|     const api = useApiSingleton(); |     const api = useUserApi(); | ||||||
|  |  | ||||||
|     const { recipeImage, recipeSmallImage, recipeTinyImage } = useStaticRoutes(); |     const { recipeImage, recipeSmallImage, recipeTinyImage } = useStaticRoutes(); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -67,7 +67,7 @@ | |||||||
| import { defineComponent } from "@nuxtjs/composition-api"; | import { defineComponent } from "@nuxtjs/composition-api"; | ||||||
| import RecipeFavoriteBadge from "./RecipeFavoriteBadge"; | import RecipeFavoriteBadge from "./RecipeFavoriteBadge"; | ||||||
| import RecipeContextMenu from "./RecipeContextMenu"; | import RecipeContextMenu from "./RecipeContextMenu"; | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
| export default defineComponent({ | export default defineComponent({ | ||||||
|   components: { |   components: { | ||||||
|     RecipeFavoriteBadge, |     RecipeFavoriteBadge, | ||||||
| @@ -104,7 +104,7 @@ export default defineComponent({ | |||||||
|     }, |     }, | ||||||
|   }, |   }, | ||||||
|   setup() { |   setup() { | ||||||
|     const api = useApiSingleton(); |     const api = useUserApi(); | ||||||
|  |  | ||||||
|     return { api }; |     return { api }; | ||||||
|   }, |   }, | ||||||
|   | |||||||
| @@ -103,7 +103,7 @@ | |||||||
| <script> | <script> | ||||||
| import RecipeCard from "./RecipeCard"; | import RecipeCard from "./RecipeCard"; | ||||||
| import RecipeCardMobile from "./RecipeCardMobile"; | import RecipeCardMobile from "./RecipeCardMobile"; | ||||||
| import { useSorter } from "~/composables/use-recipes"; | import { useSorter } from "~/composables/recipes"; | ||||||
| const SORT_EVENT = "sort"; | const SORT_EVENT = "sort"; | ||||||
|  |  | ||||||
| export default { | export default { | ||||||
|   | |||||||
| @@ -36,7 +36,7 @@ | |||||||
|  |  | ||||||
| <script> | <script> | ||||||
| import { defineComponent } from "@nuxtjs/composition-api"; | import { defineComponent } from "@nuxtjs/composition-api"; | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
| const CREATED_ITEM_EVENT = "created-item"; | const CREATED_ITEM_EVENT = "created-item"; | ||||||
| export default defineComponent({ | export default defineComponent({ | ||||||
|   props: { |   props: { | ||||||
| @@ -58,7 +58,7 @@ export default defineComponent({ | |||||||
|     }, |     }, | ||||||
|   }, |   }, | ||||||
|   setup() { |   setup() { | ||||||
|     const api = useApiSingleton(); |     const api = useUserApi(); | ||||||
|  |  | ||||||
|     return { api }; |     return { api }; | ||||||
|   }, |   }, | ||||||
|   | |||||||
| @@ -44,8 +44,8 @@ | |||||||
|  |  | ||||||
| <script> | <script> | ||||||
| import RecipeCategoryTagDialog from "./RecipeCategoryTagDialog"; | import RecipeCategoryTagDialog from "./RecipeCategoryTagDialog"; | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
| import { useTags, useCategories } from "~/composables/use-tags-categories"; | import { useTags, useCategories } from "~/composables/recipes"; | ||||||
| const MOUNTED_EVENT = "mounted"; | const MOUNTED_EVENT = "mounted"; | ||||||
| export default { | export default { | ||||||
|   components: { |   components: { | ||||||
| @@ -91,7 +91,7 @@ export default { | |||||||
|   }, |   }, | ||||||
|  |  | ||||||
|   setup() { |   setup() { | ||||||
|     const api = useApiSingleton(); |     const api = useUserApi(); | ||||||
|  |  | ||||||
|     const { allTags, useAsyncGetAll: getAllTags } = useTags(); |     const { allTags, useAsyncGetAll: getAllTags } = useTags(); | ||||||
|     const { allCategories, useAsyncGetAll: getAllCategories } = useCategories(); |     const { allCategories, useAsyncGetAll: getAllCategories } = useCategories(); | ||||||
|   | |||||||
| @@ -50,7 +50,7 @@ | |||||||
| </template> | </template> | ||||||
|  |  | ||||||
| <script> | <script> | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
| const NEW_COMMENT_EVENT = "new-comment"; | const NEW_COMMENT_EVENT = "new-comment"; | ||||||
| const UPDATE_COMMENT_EVENT = "update-comment"; | const UPDATE_COMMENT_EVENT = "update-comment"; | ||||||
| export default { | export default { | ||||||
| @@ -65,7 +65,7 @@ export default { | |||||||
|     }, |     }, | ||||||
|   }, |   }, | ||||||
|   setup() { |   setup() { | ||||||
|     const api = useApiSingleton(); |     const api = useUserApi(); | ||||||
|  |  | ||||||
|     return { api }; |     return { api }; | ||||||
|   }, |   }, | ||||||
|   | |||||||
| @@ -75,7 +75,7 @@ | |||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| import { defineComponent, reactive, ref, toRefs, useContext, useRouter } from "@nuxtjs/composition-api"; | import { defineComponent, reactive, ref, toRefs, useContext, useRouter } from "@nuxtjs/composition-api"; | ||||||
| import { useClipboard, useShare } from "@vueuse/core"; | import { useClipboard, useShare } from "@vueuse/core"; | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
| import { alert } from "~/composables/use-toast"; | import { alert } from "~/composables/use-toast"; | ||||||
|  |  | ||||||
| export interface ContextMenuIncludes { | export interface ContextMenuIncludes { | ||||||
| @@ -147,7 +147,7 @@ export default defineComponent({ | |||||||
|     }, |     }, | ||||||
|   }, |   }, | ||||||
|   setup(props, context) { |   setup(props, context) { | ||||||
|     const api = useApiSingleton(); |     const api = useUserApi(); | ||||||
|  |  | ||||||
|     const state = reactive({ |     const state = reactive({ | ||||||
|       loading: false, |       loading: false, | ||||||
|   | |||||||
| @@ -39,7 +39,7 @@ | |||||||
| import { computed, defineComponent, onMounted, ref } from "@nuxtjs/composition-api"; | import { computed, defineComponent, onMounted, ref } from "@nuxtjs/composition-api"; | ||||||
| import RecipeChip from "./RecipeChips.vue"; | import RecipeChip from "./RecipeChips.vue"; | ||||||
| import { Recipe } from "~/types/api-types/recipe"; | import { Recipe } from "~/types/api-types/recipe"; | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
| import { UserOut } from "~/types/api-types/user"; | import { UserOut } from "~/types/api-types/user"; | ||||||
|  |  | ||||||
| const INPUT_EVENT = "input"; | const INPUT_EVENT = "input"; | ||||||
| @@ -114,7 +114,7 @@ export default defineComponent({ | |||||||
|  |  | ||||||
|     // ============ |     // ============ | ||||||
|     // Group Members |     // Group Members | ||||||
|     const api = useApiSingleton(); |     const api = useUserApi(); | ||||||
|     const members = ref<UserOut[] | null[]>([]); |     const members = ref<UserOut[] | null[]>([]); | ||||||
|  |  | ||||||
|     async function refreshMembers() { |     async function refreshMembers() { | ||||||
|   | |||||||
| @@ -82,7 +82,7 @@ export default defineComponent({ | |||||||
|         .join("\n"); |         .join("\n"); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     const numberedLineRegex = /\d[.):] /gm; |     const numberedLineRegex = /\d+[.):] /gm; | ||||||
|  |  | ||||||
|     function splitByNumberedLine() { |     function splitByNumberedLine() { | ||||||
|       // Split inputText by numberedLineRegex |       // Split inputText by numberedLineRegex | ||||||
|   | |||||||
| @@ -22,7 +22,7 @@ | |||||||
|  |  | ||||||
| <script> | <script> | ||||||
| import { defineComponent } from "@nuxtjs/composition-api"; | import { defineComponent } from "@nuxtjs/composition-api"; | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
| export default defineComponent({ | export default defineComponent({ | ||||||
|   props: { |   props: { | ||||||
|     slug: { |     slug: { | ||||||
| @@ -39,7 +39,7 @@ export default defineComponent({ | |||||||
|     }, |     }, | ||||||
|   }, |   }, | ||||||
|   setup() { |   setup() { | ||||||
|     const api = useApiSingleton(); |     const api = useUserApi(); | ||||||
|  |  | ||||||
|     return { api }; |     return { api }; | ||||||
|   }, |   }, | ||||||
|   | |||||||
| @@ -41,7 +41,7 @@ | |||||||
|  |  | ||||||
| <script> | <script> | ||||||
| import { defineComponent } from "@nuxtjs/composition-api"; | import { defineComponent } from "@nuxtjs/composition-api"; | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
| const REFRESH_EVENT = "refresh"; | const REFRESH_EVENT = "refresh"; | ||||||
| const UPLOAD_EVENT = "upload"; | const UPLOAD_EVENT = "upload"; | ||||||
| export default defineComponent({ | export default defineComponent({ | ||||||
| @@ -52,7 +52,7 @@ export default defineComponent({ | |||||||
|     }, |     }, | ||||||
|   }, |   }, | ||||||
|   setup() { |   setup() { | ||||||
|     const api = useApiSingleton(); |     const api = useUserApi(); | ||||||
|  |  | ||||||
|     return { api }; |     return { api }; | ||||||
|   }, |   }, | ||||||
|   | |||||||
| @@ -95,8 +95,7 @@ | |||||||
|  |  | ||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| import { defineComponent, reactive, ref, toRefs } from "@nuxtjs/composition-api"; | import { defineComponent, reactive, ref, toRefs } from "@nuxtjs/composition-api"; | ||||||
| import { useFoods } from "~/composables/use-recipe-foods"; | import { useFoods, useUnits } from "~/composables/recipes"; | ||||||
| import { useUnits } from "~/composables/use-recipe-units"; |  | ||||||
| import { validators } from "~/composables/use-validators"; | import { validators } from "~/composables/use-validators"; | ||||||
|  |  | ||||||
| export default defineComponent({ | export default defineComponent({ | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ | |||||||
|   <div v-if="value && value.length > 0"> |   <div v-if="value && value.length > 0"> | ||||||
|     <div class="d-flex justify-start"> |     <div class="d-flex justify-start"> | ||||||
|       <h2 class="mb-4 mt-1">{{ $t("recipe.ingredients") }}</h2> |       <h2 class="mb-4 mt-1">{{ $t("recipe.ingredients") }}</h2> | ||||||
|       <AppButtonCopy btn-class="ml-auto" :copy-text="ingredientCopyText" /> |     <AppButtonCopy btn-class="ml-auto" :copy-text="ingredientCopyText" /> | ||||||
|     </div> |     </div> | ||||||
|     <div> |     <div> | ||||||
|       <div v-for="(ingredient, index) in value" :key="'ingredient' + index"> |       <div v-for="(ingredient, index) in value" :key="'ingredient' + index"> | ||||||
| @@ -11,7 +11,10 @@ | |||||||
|         <v-list-item dense @click="toggleChecked(index)"> |         <v-list-item dense @click="toggleChecked(index)"> | ||||||
|           <v-checkbox hide-details :value="checked[index]" class="pt-0 my-auto py-auto" color="secondary"> </v-checkbox> |           <v-checkbox hide-details :value="checked[index]" class="pt-0 my-auto py-auto" color="secondary"> </v-checkbox> | ||||||
|           <v-list-item-content> |           <v-list-item-content> | ||||||
|             <VueMarkdown class="ma-0 pa-0 text-subtitle-1 dense-markdown" :source="parseIngredientText(ingredient)"> |             <VueMarkdown | ||||||
|  |               class="ma-0 pa-0 text-subtitle-1 dense-markdown" | ||||||
|  |               :source="parseIngredientText(ingredient, disableAmount, scale)" | ||||||
|  |             > | ||||||
|             </VueMarkdown> |             </VueMarkdown> | ||||||
|           </v-list-item-content> |           </v-list-item-content> | ||||||
|         </v-list-item> |         </v-list-item> | ||||||
| @@ -23,7 +26,7 @@ | |||||||
| <script> | <script> | ||||||
| import { computed, defineComponent } from "@nuxtjs/composition-api"; | import { computed, defineComponent } from "@nuxtjs/composition-api"; | ||||||
| import VueMarkdown from "@adapttive/vue-markdown"; | import VueMarkdown from "@adapttive/vue-markdown"; | ||||||
| import { useFraction } from "@/composables/use-fraction"; | import { parseIngredientText } from "~/composables/recipes"; | ||||||
| export default defineComponent({ | export default defineComponent({ | ||||||
|   components: { |   components: { | ||||||
|     VueMarkdown, |     VueMarkdown, | ||||||
| @@ -43,37 +46,10 @@ export default defineComponent({ | |||||||
|     }, |     }, | ||||||
|   }, |   }, | ||||||
|   setup(props) { |   setup(props) { | ||||||
|     const { frac } = useFraction(); |  | ||||||
|  |  | ||||||
|     function parseIngredientText(ingredient) { |  | ||||||
|       if (props.disableAmount) { |  | ||||||
|         return ingredient.note; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       const { quantity, food, unit, note } = ingredient; |  | ||||||
|  |  | ||||||
|       let return_qty = ""; |  | ||||||
|       if (unit?.fraction) { |  | ||||||
|         const fraction = frac(quantity * props.scale, 10, true); |  | ||||||
|         if (fraction[0] !== undefined && fraction[0] > 0) { |  | ||||||
|           return_qty += fraction[0]; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (fraction[1] > 0) { |  | ||||||
|           return_qty += ` <sup>${fraction[1]}</sup>⁄<sub>${fraction[2]}</sub>`; |  | ||||||
|         } |  | ||||||
|       } else { |  | ||||||
|         return_qty = quantity * props.scale; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       return `${return_qty} ${unit?.name || " "}  ${food?.name || " "} ${note}`; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     const ingredientCopyText = computed(() => { |     const ingredientCopyText = computed(() => { | ||||||
|       // Returns a string of all ingredients in markdown list format -[ ] |  | ||||||
|       return props.value |       return props.value | ||||||
|         .map((ingredient) => { |         .map((ingredient) => { | ||||||
|           return `- [ ] ${parseIngredientText(ingredient)}`; |           return `- [ ] ${parseIngredientText(ingredient, props.disableAmount, props.scale)}`; | ||||||
|         }) |         }) | ||||||
|         .join("\n"); |         .join("\n"); | ||||||
|     }); |     }); | ||||||
|   | |||||||
| @@ -17,13 +17,31 @@ | |||||||
|           </p> |           </p> | ||||||
|           <v-divider class="mb-4"></v-divider> |           <v-divider class="mb-4"></v-divider> | ||||||
|           <v-checkbox |           <v-checkbox | ||||||
|             v-for="ing in ingredients" |             v-for="ing in unusedIngredients" | ||||||
|             :key="ing.referenceId" |             :key="ing.referenceId" | ||||||
|             v-model="activeRefs" |             v-model="activeRefs" | ||||||
|             :label="ing.note" |  | ||||||
|             :value="ing.referenceId" |             :value="ing.referenceId" | ||||||
|             class="mb-n2 mt-n2" |             class="mb-n2 mt-n2" | ||||||
|           ></v-checkbox> |           > | ||||||
|  |             <template #label> | ||||||
|  |               <div v-html="parseIngredientText(ing, disableAmount)"></div> | ||||||
|  |             </template> | ||||||
|  |           </v-checkbox> | ||||||
|  |  | ||||||
|  |           <template v-if="usedIngredients.length > 0"> | ||||||
|  |             <h4 class="py-3 ml-1">Linked to other step</h4> | ||||||
|  |             <v-checkbox | ||||||
|  |               v-for="ing in usedIngredients" | ||||||
|  |               :key="ing.referenceId" | ||||||
|  |               v-model="activeRefs" | ||||||
|  |               :value="ing.referenceId" | ||||||
|  |               class="mb-n2 mt-n2" | ||||||
|  |             > | ||||||
|  |               <template #label> | ||||||
|  |                 <div v-html="parseIngredientText(ing, disableAmount)"></div> | ||||||
|  |               </template> | ||||||
|  |             </v-checkbox> | ||||||
|  |           </template> | ||||||
|         </v-card-text> |         </v-card-text> | ||||||
|  |  | ||||||
|         <v-divider></v-divider> |         <v-divider></v-divider> | ||||||
| @@ -111,17 +129,16 @@ | |||||||
|             <v-card-text v-if="edit"> |             <v-card-text v-if="edit"> | ||||||
|               <v-textarea :key="'instructions' + index" v-model="value[index]['text']" auto-grow dense rows="4"> |               <v-textarea :key="'instructions' + index" v-model="value[index]['text']" auto-grow dense rows="4"> | ||||||
|               </v-textarea> |               </v-textarea> | ||||||
|               <div v-for="ing in step.ingredientReferences" :key="ing.referenceId"> |               <div | ||||||
|                 {{ getIngredientByRefId(ing.referenceId).note }} |                 v-for="ing in step.ingredientReferences" | ||||||
|               </div> |                 :key="ing.referenceId" | ||||||
|  |                 v-html="getIngredientByRefId(ing.referenceId)" | ||||||
|  |               /> | ||||||
|             </v-card-text> |             </v-card-text> | ||||||
|             <v-expand-transition> |             <v-expand-transition> | ||||||
|               <div v-show="!isChecked(index) && !edit" class="m-0 p-0"> |               <div v-show="!isChecked(index) && !edit" class="m-0 p-0"> | ||||||
|                 <v-card-text> |                 <v-card-text> | ||||||
|                   <VueMarkdown :source="step.text"> </VueMarkdown> |                   <VueMarkdown :source="step.text"> </VueMarkdown> | ||||||
|                   <div v-for="ing in step.ingredientReferences" :key="ing.referenceId"> |  | ||||||
|                     {{ getIngredientByRefId(ing.referenceId).note }} |  | ||||||
|                   </div> |  | ||||||
|                 </v-card-text> |                 </v-card-text> | ||||||
|               </div> |               </div> | ||||||
|             </v-expand-transition> |             </v-expand-transition> | ||||||
| @@ -138,6 +155,7 @@ import draggable from "vuedraggable"; | |||||||
| import VueMarkdown from "@adapttive/vue-markdown"; | import VueMarkdown from "@adapttive/vue-markdown"; | ||||||
| import { ref, toRefs, reactive, defineComponent, watch, onMounted } from "@nuxtjs/composition-api"; | import { ref, toRefs, reactive, defineComponent, watch, onMounted } from "@nuxtjs/composition-api"; | ||||||
| import { RecipeStep, IngredientToStepRef, RecipeIngredient } from "~/types/api-types/recipe"; | import { RecipeStep, IngredientToStepRef, RecipeIngredient } from "~/types/api-types/recipe"; | ||||||
|  | import { parseIngredientText } from "~/composables/recipes"; | ||||||
|  |  | ||||||
| interface MergerHistory { | interface MergerHistory { | ||||||
|   target: number; |   target: number; | ||||||
| @@ -164,12 +182,18 @@ export default defineComponent({ | |||||||
|       type: Array as () => RecipeIngredient[], |       type: Array as () => RecipeIngredient[], | ||||||
|       default: () => [], |       default: () => [], | ||||||
|     }, |     }, | ||||||
|  |     disableAmount: { | ||||||
|  |       type: Boolean, | ||||||
|  |       default: false, | ||||||
|  |     }, | ||||||
|   }, |   }, | ||||||
|  |  | ||||||
|   setup(props, context) { |   setup(props, context) { | ||||||
|     const state = reactive({ |     const state = reactive({ | ||||||
|       dialog: false, |       dialog: false, | ||||||
|       disabledSteps: [] as number[], |       disabledSteps: [] as number[], | ||||||
|  |       unusedIngredients: [] as RecipeIngredient[], | ||||||
|  |       usedIngredients: [] as RecipeIngredient[], | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     const showTitleEditor = ref<boolean[]>([]); |     const showTitleEditor = ref<boolean[]>([]); | ||||||
| @@ -245,6 +269,7 @@ export default defineComponent({ | |||||||
|     const activeText = ref(""); |     const activeText = ref(""); | ||||||
|  |  | ||||||
|     function openDialog(idx: number, refs: IngredientToStepRef[], text: string) { |     function openDialog(idx: number, refs: IngredientToStepRef[], text: string) { | ||||||
|  |       setUsedIngredients(); | ||||||
|       activeText.value = text; |       activeText.value = text; | ||||||
|       activeIndex.value = idx; |       activeIndex.value = idx; | ||||||
|       state.dialog = true; |       state.dialog = true; | ||||||
| @@ -261,6 +286,24 @@ export default defineComponent({ | |||||||
|       state.dialog = false; |       state.dialog = false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     function setUsedIngredients() { | ||||||
|  |       const usedRefs: { [key: string]: boolean } = {}; | ||||||
|  |  | ||||||
|  |       props.value.forEach((element) => { | ||||||
|  |         element.ingredientReferences.forEach((ref) => { | ||||||
|  |           usedRefs[ref.referenceId] = true; | ||||||
|  |         }); | ||||||
|  |       }); | ||||||
|  |  | ||||||
|  |       state.usedIngredients = props.ingredients.filter((ing) => { | ||||||
|  |         return ing.referenceId in usedRefs; | ||||||
|  |       }); | ||||||
|  |  | ||||||
|  |       state.unusedIngredients = props.ingredients.filter((ing) => { | ||||||
|  |         return !(ing.referenceId in usedRefs); | ||||||
|  |       }); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     function autoSetReferences() { |     function autoSetReferences() { | ||||||
|       // Ingore matching blacklisted words when auto-linking - This is kind of a cludgey implementation. We're blacklisting common words but |       // Ingore matching blacklisted words when auto-linking - This is kind of a cludgey implementation. We're blacklisting common words but | ||||||
|       // other common phrases trigger false positives and I'm not sure how else to approach this. In the future I maybe look at looking directly |       // other common phrases trigger false positives and I'm not sure how else to approach this. In the future I maybe look at looking directly | ||||||
| @@ -294,10 +337,9 @@ export default defineComponent({ | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         props.ingredients.forEach((ingredient) => { |         props.ingredients.forEach((ingredient) => { | ||||||
|           if ( |           const searchText = parseIngredientText(ingredient, props.disableAmount); | ||||||
|             ingredient.note.toLowerCase().includes(" " + word) && |  | ||||||
|             !activeRefs.value.includes(ingredient.referenceId) |           if (searchText.toLowerCase().includes(" " + word) && !activeRefs.value.includes(ingredient.referenceId)) { | ||||||
|           ) { |  | ||||||
|             console.info("Word Matched", `'${word}'`, ingredient.note); |             console.info("Word Matched", `'${word}'`, ingredient.note); | ||||||
|             activeRefs.value.push(ingredient.referenceId); |             activeRefs.value.push(ingredient.referenceId); | ||||||
|           } |           } | ||||||
| @@ -306,7 +348,11 @@ export default defineComponent({ | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     function getIngredientByRefId(refId: String) { |     function getIngredientByRefId(refId: String) { | ||||||
|       return props.ingredients.find((ing) => ing.referenceId === refId) || ""; |       const ing = props.ingredients.find((ing) => ing.referenceId === refId) || ""; | ||||||
|  |       if (ing === "") { | ||||||
|  |         return ""; | ||||||
|  |       } | ||||||
|  |       return parseIngredientText(ing, props.disableAmount); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // =============================================================== |     // =============================================================== | ||||||
| @@ -365,6 +411,7 @@ export default defineComponent({ | |||||||
|       toggleShowTitle, |       toggleShowTitle, | ||||||
|       updateIndex, |       updateIndex, | ||||||
|       autoSetReferences, |       autoSetReferences, | ||||||
|  |       parseIngredientText, | ||||||
|     }; |     }; | ||||||
|   }, |   }, | ||||||
| }); | }); | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ | |||||||
|  |  | ||||||
| <script> | <script> | ||||||
| import { defineComponent } from "@nuxtjs/composition-api"; | import { defineComponent } from "@nuxtjs/composition-api"; | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
| export default defineComponent({ | export default defineComponent({ | ||||||
|   props: { |   props: { | ||||||
|     emitOnly: { |     emitOnly: { | ||||||
| @@ -43,7 +43,7 @@ export default defineComponent({ | |||||||
|     }, |     }, | ||||||
|   }, |   }, | ||||||
|   setup() { |   setup() { | ||||||
|     const api = useApiSingleton(); |     const api = useUserApi(); | ||||||
|  |  | ||||||
|     return { api }; |     return { api }; | ||||||
|   }, |   }, | ||||||
|   | |||||||
| @@ -140,7 +140,7 @@ | |||||||
| // import AppButtonUpload from "@/components/UI/Buttons/AppButtonUpload.vue"; | // import AppButtonUpload from "@/components/UI/Buttons/AppButtonUpload.vue"; | ||||||
| import { defineComponent, ref } from "@nuxtjs/composition-api"; | import { defineComponent, ref } from "@nuxtjs/composition-api"; | ||||||
| import { fieldTypes } from "~/composables/forms"; | import { fieldTypes } from "~/composables/forms"; | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
| import { validators } from "~/composables/use-validators"; | import { validators } from "~/composables/use-validators"; | ||||||
|  |  | ||||||
| export default defineComponent({ | export default defineComponent({ | ||||||
| @@ -160,7 +160,7 @@ export default defineComponent({ | |||||||
|     const domImportFromUrlDialog = ref(null); |     const domImportFromUrlDialog = ref(null); | ||||||
|     const domImportFromUrlForm = ref<VForm | null>(null); |     const domImportFromUrlForm = ref<VForm | null>(null); | ||||||
|  |  | ||||||
|     const api = useApiSingleton(); |     const api = useUserApi(); | ||||||
|  |  | ||||||
|     return { |     return { | ||||||
|       domCreateDialog, |       domCreateDialog, | ||||||
|   | |||||||
| @@ -68,8 +68,8 @@ export default { | |||||||
|       this.show = true; |       this.show = true; | ||||||
|       const copyText = this.copyText; |       const copyText = this.copyText; | ||||||
|       navigator.clipboard.writeText(copyText).then( |       navigator.clipboard.writeText(copyText).then( | ||||||
|         () => console.log("Copied", copyText), |         () => console.log(`Copied\n${copyText}`), | ||||||
|         () => console.log("Copied Failed", copyText) |         () => console.log(`Copied Failed\n${copyText}`) | ||||||
|       ); |       ); | ||||||
|       setTimeout(() => { |       setTimeout(() => { | ||||||
|         this.toggleBlur(); |         this.toggleBlur(); | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ | |||||||
| </template> | </template> | ||||||
|  |  | ||||||
| <script> | <script> | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
| const UPLOAD_EVENT = "uploaded"; | const UPLOAD_EVENT = "uploaded"; | ||||||
| export default { | export default { | ||||||
|   props: { |   props: { | ||||||
| @@ -45,7 +45,7 @@ export default { | |||||||
|     }, |     }, | ||||||
|   }, |   }, | ||||||
|   setup() { |   setup() { | ||||||
|     const api = useApiSingleton(); |     const api = useUserApi(); | ||||||
|  |  | ||||||
|     return { api }; |     return { api }; | ||||||
|   }, |   }, | ||||||
|   | |||||||
| @@ -29,7 +29,7 @@ | |||||||
| </template> | </template> | ||||||
|  |  | ||||||
| <script> | <script> | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
| export default { | export default { | ||||||
|   name: "BaseButton", |   name: "BaseButton", | ||||||
|   props: { |   props: { | ||||||
| @@ -107,7 +107,7 @@ export default { | |||||||
|     }, |     }, | ||||||
|   }, |   }, | ||||||
|   setup() { |   setup() { | ||||||
|     const api = useApiSingleton(); |     const api = useUserApi(); | ||||||
|  |  | ||||||
|     return { api }; |     return { api }; | ||||||
|   }, |   }, | ||||||
|   | |||||||
| @@ -59,7 +59,7 @@ export const useAdminApi = function (): AdminAPI { | |||||||
|   return new AdminAPI(requests); |   return new AdminAPI(requests); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export const useApiSingleton = function (): Api { | export const useUserApi = function (): Api { | ||||||
|   const { $axios } = useContext(); |   const { $axios } = useContext(); | ||||||
|   const requests = getRequests($axios); |   const requests = getRequests($axios); | ||||||
| 
 | 
 | ||||||
| @@ -1 +1,2 @@ | |||||||
| export { useStaticRoutes } from "./static-routes"; | export { useStaticRoutes } from "./static-routes"; | ||||||
|  | export { useAdminApi, useUserApi } from "./api-client"; | ||||||
|   | |||||||
							
								
								
									
										7
									
								
								frontend/composables/recipes/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								frontend/composables/recipes/index.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | export { useFraction } from "./use-fraction"; | ||||||
|  | export { useRecipe } from "./use-recipe"; | ||||||
|  | export { useFoods } from "./use-recipe-foods"; | ||||||
|  | export { useUnits } from "./use-recipe-units"; | ||||||
|  | export { useRecipes, recentRecipes, allRecipes, useLazyRecipes, useSorter } from "./use-recipes"; | ||||||
|  | export { useTags, useCategories, allCategories, allTags } from "./use-tags-categories"; | ||||||
|  | export { parseIngredientText } from "./use-recipe-ingredients"; | ||||||
| @@ -1,12 +1,12 @@ | |||||||
| import { useAsync, ref, reactive, Ref } from "@nuxtjs/composition-api"; | import { useAsync, ref, reactive, Ref } from "@nuxtjs/composition-api"; | ||||||
| import { useAsyncKey } from "./use-utils"; | import { useAsyncKey } from "../use-utils"; | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
| import { Food } from "~/api/class-interfaces/recipe-foods"; | import { Food } from "~/api/class-interfaces/recipe-foods"; | ||||||
| 
 | 
 | ||||||
| let foodStore: Ref<Food[] | null> | null = null; | let foodStore: Ref<Food[] | null> | null = null; | ||||||
| 
 | 
 | ||||||
| export const useFoods = function () { | export const useFoods = function () { | ||||||
|   const api = useApiSingleton(); |   const api = useUserApi(); | ||||||
|   const loading = ref(false); |   const loading = ref(false); | ||||||
|   const deleteTargetId = ref(0); |   const deleteTargetId = ref(0); | ||||||
|   const validForm = ref(true); |   const validForm = ref(true); | ||||||
							
								
								
									
										28
									
								
								frontend/composables/recipes/use-recipe-ingredients.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								frontend/composables/recipes/use-recipe-ingredients.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | |||||||
|  | import { useFraction } from "./use-fraction"; | ||||||
|  | import { RecipeIngredient } from "~/types/api-types/recipe"; | ||||||
|  |  | ||||||
|  | const { frac } = useFraction(); | ||||||
|  |  | ||||||
|  | export function parseIngredientText(ingredient: RecipeIngredient, disableAmount: boolean, scale: number = 1): string { | ||||||
|  |   if (disableAmount) { | ||||||
|  |     return ingredient.note; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   const { quantity, food, unit, note } = ingredient; | ||||||
|  |  | ||||||
|  |   let returnQty = ""; | ||||||
|  |   if (unit?.fraction) { | ||||||
|  |     const fraction = frac(quantity * scale, 10, true); | ||||||
|  |     if (fraction[0] !== undefined && fraction[0] > 0) { | ||||||
|  |       returnQty += fraction[0]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (fraction[1] > 0) { | ||||||
|  |       returnQty += ` <sup>${fraction[1]}</sup>⁄<sub>${fraction[2]}</sub>`; | ||||||
|  |     } | ||||||
|  |   } else { | ||||||
|  |     returnQty = (quantity * scale).toString(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return `${returnQty} ${unit?.name || " "}  ${food?.name || " "} ${note}`.replace(/ {2,}/g, " "); | ||||||
|  | } | ||||||
| @@ -1,12 +1,12 @@ | |||||||
| import { useAsync, ref, reactive, Ref } from "@nuxtjs/composition-api"; | import { useAsync, ref, reactive, Ref } from "@nuxtjs/composition-api"; | ||||||
| import { useAsyncKey } from "./use-utils"; | import { useAsyncKey } from "../use-utils"; | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
| import { Unit } from "~/api/class-interfaces/recipe-units"; | import { Unit } from "~/api/class-interfaces/recipe-units"; | ||||||
| 
 | 
 | ||||||
| let unitStore: Ref<Unit[] | null> | null = null; | let unitStore: Ref<Unit[] | null> | null = null; | ||||||
| 
 | 
 | ||||||
| export const useUnits = function () { | export const useUnits = function () { | ||||||
|   const api = useApiSingleton(); |   const api = useUserApi(); | ||||||
|   const loading = ref(false); |   const loading = ref(false); | ||||||
|   const deleteTargetId = ref(0); |   const deleteTargetId = ref(0); | ||||||
|   const validForm = ref(true); |   const validForm = ref(true); | ||||||
							
								
								
									
										47
									
								
								frontend/composables/recipes/use-recipe.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								frontend/composables/recipes/use-recipe.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | |||||||
|  | import { ref, onMounted } from "@nuxtjs/composition-api"; | ||||||
|  | import { useUserApi } from "~/composables/api"; | ||||||
|  | import { Recipe } from "~/types/api-types/recipe"; | ||||||
|  |  | ||||||
|  | export const useRecipe = function (slug: string, eager: boolean = true) { | ||||||
|  |   const api = useUserApi(); | ||||||
|  |   const loading = ref(false); | ||||||
|  |  | ||||||
|  |   const recipe = ref<Recipe | null>(null); | ||||||
|  |  | ||||||
|  |   async function fetchRecipe() { | ||||||
|  |     loading.value = true; | ||||||
|  |     const { data } = await api.recipes.getOne(slug); | ||||||
|  |     loading.value = false; | ||||||
|  |     if (data) { | ||||||
|  |       recipe.value = data; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async function deleteRecipe() { | ||||||
|  |     loading.value = true; | ||||||
|  |     const { data } = await api.recipes.deleteOne(slug); | ||||||
|  |     loading.value = false; | ||||||
|  |     return data; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async function updateRecipe(recipe: Recipe) { | ||||||
|  |     loading.value = true; | ||||||
|  |     const { data } = await api.recipes.updateOne(slug, recipe); | ||||||
|  |     loading.value = false; | ||||||
|  |     return data; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   onMounted(() => { | ||||||
|  |     if (eager) { | ||||||
|  |       fetchRecipe(); | ||||||
|  |     } | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   return { | ||||||
|  |     recipe, | ||||||
|  |     loading, | ||||||
|  |     fetchRecipe, | ||||||
|  |     deleteRecipe, | ||||||
|  |     updateRecipe, | ||||||
|  |   }; | ||||||
|  | }; | ||||||
| @@ -1,7 +1,7 @@ | |||||||
| import { useAsync, ref } from "@nuxtjs/composition-api"; | import { useAsync, ref } from "@nuxtjs/composition-api"; | ||||||
| import { set } from "@vueuse/core"; | import { set } from "@vueuse/core"; | ||||||
| import { useAsyncKey } from "./use-utils"; | import { useAsyncKey } from "../use-utils"; | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
| import { Recipe } from "~/types/api-types/recipe"; | import { Recipe } from "~/types/api-types/recipe"; | ||||||
| 
 | 
 | ||||||
| export const allRecipes = ref<Recipe[] | null>([]); | export const allRecipes = ref<Recipe[] | null>([]); | ||||||
| @@ -58,7 +58,7 @@ export const useSorter = () => { | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export const useLazyRecipes = function () { | export const useLazyRecipes = function () { | ||||||
|   const api = useApiSingleton(); |   const api = useUserApi(); | ||||||
| 
 | 
 | ||||||
|   const recipes = ref<Recipe[] | null>([]); |   const recipes = ref<Recipe[] | null>([]); | ||||||
| 
 | 
 | ||||||
| @@ -78,7 +78,7 @@ export const useLazyRecipes = function () { | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export const useRecipes = (all = false, fetchRecipes = true) => { | export const useRecipes = (all = false, fetchRecipes = true) => { | ||||||
|   const api = useApiSingleton(); |   const api = useUserApi(); | ||||||
| 
 | 
 | ||||||
|   // recipes is non-reactive!!
 |   // recipes is non-reactive!!
 | ||||||
|   const { recipes, start, end } = (() => { |   const { recipes, start, end } = (() => { | ||||||
| @@ -1,6 +1,6 @@ | |||||||
| import { Ref, ref, useAsync } from "@nuxtjs/composition-api"; | import { Ref, ref, useAsync } from "@nuxtjs/composition-api"; | ||||||
| import { useApiSingleton } from "./use-api"; | import { useUserApi } from "../api"; | ||||||
| import { useAsyncKey } from "./use-utils"; | import { useAsyncKey } from "../use-utils"; | ||||||
| import { CategoriesAPI, Category } from "~/api/class-interfaces/categories"; | import { CategoriesAPI, Category } from "~/api/class-interfaces/categories"; | ||||||
| import { Tag, TagsAPI } from "~/api/class-interfaces/tags"; | import { Tag, TagsAPI } from "~/api/class-interfaces/tags"; | ||||||
| 
 | 
 | ||||||
| @@ -45,14 +45,14 @@ function baseTagsCategories(reference: Ref<Category[] | null> | Ref<Tag[] | null | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export const useTags = function () { | export const useTags = function () { | ||||||
|   const api = useApiSingleton(); |   const api = useUserApi(); | ||||||
|   return { |   return { | ||||||
|     allTags, |     allTags, | ||||||
|     ...baseTagsCategories(allTags, api.tags), |     ...baseTagsCategories(allTags, api.tags), | ||||||
|   }; |   }; | ||||||
| }; | }; | ||||||
| export const useCategories = function () { | export const useCategories = function () { | ||||||
|   const api = useApiSingleton(); |   const api = useUserApi(); | ||||||
|   return { |   return { | ||||||
|     allCategories, |     allCategories, | ||||||
|     ...baseTagsCategories(allCategories, api.categories), |     ...baseTagsCategories(allCategories, api.categories), | ||||||
| @@ -2,7 +2,7 @@ import { useAsync, ref, reactive } from "@nuxtjs/composition-api"; | |||||||
| import { set } from "@vueuse/core"; | import { set } from "@vueuse/core"; | ||||||
| import { toastLoading, loader } from "./use-toast"; | import { toastLoading, loader } from "./use-toast"; | ||||||
| import { AllBackups, ImportBackup } from "~/api/class-interfaces/backups"; | import { AllBackups, ImportBackup } from "~/api/class-interfaces/backups"; | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
|  |  | ||||||
| const backups = ref<AllBackups>({ | const backups = ref<AllBackups>({ | ||||||
|   imports: [], |   imports: [], | ||||||
| @@ -32,7 +32,7 @@ function optionsFactory() { | |||||||
| } | } | ||||||
|  |  | ||||||
| export const useBackups = function (fetch = true) { | export const useBackups = function (fetch = true) { | ||||||
|   const api = useApiSingleton(); |   const api = useUserApi(); | ||||||
|  |  | ||||||
|   const backupOptions = reactive(optionsFactory()); |   const backupOptions = reactive(optionsFactory()); | ||||||
|   const deleteTarget = ref(""); |   const deleteTarget = ref(""); | ||||||
|   | |||||||
| @@ -1,13 +1,13 @@ | |||||||
| import { useAsync, ref, reactive, Ref } from "@nuxtjs/composition-api"; | import { useAsync, ref, reactive, Ref } from "@nuxtjs/composition-api"; | ||||||
| import { useAsyncKey } from "./use-utils"; | import { useAsyncKey } from "./use-utils"; | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
| import { CookBook } from "~/api/class-interfaces/group-cookbooks"; | import { CookBook } from "~/api/class-interfaces/group-cookbooks"; | ||||||
|  |  | ||||||
| let cookbookStore: Ref<CookBook[] | null> | null = null; | let cookbookStore: Ref<CookBook[] | null> | null = null; | ||||||
|  |  | ||||||
| export const useCookbook = function () { | export const useCookbook = function () { | ||||||
|   function getOne(id: string | number) { |   function getOne(id: string | number) { | ||||||
|     const api = useApiSingleton(); |     const api = useUserApi(); | ||||||
|  |  | ||||||
|     const units = useAsync(async () => { |     const units = useAsync(async () => { | ||||||
|       const { data } = await api.cookbooks.getOne(id); |       const { data } = await api.cookbooks.getOne(id); | ||||||
| @@ -22,7 +22,7 @@ export const useCookbook = function () { | |||||||
| }; | }; | ||||||
|  |  | ||||||
| export const useCookbooks = function () { | export const useCookbooks = function () { | ||||||
|   const api = useApiSingleton(); |   const api = useUserApi(); | ||||||
|   const loading = ref(false); |   const loading = ref(false); | ||||||
|   const deleteTargetId = ref(0); |   const deleteTargetId = ref(0); | ||||||
|   const validForm = ref(true); |   const validForm = ref(true); | ||||||
|   | |||||||
| @@ -1,11 +1,11 @@ | |||||||
| import { useAsync, ref } from "@nuxtjs/composition-api"; | import { useAsync, ref } from "@nuxtjs/composition-api"; | ||||||
| import { addDays, subDays, format } from "date-fns"; | import { addDays, subDays, format } from "date-fns"; | ||||||
| import { useAsyncKey } from "./use-utils"; | import { useAsyncKey } from "./use-utils"; | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
| import { CreateMealPlan, UpdateMealPlan } from "~/api/class-interfaces/group-mealplan"; | import { CreateMealPlan, UpdateMealPlan } from "~/api/class-interfaces/group-mealplan"; | ||||||
|  |  | ||||||
| export const useMealplans = function () { | export const useMealplans = function () { | ||||||
|   const api = useApiSingleton(); |   const api = useUserApi(); | ||||||
|   const loading = ref(false); |   const loading = ref(false); | ||||||
|   const validForm = ref(true); |   const validForm = ref(true); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,10 +1,10 @@ | |||||||
| import { useAsync, ref } from "@nuxtjs/composition-api"; | import { useAsync, ref } from "@nuxtjs/composition-api"; | ||||||
| import { useAsyncKey } from "./use-utils"; | import { useAsyncKey } from "./use-utils"; | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
| import { GroupWebhook } from "~/api/class-interfaces/group-webhooks"; | import { GroupWebhook } from "~/api/class-interfaces/group-webhooks"; | ||||||
|  |  | ||||||
| export const useGroupWebhooks = function () { | export const useGroupWebhooks = function () { | ||||||
|   const api = useApiSingleton(); |   const api = useUserApi(); | ||||||
|   const loading = ref(false); |   const loading = ref(false); | ||||||
|   const validForm = ref(true); |   const validForm = ref(true); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,10 +1,10 @@ | |||||||
| import { useAsync, ref } from "@nuxtjs/composition-api"; | import { useAsync, ref } from "@nuxtjs/composition-api"; | ||||||
| import { useAsyncKey } from "./use-utils"; | import { useAsyncKey } from "./use-utils"; | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
| import { CreateGroup } from "~/api/class-interfaces/groups"; | import { CreateGroup } from "~/api/class-interfaces/groups"; | ||||||
|  |  | ||||||
| export const useGroupSelf = function () { | export const useGroupSelf = function () { | ||||||
|   const api = useApiSingleton(); |   const api = useUserApi(); | ||||||
|  |  | ||||||
|   const actions = { |   const actions = { | ||||||
|     get() { |     get() { | ||||||
| @@ -35,7 +35,7 @@ export const useGroupSelf = function () { | |||||||
| }; | }; | ||||||
|  |  | ||||||
| export const useGroupCategories = function () { | export const useGroupCategories = function () { | ||||||
|   const api = useApiSingleton(); |   const api = useUserApi(); | ||||||
|  |  | ||||||
|   const actions = { |   const actions = { | ||||||
|     getAll() { |     getAll() { | ||||||
| @@ -61,7 +61,7 @@ export const useGroupCategories = function () { | |||||||
| }; | }; | ||||||
|  |  | ||||||
| export const useGroups = function () { | export const useGroups = function () { | ||||||
|   const api = useApiSingleton(); |   const api = useUserApi(); | ||||||
|   const loading = ref(false); |   const loading = ref(false); | ||||||
|  |  | ||||||
|   function getAllGroups() { |   function getAllGroups() { | ||||||
|   | |||||||
| @@ -1,13 +1,12 @@ | |||||||
| import { useAsync, ref } from "@nuxtjs/composition-api"; | import { useAsync, ref } from "@nuxtjs/composition-api"; | ||||||
| import { CreateEventNotification } from "@/api/class-interfaces/event-notifications"; |  | ||||||
| import { useAsyncKey } from "./use-utils"; | import { useAsyncKey } from "./use-utils"; | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { CreateEventNotification } from "@/api/class-interfaces/event-notifications"; | ||||||
|  | import { useUserApi } from "~/composables/api"; | ||||||
|  |  | ||||||
| const notificationTypes = ["General", "Discord", "Gotify", "Pushover", "Home Assistant"]; | const notificationTypes = ["General", "Discord", "Gotify", "Pushover", "Home Assistant"]; | ||||||
|  |  | ||||||
|  |  | ||||||
| export const useNotifications = function () { | export const useNotifications = function () { | ||||||
|   const api = useApiSingleton(); |   const api = useUserApi(); | ||||||
|   const loading = ref(false); |   const loading = ref(false); | ||||||
|  |  | ||||||
|   const createNotificationData = ref<CreateEventNotification>({ |   const createNotificationData = ref<CreateEventNotification>({ | ||||||
| @@ -23,7 +22,7 @@ export const useNotifications = function () { | |||||||
|     notificationUrl: "", |     notificationUrl: "", | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|   const deleteTarget = ref(0) |   const deleteTarget = ref(0); | ||||||
|  |  | ||||||
|   function getNotifications() { |   function getNotifications() { | ||||||
|     loading.value = true; |     loading.value = true; | ||||||
| @@ -63,13 +62,13 @@ export const useNotifications = function () { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   async function testById(id: number) { |   async function testById(id: number) { | ||||||
|     const {data} = await api.notifications.testNotification(id, null) |     const { data } = await api.notifications.testNotification(id, null); | ||||||
|     console.log(data) |     console.log(data); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async function testByUrl(testUrl: string) { |   async function testByUrl(testUrl: string) { | ||||||
|     const {data} = await api.notifications.testNotification(null, testUrl) |     const { data } = await api.notifications.testNotification(null, testUrl); | ||||||
|     console.log(data) |     console.log(data); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   const notifications = getNotifications(); |   const notifications = getNotifications(); | ||||||
|   | |||||||
| @@ -1,43 +0,0 @@ | |||||||
| import { useAsync, ref } from "@nuxtjs/composition-api"; |  | ||||||
| import { useApiSingleton } from "~/composables/use-api"; |  | ||||||
| import { Recipe } from "~/types/api-types/recipe"; |  | ||||||
|  |  | ||||||
| export const useRecipeContext = function () { |  | ||||||
|   const api = useApiSingleton(); |  | ||||||
|   const loading = ref(false); |  | ||||||
|  |  | ||||||
|   function getBySlug(slug: string) { |  | ||||||
|     loading.value = true; |  | ||||||
|     const recipe = useAsync(async () => { |  | ||||||
|       const { data } = await api.recipes.getOne(slug); |  | ||||||
|       return data; |  | ||||||
|     }, slug); |  | ||||||
|  |  | ||||||
|     loading.value = false; |  | ||||||
|  |  | ||||||
|     return recipe; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   async function fetchRecipe(slug: string) { |  | ||||||
|     loading.value = true; |  | ||||||
|     const { data } = await api.recipes.getOne(slug); |  | ||||||
|     loading.value = false; |  | ||||||
|     return data; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   async function deleteRecipe(slug: string) { |  | ||||||
|     loading.value = true; |  | ||||||
|     const { data } = await api.recipes.deleteOne(slug); |  | ||||||
|     loading.value = false; |  | ||||||
|     return data; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   async function updateRecipe(slug: string, recipe: Recipe) { |  | ||||||
|     loading.value = true; |  | ||||||
|     const { data } = await api.recipes.updateOne(slug, recipe); |  | ||||||
|     loading.value = false; |  | ||||||
|     return data; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   return { loading, getBySlug, deleteRecipe, updateRecipe, fetchRecipe }; |  | ||||||
| }; |  | ||||||
| @@ -1,5 +1,5 @@ | |||||||
| import { useAsync, ref } from "@nuxtjs/composition-api"; | import { useAsync, ref } from "@nuxtjs/composition-api"; | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
| import { UserIn, UserOut } from "~/types/api-types/user"; | import { UserIn, UserOut } from "~/types/api-types/user"; | ||||||
|  |  | ||||||
| /* | /* | ||||||
| @@ -9,7 +9,7 @@ to control whether the object is substantiated... but some of the others rely on | |||||||
| */ | */ | ||||||
|  |  | ||||||
| export const useAllUsers = function () { | export const useAllUsers = function () { | ||||||
|   const api = useApiSingleton(); |   const api = useUserApi(); | ||||||
|   const loading = ref(false); |   const loading = ref(false); | ||||||
|  |  | ||||||
|   function getAllUsers() { |   function getAllUsers() { | ||||||
| @@ -37,7 +37,7 @@ export const useAllUsers = function () { | |||||||
| }; | }; | ||||||
|  |  | ||||||
| export const useUser = function (refreshFunc: CallableFunction | null = null) { | export const useUser = function (refreshFunc: CallableFunction | null = null) { | ||||||
|   const api = useApiSingleton(); |   const api = useUserApi(); | ||||||
|   const loading = ref(false); |   const loading = ref(false); | ||||||
|  |  | ||||||
|   function getUser(id: string) { |   function getUser(id: string) { | ||||||
|   | |||||||
| @@ -1,3 +1,10 @@ | |||||||
| export const useAsyncKey = function () { | export const useAsyncKey = function () { | ||||||
|   return String(Date.now()); |   return String(Date.now()); | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | export function uuid4() { | ||||||
|  |   // @ts-ignore | ||||||
|  |   return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c) => | ||||||
|  |     (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16) | ||||||
|  |   ); | ||||||
|  | } | ||||||
|   | |||||||
| @@ -1,12 +0,0 @@ | |||||||
| const max = 1000000; |  | ||||||
|  |  | ||||||
| export function uniqueId() { |  | ||||||
|   return Date.now() + Math.random() * max; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| export function uuid4() { |  | ||||||
|   // @ts-ignore |  | ||||||
|   return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c) => |  | ||||||
|     (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16) |  | ||||||
|   ); |  | ||||||
| } |  | ||||||
| @@ -42,7 +42,7 @@ | |||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| import { defineComponent, onMounted, ref } from "@nuxtjs/composition-api"; | import { defineComponent, onMounted, ref } from "@nuxtjs/composition-api"; | ||||||
| import { ServerTask } from "~/api/types/server-task"; | import { ServerTask } from "~/api/types/server-task"; | ||||||
| import { useAdminApi } from "~/composables/use-api"; | import { useAdminApi } from "~/composables/api"; | ||||||
|  |  | ||||||
| export default defineComponent({ | export default defineComponent({ | ||||||
|   layout: "admin", |   layout: "admin", | ||||||
|   | |||||||
| @@ -92,14 +92,14 @@ | |||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| import { defineComponent, useAsync } from "@nuxtjs/composition-api"; | import { defineComponent, useAsync } from "@nuxtjs/composition-api"; | ||||||
| import AdminEventViewer from "@/components/Domain/Admin/AdminEventViewer.vue"; | import AdminEventViewer from "@/components/Domain/Admin/AdminEventViewer.vue"; | ||||||
| import { useAdminApi, useApiSingleton } from "~/composables/use-api"; | import { useAdminApi, useUserApi } from "~/composables/api"; | ||||||
| import { useAsyncKey } from "~/composables/use-utils"; | import { useAsyncKey } from "~/composables/use-utils"; | ||||||
|  |  | ||||||
| export default defineComponent({ | export default defineComponent({ | ||||||
|   components: { AdminEventViewer }, |   components: { AdminEventViewer }, | ||||||
|   layout: "admin", |   layout: "admin", | ||||||
|   setup() { |   setup() { | ||||||
|     const api = useApiSingleton(); |     const api = useUserApi(); | ||||||
|  |  | ||||||
|     const adminApi = useAdminApi(); |     const adminApi = useAdminApi(); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -72,14 +72,14 @@ | |||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| import { defineComponent, ref } from "@nuxtjs/composition-api"; | import { defineComponent, ref } from "@nuxtjs/composition-api"; | ||||||
| import { fieldTypes } from "~/composables/forms"; | import { fieldTypes } from "~/composables/forms"; | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
| import { useGroups } from "~/composables/use-groups"; | import { useGroups } from "~/composables/use-groups"; | ||||||
| import { useUser, useAllUsers } from "~/composables/use-user"; | import { useUser, useAllUsers } from "~/composables/use-user"; | ||||||
|  |  | ||||||
| export default defineComponent({ | export default defineComponent({ | ||||||
|   layout: "admin", |   layout: "admin", | ||||||
|   setup() { |   setup() { | ||||||
|     const api = useApiSingleton(); |     const api = useUserApi(); | ||||||
|     const refUserDialog = ref(); |     const refUserDialog = ref(); | ||||||
|  |  | ||||||
|     const { groups } = useGroups(); |     const { groups } = useGroups(); | ||||||
|   | |||||||
| @@ -69,12 +69,12 @@ | |||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| import { defineComponent, reactive, ref, toRefs } from "@nuxtjs/composition-api"; | import { defineComponent, reactive, ref, toRefs } from "@nuxtjs/composition-api"; | ||||||
| import { Confidence, Parser } from "~/api/class-interfaces/recipes"; | import { Confidence, Parser } from "~/api/class-interfaces/recipes"; | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
|  |  | ||||||
| export default defineComponent({ | export default defineComponent({ | ||||||
|   layout: "admin", |   layout: "admin", | ||||||
|   setup() { |   setup() { | ||||||
|     const api = useApiSingleton(); |     const api = useUserApi(); | ||||||
|  |  | ||||||
|     const state = reactive({ |     const state = reactive({ | ||||||
|       loading: false, |       loading: false, | ||||||
|   | |||||||
| @@ -102,7 +102,7 @@ import { | |||||||
|   useContext, |   useContext, | ||||||
| } from "@nuxtjs/composition-api"; | } from "@nuxtjs/composition-api"; | ||||||
| import { CheckAppConfig } from "~/api/admin/admin-about"; | import { CheckAppConfig } from "~/api/admin/admin-about"; | ||||||
| import { useAdminApi, useApiSingleton } from "~/composables/use-api"; | import { useAdminApi, useUserApi } from "~/composables/api"; | ||||||
| import { validators } from "~/composables/use-validators"; | import { validators } from "~/composables/use-validators"; | ||||||
| import { useAsyncKey } from "~/composables/use-utils"; | import { useAsyncKey } from "~/composables/use-utils"; | ||||||
|  |  | ||||||
| @@ -130,7 +130,7 @@ export default defineComponent({ | |||||||
|       isSiteSecure: false, |       isSiteSecure: false, | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     const api = useApiSingleton(); |     const api = useUserApi(); | ||||||
|  |  | ||||||
|     const adminApi = useAdminApi(); |     const adminApi = useAdminApi(); | ||||||
|     onMounted(async () => { |     onMounted(async () => { | ||||||
|   | |||||||
| @@ -65,7 +65,7 @@ | |||||||
|      |      | ||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| import { defineComponent, reactive, toRefs, ref, computed } from "@nuxtjs/composition-api"; | import { defineComponent, reactive, toRefs, ref, computed } from "@nuxtjs/composition-api"; | ||||||
| import { useFoods } from "~/composables/use-recipe-foods"; | import { useFoods } from "~/composables/recipes"; | ||||||
| import { validators } from "~/composables/use-validators"; | import { validators } from "~/composables/use-validators"; | ||||||
| export default defineComponent({ | export default defineComponent({ | ||||||
|   layout: "admin", |   layout: "admin", | ||||||
|   | |||||||
| @@ -66,7 +66,7 @@ | |||||||
|      |      | ||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| import { defineComponent, reactive, toRefs, ref, computed } from "@nuxtjs/composition-api"; | import { defineComponent, reactive, toRefs, ref, computed } from "@nuxtjs/composition-api"; | ||||||
| import { useUnits } from "~/composables/use-recipe-units"; | import { useUnits } from "~/composables/recipes"; | ||||||
| import { validators } from "~/composables/use-validators"; | import { validators } from "~/composables/use-validators"; | ||||||
| export default defineComponent({ | export default defineComponent({ | ||||||
|   layout: "admin", |   layout: "admin", | ||||||
|   | |||||||
| @@ -35,7 +35,7 @@ | |||||||
|  |  | ||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| import { defineComponent, toRefs, reactive } from "@nuxtjs/composition-api"; | import { defineComponent, toRefs, reactive } from "@nuxtjs/composition-api"; | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
| import { alert } from "~/composables/use-toast"; | import { alert } from "~/composables/use-toast"; | ||||||
| export default defineComponent({ | export default defineComponent({ | ||||||
|   layout: "basic", |   layout: "basic", | ||||||
| @@ -47,7 +47,7 @@ export default defineComponent({ | |||||||
|       error: false, |       error: false, | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     const api = useApiSingleton(); |     const api = useUserApi(); | ||||||
|  |  | ||||||
|     async function requestLink() { |     async function requestLink() { | ||||||
|       state.loading = true; |       state.loading = true; | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ | |||||||
|   <script lang="ts"> |   <script lang="ts"> | ||||||
| import { defineComponent } from "@nuxtjs/composition-api"; | import { defineComponent } from "@nuxtjs/composition-api"; | ||||||
| import RecipeCardSection from "~/components/Domain/Recipe/RecipeCardSection.vue"; | import RecipeCardSection from "~/components/Domain/Recipe/RecipeCardSection.vue"; | ||||||
| import { useRecipes, recentRecipes } from "~/composables/use-recipes"; | import { useRecipes, recentRecipes } from "~/composables/recipes"; | ||||||
| import { useStaticRoutes } from "~/composables/api"; | import { useStaticRoutes } from "~/composables/api"; | ||||||
|  |  | ||||||
| export default defineComponent({ | export default defineComponent({ | ||||||
|   | |||||||
| @@ -152,7 +152,7 @@ import { isSameDay, addDays, subDays, parseISO, format } from "date-fns"; | |||||||
| import { SortableEvent } from "sortablejs"; // eslint-disable-line | import { SortableEvent } from "sortablejs"; // eslint-disable-line | ||||||
| import draggable from "vuedraggable"; | import draggable from "vuedraggable"; | ||||||
| import { useMealplans } from "~/composables/use-group-mealplan"; | import { useMealplans } from "~/composables/use-group-mealplan"; | ||||||
| import { useRecipes, allRecipes } from "~/composables/use-recipes"; | import { useRecipes, allRecipes } from "~/composables/recipes"; | ||||||
| import RecipeCardImage from "~/components/Domain/Recipe/RecipeCardImage.vue"; | import RecipeCardImage from "~/components/Domain/Recipe/RecipeCardImage.vue"; | ||||||
|  |  | ||||||
| export default defineComponent({ | export default defineComponent({ | ||||||
|   | |||||||
| @@ -8,12 +8,30 @@ | |||||||
|     <v-card-title> |     <v-card-title> | ||||||
|       <h1 class="headline">{{ recipe.name }}</h1> |       <h1 class="headline">{{ recipe.name }}</h1> | ||||||
|     </v-card-title> |     </v-card-title> | ||||||
|  |  | ||||||
|     <v-stepper v-model="activeStep" flat> |     <v-stepper v-model="activeStep" flat> | ||||||
|       <v-toolbar class="ma-1 elevation-2 rounded"> |       <v-toolbar class="ma-1 elevation-2 rounded"> | ||||||
|         <v-toolbar-title class="headline"> |         <v-toolbar-title class="headline"> | ||||||
|           Step {{ activeStep }} of {{ recipe.recipeInstructions.length }}</v-toolbar-title |           Step {{ activeStep }} of {{ recipe.recipeInstructions.length }}</v-toolbar-title | ||||||
|         > |         > | ||||||
|       </v-toolbar> |       </v-toolbar> | ||||||
|  |       <div class="d-flex mt-3 px-2"> | ||||||
|  |         <BaseButton color="primary" @click="$router.go(-1)"> | ||||||
|  |           <template #icon> {{ $globals.icons.arrowLeftBold }}</template> | ||||||
|  |           To Recipe | ||||||
|  |         </BaseButton> | ||||||
|  |         <v-btn rounded icon color="primary" class="ml-auto" small @click="scale > 1 ? scale-- : null"> | ||||||
|  |           <v-icon> | ||||||
|  |             {{ $globals.icons.minus }} | ||||||
|  |           </v-icon> | ||||||
|  |         </v-btn> | ||||||
|  |         <v-btn rounded color="primary" small> Scale: {{ scale }} </v-btn> | ||||||
|  |         <v-btn rounded icon color="primary" small @click="scale++"> | ||||||
|  |           <v-icon> | ||||||
|  |             {{ $globals.icons.createAlt }} | ||||||
|  |           </v-icon> | ||||||
|  |         </v-btn> | ||||||
|  |       </div> | ||||||
|       <v-stepper-items> |       <v-stepper-items> | ||||||
|         <template v-for="(step, index) in recipe.recipeInstructions"> |         <template v-for="(step, index) in recipe.recipeInstructions"> | ||||||
|           <v-stepper-content :key="index + 1 + '-content'" :step="index + 1" class="pa-0 mt-2 elevation-0"> |           <v-stepper-content :key="index + 1 + '-content'" :step="index + 1" class="pa-0 mt-2 elevation-0"> | ||||||
| @@ -21,11 +39,17 @@ | |||||||
|               <v-card-text> |               <v-card-text> | ||||||
|                 <h2 class="mb-4">{{ $t("recipe.instructions") }}</h2> |                 <h2 class="mb-4">{{ $t("recipe.instructions") }}</h2> | ||||||
|                 <VueMarkdown :source="step.text"> </VueMarkdown> |                 <VueMarkdown :source="step.text"> </VueMarkdown> | ||||||
|                 <v-divider></v-divider> |                 <template v-if="step.ingredientReferences.length > 0"> | ||||||
|                 <h2 class="mb-4 mt-4">{{ $t("recipe.ingredients") }}</h2> |                   <v-divider></v-divider> | ||||||
|                 <div v-for="ing in step.ingredientReferences" :key="ing.referenceId"> |                   <div> | ||||||
|                   {{ getIngredientByRefId(ing.referenceId).note }} |                     <h2 class="mb-4 mt-4">{{ $t("recipe.ingredients") }}</h2> | ||||||
|                 </div> |                     <div | ||||||
|  |                       v-for="ing in step.ingredientReferences" | ||||||
|  |                       :key="ing.referenceId" | ||||||
|  |                       v-html="getIngredientByRefId(ing.referenceId)" | ||||||
|  |                     ></div> | ||||||
|  |                   </div> | ||||||
|  |                 </template> | ||||||
|               </v-card-text> |               </v-card-text> | ||||||
|             </v-card> |             </v-card> | ||||||
|             <v-card-actions class="justify-center"> |             <v-card-actions class="justify-center"> | ||||||
| @@ -33,6 +57,7 @@ | |||||||
|                 <template #icon> {{ $globals.icons.arrowLeftBold }}</template> |                 <template #icon> {{ $globals.icons.arrowLeftBold }}</template> | ||||||
|                 Back |                 Back | ||||||
|               </BaseButton> |               </BaseButton> | ||||||
|  |  | ||||||
|               <BaseButton |               <BaseButton | ||||||
|                 icon-right |                 icon-right | ||||||
|                 :disabled="index + 1 == recipe.recipeInstructions.length" |                 :disabled="index + 1 == recipe.recipeInstructions.length" | ||||||
| @@ -55,25 +80,35 @@ import { defineComponent, useRoute, ref } from "@nuxtjs/composition-api"; | |||||||
| // @ts-ignore | // @ts-ignore | ||||||
| import VueMarkdown from "@adapttive/vue-markdown"; | import VueMarkdown from "@adapttive/vue-markdown"; | ||||||
| import { useStaticRoutes } from "~/composables/api"; | import { useStaticRoutes } from "~/composables/api"; | ||||||
| import { useRecipeContext } from "~/composables/use-recipe-context"; | import { parseIngredientText, useRecipe } from "~/composables/recipes"; | ||||||
|  |  | ||||||
| export default defineComponent({ | export default defineComponent({ | ||||||
|   components: { VueMarkdown }, |   components: { VueMarkdown }, | ||||||
|   setup() { |   setup() { | ||||||
|     const route = useRoute(); |     const route = useRoute(); | ||||||
|     const slug = route.value.params.slug; |     const slug = route.value.params.slug; | ||||||
|     const activeStep = ref(1); |     const activeStep = ref(1); | ||||||
|  |     const scale = ref(1); | ||||||
|  |  | ||||||
|     const { getBySlug } = useRecipeContext(); |     const { recipe } = useRecipe(slug); | ||||||
|  |  | ||||||
|     const { recipeImage } = useStaticRoutes(); |     const { recipeImage } = useStaticRoutes(); | ||||||
|  |  | ||||||
|     const recipe = getBySlug(slug); |  | ||||||
|  |  | ||||||
|     function getIngredientByRefId(refId: String) { |     function getIngredientByRefId(refId: String) { | ||||||
|       return recipe.value?.recipeIngredient.find((ing) => ing.referenceId === refId) || ""; |       if (!recipe.value) { | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       const ing = recipe?.value.recipeIngredient.find((ing) => ing.referenceId === refId) || ""; | ||||||
|  |       if (ing === "") { | ||||||
|  |         return ""; | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       return parseIngredientText(ing, recipe?.value?.settings?.disableAmount || false, scale.value); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return { |     return { | ||||||
|  |       scale, | ||||||
|       getIngredientByRefId, |       getIngredientByRefId, | ||||||
|       activeStep, |       activeStep, | ||||||
|       slug, |       slug, | ||||||
|   | |||||||
| @@ -233,6 +233,7 @@ | |||||||
|               <RecipeInstructions |               <RecipeInstructions | ||||||
|                 v-model="recipe.recipeInstructions" |                 v-model="recipe.recipeInstructions" | ||||||
|                 :ingredients="recipe.recipeIngredient" |                 :ingredients="recipe.recipeIngredient" | ||||||
|  |                 :disable-amount="recipe.settings.disableAmount" | ||||||
|                 :edit="form" |                 :edit="form" | ||||||
|               /> |               /> | ||||||
|               <div v-if="form" class="d-flex"> |               <div v-if="form" class="d-flex"> | ||||||
| @@ -289,9 +290,9 @@ import VueMarkdown from "@adapttive/vue-markdown"; | |||||||
| import draggable from "vuedraggable"; | import draggable from "vuedraggable"; | ||||||
| import RecipeCategoryTagSelector from "@/components/Domain/Recipe/RecipeCategoryTagSelector.vue"; | import RecipeCategoryTagSelector from "@/components/Domain/Recipe/RecipeCategoryTagSelector.vue"; | ||||||
| import RecipeDialogBulkAdd from "@/components/Domain/Recipe//RecipeDialogBulkAdd.vue"; | import RecipeDialogBulkAdd from "@/components/Domain/Recipe//RecipeDialogBulkAdd.vue"; | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi, useStaticRoutes } from "~/composables/api"; | ||||||
| import { validators } from "~/composables/use-validators"; | import { validators } from "~/composables/use-validators"; | ||||||
| import { useRecipeContext } from "~/composables/use-recipe-context"; | import { useRecipe } from "~/composables/recipes"; | ||||||
| import RecipeActionMenu from "~/components/Domain/Recipe/RecipeActionMenu.vue"; | import RecipeActionMenu from "~/components/Domain/Recipe/RecipeActionMenu.vue"; | ||||||
| import RecipeChips from "~/components/Domain/Recipe/RecipeChips.vue"; | import RecipeChips from "~/components/Domain/Recipe/RecipeChips.vue"; | ||||||
| import RecipeIngredients from "~/components/Domain/Recipe/RecipeIngredients.vue"; | import RecipeIngredients from "~/components/Domain/Recipe/RecipeIngredients.vue"; | ||||||
| @@ -307,8 +308,7 @@ import RecipeIngredientEditor from "~/components/Domain/Recipe/RecipeIngredientE | |||||||
| import RecipeIngredientParserMenu from "~/components/Domain/Recipe/RecipeIngredientParserMenu.vue"; | import RecipeIngredientParserMenu from "~/components/Domain/Recipe/RecipeIngredientParserMenu.vue"; | ||||||
| import RecipePrintView from "~/components/Domain/Recipe/RecipePrintView.vue"; | import RecipePrintView from "~/components/Domain/Recipe/RecipePrintView.vue"; | ||||||
| import { Recipe } from "~/types/api-types/recipe"; | import { Recipe } from "~/types/api-types/recipe"; | ||||||
| import { useStaticRoutes } from "~/composables/api"; | import { uuid4 } from "~/composables/use-utils"; | ||||||
| import { uuid4 } from "~/composables/use-uuid"; |  | ||||||
|  |  | ||||||
| export default defineComponent({ | export default defineComponent({ | ||||||
|   components: { |   components: { | ||||||
| @@ -335,7 +335,7 @@ export default defineComponent({ | |||||||
|     const route = useRoute(); |     const route = useRoute(); | ||||||
|     const router = useRouter(); |     const router = useRouter(); | ||||||
|     const slug = route.value.params.slug; |     const slug = route.value.params.slug; | ||||||
|     const api = useApiSingleton(); |     const api = useUserApi(); | ||||||
|  |  | ||||||
|     const state = reactive({ |     const state = reactive({ | ||||||
|       form: false, |       form: false, | ||||||
| @@ -352,15 +352,13 @@ export default defineComponent({ | |||||||
|       }, |       }, | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     const { getBySlug, loading, fetchRecipe } = useRecipeContext(); |     const { recipe, loading, fetchRecipe } = useRecipe(slug); | ||||||
|  |  | ||||||
|     const { recipeImage } = useStaticRoutes(); |     const { recipeImage } = useStaticRoutes(); | ||||||
|  |  | ||||||
|     // @ts-ignore |     // @ts-ignore | ||||||
|     const { $vuetify } = useContext(); |     const { $vuetify } = useContext(); | ||||||
|  |  | ||||||
|     const recipe = getBySlug(slug); |  | ||||||
|  |  | ||||||
|     // =========================================================================== |     // =========================================================================== | ||||||
|     // Layout Helpers |     // Layout Helpers | ||||||
|  |  | ||||||
| @@ -399,7 +397,7 @@ export default defineComponent({ | |||||||
|     async function closeEditor() { |     async function closeEditor() { | ||||||
|       state.form = false; |       state.form = false; | ||||||
|       state.jsonEditor = false; |       state.jsonEditor = false; | ||||||
|       recipe.value = await fetchRecipe(slug); |       await fetchRecipe(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     function toggleJson() { |     function toggleJson() { | ||||||
|   | |||||||
| @@ -75,10 +75,8 @@ | |||||||
| import { defineComponent, ref, useRoute, useRouter } from "@nuxtjs/composition-api"; | import { defineComponent, ref, useRoute, useRouter } from "@nuxtjs/composition-api"; | ||||||
| import { Food, ParsedIngredient, Parser } from "~/api/class-interfaces/recipes"; | import { Food, ParsedIngredient, Parser } from "~/api/class-interfaces/recipes"; | ||||||
| import RecipeIngredientEditor from "~/components/Domain/Recipe/RecipeIngredientEditor.vue"; | import RecipeIngredientEditor from "~/components/Domain/Recipe/RecipeIngredientEditor.vue"; | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
| import { useRecipeContext } from "~/composables/use-recipe-context"; | import { useRecipe, useFoods, useUnits } from "~/composables/recipes"; | ||||||
| import { useFoods } from "~/composables/use-recipe-foods"; |  | ||||||
| import { useUnits } from "~/composables/use-recipe-units"; |  | ||||||
| import { RecipeIngredientUnit } from "~/types/api-types/recipe"; | import { RecipeIngredientUnit } from "~/types/api-types/recipe"; | ||||||
|  |  | ||||||
| interface Error { | interface Error { | ||||||
| @@ -99,11 +97,9 @@ export default defineComponent({ | |||||||
|     const route = useRoute(); |     const route = useRoute(); | ||||||
|     const router = useRouter(); |     const router = useRouter(); | ||||||
|     const slug = route.value.params.slug; |     const slug = route.value.params.slug; | ||||||
|     const api = useApiSingleton(); |     const api = useUserApi(); | ||||||
|  |  | ||||||
|     const { getBySlug, loading } = useRecipeContext(); |     const { recipe, loading } = useRecipe(slug); | ||||||
|  |  | ||||||
|     const recipe = getBySlug(slug); |  | ||||||
|  |  | ||||||
|     const ingredients = ref<any[]>([]); |     const ingredients = ref<any[]>([]); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -313,7 +313,7 @@ | |||||||
| import { defineComponent, reactive, toRefs, ref, useRouter, useContext } from "@nuxtjs/composition-api"; | import { defineComponent, reactive, toRefs, ref, useRouter, useContext } from "@nuxtjs/composition-api"; | ||||||
| // @ts-ignore No Types for v-jsoneditor | // @ts-ignore No Types for v-jsoneditor | ||||||
| import VJsoneditor from "v-jsoneditor"; | import VJsoneditor from "v-jsoneditor"; | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
| import RecipeCategoryTagSelector from "~/components/Domain/Recipe/RecipeCategoryTagSelector.vue"; | import RecipeCategoryTagSelector from "~/components/Domain/Recipe/RecipeCategoryTagSelector.vue"; | ||||||
| import { validators } from "~/composables/use-validators"; | import { validators } from "~/composables/use-validators"; | ||||||
| import { Recipe } from "~/types/api-types/recipe"; | import { Recipe } from "~/types/api-types/recipe"; | ||||||
| @@ -357,7 +357,7 @@ export default defineComponent({ | |||||||
|       }, |       }, | ||||||
|     ]; |     ]; | ||||||
|  |  | ||||||
|     const api = useApiSingleton(); |     const api = useUserApi(); | ||||||
|     const router = useRouter(); |     const router = useRouter(); | ||||||
|  |  | ||||||
|     function handleResponse(response: any, edit: Boolean = false) { |     function handleResponse(response: any, edit: Boolean = false) { | ||||||
|   | |||||||
| @@ -17,7 +17,7 @@ | |||||||
| import { defineComponent, onMounted, ref } from "@nuxtjs/composition-api"; | import { defineComponent, onMounted, ref } from "@nuxtjs/composition-api"; | ||||||
| import { useThrottleFn } from "@vueuse/core"; | import { useThrottleFn } from "@vueuse/core"; | ||||||
| import RecipeCardSection from "~/components/Domain/Recipe/RecipeCardSection.vue"; | import RecipeCardSection from "~/components/Domain/Recipe/RecipeCardSection.vue"; | ||||||
| import { useLazyRecipes } from "~/composables/use-recipes"; | import { useLazyRecipes } from "~/composables/recipes"; | ||||||
|  |  | ||||||
| export default defineComponent({ | export default defineComponent({ | ||||||
|   components: { RecipeCardSection }, |   components: { RecipeCardSection }, | ||||||
|   | |||||||
| @@ -13,13 +13,13 @@ | |||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| import { defineComponent, useAsync, useRoute } from "@nuxtjs/composition-api"; | import { defineComponent, useAsync, useRoute } from "@nuxtjs/composition-api"; | ||||||
| import RecipeCardSection from "~/components/Domain/Recipe/RecipeCardSection.vue"; | import RecipeCardSection from "~/components/Domain/Recipe/RecipeCardSection.vue"; | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
| import { Recipe } from "~/types/api-types/recipe"; | import { Recipe } from "~/types/api-types/recipe"; | ||||||
|  |  | ||||||
| export default defineComponent({ | export default defineComponent({ | ||||||
|   components: { RecipeCardSection }, |   components: { RecipeCardSection }, | ||||||
|   setup() { |   setup() { | ||||||
|     const api = useApiSingleton(); |     const api = useUserApi(); | ||||||
|     const route = useRoute(); |     const route = useRoute(); | ||||||
|     const slug = route.value.params.slug; |     const slug = route.value.params.slug; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -28,12 +28,12 @@ | |||||||
|    |    | ||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| import { computed, defineComponent, useAsync } from "@nuxtjs/composition-api"; | import { computed, defineComponent, useAsync } from "@nuxtjs/composition-api"; | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
| import { useAsyncKey } from "~/composables/use-utils"; | import { useAsyncKey } from "~/composables/use-utils"; | ||||||
|  |  | ||||||
| export default defineComponent({ | export default defineComponent({ | ||||||
|   setup() { |   setup() { | ||||||
|     const api = useApiSingleton(); |     const api = useUserApi(); | ||||||
|  |  | ||||||
|     const categories = useAsync(async () => { |     const categories = useAsync(async () => { | ||||||
|       const { data } = await api.categories.getAll(); |       const { data } = await api.categories.getAll(); | ||||||
|   | |||||||
| @@ -13,13 +13,13 @@ | |||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| import { defineComponent, useAsync, useRoute } from "@nuxtjs/composition-api"; | import { defineComponent, useAsync, useRoute } from "@nuxtjs/composition-api"; | ||||||
| import RecipeCardSection from "~/components/Domain/Recipe/RecipeCardSection.vue"; | import RecipeCardSection from "~/components/Domain/Recipe/RecipeCardSection.vue"; | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
| import { Recipe } from "~/types/api-types/admin"; | import { Recipe } from "~/types/api-types/admin"; | ||||||
|  |  | ||||||
| export default defineComponent({ | export default defineComponent({ | ||||||
|   components: { RecipeCardSection }, |   components: { RecipeCardSection }, | ||||||
|   setup() { |   setup() { | ||||||
|     const api = useApiSingleton(); |     const api = useUserApi(); | ||||||
|     const route = useRoute(); |     const route = useRoute(); | ||||||
|     const slug = route.value.params.slug; |     const slug = route.value.params.slug; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -28,12 +28,12 @@ | |||||||
|    |    | ||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| import { defineComponent, useAsync, computed } from "@nuxtjs/composition-api"; | import { defineComponent, useAsync, computed } from "@nuxtjs/composition-api"; | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
| import { useAsyncKey } from "~/composables/use-utils"; | import { useAsyncKey } from "~/composables/use-utils"; | ||||||
|  |  | ||||||
| export default defineComponent({ | export default defineComponent({ | ||||||
|   setup() { |   setup() { | ||||||
|     const api = useApiSingleton(); |     const api = useUserApi(); | ||||||
|  |  | ||||||
|     const tags = useAsync(async () => { |     const tags = useAsync(async () => { | ||||||
|       const { data } = await api.tags.getAll(); |       const { data } = await api.tags.getAll(); | ||||||
|   | |||||||
| @@ -101,14 +101,14 @@ | |||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| import { computed, defineComponent, reactive, toRefs, ref, useRouter, watch } from "@nuxtjs/composition-api"; | import { computed, defineComponent, reactive, toRefs, ref, useRouter, watch } from "@nuxtjs/composition-api"; | ||||||
| import { validators } from "@/composables/use-validators"; | import { validators } from "@/composables/use-validators"; | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
| import { alert } from "~/composables/use-toast"; | import { alert } from "~/composables/use-toast"; | ||||||
| import { useRouterQuery } from "@/composables/use-router"; | import { useRouterQuery } from "@/composables/use-router"; | ||||||
|  |  | ||||||
| export default defineComponent({ | export default defineComponent({ | ||||||
|   layout: "basic", |   layout: "basic", | ||||||
|   setup() { |   setup() { | ||||||
|     const api = useApiSingleton(); |     const api = useUserApi(); | ||||||
|     const state = reactive({ |     const state = reactive({ | ||||||
|       joinGroup: false, |       joinGroup: false, | ||||||
|       loggingIn: false, |       loggingIn: false, | ||||||
|   | |||||||
| @@ -68,7 +68,7 @@ | |||||||
|  |  | ||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| import { defineComponent, toRefs, reactive } from "@nuxtjs/composition-api"; | import { defineComponent, toRefs, reactive } from "@nuxtjs/composition-api"; | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
| import { alert } from "~/composables/use-toast"; | import { alert } from "~/composables/use-toast"; | ||||||
| import { validators } from "@/composables/use-validators"; | import { validators } from "@/composables/use-validators"; | ||||||
| import { useRouteQuery } from "~/composables/use-router"; | import { useRouteQuery } from "~/composables/use-router"; | ||||||
| @@ -92,7 +92,7 @@ export default defineComponent({ | |||||||
|  |  | ||||||
|     // =================== |     // =================== | ||||||
|     // API |     // API | ||||||
|     const api = useApiSingleton(); |     const api = useUserApi(); | ||||||
|     async function requestLink() { |     async function requestLink() { | ||||||
|       state.loading = true; |       state.loading = true; | ||||||
|       // TODO: Fix Response to send meaningful error |       // TODO: Fix Response to send meaningful error | ||||||
|   | |||||||
| @@ -70,7 +70,7 @@ import { defineComponent } from "@nuxtjs/composition-api"; | |||||||
| import RecipeSearchFilterSelector from "~/components/Domain/Recipe/RecipeSearchFilterSelector.vue"; | import RecipeSearchFilterSelector from "~/components/Domain/Recipe/RecipeSearchFilterSelector.vue"; | ||||||
| import RecipeCategoryTagSelector from "~/components/Domain/Recipe/RecipeCategoryTagSelector.vue"; | import RecipeCategoryTagSelector from "~/components/Domain/Recipe/RecipeCategoryTagSelector.vue"; | ||||||
| import RecipeCardSection from "~/components/Domain/Recipe/RecipeCardSection.vue"; | import RecipeCardSection from "~/components/Domain/Recipe/RecipeCardSection.vue"; | ||||||
| import { useRecipes, allRecipes } from "~/composables/use-recipes"; | import { useRecipes, allRecipes } from "~/composables/recipes"; | ||||||
|  |  | ||||||
| export default defineComponent({ | export default defineComponent({ | ||||||
|   components: { |   components: { | ||||||
|   | |||||||
| @@ -64,12 +64,12 @@ | |||||||
|      |      | ||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| import { defineComponent, ref, onMounted, useContext } from "@nuxtjs/composition-api"; | import { defineComponent, ref, onMounted, useContext } from "@nuxtjs/composition-api"; | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
| import { UserOut } from "~/types/api-types/user"; | import { UserOut } from "~/types/api-types/user"; | ||||||
|  |  | ||||||
| export default defineComponent({ | export default defineComponent({ | ||||||
|   setup() { |   setup() { | ||||||
|     const api = useApiSingleton(); |     const api = useUserApi(); | ||||||
|  |  | ||||||
|     const { i18n } = useContext(); |     const { i18n } = useContext(); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -96,8 +96,8 @@ | |||||||
| import { defineComponent, reactive, ref, useContext } from "@nuxtjs/composition-api"; | import { defineComponent, reactive, ref, useContext } from "@nuxtjs/composition-api"; | ||||||
| import RecipeDataTable from "~/components/Domain/Recipe/RecipeDataTable.vue"; | import RecipeDataTable from "~/components/Domain/Recipe/RecipeDataTable.vue"; | ||||||
| import RecipeCategoryTagSelector from "~/components/Domain/Recipe/RecipeCategoryTagSelector.vue"; | import RecipeCategoryTagSelector from "~/components/Domain/Recipe/RecipeCategoryTagSelector.vue"; | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
| import { useRecipes, allRecipes } from "~/composables/use-recipes"; | import { useRecipes, allRecipes } from "~/composables/recipes"; | ||||||
| import { Recipe } from "~/types/api-types/recipe"; | import { Recipe } from "~/types/api-types/recipe"; | ||||||
|  |  | ||||||
| const MODES = { | const MODES = { | ||||||
| @@ -169,7 +169,7 @@ export default defineComponent({ | |||||||
|       }, |       }, | ||||||
|     ]; |     ]; | ||||||
|  |  | ||||||
|     const api = useApiSingleton(); |     const api = useUserApi(); | ||||||
|  |  | ||||||
|     function exportSelected() { |     function exportSelected() { | ||||||
|       console.log("Export Selected"); |       console.log("Export Selected"); | ||||||
|   | |||||||
| @@ -65,7 +65,7 @@ | |||||||
|      |      | ||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| import { computed, defineComponent, useContext, ref } from "@nuxtjs/composition-api"; | import { computed, defineComponent, useContext, ref } from "@nuxtjs/composition-api"; | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
|  |  | ||||||
| export default defineComponent({ | export default defineComponent({ | ||||||
|   setup() { |   setup() { | ||||||
| @@ -75,7 +75,7 @@ export default defineComponent({ | |||||||
|       return nuxtContext.$auth.user; |       return nuxtContext.$auth.user; | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     const api = useApiSingleton(); |     const api = useUserApi(); | ||||||
|  |  | ||||||
|     const domNewTokenForm = ref<VForm | null>(null); |     const domNewTokenForm = ref<VForm | null>(null); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -104,7 +104,7 @@ | |||||||
|      |      | ||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| import { ref, reactive, defineComponent, computed, useContext, watch } from "@nuxtjs/composition-api"; | import { ref, reactive, defineComponent, computed, useContext, watch } from "@nuxtjs/composition-api"; | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
|  |  | ||||||
| export default defineComponent({ | export default defineComponent({ | ||||||
|   setup() { |   setup() { | ||||||
| @@ -117,7 +117,7 @@ export default defineComponent({ | |||||||
|  |  | ||||||
|     const userCopy = ref({ ...user.value }); |     const userCopy = ref({ ...user.value }); | ||||||
|  |  | ||||||
|     const api = useApiSingleton(); |     const api = useUserApi(); | ||||||
|  |  | ||||||
|     const domUpdatePassword = ref<VForm | null>(null); |     const domUpdatePassword = ref<VForm | null>(null); | ||||||
|     const password = reactive({ |     const password = reactive({ | ||||||
|   | |||||||
| @@ -125,7 +125,7 @@ | |||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| import { computed, defineComponent, useContext, ref, toRefs, reactive } from "@nuxtjs/composition-api"; | import { computed, defineComponent, useContext, ref, toRefs, reactive } from "@nuxtjs/composition-api"; | ||||||
| import UserProfileLinkCard from "@/components/Domain/User/UserProfileLinkCard.vue"; | import UserProfileLinkCard from "@/components/Domain/User/UserProfileLinkCard.vue"; | ||||||
| import { useApiSingleton } from "~/composables/use-api"; | import { useUserApi } from "~/composables/api"; | ||||||
| import { validators } from "~/composables/use-validators"; | import { validators } from "~/composables/use-validators"; | ||||||
| import { alert } from "~/composables/use-toast"; | import { alert } from "~/composables/use-toast"; | ||||||
|  |  | ||||||
| @@ -141,7 +141,7 @@ export default defineComponent({ | |||||||
|  |  | ||||||
|     const generatedLink = ref(""); |     const generatedLink = ref(""); | ||||||
|     const token = ref(""); |     const token = ref(""); | ||||||
|     const api = useApiSingleton(); |     const api = useUserApi(); | ||||||
|     async function getSignupLink() { |     async function getSignupLink() { | ||||||
|       const { data } = await api.groups.createInvitation({ uses: 1 }); |       const { data } = await api.groups.createInvitation({ uses: 1 }); | ||||||
|       if (data) { |       if (data) { | ||||||
|   | |||||||
| @@ -91,6 +91,7 @@ export interface RecipeIngredient { | |||||||
| export interface RecipeIngredientUnit { | export interface RecipeIngredientUnit { | ||||||
|   name?: string; |   name?: string; | ||||||
|   description?: string; |   description?: string; | ||||||
|  |   fraction?: boolean; | ||||||
| } | } | ||||||
| export interface RecipeIngredientFood { | export interface RecipeIngredientFood { | ||||||
|   name?: string; |   name?: string; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user