mirror of
https://github.com/hay-kot/mealie.git
synced 2025-08-14 18:57:44 -07:00
feature/mobile-layout (#431)
* lazy load cards * shopping list recipe search bug * admin layout fluid * site loader * username support * mobile tabs * set username at signup * update user tests * patch bug on shopping list * public mealplan links * support link (I'm a monster) * icon only on mobile * padding Co-authored-by: hay-kot <hay-kot@pm.me>
This commit is contained in:
parent
8f8127a5fc
commit
822663905d
33 changed files with 273 additions and 119 deletions
|
@ -9,6 +9,7 @@ const mealPlanURLs = {
|
|||
all: `${prefix}all`,
|
||||
create: `${prefix}create`,
|
||||
thisWeek: `${prefix}this-week`,
|
||||
byId: planID => `${prefix}${planID}`,
|
||||
update: planID => `${prefix}${planID}`,
|
||||
delete: planID => `${prefix}${planID}`,
|
||||
today: `${prefix}today`,
|
||||
|
@ -40,6 +41,11 @@ export const mealplanAPI = {
|
|||
return response;
|
||||
},
|
||||
|
||||
async getById(id) {
|
||||
let response = await apiReq.get(mealPlanURLs.byId(id));
|
||||
return response.data;
|
||||
},
|
||||
|
||||
delete(id) {
|
||||
return apiReq.delete(
|
||||
mealPlanURLs.delete(id),
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
</div>
|
||||
</v-row>
|
||||
</v-card-text>
|
||||
<v-tabs v-model="tab">
|
||||
<v-tabs v-model="tab" show-arrows="">
|
||||
<v-tab>{{ $t("general.recipes") }}</v-tab>
|
||||
<v-tab>{{ $t("general.themes") }}</v-tab>
|
||||
<v-tab>{{ $t("general.settings") }}</v-tab>
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
v-model="user.email"
|
||||
prepend-icon="mdi-email"
|
||||
validate-on-blur
|
||||
:label="$t('user.email')"
|
||||
:label="`${$t('user.email')} or ${$t('user.username')} `"
|
||||
type="email"
|
||||
></v-text-field>
|
||||
<v-text-field
|
||||
|
|
|
@ -21,8 +21,15 @@
|
|||
:prepend-icon="$globals.icons.user"
|
||||
validate-on-blur
|
||||
:rules="[existsRule]"
|
||||
:label="$t('signup.display-name')"
|
||||
type="email"
|
||||
:label="$t('user.full-name')"
|
||||
></v-text-field>
|
||||
<v-text-field
|
||||
v-model="user.username"
|
||||
light="light"
|
||||
:prepend-icon="$globals.icons.user"
|
||||
validate-on-blur
|
||||
:rules="[existsRule]"
|
||||
:label="$t('user.username')"
|
||||
></v-text-field>
|
||||
<v-text-field
|
||||
v-model="user.email"
|
||||
|
@ -111,6 +118,7 @@ export default {
|
|||
|
||||
const userData = {
|
||||
fullName: this.user.name,
|
||||
username: this.user.username,
|
||||
email: this.user.email,
|
||||
group: "default",
|
||||
password: this.user.password,
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
<v-icon left dark>
|
||||
mdi-clipboard-check
|
||||
</v-icon>
|
||||
{{ $t("general.coppied") }}!
|
||||
<slot> {{ $t("general.coppied") }}! </slot>
|
||||
</span>
|
||||
</v-tooltip>
|
||||
</template>
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
<template>
|
||||
<div v-if="recipes">
|
||||
<v-app-bar color="transparent" flat class="mt-n1 rounded" v-if="!disableToolbar">
|
||||
<v-app-bar color="transparent" flat class="mt-n1 flex-sm-wrap rounded " v-if="!disableToolbar">
|
||||
<v-icon large left v-if="title">
|
||||
{{ displayTitleIcon }}
|
||||
</v-icon>
|
||||
<v-toolbar-title class="headline"> {{ title }} </v-toolbar-title>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn text @click="navigateRandom">
|
||||
<v-icon left>
|
||||
<v-btn :icon="$vuetify.breakpoint.xsOnly" text @click="navigateRandom">
|
||||
<v-icon :left="!$vuetify.breakpoint.xsOnly">
|
||||
mdi-dice-multiple
|
||||
</v-icon>
|
||||
{{ $t("general.random") }}
|
||||
{{ $vuetify.breakpoint.xsOnly ? null : $t("general.random") }}
|
||||
</v-btn>
|
||||
<v-menu offset-y left v-if="$listeners.sort">
|
||||
<template v-slot:activator="{ on, attrs }">
|
||||
<v-btn text v-bind="attrs" v-on="on" :loading="sortLoading">
|
||||
<v-icon left>
|
||||
<v-btn text :icon="$vuetify.breakpoint.xsOnly" v-bind="attrs" v-on="on" :loading="sortLoading">
|
||||
<v-icon :left="!$vuetify.breakpoint.xsOnly">
|
||||
mdi-sort
|
||||
</v-icon>
|
||||
{{ $t("general.sort") }}
|
||||
{{ $vuetify.breakpoint.xsOnly ? null : $t("general.sort") }}
|
||||
</v-btn>
|
||||
</template>
|
||||
<v-list>
|
||||
|
@ -58,14 +58,16 @@
|
|||
<div v-if="recipes" class="mt-2">
|
||||
<v-row v-if="!viewScale">
|
||||
<v-col :sm="6" :md="6" :lg="4" :xl="3" v-for="recipe in recipes.slice(0, cardLimit)" :key="recipe.name">
|
||||
<RecipeCard
|
||||
:name="recipe.name"
|
||||
:description="recipe.description"
|
||||
:slug="recipe.slug"
|
||||
:rating="recipe.rating"
|
||||
:image="recipe.image"
|
||||
:tags="recipe.tags"
|
||||
/>
|
||||
<v-lazy>
|
||||
<RecipeCard
|
||||
:name="recipe.name"
|
||||
:description="recipe.description"
|
||||
:slug="recipe.slug"
|
||||
:rating="recipe.rating"
|
||||
:image="recipe.image"
|
||||
:tags="recipe.tags"
|
||||
/>
|
||||
</v-lazy>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row v-else dense>
|
||||
|
@ -78,33 +80,29 @@
|
|||
v-for="recipe in recipes.slice(0, cardLimit)"
|
||||
:key="recipe.name"
|
||||
>
|
||||
<MobileRecipeCard
|
||||
:name="recipe.name"
|
||||
:description="recipe.description"
|
||||
:slug="recipe.slug"
|
||||
:rating="recipe.rating"
|
||||
:image="recipe.image"
|
||||
:tags="recipe.tags"
|
||||
/>
|
||||
<v-lazy>
|
||||
<MobileRecipeCard
|
||||
:name="recipe.name"
|
||||
:description="recipe.description"
|
||||
:slug="recipe.slug"
|
||||
:rating="recipe.rating"
|
||||
:image="recipe.image"
|
||||
:tags="recipe.tags"
|
||||
/>
|
||||
</v-lazy>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
<div v-intersect="bumpList" class="d-flex">
|
||||
<v-expand-x-transition>
|
||||
<v-progress-circular
|
||||
v-if="loading"
|
||||
class="mx-auto mt-1"
|
||||
:size="50"
|
||||
:width="7"
|
||||
color="primary"
|
||||
indeterminate
|
||||
></v-progress-circular>
|
||||
<SiteLoader v-if="loading" :loading="loading" :size="150" />
|
||||
</v-expand-x-transition>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SiteLoader from "@/components/UI/SiteLoader";
|
||||
import RecipeCard from "../Recipe/RecipeCard";
|
||||
import MobileRecipeCard from "@/components/Recipe/MobileRecipeCard";
|
||||
import { utils } from "@/utils";
|
||||
|
@ -114,6 +112,7 @@ export default {
|
|||
components: {
|
||||
RecipeCard,
|
||||
MobileRecipeCard,
|
||||
SiteLoader,
|
||||
},
|
||||
props: {
|
||||
disableToolbar: {
|
||||
|
@ -139,7 +138,7 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
sortLoading: false,
|
||||
cardLimit: 30,
|
||||
cardLimit: 50,
|
||||
loading: false,
|
||||
EVENTS: {
|
||||
az: "az",
|
||||
|
|
|
@ -43,25 +43,31 @@
|
|||
</div>
|
||||
<router-link to="/search"> Advanced Search </router-link>
|
||||
</v-card-actions>
|
||||
<MobileRecipeCard
|
||||
v-for="(recipe, index) in results.slice(0, 10)"
|
||||
:tabindex="index"
|
||||
:key="index"
|
||||
class="ma-1 arrow-nav"
|
||||
:name="recipe.name"
|
||||
:description="recipe.description"
|
||||
:slug="recipe.slug"
|
||||
:rating="recipe.rating"
|
||||
:image="recipe.image"
|
||||
:route="true"
|
||||
v-on="$listeners.selected ? { selected: () => grabRecipe(recipe) } : {}"
|
||||
/>
|
||||
<v-card-actions v-if="loading">
|
||||
<SiteLoader :loading="loading" />
|
||||
</v-card-actions>
|
||||
<div v-else>
|
||||
<MobileRecipeCard
|
||||
v-for="(recipe, index) in results.slice(0, 10)"
|
||||
:tabindex="index"
|
||||
:key="index"
|
||||
class="ma-1 arrow-nav"
|
||||
:name="recipe.name"
|
||||
:description="recipe.description"
|
||||
:slug="recipe.slug"
|
||||
:rating="recipe.rating"
|
||||
:image="recipe.image"
|
||||
:route="true"
|
||||
v-on="$listeners.selected ? { selected: () => grabRecipe(recipe) } : {}"
|
||||
/>
|
||||
</div>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SiteLoader from "@/components/UI/SiteLoader";
|
||||
const SELECTED_EVENT = "selected";
|
||||
import FuseSearchBar from "@/components/UI/Search/FuseSearchBar";
|
||||
import MobileRecipeCard from "@/components/Recipe/MobileRecipeCard";
|
||||
|
@ -69,9 +75,11 @@ export default {
|
|||
components: {
|
||||
FuseSearchBar,
|
||||
MobileRecipeCard,
|
||||
SiteLoader,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
selectedIndex: -1,
|
||||
dialog: false,
|
||||
searchString: "",
|
||||
|
@ -82,14 +90,17 @@ export default {
|
|||
$route() {
|
||||
this.dialog = false;
|
||||
},
|
||||
dialog(val) {
|
||||
async dialog(val) {
|
||||
if (!val) {
|
||||
this.resetSelected();
|
||||
} else if (this.allItems.length <= 0) {
|
||||
this.loading = true;
|
||||
await this.$store.dispatch("requestAllRecipes");
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.$store.dispatch("requestAllRecipes");
|
||||
document.addEventListener("keydown", this.onUpDown);
|
||||
},
|
||||
beforeDestroy() {
|
||||
|
|
25
frontend/src/components/UI/SiteLoader.vue
Normal file
25
frontend/src/components/UI/SiteLoader.vue
Normal file
|
@ -0,0 +1,25 @@
|
|||
<template>
|
||||
<v-progress-circular class="mx-auto" :width="size / 20" :size="size" color="primary lighten-2" indeterminate>
|
||||
<div class="text-center">
|
||||
<v-icon :size="size / 2" color="primary lighten-2">
|
||||
{{ $globals.icons.primary }}
|
||||
</v-icon>
|
||||
<div>
|
||||
Loading Recipes
|
||||
</div>
|
||||
</div>
|
||||
</v-progress-circular>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
loading: {
|
||||
default: true,
|
||||
},
|
||||
size: {
|
||||
default: 200,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -18,12 +18,9 @@
|
|||
</div>
|
||||
|
||||
<v-spacer></v-spacer>
|
||||
<SearchBar
|
||||
v-if="!isMobile"
|
||||
:show-results="true"
|
||||
@selected="navigateFromSearch"
|
||||
:max-width="isMobile ? '100%' : '450px'"
|
||||
/>
|
||||
<div v-if="!isMobile" style="width: 350px;">
|
||||
<SearchBar :show-results="true" @selected="navigateFromSearch" :max-width="isMobile ? '100%' : '450px'" />
|
||||
</div>
|
||||
<div v-else>
|
||||
<v-btn icon @click="$refs.recipeSearch.open()">
|
||||
<v-icon> mdi-magnify </v-icon>
|
||||
|
|
|
@ -29,6 +29,14 @@
|
|||
|
||||
<!-- Version List Item -->
|
||||
<v-list nav dense class="fixedBottom" v-if="!isMain">
|
||||
<v-list-item href="https://github.com/sponsors/hay-kot" target="_target">
|
||||
<v-list-item-icon >
|
||||
<v-icon color="pink">
|
||||
mdi-heart
|
||||
</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-title> Support </v-list-item-title>
|
||||
</v-list-item>
|
||||
<v-list-item to="/admin/about">
|
||||
<v-list-item-icon class="mr-3 pt-1">
|
||||
<v-icon :color="newVersionAvailable ? 'red--text' : ''">
|
||||
|
|
|
@ -377,6 +377,7 @@
|
|||
"untagged-count": "Untagged {count}"
|
||||
},
|
||||
"user": {
|
||||
"username": "Username",
|
||||
"admin": "Admin",
|
||||
"are-you-sure-you-want-to-delete-the-link": "Are you sure you want to delete the link <b>{link}<b/>?",
|
||||
"are-you-sure-you-want-to-delete-the-user": "Are you sure you want to delete the user <b>{activeName} ID: {activeId}<b/>?",
|
||||
|
|
|
@ -1,5 +1,33 @@
|
|||
<template>
|
||||
<div>
|
||||
<v-app-bar color="primary">
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn href="https://github.com/sponsors/hay-kot" target="_blank" class="mx-1" color="secondary">
|
||||
<v-icon left>
|
||||
mdi-heart
|
||||
</v-icon>
|
||||
Support
|
||||
</v-btn>
|
||||
<v-btn href="https://github.com/hay-kot" target="_blank" class="mx-1" color="secondary">
|
||||
<v-icon left>
|
||||
mdi-github
|
||||
</v-icon>
|
||||
Github
|
||||
</v-btn>
|
||||
<v-btn href="https://hay-kot.dev" target="_blank" class="mx-1" color="secondary">
|
||||
<v-icon left>
|
||||
mdi-account
|
||||
</v-icon>
|
||||
Portfolio
|
||||
</v-btn>
|
||||
<v-btn href="https://hay-kot.github.io/mealie/" target="_blank" class="mx-1" color="secondary">
|
||||
<v-icon left>
|
||||
mdi-folder-outline
|
||||
</v-icon>
|
||||
Docs
|
||||
</v-btn>
|
||||
<v-spacer></v-spacer>
|
||||
</v-app-bar>
|
||||
<v-card class="mt-3">
|
||||
<v-card-title class="headline">
|
||||
{{ $t("about.about-mealie") }}
|
||||
|
|
|
@ -155,6 +155,7 @@ export default {
|
|||
sortable: false,
|
||||
value: "id",
|
||||
},
|
||||
{ text: this.$t("user.username"), value: "username" },
|
||||
{ text: this.$t("user.full-name"), value: "fullName" },
|
||||
{ text: this.$t("user.email"), value: "email" },
|
||||
{ text: this.$t("group.group"), value: "group" },
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div>
|
||||
<v-card flat>
|
||||
<v-tabs v-model="tab" background-color="primary" centered dark icons-and-text>
|
||||
<v-tabs v-model="tab" background-color="primary" centered dark icons-and-text show-arrows>
|
||||
<v-tabs-slider></v-tabs-slider>
|
||||
|
||||
<v-tab href="#users">
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
</div>
|
||||
</v-row>
|
||||
</v-card-text>
|
||||
<v-tabs v-model="tab">
|
||||
<v-tabs v-model="tab" show-arrows="">
|
||||
<v-tab>{{ $t("general.recipes") }}</v-tab>
|
||||
</v-tabs>
|
||||
<v-tabs-items v-model="tab">
|
||||
|
|
|
@ -67,7 +67,15 @@
|
|||
</template>
|
||||
<template v-slot:bottom>
|
||||
<v-card-text>
|
||||
<v-form>
|
||||
<v-form ref="userUpdate">
|
||||
<v-text-field
|
||||
:label="$t('user.username')"
|
||||
required
|
||||
v-model="user.username"
|
||||
:rules="[existsRule]"
|
||||
validate-on-blur
|
||||
>
|
||||
</v-text-field>
|
||||
<v-text-field
|
||||
:label="$t('user.full-name')"
|
||||
required
|
||||
|
@ -151,6 +159,9 @@ export default {
|
|||
this.user.avatar = avatar;
|
||||
},
|
||||
async updateUser() {
|
||||
if (!this.$refs.userUpdate.validate()) {
|
||||
return;
|
||||
}
|
||||
this.loading = true;
|
||||
|
||||
const response = await api.users.update(this.user);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div>
|
||||
<v-card flat>
|
||||
<v-tabs v-model="tab" background-color="primary" centered dark icons-and-text>
|
||||
<v-tabs v-model="tab" background-color="primary" centered dark icons-and-text show-arrows>
|
||||
<v-tabs-slider></v-tabs-slider>
|
||||
|
||||
<v-tab href="#event-notifications">
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
<template>
|
||||
<div>
|
||||
<v-container>
|
||||
<v-slide-x-transition hide-on-leave>
|
||||
<router-view></router-view>
|
||||
</v-slide-x-transition>
|
||||
</v-container>
|
||||
</div>
|
||||
<v-container fluid class="pa-5">
|
||||
<v-slide-x-transition hide-on-leave>
|
||||
<router-view></router-view>
|
||||
</v-slide-x-transition>
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
|
|
@ -37,6 +37,8 @@
|
|||
</v-icon>
|
||||
Shopping List
|
||||
</v-btn>
|
||||
<v-spacer></v-spacer>
|
||||
<TheCopyButton color="info" :copy-text="mealPlanURL(mealplan.uid)"> Link Coppied </TheCopyButton>
|
||||
</v-card-actions>
|
||||
|
||||
<v-list class="mt-0 pt-0">
|
||||
|
@ -84,11 +86,12 @@ import { api } from "@/api";
|
|||
import { utils } from "@/utils";
|
||||
import NewMeal from "@/components/MealPlan/MealPlanNew";
|
||||
import EditPlan from "@/components/MealPlan/MealPlanEditor";
|
||||
|
||||
import TheCopyButton from "@/components/UI/Buttons/TheCopyButton";
|
||||
export default {
|
||||
components: {
|
||||
NewMeal,
|
||||
EditPlan,
|
||||
TheCopyButton,
|
||||
},
|
||||
data: () => ({
|
||||
plannedMeals: [],
|
||||
|
@ -103,6 +106,9 @@ export default {
|
|||
this.plannedMeals = response.data;
|
||||
console.log(this.plannedMeals);
|
||||
},
|
||||
mealPlanURL(uid) {
|
||||
return window.location.origin + "/meal-plan?id=" + uid;
|
||||
},
|
||||
generateKey(name, index) {
|
||||
return utils.generateUniqueKey(name, index);
|
||||
},
|
||||
|
|
|
@ -46,11 +46,20 @@ export default {
|
|||
};
|
||||
},
|
||||
async mounted() {
|
||||
this.mealPlan = await api.mealPlans.thisWeek();
|
||||
if (this.mealplanId) {
|
||||
this.mealPlan = await api.mealPlans.getById(this.mealplanId);
|
||||
} else {
|
||||
this.mealPlan = await api.mealPlans.thisWeek();
|
||||
}
|
||||
console.log(this.mealPlans);
|
||||
if (!this.mealPlan) {
|
||||
utils.notify.warning(this.$t("meal-plan.no-meal-plan-defined-yet"));
|
||||
}
|
||||
console.log(this.mealPlan);
|
||||
},
|
||||
computed: {
|
||||
mealplanId() {
|
||||
return this.$route.query.id || false;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getOrder(index) {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<template>
|
||||
<v-container>
|
||||
<v-progress-linear v-if="loading" indeterminate color="primary"></v-progress-linear>
|
||||
<CardSection
|
||||
title-icon=""
|
||||
:sortable="true"
|
||||
|
@ -8,14 +7,19 @@
|
|||
:recipes="shownRecipes"
|
||||
@sort="assignSorted"
|
||||
/>
|
||||
<v-row class="d-flex">
|
||||
<SiteLoader class="mx-auto" v-if="loading" :loading="loading" :size="200" />
|
||||
</v-row>
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SiteLoader from "@/components/UI/SiteLoader";
|
||||
import CardSection from "@/components/UI/CardSection";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
SiteLoader,
|
||||
CardSection,
|
||||
},
|
||||
data() {
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
</v-app-bar>
|
||||
|
||||
<div v-if="render">
|
||||
<v-tabs v-model="tab" background-color="transparent" grow>
|
||||
<v-tabs v-model="tab" background-color="transparent" grow show-arrows="">
|
||||
<v-tab v-for="item in page.categories" :key="item.slug" :href="`#${item.slug}`">
|
||||
{{ item.name }}
|
||||
</v-tab>
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
</v-card-title>
|
||||
<v-divider class="mx-2 mb-1"></v-divider>
|
||||
|
||||
<SearchDialog ref="searchRecipe" @select="importIngredients" />
|
||||
<SearchDialog ref="searchRecipe" @selected="importIngredients" />
|
||||
<v-card-text>
|
||||
<v-row dense v-for="(item, index) in activeList.items" :key="index">
|
||||
<v-col v-if="edit" cols="12" class="d-flex no-wrap align-center">
|
||||
|
@ -80,7 +80,7 @@
|
|||
</v-btn>
|
||||
</v-col>
|
||||
|
||||
<v-col cols="12" class="d-flex no-wrap align-center">
|
||||
<v-col cols="12" class="no-wrap align-center" :class="!edit ? 'd-flex' : null">
|
||||
<v-checkbox
|
||||
v-if="!edit"
|
||||
hide-details
|
||||
|
@ -97,18 +97,16 @@
|
|||
</v-icon>
|
||||
|
||||
<v-lazy>
|
||||
<div>
|
||||
<vue-markdown v-if="!edit" class="dense-markdown" :source="item.text"> </vue-markdown>
|
||||
<v-textarea
|
||||
single-line
|
||||
rows="1"
|
||||
auto-grow
|
||||
class="mb-n2 pa-0"
|
||||
dense
|
||||
v-else
|
||||
v-model="activeList.items[index].text"
|
||||
></v-textarea>
|
||||
</div>
|
||||
<vue-markdown v-if="!edit" class="dense-markdown" :source="item.text"> </vue-markdown>
|
||||
<v-textarea
|
||||
single-line
|
||||
rows="1"
|
||||
auto-grow
|
||||
class="mb-n2 pa-0"
|
||||
dense
|
||||
v-else
|
||||
v-model="activeList.items[index].text"
|
||||
></v-textarea>
|
||||
</v-lazy>
|
||||
</v-col>
|
||||
<v-divider class="ma-1"></v-divider>
|
||||
|
@ -137,7 +135,7 @@
|
|||
|
||||
<script>
|
||||
import BaseDialog from "@/components/UI/Dialogs/BaseDialog";
|
||||
import SearchDialog from "@/components/UI/Search/SearchDialog";
|
||||
import SearchDialog from "@/components/UI/Dialogs/SearchDialog";
|
||||
import TheCopyButton from "@/components/UI/Buttons/TheCopyButton";
|
||||
import VueMarkdown from "@adapttive/vue-markdown";
|
||||
import { api } from "@/api";
|
||||
|
@ -194,8 +192,8 @@ export default {
|
|||
openSearch() {
|
||||
this.$refs.searchRecipe.open();
|
||||
},
|
||||
async importIngredients(_, slug) {
|
||||
const recipe = await api.recipes.requestDetails(slug);
|
||||
async importIngredients(selected) {
|
||||
const recipe = await api.recipes.requestDetails(selected.slug);
|
||||
|
||||
const ingredients = recipe.recipeIngredient.map(x => ({
|
||||
title: "",
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
const Admin = () => import("@/pages/Admin");
|
||||
const Migration = () => import("@/pages/Admin/Migration");
|
||||
const Profile = () => import("@/pages/Admin/Profile");
|
||||
const ManageUsers = () => import("@/pages/Admin/ManageUsers");
|
||||
const Settings = () => import("@/pages/Admin/Settings");
|
||||
const About = () => import("@/pages/Admin/About");
|
||||
const ToolBox = () => import("@/pages/Admin/ToolBox");
|
||||
const Dashboard = () => import("@/pages/Admin/Dashboard");
|
||||
const Admin = () => import(/* webpackChunkName: "admin" */ "@/pages/Admin");
|
||||
const Migration = () => import(/* webpackChunkName: "admin" */ "@/pages/Admin/Migration");
|
||||
const Profile = () => import(/* webpackChunkName: "admin" */ "@/pages/Admin/Profile");
|
||||
const ManageUsers = () => import(/* webpackChunkName: "admin" */ "@/pages/Admin/ManageUsers");
|
||||
const Settings = () => import(/* webpackChunkName: "admin" */ "@/pages/Admin/Settings");
|
||||
const About = () => import(/* webpackChunkName: "admin" */ "@/pages/Admin/About");
|
||||
const ToolBox = () => import(/* webpackChunkName: "admin" */ "@/pages/Admin/ToolBox");
|
||||
const Dashboard = () => import(/* webpackChunkName: "admin" */ "@/pages/Admin/Dashboard");
|
||||
import { store } from "../store";
|
||||
|
||||
export const adminRoutes = {
|
||||
|
|
|
@ -5,6 +5,13 @@ import { utils } from "@/utils";
|
|||
import i18n from "@/i18n.js";
|
||||
|
||||
export const mealRoutes = [
|
||||
{
|
||||
path: "/meal-plan",
|
||||
component: ThisWeek,
|
||||
meta: {
|
||||
title: "meal-plan.dinner-this-week",
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "/meal-plan/planner",
|
||||
component: Planner,
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
const ViewRecipe = () => import("@/pages/Recipe/ViewRecipe");
|
||||
const NewRecipe = () => import("@/pages/Recipe/NewRecipe");
|
||||
const CustomPage = () => import("@/pages/Recipes/CustomPage");
|
||||
const AllRecipes = () => import("@/pages/Recipes/AllRecipes");
|
||||
const CategoryTagPage = () => import("@/pages/Recipes/CategoryTagPage");
|
||||
const ViewRecipe = () => import(/* webpackChunkName: "recipes" */ "@/pages/Recipe/ViewRecipe");
|
||||
const NewRecipe = () => import(/* webpackChunkName: "recipes" */ "@/pages/Recipe/NewRecipe");
|
||||
const CustomPage = () => import(/* webpackChunkName: "recipes" */ "@/pages/Recipes/CustomPage");
|
||||
const AllRecipes = () => import(/* webpackChunkName: "recipes" */ "@/pages/Recipes/AllRecipes");
|
||||
const CategoryTagPage = () => import(/* webpackChunkName: "recipes" */ "@/pages/Recipes/CategoryTagPage");
|
||||
import { api } from "@/api";
|
||||
|
||||
export const recipeRoutes = [
|
||||
|
|
|
@ -41,6 +41,7 @@ const actions = {
|
|||
this.commit("setRecentRecipes", hash);
|
||||
},
|
||||
async requestAllRecipes({ getters }) {
|
||||
console.log("All Recipes");
|
||||
const all = getters.getAllRecipes;
|
||||
const payload = await api.recipes.allSummary(all.length, 9999);
|
||||
const hash = Object.fromEntries([...all, ...payload].map(e => [e.id, e]));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue