1
0
Fork 0
mirror of https://github.com/mealie-recipes/mealie.git synced 2025-08-02 20:15:24 +02: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:
Hayden 2021-11-06 11:28:47 -08:00 committed by GitHub
parent 095d3bda3f
commit 788e176b16
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
68 changed files with 330 additions and 245 deletions

View file

@ -42,7 +42,7 @@
<script lang="ts">
import { defineComponent, onMounted, ref } from "@nuxtjs/composition-api";
import { ServerTask } from "~/api/types/server-task";
import { useAdminApi } from "~/composables/use-api";
import { useAdminApi } from "~/composables/api";
export default defineComponent({
layout: "admin",

View file

@ -92,14 +92,14 @@
<script lang="ts">
import { defineComponent, useAsync } from "@nuxtjs/composition-api";
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";
export default defineComponent({
components: { AdminEventViewer },
layout: "admin",
setup() {
const api = useApiSingleton();
const api = useUserApi();
const adminApi = useAdminApi();

View file

@ -72,14 +72,14 @@
<script lang="ts">
import { defineComponent, ref } from "@nuxtjs/composition-api";
import { fieldTypes } from "~/composables/forms";
import { useApiSingleton } from "~/composables/use-api";
import { useUserApi } from "~/composables/api";
import { useGroups } from "~/composables/use-groups";
import { useUser, useAllUsers } from "~/composables/use-user";
export default defineComponent({
layout: "admin",
setup() {
const api = useApiSingleton();
const api = useUserApi();
const refUserDialog = ref();
const { groups } = useGroups();

View file

@ -69,12 +69,12 @@
<script lang="ts">
import { defineComponent, reactive, ref, toRefs } from "@nuxtjs/composition-api";
import { Confidence, Parser } from "~/api/class-interfaces/recipes";
import { useApiSingleton } from "~/composables/use-api";
import { useUserApi } from "~/composables/api";
export default defineComponent({
layout: "admin",
setup() {
const api = useApiSingleton();
const api = useUserApi();
const state = reactive({
loading: false,

View file

@ -102,7 +102,7 @@ import {
useContext,
} from "@nuxtjs/composition-api";
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 { useAsyncKey } from "~/composables/use-utils";
@ -130,7 +130,7 @@ export default defineComponent({
isSiteSecure: false,
});
const api = useApiSingleton();
const api = useUserApi();
const adminApi = useAdminApi();
onMounted(async () => {

View file

@ -65,7 +65,7 @@
<script lang="ts">
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";
export default defineComponent({
layout: "admin",

View file

@ -66,7 +66,7 @@
<script lang="ts">
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";
export default defineComponent({
layout: "admin",

View file

@ -35,7 +35,7 @@
<script lang="ts">
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";
export default defineComponent({
layout: "basic",
@ -47,7 +47,7 @@ export default defineComponent({
error: false,
});
const api = useApiSingleton();
const api = useUserApi();
async function requestLink() {
state.loading = true;

View file

@ -11,7 +11,7 @@
<script lang="ts">
import { defineComponent } from "@nuxtjs/composition-api";
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";
export default defineComponent({

View file

@ -152,7 +152,7 @@ import { isSameDay, addDays, subDays, parseISO, format } from "date-fns";
import { SortableEvent } from "sortablejs"; // eslint-disable-line
import draggable from "vuedraggable";
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";
export default defineComponent({

View file

@ -8,12 +8,30 @@
<v-card-title>
<h1 class="headline">{{ recipe.name }}</h1>
</v-card-title>
<v-stepper v-model="activeStep" flat>
<v-toolbar class="ma-1 elevation-2 rounded">
<v-toolbar-title class="headline">
Step {{ activeStep }} of {{ recipe.recipeInstructions.length }}</v-toolbar-title
>
</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>
<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">
@ -21,11 +39,17 @@
<v-card-text>
<h2 class="mb-4">{{ $t("recipe.instructions") }}</h2>
<VueMarkdown :source="step.text"> </VueMarkdown>
<v-divider></v-divider>
<h2 class="mb-4 mt-4">{{ $t("recipe.ingredients") }}</h2>
<div v-for="ing in step.ingredientReferences" :key="ing.referenceId">
{{ getIngredientByRefId(ing.referenceId).note }}
</div>
<template v-if="step.ingredientReferences.length > 0">
<v-divider></v-divider>
<div>
<h2 class="mb-4 mt-4">{{ $t("recipe.ingredients") }}</h2>
<div
v-for="ing in step.ingredientReferences"
:key="ing.referenceId"
v-html="getIngredientByRefId(ing.referenceId)"
></div>
</div>
</template>
</v-card-text>
</v-card>
<v-card-actions class="justify-center">
@ -33,6 +57,7 @@
<template #icon> {{ $globals.icons.arrowLeftBold }}</template>
Back
</BaseButton>
<BaseButton
icon-right
:disabled="index + 1 == recipe.recipeInstructions.length"
@ -55,25 +80,35 @@ import { defineComponent, useRoute, ref } from "@nuxtjs/composition-api";
// @ts-ignore
import VueMarkdown from "@adapttive/vue-markdown";
import { useStaticRoutes } from "~/composables/api";
import { useRecipeContext } from "~/composables/use-recipe-context";
import { parseIngredientText, useRecipe } from "~/composables/recipes";
export default defineComponent({
components: { VueMarkdown },
setup() {
const route = useRoute();
const slug = route.value.params.slug;
const activeStep = ref(1);
const scale = ref(1);
const { getBySlug } = useRecipeContext();
const { recipe } = useRecipe(slug);
const { recipeImage } = useStaticRoutes();
const recipe = getBySlug(slug);
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 {
scale,
getIngredientByRefId,
activeStep,
slug,

View file

@ -233,6 +233,7 @@
<RecipeInstructions
v-model="recipe.recipeInstructions"
:ingredients="recipe.recipeIngredient"
:disable-amount="recipe.settings.disableAmount"
:edit="form"
/>
<div v-if="form" class="d-flex">
@ -289,9 +290,9 @@ import VueMarkdown from "@adapttive/vue-markdown";
import draggable from "vuedraggable";
import RecipeCategoryTagSelector from "@/components/Domain/Recipe/RecipeCategoryTagSelector.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 { useRecipeContext } from "~/composables/use-recipe-context";
import { useRecipe } from "~/composables/recipes";
import RecipeActionMenu from "~/components/Domain/Recipe/RecipeActionMenu.vue";
import RecipeChips from "~/components/Domain/Recipe/RecipeChips.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 RecipePrintView from "~/components/Domain/Recipe/RecipePrintView.vue";
import { Recipe } from "~/types/api-types/recipe";
import { useStaticRoutes } from "~/composables/api";
import { uuid4 } from "~/composables/use-uuid";
import { uuid4 } from "~/composables/use-utils";
export default defineComponent({
components: {
@ -335,7 +335,7 @@ export default defineComponent({
const route = useRoute();
const router = useRouter();
const slug = route.value.params.slug;
const api = useApiSingleton();
const api = useUserApi();
const state = reactive({
form: false,
@ -352,15 +352,13 @@ export default defineComponent({
},
});
const { getBySlug, loading, fetchRecipe } = useRecipeContext();
const { recipe, loading, fetchRecipe } = useRecipe(slug);
const { recipeImage } = useStaticRoutes();
// @ts-ignore
const { $vuetify } = useContext();
const recipe = getBySlug(slug);
// ===========================================================================
// Layout Helpers
@ -399,7 +397,7 @@ export default defineComponent({
async function closeEditor() {
state.form = false;
state.jsonEditor = false;
recipe.value = await fetchRecipe(slug);
await fetchRecipe();
}
function toggleJson() {

View file

@ -75,10 +75,8 @@
import { defineComponent, ref, useRoute, useRouter } from "@nuxtjs/composition-api";
import { Food, ParsedIngredient, Parser } from "~/api/class-interfaces/recipes";
import RecipeIngredientEditor from "~/components/Domain/Recipe/RecipeIngredientEditor.vue";
import { useApiSingleton } from "~/composables/use-api";
import { useRecipeContext } from "~/composables/use-recipe-context";
import { useFoods } from "~/composables/use-recipe-foods";
import { useUnits } from "~/composables/use-recipe-units";
import { useUserApi } from "~/composables/api";
import { useRecipe, useFoods, useUnits } from "~/composables/recipes";
import { RecipeIngredientUnit } from "~/types/api-types/recipe";
interface Error {
@ -99,11 +97,9 @@ export default defineComponent({
const route = useRoute();
const router = useRouter();
const slug = route.value.params.slug;
const api = useApiSingleton();
const api = useUserApi();
const { getBySlug, loading } = useRecipeContext();
const recipe = getBySlug(slug);
const { recipe, loading } = useRecipe(slug);
const ingredients = ref<any[]>([]);

View file

@ -313,7 +313,7 @@
import { defineComponent, reactive, toRefs, ref, useRouter, useContext } from "@nuxtjs/composition-api";
// @ts-ignore No Types for 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 { validators } from "~/composables/use-validators";
import { Recipe } from "~/types/api-types/recipe";
@ -357,7 +357,7 @@ export default defineComponent({
},
];
const api = useApiSingleton();
const api = useUserApi();
const router = useRouter();
function handleResponse(response: any, edit: Boolean = false) {

View file

@ -17,7 +17,7 @@
import { defineComponent, onMounted, ref } from "@nuxtjs/composition-api";
import { useThrottleFn } from "@vueuse/core";
import RecipeCardSection from "~/components/Domain/Recipe/RecipeCardSection.vue";
import { useLazyRecipes } from "~/composables/use-recipes";
import { useLazyRecipes } from "~/composables/recipes";
export default defineComponent({
components: { RecipeCardSection },

View file

@ -13,13 +13,13 @@
<script lang="ts">
import { defineComponent, useAsync, useRoute } from "@nuxtjs/composition-api";
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";
export default defineComponent({
components: { RecipeCardSection },
setup() {
const api = useApiSingleton();
const api = useUserApi();
const route = useRoute();
const slug = route.value.params.slug;

View file

@ -28,12 +28,12 @@
<script lang="ts">
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";
export default defineComponent({
setup() {
const api = useApiSingleton();
const api = useUserApi();
const categories = useAsync(async () => {
const { data } = await api.categories.getAll();

View file

@ -13,13 +13,13 @@
<script lang="ts">
import { defineComponent, useAsync, useRoute } from "@nuxtjs/composition-api";
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";
export default defineComponent({
components: { RecipeCardSection },
setup() {
const api = useApiSingleton();
const api = useUserApi();
const route = useRoute();
const slug = route.value.params.slug;

View file

@ -28,12 +28,12 @@
<script lang="ts">
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";
export default defineComponent({
setup() {
const api = useApiSingleton();
const api = useUserApi();
const tags = useAsync(async () => {
const { data } = await api.tags.getAll();

View file

@ -101,14 +101,14 @@
<script lang="ts">
import { computed, defineComponent, reactive, toRefs, ref, useRouter, watch } from "@nuxtjs/composition-api";
import { validators } from "@/composables/use-validators";
import { useApiSingleton } from "~/composables/use-api";
import { useUserApi } from "~/composables/api";
import { alert } from "~/composables/use-toast";
import { useRouterQuery } from "@/composables/use-router";
export default defineComponent({
layout: "basic",
setup() {
const api = useApiSingleton();
const api = useUserApi();
const state = reactive({
joinGroup: false,
loggingIn: false,

View file

@ -68,7 +68,7 @@
<script lang="ts">
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 { validators } from "@/composables/use-validators";
import { useRouteQuery } from "~/composables/use-router";
@ -92,7 +92,7 @@ export default defineComponent({
// ===================
// API
const api = useApiSingleton();
const api = useUserApi();
async function requestLink() {
state.loading = true;
// TODO: Fix Response to send meaningful error

View file

@ -70,7 +70,7 @@ import { defineComponent } from "@nuxtjs/composition-api";
import RecipeSearchFilterSelector from "~/components/Domain/Recipe/RecipeSearchFilterSelector.vue";
import RecipeCategoryTagSelector from "~/components/Domain/Recipe/RecipeCategoryTagSelector.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({
components: {

View file

@ -64,12 +64,12 @@
<script lang="ts">
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";
export default defineComponent({
setup() {
const api = useApiSingleton();
const api = useUserApi();
const { i18n } = useContext();

View file

@ -96,8 +96,8 @@
import { defineComponent, reactive, ref, useContext } from "@nuxtjs/composition-api";
import RecipeDataTable from "~/components/Domain/Recipe/RecipeDataTable.vue";
import RecipeCategoryTagSelector from "~/components/Domain/Recipe/RecipeCategoryTagSelector.vue";
import { useApiSingleton } from "~/composables/use-api";
import { useRecipes, allRecipes } from "~/composables/use-recipes";
import { useUserApi } from "~/composables/api";
import { useRecipes, allRecipes } from "~/composables/recipes";
import { Recipe } from "~/types/api-types/recipe";
const MODES = {
@ -169,7 +169,7 @@ export default defineComponent({
},
];
const api = useApiSingleton();
const api = useUserApi();
function exportSelected() {
console.log("Export Selected");

View file

@ -65,7 +65,7 @@
<script lang="ts">
import { computed, defineComponent, useContext, ref } from "@nuxtjs/composition-api";
import { useApiSingleton } from "~/composables/use-api";
import { useUserApi } from "~/composables/api";
export default defineComponent({
setup() {
@ -75,7 +75,7 @@ export default defineComponent({
return nuxtContext.$auth.user;
});
const api = useApiSingleton();
const api = useUserApi();
const domNewTokenForm = ref<VForm | null>(null);

View file

@ -104,7 +104,7 @@
<script lang="ts">
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({
setup() {
@ -117,7 +117,7 @@ export default defineComponent({
const userCopy = ref({ ...user.value });
const api = useApiSingleton();
const api = useUserApi();
const domUpdatePassword = ref<VForm | null>(null);
const password = reactive({

View file

@ -125,7 +125,7 @@
<script lang="ts">
import { computed, defineComponent, useContext, ref, toRefs, reactive } from "@nuxtjs/composition-api";
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 { alert } from "~/composables/use-toast";
@ -141,7 +141,7 @@ export default defineComponent({
const generatedLink = ref("");
const token = ref("");
const api = useApiSingleton();
const api = useUserApi();
async function getSignupLink() {
const { data } = await api.groups.createInvitation({ uses: 1 });
if (data) {