mirror of
https://github.com/hay-kot/mealie.git
synced 2025-08-22 14:33:33 -07:00
consolidate mealplan to profile dashboard
This commit is contained in:
parent
5921922472
commit
75147e22ce
7 changed files with 149 additions and 201 deletions
|
@ -1,137 +0,0 @@
|
|||
<template>
|
||||
<v-card>
|
||||
<v-card-title class="headline">
|
||||
{{ $t("meal-plan.meal-planner") }}
|
||||
</v-card-title>
|
||||
<v-divider></v-divider>
|
||||
<v-card-text>
|
||||
<h2 class="mt-1">{{ $t("recipe.categories") }}</h2>
|
||||
|
||||
<CategoryTagSelector
|
||||
class="mt-4"
|
||||
:solo="true"
|
||||
:dense="false"
|
||||
v-model="groupSettings.categories"
|
||||
:return-object="true"
|
||||
:show-add="true"
|
||||
:hint="$t('meal-plan.only-recipes-with-these-categories-will-be-used-in-meal-plans')"
|
||||
/>
|
||||
</v-card-text>
|
||||
<v-divider> </v-divider>
|
||||
<v-card-text>
|
||||
<h2 class="mt-1 mb-4">
|
||||
{{ $t("settings.webhooks.meal-planner-webhooks") }}
|
||||
</h2>
|
||||
<p>
|
||||
{{
|
||||
$t(
|
||||
"settings.webhooks.the-urls-listed-below-will-recieve-webhooks-containing-the-recipe-data-for-the-meal-plan-on-its-scheduled-day-currently-webhooks-will-execute-at"
|
||||
)
|
||||
}}
|
||||
<strong>{{ groupSettings.webhookTime }}</strong>
|
||||
</p>
|
||||
|
||||
<v-row dense class="flex align-center">
|
||||
<v-switch class="mx-2" v-model="groupSettings.webhookEnable" :label="$t('general.enabled')"></v-switch>
|
||||
<TimePickerDialog @save-time="saveTime" class="ma-2" />
|
||||
<v-btn class="ma-2" color="info" @click="testWebhooks">
|
||||
<v-icon left> mdi-webhook </v-icon>
|
||||
{{ $t("settings.webhooks.test-webhooks") }}
|
||||
</v-btn>
|
||||
</v-row>
|
||||
|
||||
<v-row v-for="(url, index) in groupSettings.webhookUrls" :key="index" align=" center" dense>
|
||||
<v-col cols="1">
|
||||
<v-btn icon color="error" @click="removeWebhook(index)">
|
||||
<v-icon>mdi-minus</v-icon>
|
||||
</v-btn>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<v-text-field
|
||||
v-model="groupSettings.webhookUrls[index]"
|
||||
:label="$t('settings.webhooks.webhook-url')"
|
||||
></v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-btn icon color="success" @click="addWebhook">
|
||||
<v-icon>mdi-plus</v-icon>
|
||||
</v-btn>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn color="success" @click="saveGroupSettings" class="mr-2 mb-1">
|
||||
<v-icon left> mdi-content-save </v-icon>
|
||||
{{ $t("general.save") }}
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { api } from "@/api";
|
||||
import TimePickerDialog from "@/components/FormHelpers/TimePickerDialog";
|
||||
import CategoryTagSelector from "@/components/FormHelpers/CategoryTagSelector";
|
||||
export default {
|
||||
components: {
|
||||
TimePickerDialog,
|
||||
CategoryTagSelector,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
groupSettings: {
|
||||
name: "home",
|
||||
id: 1,
|
||||
mealplans: [],
|
||||
categories: [],
|
||||
webhookUrls: [],
|
||||
webhookTime: "00:00",
|
||||
webhookEnable: false,
|
||||
},
|
||||
};
|
||||
},
|
||||
async mounted() {
|
||||
await this.$store.dispatch("requestCurrentGroup");
|
||||
this.getSiteSettings();
|
||||
},
|
||||
computed: {
|
||||
categories() {
|
||||
return this.$store.getters.getAllCategories;
|
||||
},
|
||||
isFlat() {
|
||||
return this.groupSettings.categories >= 1 ? true : false;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
saveTime(value) {
|
||||
this.groupSettings.webhookTime = value;
|
||||
},
|
||||
getSiteSettings() {
|
||||
let settings = this.$store.getters.getCurrentGroup;
|
||||
|
||||
this.groupSettings.name = settings.name;
|
||||
this.groupSettings.id = settings.id;
|
||||
this.groupSettings.categories = settings.categories;
|
||||
this.groupSettings.webhookUrls = settings.webhookUrls;
|
||||
this.groupSettings.webhookTime = settings.webhookTime;
|
||||
this.groupSettings.webhookEnable = settings.webhookEnable;
|
||||
},
|
||||
addWebhook() {
|
||||
this.groupSettings.webhookUrls.push(" ");
|
||||
},
|
||||
removeWebhook(index) {
|
||||
this.groupSettings.webhookUrls.splice(index, 1);
|
||||
},
|
||||
async saveGroupSettings() {
|
||||
if (await api.groups.update(this.groupSettings)) {
|
||||
await this.$store.dispatch("requestCurrentGroup");
|
||||
this.getSiteSettings();
|
||||
}
|
||||
},
|
||||
testWebhooks() {
|
||||
api.settings.testWebhooks();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style></style>
|
|
@ -53,7 +53,7 @@
|
|||
<v-textarea
|
||||
class="mb-0 pb-0"
|
||||
label="API Token"
|
||||
read
|
||||
readonly
|
||||
v-model="createdToken"
|
||||
append-outer-icon="mdi-content-copy"
|
||||
@click:append-outer="copyToken"
|
||||
|
|
|
@ -24,9 +24,9 @@
|
|||
<v-subheader>USERS</v-subheader>
|
||||
<v-divider></v-divider>
|
||||
|
||||
<v-virtual-scroll v-if="currentGroup.users" :items="currentGroup.users" height="260" item-height="64">
|
||||
<v-virtual-scroll v-if="currentGroup.users" :items="currentGroup.users" height="257" item-height="64">
|
||||
<template v-slot:default="{ item }">
|
||||
<v-list-item :key="item.id">
|
||||
<v-list-item :key="item.id" @click.prevent>
|
||||
<v-list-item-action>
|
||||
<v-btn fab small depressed color="primary">
|
||||
{{ generateInitials(item.fullName) }}
|
||||
|
@ -38,22 +38,85 @@
|
|||
{{ item.fullName }}
|
||||
</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
<!-- TODO: Future Profile Pages-->
|
||||
<!-- <v-list-item-action>
|
||||
<v-icon small>
|
||||
mdi-open-in-new
|
||||
</v-icon>
|
||||
</v-list-item-action> -->
|
||||
</v-list-item>
|
||||
|
||||
<v-divider></v-divider>
|
||||
</template>
|
||||
</v-virtual-scroll>
|
||||
|
||||
<div class="mt-3">
|
||||
<h3 class="display-2 font-weight-light text--primary">
|
||||
<v-icon x-large>
|
||||
mdi-food-variant
|
||||
</v-icon>
|
||||
<small> Mealplan Settings </small>
|
||||
</h3>
|
||||
</div>
|
||||
<v-divider></v-divider>
|
||||
|
||||
<v-subheader>MEALPLAN CATEGORIES</v-subheader>
|
||||
<v-card-text class="mt-0 pt-0">
|
||||
{{ $t("meal-plan.only-recipes-with-these-categories-will-be-used-in-meal-plans") }}
|
||||
</v-card-text>
|
||||
<CategoryTagSelector
|
||||
:solo="true"
|
||||
:dense="false"
|
||||
v-model="groupSettings.categories"
|
||||
:return-object="true"
|
||||
:show-add="true"
|
||||
/>
|
||||
|
||||
<v-divider></v-divider>
|
||||
<v-subheader>WEBHOOKS</v-subheader>
|
||||
<v-card-text class="mt-0 pt-0">
|
||||
{{
|
||||
$t(
|
||||
"settings.webhooks.the-urls-listed-below-will-recieve-webhooks-containing-the-recipe-data-for-the-meal-plan-on-its-scheduled-day-currently-webhooks-will-execute-at"
|
||||
)
|
||||
}}
|
||||
<strong>{{ groupSettings.webhookTime }}</strong>
|
||||
</v-card-text>
|
||||
<v-row dense class="flex align-center">
|
||||
<v-switch class="ml-5 mr-auto" v-model="groupSettings.webhookEnable" :label="$t('general.enabled')"></v-switch>
|
||||
<TimePickerDialog @save-time="saveTime" class="" />
|
||||
</v-row>
|
||||
|
||||
<v-card-text>
|
||||
<v-text-field
|
||||
prepend-icon="mdi-delete"
|
||||
v-for="(url, index) in groupSettings.webhookUrls"
|
||||
@click:prepend="removeWebhook(index)"
|
||||
:key="index"
|
||||
v-model="groupSettings.webhookUrls[index]"
|
||||
:label="$t('settings.webhooks.webhook-url')"
|
||||
></v-text-field>
|
||||
<v-card-actions class="pa-0">
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn small color="success" @click="addWebhook">
|
||||
<v-icon left> mdi-webhook </v-icon>
|
||||
New
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card-text>
|
||||
|
||||
<v-divider></v-divider>
|
||||
<v-card-actions class="pb-0">
|
||||
<v-btn class="ma-2" color="info" @click="testWebhooks">
|
||||
<v-icon left> mdi-webhook </v-icon>
|
||||
{{ $t("settings.webhooks.test-webhooks") }}
|
||||
</v-btn>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn color="success" @click="saveGroupSettings">
|
||||
<v-icon left> mdi-content-save </v-icon>
|
||||
{{ $t("general.update") }}
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</template>
|
||||
</StatCard>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TimePickerDialog from "@/components/FormHelpers/TimePickerDialog";
|
||||
import CategoryTagSelector from "@/components/FormHelpers/CategoryTagSelector";
|
||||
import StatCard from "@/components/UI/StatCard";
|
||||
import MobileRecipeCard from "@/components/Recipe/MobileRecipeCard";
|
||||
import { validators } from "@/mixins/validators";
|
||||
|
@ -63,6 +126,8 @@ export default {
|
|||
components: {
|
||||
StatCard,
|
||||
MobileRecipeCard,
|
||||
CategoryTagSelector,
|
||||
TimePickerDialog,
|
||||
},
|
||||
mixins: [validators, initials],
|
||||
data() {
|
||||
|
@ -75,6 +140,7 @@ export default {
|
|||
newOne: "",
|
||||
newTwo: "",
|
||||
},
|
||||
groupSettings: {},
|
||||
showPassword: false,
|
||||
loading: false,
|
||||
user: {
|
||||
|
@ -97,8 +163,10 @@ export default {
|
|||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
async mounted() {
|
||||
this.getTodaysMeal();
|
||||
await this.$store.dispatch("requestCurrentGroup");
|
||||
this.getSiteSettings();
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
@ -118,6 +186,27 @@ export default {
|
|||
[""]
|
||||
);
|
||||
},
|
||||
getSiteSettings() {
|
||||
this.groupSettings = this.$store.getters.getCurrentGroup;
|
||||
},
|
||||
saveTime(value) {
|
||||
this.groupSettings.webhookTime = value;
|
||||
},
|
||||
addWebhook() {
|
||||
this.groupSettings.webhookUrls.push(" ");
|
||||
},
|
||||
removeWebhook(index) {
|
||||
this.groupSettings.webhookUrls.splice(index, 1);
|
||||
},
|
||||
async saveGroupSettings() {
|
||||
if (await api.groups.update(this.groupSettings)) {
|
||||
await this.$store.dispatch("requestCurrentGroup");
|
||||
this.getSiteSettings();
|
||||
}
|
||||
},
|
||||
testWebhooks() {
|
||||
api.settings.testWebhooks();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
<v-col cols="12" sm="12" lg="6">
|
||||
<UserCard />
|
||||
<ProfileThemeCard class="mt-10" />
|
||||
<APITokenCard class="mt-10" />
|
||||
</v-col>
|
||||
<v-col cols="12" sm="12" lg="6">
|
||||
<ProfileGroupCard />
|
||||
<APITokenCard class="mt-10" />
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row class="mt-7">
|
||||
|
|
|
@ -1,13 +1,6 @@
|
|||
<template>
|
||||
<v-container>
|
||||
<CardSection
|
||||
:sortable="true"
|
||||
:title="title"
|
||||
:recipes="recipes"
|
||||
:card-limit="9999"
|
||||
@sort="sortAZ"
|
||||
@sort-recent="sortRecent"
|
||||
/>
|
||||
<CardSection :sortable="true" :title="title" :recipes="shownRecipes" @sort="assignSorted" />
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
|
@ -22,20 +15,30 @@ export default {
|
|||
return {
|
||||
title: "",
|
||||
recipes: [],
|
||||
sortedResults: [],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
currentCategory() {
|
||||
return this.$route.params.category;
|
||||
},
|
||||
shownRecipes() {
|
||||
if (this.sortedResults.length > 0) {
|
||||
return this.sortedResults;
|
||||
} else {
|
||||
return this.recipes;
|
||||
}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
async currentCategory() {
|
||||
this.sortedResults = [];
|
||||
this.getRecipes();
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.getRecipes();
|
||||
this.sortedResults = [];
|
||||
},
|
||||
methods: {
|
||||
async getRecipes() {
|
||||
|
@ -43,11 +46,8 @@ export default {
|
|||
this.title = data.name;
|
||||
this.recipes = data.recipes;
|
||||
},
|
||||
sortAZ() {
|
||||
this.recipes.sort((a, b) => (a.name > b.name ? 1 : -1));
|
||||
},
|
||||
sortRecent() {
|
||||
this.recipes.sort((a, b) => (a.dateAdded > b.dateAdded ? -1 : 1));
|
||||
assignSorted(val) {
|
||||
this.sortedResults = val.slice();
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,24 +1,23 @@
|
|||
<template>
|
||||
<v-container>
|
||||
<v-card flat height="100%">
|
||||
<v-app-bar flat>
|
||||
<v-spacer></v-spacer>
|
||||
<v-card-title class="text-center justify-center py-3 ">
|
||||
{{ title.toUpperCase() }}
|
||||
</v-card-title>
|
||||
<v-spacer></v-spacer>
|
||||
<v-app-bar color="transparent" flat class="mt-n1 rounded">
|
||||
<v-icon large left>
|
||||
mdi-tag-multiple-outline
|
||||
</v-icon>
|
||||
<v-toolbar-title class="headline"> {{ page.name }} </v-toolbar-title>
|
||||
</v-app-bar>
|
||||
|
||||
<div v-if="render">
|
||||
<v-tabs v-model="tab" background-color="transparent" grow>
|
||||
<v-tab v-for="item in categories" :key="item.slug">
|
||||
<v-tab v-for="item in page.categories" :key="item.slug" :href="`#${item.slug}`">
|
||||
{{ item.name }}
|
||||
</v-tab>
|
||||
</v-tabs>
|
||||
|
||||
<v-tabs-items v-model="tab">
|
||||
<v-tab-item v-for="(item, index) in categories" :key="item.slug + index">
|
||||
<CardSection class="mb-5 mx-1" :recipes="filterRecipe(item.slug)" />
|
||||
<v-tab-item v-for="(item, index) in page.categories" :key="item.slug + index" :value="item.slug">
|
||||
<CardSection class="mb-5 mx-1" :recipes="item.recipes" @sort="sortRecipes($event, index)" />
|
||||
</v-tab-item>
|
||||
</v-tabs-items>
|
||||
</div>
|
||||
|
@ -36,8 +35,8 @@ export default {
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
page: "",
|
||||
title: "",
|
||||
tab: null,
|
||||
render: false,
|
||||
recipeStore: [],
|
||||
categories: [],
|
||||
|
@ -47,6 +46,14 @@ export default {
|
|||
pageSlug() {
|
||||
return this.$route.params.customPage;
|
||||
},
|
||||
tab: {
|
||||
set(tab) {
|
||||
this.$router.replace({ query: { ...this.$route.query, tab } });
|
||||
},
|
||||
get() {
|
||||
return this.$route.query.tab;
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
watch: {
|
||||
|
@ -61,27 +68,15 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
async buildPage() {
|
||||
const page = await api.siteSettings.getPage(this.pageSlug);
|
||||
this.title = page.name;
|
||||
this.categories = page.categories;
|
||||
page.categories.forEach(async element => {
|
||||
let categoryRecipes = await this.getRecipeByCategory(element.slug);
|
||||
this.recipeStore.push(categoryRecipes);
|
||||
});
|
||||
},
|
||||
async getRecipeByCategory(category) {
|
||||
return await api.categories.getRecipesInCategory(category);
|
||||
this.page = await api.siteSettings.getPage(this.pageSlug);
|
||||
},
|
||||
filterRecipe(slug) {
|
||||
const storeCategory = this.recipeStore.find(element => element.slug === slug);
|
||||
return storeCategory ? storeCategory.recipes : [];
|
||||
},
|
||||
sortRecipes(sortedRecipes, destKey) {
|
||||
this.page.categories[destKey].recipes = sortedRecipes;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.header-background {
|
||||
background-color: #121619;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,13 +1,6 @@
|
|||
<template>
|
||||
<v-container>
|
||||
<CardSection
|
||||
:sortable="true"
|
||||
:title="title"
|
||||
:recipes="recipes"
|
||||
:card-limit="9999"
|
||||
@sort="sortAZ"
|
||||
@sort-recent="sortRecent"
|
||||
/>
|
||||
<CardSection :sortable="true" :title="title" :recipes="shownRecipes" @sort="assignSorted" />
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
|
@ -22,20 +15,30 @@ export default {
|
|||
return {
|
||||
title: "",
|
||||
recipes: [],
|
||||
sortedResults: [],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
currentTag() {
|
||||
return this.$route.params.tag;
|
||||
},
|
||||
shownRecipes() {
|
||||
if (this.sortedResults.length > 0) {
|
||||
return this.sortedResults;
|
||||
} else {
|
||||
return this.recipes;
|
||||
}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
async currentTag() {
|
||||
this.getRecipes();
|
||||
this.sortedResults = [];
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.getRecipes();
|
||||
this.sortedResults = [];
|
||||
},
|
||||
methods: {
|
||||
async getRecipes() {
|
||||
|
@ -43,11 +46,9 @@ export default {
|
|||
this.title = data.name;
|
||||
this.recipes = data.recipes;
|
||||
},
|
||||
sortAZ() {
|
||||
this.recipes.sort((a, b) => (a.name > b.name ? 1 : -1));
|
||||
},
|
||||
sortRecent() {
|
||||
this.recipes.sort((a, b) => (a.dateAdded > b.dateAdded ? -1 : 1));
|
||||
assignSorted(val) {
|
||||
console.log(val);
|
||||
this.sortedResults = val.slice();
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue