mirror of
https://github.com/hay-kot/mealie.git
synced 2025-08-22 14:33:33 -07:00
majors settings rework
This commit is contained in:
parent
11b7052226
commit
194713ebe7
18 changed files with 506 additions and 182 deletions
|
@ -28,6 +28,7 @@
|
||||||
</v-btn>
|
</v-btn>
|
||||||
|
|
||||||
<SiteMenu />
|
<SiteMenu />
|
||||||
|
<LanguageMenu />
|
||||||
</v-app-bar>
|
</v-app-bar>
|
||||||
<v-main>
|
<v-main>
|
||||||
<v-container>
|
<v-container>
|
||||||
|
@ -40,10 +41,12 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import SiteMenu from "./components/UI/SiteMenu";
|
import SiteMenu from "@/components/UI/SiteMenu";
|
||||||
import SearchBar from "./components/UI/Search/SearchBar";
|
import SearchBar from "@/components/UI/Search/SearchBar";
|
||||||
import AddRecipeFab from "./components/UI/AddRecipeFab";
|
import AddRecipeFab from "@/components/UI/AddRecipeFab";
|
||||||
|
import LanguageMenu from "@/components/UI/LanguageMenu";
|
||||||
import Vuetify from "./plugins/vuetify";
|
import Vuetify from "./plugins/vuetify";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "App",
|
name: "App",
|
||||||
|
|
||||||
|
@ -51,6 +54,7 @@ export default {
|
||||||
SiteMenu,
|
SiteMenu,
|
||||||
AddRecipeFab,
|
AddRecipeFab,
|
||||||
SearchBar,
|
SearchBar,
|
||||||
|
LanguageMenu,
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
|
|
|
@ -70,7 +70,7 @@ export default {
|
||||||
router.push(`/`);
|
router.push(`/`);
|
||||||
},
|
},
|
||||||
|
|
||||||
async allByKeys(recipeKeys, num = 100) {
|
async allByKeys(recipeKeys, num = 999) {
|
||||||
const response = await apiReq.get(recipeURLs.allRecipes, {
|
const response = await apiReq.get(recipeURLs.allRecipes, {
|
||||||
params: {
|
params: {
|
||||||
keys: recipeKeys,
|
keys: recipeKeys,
|
||||||
|
|
|
@ -75,38 +75,16 @@ export default {
|
||||||
mobile: false,
|
mobile: false,
|
||||||
links: [],
|
links: [],
|
||||||
superLinks: [
|
superLinks: [
|
||||||
|
{
|
||||||
|
icon: "mdi-cog",
|
||||||
|
to: "/admin/settings",
|
||||||
|
title: "Site Settings",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
icon: "mdi-account-group",
|
icon: "mdi-account-group",
|
||||||
to: "/admin/manage-users",
|
to: "/admin/manage-users",
|
||||||
title: "Manage Users",
|
title: "Manage Users",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
icon: "mdi-cog",
|
|
||||||
to: "/admin/settings",
|
|
||||||
title: "Admin Settings",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
baseLinks: [
|
|
||||||
{
|
|
||||||
icon: "mdi-account",
|
|
||||||
to: "/admin/profile",
|
|
||||||
title: "Profile",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: "mdi-card-bulleted-settings-outline",
|
|
||||||
to: "/admin/general",
|
|
||||||
title: "General",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: "mdi-format-color-fill",
|
|
||||||
to: "/admin/themes",
|
|
||||||
title: "Themes",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: "mdi-food",
|
|
||||||
to: "/admin/meal-planner",
|
|
||||||
title: "Meal Planner",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
icon: "mdi-backup-restore",
|
icon: "mdi-backup-restore",
|
||||||
to: "/admin/backups",
|
to: "/admin/backups",
|
||||||
|
@ -118,6 +96,23 @@ export default {
|
||||||
title: "Migrations",
|
title: "Migrations",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
baseLinks: [
|
||||||
|
{
|
||||||
|
icon: "mdi-account",
|
||||||
|
to: "/admin/profile",
|
||||||
|
title: "Profile",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: "mdi-format-color-fill",
|
||||||
|
to: "/admin/themes",
|
||||||
|
title: "Themes",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: "mdi-food",
|
||||||
|
to: "/admin/meal-planner",
|
||||||
|
title: "Meal Planner",
|
||||||
|
},
|
||||||
|
],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|
|
@ -25,17 +25,19 @@
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
<v-row>
|
<v-row>
|
||||||
<v-col cols="12" sm="6">
|
<v-col cols="12" sm="6">
|
||||||
<v-card outlined min-height="250">
|
<v-card outlined min-height="350px">
|
||||||
<v-card-text class="pt-2 pb-1">
|
<v-app-bar dark dense color="primary">
|
||||||
<h3>Homepage Categories</h3>
|
<v-icon left>
|
||||||
</v-card-text>
|
mdi-home
|
||||||
<v-divider></v-divider>
|
</v-icon>
|
||||||
<v-list
|
|
||||||
min-height="200"
|
<v-toolbar-title class="headline">
|
||||||
dense
|
Home Page Categories
|
||||||
max-height="200"
|
</v-toolbar-title>
|
||||||
style="overflow:auto"
|
|
||||||
>
|
<v-spacer></v-spacer>
|
||||||
|
</v-app-bar>
|
||||||
|
<v-list height="300" dense style="overflow:auto">
|
||||||
<v-list-item-group>
|
<v-list-item-group>
|
||||||
<draggable
|
<draggable
|
||||||
v-model="homeCategories"
|
v-model="homeCategories"
|
||||||
|
@ -65,24 +67,19 @@
|
||||||
</v-card>
|
</v-card>
|
||||||
</v-col>
|
</v-col>
|
||||||
<v-col cols="12" sm="6">
|
<v-col cols="12" sm="6">
|
||||||
<v-card outlined min-height="250px">
|
<v-card outlined height="350px">
|
||||||
<v-card-text class="pt-2 pb-1">
|
<v-app-bar dark dense color="primary">
|
||||||
<h3>
|
<v-icon left>
|
||||||
|
mdi-tag
|
||||||
|
</v-icon>
|
||||||
|
|
||||||
|
<v-toolbar-title class="headline">
|
||||||
All Categories
|
All Categories
|
||||||
<span>
|
</v-toolbar-title>
|
||||||
<v-btn absolute right x-small color="success" icon>
|
|
||||||
<v-icon>mdi-plus</v-icon></v-btn
|
<v-spacer></v-spacer>
|
||||||
>
|
</v-app-bar>
|
||||||
</span>
|
<v-list height="300" dense style="overflow:auto">
|
||||||
</h3>
|
|
||||||
</v-card-text>
|
|
||||||
<v-divider></v-divider>
|
|
||||||
<v-list
|
|
||||||
min-height="200"
|
|
||||||
dense
|
|
||||||
max-height="200"
|
|
||||||
style="overflow:auto"
|
|
||||||
>
|
|
||||||
<v-list-item-group>
|
<v-list-item-group>
|
||||||
<draggable
|
<draggable
|
||||||
v-model="categories"
|
v-model="categories"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<v-card class="my-2" :loading="loading">
|
<v-card outlined class="my-2" :loading="loading">
|
||||||
<v-card-title>
|
<v-card-title>
|
||||||
{{ title }}
|
{{ title }}
|
||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
|
|
|
@ -134,6 +134,7 @@ export default {
|
||||||
this.clear();
|
this.clear();
|
||||||
}
|
}
|
||||||
console.log(key);
|
console.log(key);
|
||||||
|
this.$store.commit("setToken", key.data.access_token)
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
80
frontend/src/components/UI/LanguageMenu.vue
Normal file
80
frontend/src/components/UI/LanguageMenu.vue
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
<template>
|
||||||
|
<div class="text-center">
|
||||||
|
<LoginDialog ref="loginDialog" />
|
||||||
|
<v-menu
|
||||||
|
transition="slide-x-transition"
|
||||||
|
bottom
|
||||||
|
right
|
||||||
|
offset-y
|
||||||
|
close-delay="200"
|
||||||
|
>
|
||||||
|
<template v-slot:activator="{ on, attrs }">
|
||||||
|
<v-btn v-bind="attrs" v-on="on" icon>
|
||||||
|
<v-icon>mdi-translate</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<v-list>
|
||||||
|
<v-list-item-group v-model="selectedItem" color="primary">
|
||||||
|
<v-list-item
|
||||||
|
v-for="(item, i) in allLanguages"
|
||||||
|
:key="i"
|
||||||
|
link
|
||||||
|
@click="setLanguage(item.value)"
|
||||||
|
>
|
||||||
|
<v-list-item-content>
|
||||||
|
<v-list-item-title>
|
||||||
|
{{ item.name }}
|
||||||
|
</v-list-item-title>
|
||||||
|
</v-list-item-content>
|
||||||
|
</v-list-item>
|
||||||
|
</v-list-item-group>
|
||||||
|
</v-list>
|
||||||
|
</v-menu>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import LoginDialog from "../Login/LoginDialog";
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
LoginDialog,
|
||||||
|
},
|
||||||
|
data: function() {
|
||||||
|
return {
|
||||||
|
selectedItem: 0,
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
name: "English",
|
||||||
|
value: "en",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
let active = this.$store.getters.getActiveLang;
|
||||||
|
this.allLanguages.forEach((element, index) => {
|
||||||
|
if (element.value === active) {
|
||||||
|
this.selectedItem = index;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
allLanguages() {
|
||||||
|
return this.$store.getters.getAllLangs;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
setLanguage(selectedLanguage) {
|
||||||
|
this.$store.commit("setLang", selectedLanguage);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
.menu-text {
|
||||||
|
text-align: left !important;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -52,12 +52,6 @@ export default {
|
||||||
restricted: false,
|
restricted: false,
|
||||||
login: true,
|
login: true,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
icon: "mdi-account",
|
|
||||||
title: "Logout",
|
|
||||||
restricted: true,
|
|
||||||
login: true,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
icon: "mdi-calendar-week",
|
icon: "mdi-calendar-week",
|
||||||
title: this.$i18n.t("meal-plan.dinner-this-week"),
|
title: this.$i18n.t("meal-plan.dinner-this-week"),
|
||||||
|
@ -76,6 +70,12 @@ export default {
|
||||||
nav: "/meal-plan/planner",
|
nav: "/meal-plan/planner",
|
||||||
restricted: true,
|
restricted: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
icon: "mdi-account",
|
||||||
|
title: "Logout",
|
||||||
|
restricted: true,
|
||||||
|
nav: "/logout",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
icon: "mdi-cog",
|
icon: "mdi-cog",
|
||||||
title: this.$i18n.t("general.settings"),
|
title: this.$i18n.t("general.settings"),
|
||||||
|
|
|
@ -89,6 +89,8 @@
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"general-settings": "General Settings",
|
"general-settings": "General Settings",
|
||||||
|
"change-password": "Change Password",
|
||||||
|
"admin-settings": "Admin Settings",
|
||||||
"local-api": "Local API",
|
"local-api": "Local API",
|
||||||
"language": "Language",
|
"language": "Language",
|
||||||
"add-a-new-theme": "Add a New Theme",
|
"add-a-new-theme": "Add a New Theme",
|
||||||
|
|
|
@ -1,70 +0,0 @@
|
||||||
<template>
|
|
||||||
<v-card>
|
|
||||||
<v-card-title class="headline">
|
|
||||||
{{ $t("settings.general-settings") }}
|
|
||||||
<v-spacer></v-spacer>
|
|
||||||
<span>
|
|
||||||
<v-btn class="pt-1" text href="/docs">
|
|
||||||
{{ $t("settings.local-api") }}
|
|
||||||
<v-icon right>mdi-open-in-new</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</span>
|
|
||||||
</v-card-title>
|
|
||||||
<v-divider></v-divider>
|
|
||||||
<v-card-text>
|
|
||||||
<h2 class="mt-1 mb-4">{{ $t("settings.language") }}</h2>
|
|
||||||
<v-row>
|
|
||||||
<v-col sm="3">
|
|
||||||
<v-select
|
|
||||||
dense
|
|
||||||
v-model="selectedLang"
|
|
||||||
:items="langOptions"
|
|
||||||
item-text="name"
|
|
||||||
item-value="value"
|
|
||||||
:label="$t('settings.language')"
|
|
||||||
>
|
|
||||||
</v-select>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-card-text>
|
|
||||||
<v-divider></v-divider>
|
|
||||||
<HomePageSettings />
|
|
||||||
<v-divider></v-divider>
|
|
||||||
</v-card>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import HomePageSettings from "@/components/Admin/General/HomePageSettings";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
HomePageSettings,
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
langOptions: [],
|
|
||||||
selectedLang: "en",
|
|
||||||
};
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.getOptions();
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
selectedLang() {
|
|
||||||
this.$store.commit("setLang", this.selectedLang);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getOptions() {
|
|
||||||
this.langOptions = this.$store.getters.getAllLangs;
|
|
||||||
this.selectedLang = this.$store.getters.getActiveLang;
|
|
||||||
},
|
|
||||||
removeCategory(index) {
|
|
||||||
this.value.categories.splice(index, 1);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
</style>
|
|
|
@ -1,9 +1,226 @@
|
||||||
<template>
|
<template>
|
||||||
<h1>Manage Users</h1>
|
<v-data-table
|
||||||
|
:headers="headers"
|
||||||
|
:items="users"
|
||||||
|
sort-by="calories"
|
||||||
|
class="elevation-1"
|
||||||
|
>
|
||||||
|
<template v-slot:top>
|
||||||
|
<v-toolbar flat>
|
||||||
|
<v-toolbar-title>Mealie Users</v-toolbar-title>
|
||||||
|
<v-divider class="mx-4" inset vertical></v-divider>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<v-dialog v-model="dialog" max-width="600px">
|
||||||
|
<template v-slot:activator="{ on, attrs }">
|
||||||
|
<v-btn color="primary" dark class="mb-2" v-bind="attrs" v-on="on">
|
||||||
|
Create User
|
||||||
|
</v-btn>
|
||||||
|
</template>
|
||||||
|
<v-card>
|
||||||
|
<v-app-bar dark dense color="primary">
|
||||||
|
<v-icon left>
|
||||||
|
mdi-account
|
||||||
|
</v-icon>
|
||||||
|
|
||||||
|
<v-toolbar-title class="headline">
|
||||||
|
{{ formTitle }}
|
||||||
|
</v-toolbar-title>
|
||||||
|
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<v-toolbar-title class="headline">
|
||||||
|
User ID: {{ editedItem.id }}
|
||||||
|
</v-toolbar-title>
|
||||||
|
</v-app-bar>
|
||||||
|
|
||||||
|
<v-card-text>
|
||||||
|
<v-container>
|
||||||
|
<v-row>
|
||||||
|
<v-col cols="12" sm="12" md="6">
|
||||||
|
<v-text-field
|
||||||
|
v-model="editedItem.full_name"
|
||||||
|
label="Full Name"
|
||||||
|
></v-text-field>
|
||||||
|
</v-col>
|
||||||
|
<v-col cols="12" sm="12" md="6">
|
||||||
|
<v-text-field
|
||||||
|
v-model="editedItem.email"
|
||||||
|
label="Email"
|
||||||
|
></v-text-field>
|
||||||
|
</v-col>
|
||||||
|
<v-col cols="12" sm="12" md="6">
|
||||||
|
<v-text-field
|
||||||
|
v-model="editedItem.family"
|
||||||
|
label="Family Group"
|
||||||
|
></v-text-field>
|
||||||
|
<v-col cols="12" sm="12" md="3">
|
||||||
|
<v-switch
|
||||||
|
v-model="editedItem.admin"
|
||||||
|
label="Admin"
|
||||||
|
></v-switch>
|
||||||
|
</v-col>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-container>
|
||||||
|
</v-card-text>
|
||||||
|
|
||||||
|
<v-card-actions>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<v-btn color="grey" text @click="close">
|
||||||
|
Cancel
|
||||||
|
</v-btn>
|
||||||
|
<v-btn color="primary" @click="save">
|
||||||
|
Save
|
||||||
|
</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
|
<Confirmation
|
||||||
|
ref="deleteUserDialog"
|
||||||
|
title="Confirm Delete User"
|
||||||
|
message="Are you sure you want to delete the user?"
|
||||||
|
icon="mdi-alert"
|
||||||
|
@confirm="deleteItemConfirm"
|
||||||
|
/>
|
||||||
|
</v-toolbar>
|
||||||
|
</template>
|
||||||
|
<template v-slot:item.actions="{ item }">
|
||||||
|
<v-btn class="mr-1" small color="error" @click="deleteItem(item)">
|
||||||
|
<v-icon small left>
|
||||||
|
mdi-delete
|
||||||
|
</v-icon>
|
||||||
|
Delete
|
||||||
|
</v-btn>
|
||||||
|
<v-btn small color="success" @click="editItem(item)">
|
||||||
|
<v-icon small left class="mr-2">
|
||||||
|
mdi-pencil
|
||||||
|
</v-icon>
|
||||||
|
Edit
|
||||||
|
</v-btn>
|
||||||
|
</template>
|
||||||
|
<template v-slot:item.admin="{ item }">
|
||||||
|
{{ item.admin ? "Admin" : "User" }}
|
||||||
|
</template>
|
||||||
|
<template v-slot:no-data>
|
||||||
|
<v-btn color="primary" @click="initialize">
|
||||||
|
Reset
|
||||||
|
</v-btn>
|
||||||
|
</template>
|
||||||
|
</v-data-table>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {};
|
import Confirmation from "@/components/UI/Confirmation";
|
||||||
|
export default {
|
||||||
|
components: { Confirmation },
|
||||||
|
data: () => ({
|
||||||
|
dialog: false,
|
||||||
|
dialogDelete: false,
|
||||||
|
headers: [
|
||||||
|
{
|
||||||
|
text: "User ID",
|
||||||
|
align: "start",
|
||||||
|
sortable: false,
|
||||||
|
value: "id",
|
||||||
|
},
|
||||||
|
{ text: "Full Name", value: "full_name" },
|
||||||
|
{ text: "Email", value: "email" },
|
||||||
|
{ text: "Family", value: "family" },
|
||||||
|
{ text: "Admin", value: "admin" },
|
||||||
|
{ text: "", value: "actions", sortable: false, align: "center" },
|
||||||
|
],
|
||||||
|
users: [],
|
||||||
|
editedIndex: -1,
|
||||||
|
editedItem: {
|
||||||
|
id: 0,
|
||||||
|
full_name: "",
|
||||||
|
email: "",
|
||||||
|
family: "",
|
||||||
|
admin: false,
|
||||||
|
},
|
||||||
|
defaultItem: {
|
||||||
|
id: 0,
|
||||||
|
full_name: "",
|
||||||
|
email: "",
|
||||||
|
family: "",
|
||||||
|
admin: false,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
formTitle() {
|
||||||
|
return this.editedIndex === -1 ? "New User" : "Edit User";
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
dialog(val) {
|
||||||
|
val || this.close();
|
||||||
|
},
|
||||||
|
dialogDelete(val) {
|
||||||
|
val || this.closeDelete();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
this.initialize();
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
initialize() {
|
||||||
|
this.users = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
full_name: "Change Me",
|
||||||
|
email: "changeme@email.com",
|
||||||
|
family: "public",
|
||||||
|
admin: false,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
},
|
||||||
|
|
||||||
|
editItem(item) {
|
||||||
|
this.editedIndex = this.users.indexOf(item);
|
||||||
|
this.editedItem = Object.assign({}, item);
|
||||||
|
this.dialog = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
deleteItem(item) {
|
||||||
|
this.editedIndex = this.users.indexOf(item);
|
||||||
|
this.editedItem = Object.assign({}, item);
|
||||||
|
this.$refs.deleteUserDialog.open();
|
||||||
|
},
|
||||||
|
|
||||||
|
deleteItemConfirm() {
|
||||||
|
this.users.splice(this.editedIndex, 1);
|
||||||
|
this.closeDelete();
|
||||||
|
},
|
||||||
|
|
||||||
|
close() {
|
||||||
|
this.dialog = false;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.editedItem = Object.assign({}, this.defaultItem);
|
||||||
|
this.editedIndex = -1;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
closeDelete() {
|
||||||
|
this.dialogDelete = false;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.editedItem = Object.assign({}, this.defaultItem);
|
||||||
|
this.editedIndex = -1;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
save() {
|
||||||
|
if (this.editedIndex > -1) {
|
||||||
|
Object.assign(this.users[this.editedIndex], this.editedItem);
|
||||||
|
} else {
|
||||||
|
this.users.push(this.editedItem);
|
||||||
|
}
|
||||||
|
this.close();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
|
@ -13,28 +13,30 @@
|
||||||
{{ $t("migration.recipe-migration") }}
|
{{ $t("migration.recipe-migration") }}
|
||||||
</v-card-title>
|
</v-card-title>
|
||||||
<v-divider></v-divider>
|
<v-divider></v-divider>
|
||||||
</v-card>
|
|
||||||
|
|
||||||
<v-row dense>
|
<v-card-text>
|
||||||
<v-col
|
<v-row dense>
|
||||||
:cols="12"
|
<v-col
|
||||||
:sm="6"
|
:cols="12"
|
||||||
:md="6"
|
:sm="6"
|
||||||
:lg="4"
|
:md="6"
|
||||||
:xl="3"
|
:lg="4"
|
||||||
v-for="migration in migrations"
|
:xl="3"
|
||||||
:key="migration.title"
|
v-for="migration in migrations"
|
||||||
>
|
:key="migration.title"
|
||||||
<MigrationCard
|
>
|
||||||
:title="migration.title"
|
<MigrationCard
|
||||||
:folder="migration.urlVariable"
|
:title="migration.title"
|
||||||
:description="migration.description"
|
:folder="migration.urlVariable"
|
||||||
:available="migration.availableImports"
|
:description="migration.description"
|
||||||
@refresh="getAvailableMigrations"
|
:available="migration.availableImports"
|
||||||
@imported="showReport"
|
@refresh="getAvailableMigrations"
|
||||||
/>
|
@imported="showReport"
|
||||||
</v-col>
|
/>
|
||||||
</v-row>
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-card-text>
|
||||||
|
</v-card>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,59 @@
|
||||||
<template>
|
<template>
|
||||||
<h1>Profile</h1>
|
<v-card>
|
||||||
|
<v-card-title class="headline">
|
||||||
|
<span>
|
||||||
|
<v-avatar color="accent" size="40" class="mr-2">
|
||||||
|
<img src="https://cdn.vuetifyjs.com/images/john.jpg" alt="John" />
|
||||||
|
</v-avatar>
|
||||||
|
</span>
|
||||||
|
Profile
|
||||||
|
</v-card-title>
|
||||||
|
<v-divider></v-divider>
|
||||||
|
<v-card-text>
|
||||||
|
<v-form>
|
||||||
|
<v-text-field label="Full Name"> </v-text-field>
|
||||||
|
<v-text-field label="Email"> </v-text-field>
|
||||||
|
<v-text-field label="Group" readonly> </v-text-field>
|
||||||
|
</v-form>
|
||||||
|
</v-card-text>
|
||||||
|
<v-card-actions>
|
||||||
|
<v-btn color="accent" class="mr-2">
|
||||||
|
<v-icon left> mdi-lock </v-icon>
|
||||||
|
{{ $t("settings.change-password") }}
|
||||||
|
</v-btn>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<v-btn color="success" class="mr-2">
|
||||||
|
<v-icon left> mdi-content-save </v-icon>
|
||||||
|
{{ $t("general.save") }}
|
||||||
|
</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
// import AvatarPicker from '@/components/AvatarPicker'
|
||||||
export default {
|
export default {
|
||||||
|
pageTitle: "My Profile",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loading: false,
|
||||||
|
form: {
|
||||||
|
firstName: "John",
|
||||||
|
lastName: "Doe",
|
||||||
|
contactEmail: "john@doe.com",
|
||||||
|
avatar: "MALE_CAUCASIAN_BLOND_BEARD",
|
||||||
|
},
|
||||||
|
showAvatarPicker: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
}
|
methods: {
|
||||||
</script>
|
openAvatarPicker() {
|
||||||
|
this.showAvatarPicker = true;
|
||||||
<style>
|
},
|
||||||
|
selectAvatar(avatar) {
|
||||||
</style>
|
this.form.avatar = avatar;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -1,13 +1,54 @@
|
||||||
<template>
|
<template>
|
||||||
<h1>Admin Settings</h1>
|
<v-card>
|
||||||
|
<v-card-title class="headline">
|
||||||
|
{{ $t("settings.admin-settings") }}
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<span>
|
||||||
|
<v-btn class="pt-1" text href="/docs">
|
||||||
|
{{ $t("settings.local-api") }}
|
||||||
|
<v-icon right>mdi-open-in-new</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
</span>
|
||||||
|
</v-card-title>
|
||||||
|
|
||||||
|
<v-divider></v-divider>
|
||||||
|
<HomePageSettings />
|
||||||
|
<v-divider></v-divider>
|
||||||
|
</v-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
import HomePageSettings from "@/components/Admin/General/HomePageSettings";
|
||||||
|
|
||||||
}
|
export default {
|
||||||
|
components: {
|
||||||
|
HomePageSettings,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
langOptions: [],
|
||||||
|
selectedLang: "en",
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getOptions();
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
selectedLang() {
|
||||||
|
this.$store.commit("setLang", this.selectedLang);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getOptions() {
|
||||||
|
this.langOptions = this.$store.getters.getAllLangs;
|
||||||
|
this.selectedLang = this.$store.getters.getActiveLang;
|
||||||
|
},
|
||||||
|
removeCategory(index) {
|
||||||
|
this.value.categories.splice(index, 1);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
||||||
</style>
|
</style>
|
|
@ -1,5 +1,4 @@
|
||||||
import Admin from "@/pages/Admin";
|
import Admin from "@/pages/Admin";
|
||||||
import General from "@/pages/Admin/General";
|
|
||||||
import Backup from "@/pages/Admin/Backup";
|
import Backup from "@/pages/Admin/Backup";
|
||||||
import Theme from "@/pages/Admin/Theme";
|
import Theme from "@/pages/Admin/Theme";
|
||||||
import MealPlanner from "@/pages/Admin/MealPlanner";
|
import MealPlanner from "@/pages/Admin/MealPlanner";
|
||||||
|
@ -20,10 +19,7 @@ export default {
|
||||||
path: "profile",
|
path: "profile",
|
||||||
component: Profile,
|
component: Profile,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: "general",
|
|
||||||
component: General,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: "backups",
|
path: "backups",
|
||||||
component: Backup,
|
component: Backup,
|
||||||
|
|
|
@ -11,9 +11,18 @@ import LoginPage from "../pages/LoginPage";
|
||||||
import MealPlanThisWeekPage from "../pages/MealPlanThisWeekPage";
|
import MealPlanThisWeekPage from "../pages/MealPlanThisWeekPage";
|
||||||
import api from "@/api";
|
import api from "@/api";
|
||||||
import Admin from "./admin";
|
import Admin from "./admin";
|
||||||
|
import { store } from "../store/store";
|
||||||
|
|
||||||
export const routes = [
|
export const routes = [
|
||||||
{ path: "/", name: "home", component: HomePage },
|
{ path: "/", name: "home", component: HomePage },
|
||||||
|
{
|
||||||
|
path: "/logout",
|
||||||
|
beforeEnter: (_to, _from, next) => {
|
||||||
|
store.commit("setToken", "");
|
||||||
|
store.commit("setIsLoggedIn", false);
|
||||||
|
next("/");
|
||||||
|
},
|
||||||
|
},
|
||||||
{ path: "/mealie", component: HomePage },
|
{ path: "/mealie", component: HomePage },
|
||||||
{ path: "/login", component: LoginPage },
|
{ path: "/login", component: LoginPage },
|
||||||
{ path: "/debug", component: Debug },
|
{ path: "/debug", component: Debug },
|
||||||
|
|
|
@ -18,6 +18,8 @@ const state = {
|
||||||
activeTheme: {},
|
activeTheme: {},
|
||||||
darkMode: "system",
|
darkMode: "system",
|
||||||
isDark: false,
|
isDark: false,
|
||||||
|
isLoggedIn: false,
|
||||||
|
token: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
const mutations = {
|
const mutations = {
|
||||||
|
@ -35,6 +37,13 @@ const mutations = {
|
||||||
state.darkMode = payload;
|
state.darkMode = payload;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
setIsLoggedIn(state, payload) {
|
||||||
|
state.isLoggedIn = payload;
|
||||||
|
},
|
||||||
|
setToken(state, payload) {
|
||||||
|
state.isLoggedIn = true;
|
||||||
|
state.token = payload;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const actions = {
|
const actions = {
|
||||||
|
@ -63,6 +72,8 @@ const getters = {
|
||||||
getActiveTheme: state => state.activeTheme,
|
getActiveTheme: state => state.activeTheme,
|
||||||
getDarkMode: state => state.darkMode,
|
getDarkMode: state => state.darkMode,
|
||||||
getIsDark: state => state.isDark,
|
getIsDark: state => state.isDark,
|
||||||
|
getIsLoggedIn: state => state.isLoggedIn,
|
||||||
|
getToken: state => state.token,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
@ -20,8 +20,6 @@ const store = new Vuex.Store({
|
||||||
homePage,
|
homePage,
|
||||||
},
|
},
|
||||||
state: {
|
state: {
|
||||||
// Auth
|
|
||||||
isLoggedIn: true,
|
|
||||||
|
|
||||||
// All Recipe Data Store
|
// All Recipe Data Store
|
||||||
recentRecipes: [],
|
recentRecipes: [],
|
||||||
|
@ -30,10 +28,6 @@ const store = new Vuex.Store({
|
||||||
},
|
},
|
||||||
|
|
||||||
mutations: {
|
mutations: {
|
||||||
setIsLoggedIn(state, payload) {
|
|
||||||
state.isLoggedIn = payload;
|
|
||||||
},
|
|
||||||
|
|
||||||
setRecentRecipes(state, payload) {
|
setRecentRecipes(state, payload) {
|
||||||
state.recentRecipes = payload;
|
state.recentRecipes = payload;
|
||||||
},
|
},
|
||||||
|
@ -62,7 +56,6 @@ const store = new Vuex.Store({
|
||||||
getters: {
|
getters: {
|
||||||
getRecentRecipes: state => state.recentRecipes,
|
getRecentRecipes: state => state.recentRecipes,
|
||||||
getMealPlanCategories: state => state.mealPlanCategories,
|
getMealPlanCategories: state => state.mealPlanCategories,
|
||||||
getIsLoggedIn: state => state.isLoggedIn,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue