mirror of
				https://github.com/mealie-recipes/mealie.git
				synced 2025-11-03 18:53:17 -05:00 
			
		
		
		
	feature/new-feature-cleanup (#389)
* add json editor to theme editor * add toolbars tools to recipe sections * fix recipe yield * add updated_date to recipe schema * update time cards * fix mobile buttons * fix asset URL * fix PG errors CRUD * remove -d from docker-pro * fix theme tests * remvoe old typing * abstract count function Co-authored-by: hay-kot <hay-kot@pm.me>
This commit is contained in:
		@@ -21,7 +21,7 @@
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import { api } from "@/api";
 | 
			
		||||
import utils from "@/utils";
 | 
			
		||||
import { utils } from "@/utils";
 | 
			
		||||
import MealPlanCard from "./MealPlanCard";
 | 
			
		||||
export default {
 | 
			
		||||
  components: {
 | 
			
		||||
 
 | 
			
		||||
@@ -82,7 +82,7 @@
 | 
			
		||||
const CREATE_EVENT = "created";
 | 
			
		||||
import DatePicker from "@/components/FormHelpers/DatePicker";
 | 
			
		||||
import { api } from "@/api";
 | 
			
		||||
import utils from "@/utils";
 | 
			
		||||
import { utils } from "@/utils";
 | 
			
		||||
import MealPlanCard from "./MealPlanCard";
 | 
			
		||||
export default {
 | 
			
		||||
  components: {
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
        <v-list-item-title class=" mb-1">{{ name }} </v-list-item-title>
 | 
			
		||||
        <v-list-item-subtitle> {{ description }} </v-list-item-subtitle>
 | 
			
		||||
        <div class="d-flex justify-center align-center">
 | 
			
		||||
          <RecipeChips :items="tags" :title="false" :limit="1" :small="true" :isCategory="false" />
 | 
			
		||||
          <RecipeChips :truncate="true" :items="tags" :title="false" :limit="1" :small="true" :isCategory="false" />
 | 
			
		||||
          <v-rating
 | 
			
		||||
            color="secondary"
 | 
			
		||||
            class="ml-auto"
 | 
			
		||||
 
 | 
			
		||||
@@ -56,7 +56,7 @@
 | 
			
		||||
import BulkAdd from "@/components/Recipe/Parts/Helpers/BulkAdd";
 | 
			
		||||
import VueMarkdown from "@adapttive/vue-markdown";
 | 
			
		||||
import draggable from "vuedraggable";
 | 
			
		||||
import utils from "@/utils";
 | 
			
		||||
import { utils } from "@/utils";
 | 
			
		||||
export default {
 | 
			
		||||
  components: {
 | 
			
		||||
    BulkAdd,
 | 
			
		||||
 
 | 
			
		||||
@@ -66,7 +66,7 @@
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import VueMarkdown from "@adapttive/vue-markdown";
 | 
			
		||||
import utils from "@/utils";
 | 
			
		||||
import { utils } from "@/utils";
 | 
			
		||||
export default {
 | 
			
		||||
  components: {
 | 
			
		||||
    VueMarkdown,
 | 
			
		||||
 
 | 
			
		||||
@@ -35,7 +35,7 @@
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import VueMarkdown from "@adapttive/vue-markdown";
 | 
			
		||||
import utils from "@/utils";
 | 
			
		||||
import { utils } from "@/utils";
 | 
			
		||||
export default {
 | 
			
		||||
  components: {
 | 
			
		||||
    VueMarkdown,
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,7 @@
 | 
			
		||||
      <v-card-actions>
 | 
			
		||||
        <Rating :value="rating" :name="name" :slug="slug" :small="true" />
 | 
			
		||||
        <v-spacer></v-spacer>
 | 
			
		||||
        <RecipeChips :items="tags" :title="false" :limit="2" :small="true" :isCategory="false" />
 | 
			
		||||
        <RecipeChips :truncate="true" :items="tags" :title="false" :limit="2" :small="true" :isCategory="false" />
 | 
			
		||||
        <ContextMenu :slug="slug" />
 | 
			
		||||
      </v-card-actions>
 | 
			
		||||
    </v-card>
 | 
			
		||||
 
 | 
			
		||||
@@ -124,7 +124,7 @@
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import utils from "@/utils";
 | 
			
		||||
import { utils } from "@/utils";
 | 
			
		||||
import { api } from "@/api";
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,29 +1,13 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <v-card
 | 
			
		||||
    color="accent"
 | 
			
		||||
    class="custom-transparent d-flex justify-start align-center text-center time-card-flex"
 | 
			
		||||
    tile
 | 
			
		||||
    v-if="showCards"
 | 
			
		||||
  >
 | 
			
		||||
    <v-card flat color="rgb(255, 0, 0, 0.0)">
 | 
			
		||||
      <v-icon large color="white" class="mx-2"> mdi-clock-outline </v-icon>
 | 
			
		||||
    </v-card>
 | 
			
		||||
 | 
			
		||||
    <v-card
 | 
			
		||||
      v-for="(time, index) in allTimes"
 | 
			
		||||
      :key="index"
 | 
			
		||||
      class="d-flex justify-start align-center text-center time-card-flex"
 | 
			
		||||
      flat
 | 
			
		||||
      color="rgb(255, 0, 0, 0.0)"
 | 
			
		||||
    >
 | 
			
		||||
      <v-card-text class="caption white--text py-2">
 | 
			
		||||
        <div>
 | 
			
		||||
          <strong> {{ time.name }} </strong>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div>{{ time.value }}</div>
 | 
			
		||||
      </v-card-text>
 | 
			
		||||
    </v-card>
 | 
			
		||||
  </v-card>
 | 
			
		||||
  <div>
 | 
			
		||||
    <v-chip label color="accent custom-transparent" class="ma-1" v-for="(time, index) in allTimes" :key="index">
 | 
			
		||||
      <v-icon left>
 | 
			
		||||
        mdi-clock-outline
 | 
			
		||||
      </v-icon>
 | 
			
		||||
      {{ time.name }} |
 | 
			
		||||
      {{ time.value }}
 | 
			
		||||
    </v-chip>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@
 | 
			
		||||
      :to="`/recipes/${urlParam}/${getSlug(category)}`"
 | 
			
		||||
      :key="category"
 | 
			
		||||
    >
 | 
			
		||||
      {{ category }}
 | 
			
		||||
      {{ truncateText(category) }}
 | 
			
		||||
    </v-chip>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
@@ -19,6 +19,9 @@
 | 
			
		||||
<script>
 | 
			
		||||
export default {
 | 
			
		||||
  props: {
 | 
			
		||||
    truncate: {
 | 
			
		||||
      default: false,
 | 
			
		||||
    },
 | 
			
		||||
    items: {
 | 
			
		||||
      default: [],
 | 
			
		||||
    },
 | 
			
		||||
@@ -34,6 +37,7 @@ export default {
 | 
			
		||||
    small: {
 | 
			
		||||
      default: false,
 | 
			
		||||
    },
 | 
			
		||||
    maxWidth: {},
 | 
			
		||||
  },
 | 
			
		||||
  computed: {
 | 
			
		||||
    allCategories() {
 | 
			
		||||
@@ -58,6 +62,14 @@ export default {
 | 
			
		||||
        if (matches.length > 0) return matches[0].slug;
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    truncateText(text, length = 20, clamp) {
 | 
			
		||||
      if (!this.truncate) return text;
 | 
			
		||||
      clamp = clamp || "...";
 | 
			
		||||
      var node = document.createElement("div");
 | 
			
		||||
      node.innerHTML = text;
 | 
			
		||||
      var content = node.textContent;
 | 
			
		||||
      return content.length > length ? content.slice(0, length) + clamp : content;
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
      <v-row dense disabled>
 | 
			
		||||
        <v-col>
 | 
			
		||||
          <v-btn
 | 
			
		||||
            v-if="recipe.yields"
 | 
			
		||||
            v-if="recipe.recipeYield"
 | 
			
		||||
            dense
 | 
			
		||||
            small
 | 
			
		||||
            :hover="false"
 | 
			
		||||
@@ -18,7 +18,7 @@
 | 
			
		||||
            color="secondary darken-1"
 | 
			
		||||
            class="rounded-sm static"
 | 
			
		||||
          >
 | 
			
		||||
            {{ recipe.yields }}
 | 
			
		||||
            {{ recipe.recipeYield }}
 | 
			
		||||
          </v-btn>
 | 
			
		||||
        </v-col>
 | 
			
		||||
        <Rating :value="recipe.rating" :name="recipe.name" :slug="recipe.slug" />
 | 
			
		||||
@@ -88,7 +88,7 @@
 | 
			
		||||
<script>
 | 
			
		||||
import Nutrition from "@/components/Recipe/Parts/Nutrition";
 | 
			
		||||
import VueMarkdown from "@adapttive/vue-markdown";
 | 
			
		||||
import utils from "@/utils";
 | 
			
		||||
import { utils } from "@/utils";
 | 
			
		||||
import RecipeChips from "./RecipeChips";
 | 
			
		||||
import Rating from "@/components/Recipe/Parts/Rating";
 | 
			
		||||
import Notes from "@/components/Recipe/Parts/Notes";
 | 
			
		||||
 
 | 
			
		||||
@@ -6,21 +6,28 @@
 | 
			
		||||
      </v-icon>
 | 
			
		||||
      <v-toolbar-title class="headline"> {{ title }} </v-toolbar-title>
 | 
			
		||||
      <v-spacer></v-spacer>
 | 
			
		||||
      <v-menu offset-y v-if="$listeners.sortRecent || $listeners.sort">
 | 
			
		||||
      <v-btn text @click="navigateRandom">
 | 
			
		||||
        Random
 | 
			
		||||
      </v-btn>
 | 
			
		||||
      <v-menu offset-y v-if="$listeners.sort">
 | 
			
		||||
        <template v-slot:activator="{ on, attrs }">
 | 
			
		||||
          <v-btn-toggle group>
 | 
			
		||||
            <v-btn text v-bind="attrs" v-on="on">
 | 
			
		||||
              {{ $t("general.sort") }}
 | 
			
		||||
            </v-btn>
 | 
			
		||||
          </v-btn-toggle>
 | 
			
		||||
          <v-btn text v-bind="attrs" v-on="on">
 | 
			
		||||
            {{ $t("general.sort") }}
 | 
			
		||||
          </v-btn>
 | 
			
		||||
        </template>
 | 
			
		||||
        <v-list>
 | 
			
		||||
          <v-list-item @click="$emit('sortRecent')">
 | 
			
		||||
            <v-list-item-title>{{ $t("general.recent") }}</v-list-item-title>
 | 
			
		||||
          </v-list-item>
 | 
			
		||||
          <v-list-item @click="$emit('sort')">
 | 
			
		||||
          <v-list-item @click="sortRecipes(EVENTS.az)">
 | 
			
		||||
            <v-list-item-title>{{ $t("general.sort-alphabetically") }}</v-list-item-title>
 | 
			
		||||
          </v-list-item>
 | 
			
		||||
          <v-list-item @click="sortRecipes(EVENTS.rating)">
 | 
			
		||||
            <v-list-item-title>{{ $t("general.rating") }}</v-list-item-title>
 | 
			
		||||
          </v-list-item>
 | 
			
		||||
          <v-list-item @click="sortRecipes(EVENTS.updated)">
 | 
			
		||||
            <v-list-item-title>{{ $t("general.updated") }}</v-list-item-title>
 | 
			
		||||
          </v-list-item>
 | 
			
		||||
          <v-list-item @click="sortRecipes(EVENTS.created)">
 | 
			
		||||
            <v-list-item-title>{{ $t("general.created") }}</v-list-item-title>
 | 
			
		||||
          </v-list-item>
 | 
			
		||||
        </v-list>
 | 
			
		||||
      </v-menu>
 | 
			
		||||
    </v-app-bar>
 | 
			
		||||
@@ -76,6 +83,9 @@
 | 
			
		||||
<script>
 | 
			
		||||
import RecipeCard from "../Recipe/RecipeCard";
 | 
			
		||||
import MobileRecipeCard from "@/components/Recipe/MobileRecipeCard";
 | 
			
		||||
import { utils } from "@/utils";
 | 
			
		||||
const SORT_EVENT = "sort";
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  components: {
 | 
			
		||||
    RecipeCard,
 | 
			
		||||
@@ -106,6 +116,12 @@ export default {
 | 
			
		||||
    return {
 | 
			
		||||
      cardLimit: 30,
 | 
			
		||||
      loading: false,
 | 
			
		||||
      EVENTS: {
 | 
			
		||||
        az: "az",
 | 
			
		||||
        rating: "rating",
 | 
			
		||||
        created: "created",
 | 
			
		||||
        updated: "updated",
 | 
			
		||||
      },
 | 
			
		||||
    };
 | 
			
		||||
  },
 | 
			
		||||
  watch: {
 | 
			
		||||
@@ -144,6 +160,31 @@ export default {
 | 
			
		||||
      await new Promise(r => setTimeout(r, 1000));
 | 
			
		||||
      this.loading = false;
 | 
			
		||||
    },
 | 
			
		||||
    navigateRandom() {
 | 
			
		||||
      const recipe = utils.recipe.randomRecipe(this.recipes);
 | 
			
		||||
      this.$router.push(`/recipe/${recipe.slug}`);
 | 
			
		||||
    },
 | 
			
		||||
    sortRecipes(sortType) {
 | 
			
		||||
      let sortTarget = [...this.recipes];
 | 
			
		||||
      switch (sortType) {
 | 
			
		||||
        case this.EVENTS.az:
 | 
			
		||||
          utils.recipe.sortAToZ(sortTarget);
 | 
			
		||||
          break;
 | 
			
		||||
        case this.EVENTS.rating:
 | 
			
		||||
          utils.recipe.sortByRating(sortTarget);
 | 
			
		||||
          break;
 | 
			
		||||
        case this.EVENTS.created:
 | 
			
		||||
          utils.recipe.sortByCreated(sortTarget);
 | 
			
		||||
          break;
 | 
			
		||||
        case this.EVENTS.updated:
 | 
			
		||||
          utils.recipe.sortByUpdated(sortTarget);
 | 
			
		||||
          break;
 | 
			
		||||
        default:
 | 
			
		||||
          console.log("Unknown Event", sortType);
 | 
			
		||||
          return;
 | 
			
		||||
      }
 | 
			
		||||
      this.$emit(SORT_EVENT, sortTarget);
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user