1
0
Fork 0
mirror of https://github.com/mealie-recipes/mealie.git synced 2025-08-03 20:45:23 +02:00

file reorganize

This commit is contained in:
Hayden 2021-01-08 17:09:03 -09:00
parent a731b9f6ab
commit fef8ad540a
28 changed files with 80 additions and 231 deletions

View file

@ -1,75 +0,0 @@
<template>
<v-container>
<v-alert v-if="newVersion" color="green" type="success" outlined>
A New Version of Mealie is Avaiable,
<a href="https://github.com/hay-kot/mealie" class="green--text">
Visit the Repo
</a>
</v-alert>
<Theme />
<Backup />
<Webhooks />
<Migration />
<p class="text-center my-2">
Version: {{ version }} | Latest: {{ latestVersion }} ·
<a href="https://hay-kot.github.io/mealie/" target="_blank">
Explore the Docs
</a>
·
<a
href="https://hay-kot.github.io/mealie/2.1%20-%20Contributions/"
target="_blank"
>
Contribute
</a>
</p>
</v-container>
</template>
<script>
import Backup from "./Backup";
import Webhooks from "./Webhooks";
import Theme from "./Theme";
import Migration from "./Migration";
import axios from "axios";
export default {
components: {
Backup,
Webhooks,
Theme,
Migration,
},
data() {
return {
latestVersion: null,
version: "v0.0.1",
};
},
mounted() {
this.getVersion();
},
computed: {
newVersion() {
if ((this.latestVersion != null) & (this.latestVersion != this.version)) {
console.log("New Version Avaiable");
return true;
} else {
return false;
}
},
},
methods: {
async getVersion() {
let response = await axios.get(
"https://api.github.com/repos/hay-kot/mealie/releases/latest"
);
console.log(response);
this.latestVersion = response.data.tag_name;
},
},
};
</script>
<style>
</style>

View file

@ -1,124 +0,0 @@
<template>
<v-card :loading="backupLoading" class="mt-3" min-height="410px">
<v-card-title class="secondary white--text">
Backup and Exports
</v-card-title>
<v-card-text>
<p>
Backups are exported in standard JSON format along with all the images
stored on the file system. In your backup folder you'll find a .zip file
that contains all of the recipe JSON and images from the database.
Additionally, if you selected a markdown file, those will also be stored
in the .zip file. To import a backup, it must be located in your backups
folder. Automated backups are done each day at 3:00 AM.
</p>
<v-row dense align="center">
<v-col dense cols="12" sm="12" md="4">
<v-text-field v-model="backupTag" label="Backup Tag"></v-text-field>
</v-col>
<v-col cols="12" sm="12" md="3">
<v-combobox
auto-select-first
label="Markdown Template"
:items="availableTemplates"
v-model="selectedTemplate"
></v-combobox>
</v-col>
<v-col dense cols="12" sm="12" md="2">
<v-btn block color="accent" @click="createBackup" width="165">
Backup Recipes
</v-btn>
</v-col>
</v-row>
<v-row dense align="center">
<v-col dense cols="12" sm="12" md="4">
<v-form ref="form">
<v-combobox
auto-select-first
label="Select a Backup for Import"
:items="availableBackups"
v-model="selectedBackup"
:rules="[(v) => !!v || 'Backup Selection is Required']"
required
></v-combobox>
</v-form>
</v-col>
<v-col dense cols="12" sm="12" md="3" lg="2">
<v-btn block color="accent" @click="importBackup">
Import Backup
</v-btn>
</v-col>
<v-col dense cols="12" sm="12" md="2" lg="2">
<v-btn block color="error" @click="deleteBackup">
Delete Backup
</v-btn>
</v-col>
</v-row>
</v-card-text>
</v-card>
</template>
<script>
import api from "../../api";
export default {
data() {
return {
backupLoading: false,
backupTag: null,
selectedBackup: null,
selectedTemplate: null,
availableBackups: [],
availableTemplates: [],
};
},
mounted() {
this.getAvailableBackups();
},
methods: {
async getAvailableBackups() {
let response = await api.backups.requestAvailable();
this.availableBackups = response.imports;
this.availableTemplates = response.templates;
},
importBackup() {
if (this.$refs.form.validate()) {
this.backupLoading = true;
api.backups.import(this.selectedBackup);
this.backupLoading = false;
}
},
deleteBackup() {
if (this.$refs.form.validate()) {
this.backupLoading = true;
api.backups.delete(this.selectedBackup);
this.getAvailableBackups();
this.selectedBackup = null;
this.backupLoading = false;
}
},
async createBackup() {
this.backupLoading = true;
let response = await api.backups.create(
this.backupTag,
this.selectedTemplate
);
if (response.status == 201) {
this.selectedBackup = null;
this.getAvailableBackups();
this.backupLoading = false;
}
},
},
};
</script>
<style>
</style>

View file

@ -1,69 +0,0 @@
<template>
<v-card :loading="loading">
<v-card-title class="secondary white--text mt-1">
Recipe Migration
</v-card-title>
<v-card-text>
<p>
Currently Chowdown via public Repo URL is the only supported type of
migration
</p>
<v-form>
<v-row dense align="center">
<v-col cols="12" md="5" sm="5">
<v-text-field v-model="repo" label="Chowdown Repo URL">
</v-text-field>
</v-col>
<v-col cols="12" md="4" sm="5">
<v-btn text color="info" @click="importRepo"> Migrate </v-btn>
</v-col>
</v-row>
</v-form>
<v-alert v-if="failedRecipes[1]" outlined dense type="error">
<h4>Failed Recipes</h4>
<v-list dense>
<v-list-item v-for="fail in this.failedRecipes" :key="fail">
{{ fail }}
</v-list-item>
</v-list>
</v-alert>
<v-alert v-if="failedImages[1]" outlined dense type="error">
<h4>Failed Images</h4>
<v-list dense>
<v-list-item v-for="fail in this.failedImages" :key="fail">
{{ fail }}
</v-list-item>
</v-list>
</v-alert>
</v-card-text>
</v-card>
</template>
<script>
import api from "../../api";
// import TimePicker from "./Webhooks/TimePicker";
export default {
data() {
return {
processRan: false,
loading: false,
failedImages: [],
failedRecipes: [],
repo: "",
};
},
methods: {
async importRepo() {
this.loading = true;
let response = await api.migrations.migrateChowdown(this.repo);
this.failedImages = response.failedImages;
this.failedRecipes = response.failedRecipes;
this.loading = false;
this.processRan = true;
},
},
};
</script>
<style>
</style>

View file

@ -1,12 +0,0 @@
<template>
<v-card>
<v-card-title class="card-title mt-1"> SFTP Settings </v-card-title>
</v-card>
</template>
<script>
export default {};
</script>
<style>
</style>

View file

@ -1,222 +0,0 @@
<template>
<v-card>
<v-card-title class="secondary white--text"> Theme Settings </v-card-title>
<v-card-text>
<h2 class="mt-4 mb-1">Dark Mode</h2>
<p>
Choose how Mealie looks to you. Set your theme preference to follow your
system settings, or choose to use the light or dark theme.
</p>
<v-row dense align="center">
<v-col cols="12">
<v-btn-toggle
v-model="selectedDarkMode"
color="primary "
mandatory
@change="setStoresDarkMode"
>
<v-btn value="system"> Default to system </v-btn>
<v-btn value="light"> Light </v-btn>
<v-btn value="dark"> Dark </v-btn>
</v-btn-toggle>
</v-col>
</v-row></v-card-text
>
<v-divider class=""></v-divider>
<v-card-text>
<h2 class="mt-1 mb-1">Theme</h2>
<p>
Select a theme from the dropdown or create a new theme. Note that the
default theme will be served to all users who have not set a theme
preference.
</p>
<v-form ref="form" lazy-validation>
<v-row dense align="center">
<v-col cols="12" md="4" sm="3">
<v-select
label="Saved Color Theme"
:items="availableThemes"
item-text="name"
return-object
v-model="selectedTheme"
@change="themeSelected"
:rules="[(v) => !!v || 'Theme is required']"
required
>
</v-select>
</v-col>
<v-col cols="12" sm="1">
<NewTheme @new-theme="appendTheme" />
</v-col>
<v-col cols="12" sm="1">
<v-btn text color="error" @click="deleteSelectedThemeValidation">
Delete
</v-btn>
<Confirmation
title="Delete Theme"
message="Are you sure you want to delete this theme?"
color="error"
icon="mdi-alert-circle"
ref="deleteThemeConfirm"
v-on:confirm="deleteSelectedTheme()"
/>
</v-col>
</v-row>
</v-form>
<v-row dense align-content="center" v-if="selectedTheme.colors">
<v-col>
<ColorPicker
button-text="Primary"
v-model="selectedTheme.colors.primary"
/>
</v-col>
<v-col>
<ColorPicker
button-text="Secondary"
v-model="selectedTheme.colors.secondary"
/>
</v-col>
<v-col>
<ColorPicker
button-text="Accent"
v-model="selectedTheme.colors.accent"
/>
</v-col>
<v-col>
<ColorPicker
button-text="Success"
v-model="selectedTheme.colors.success"
/>
</v-col>
<v-col>
<ColorPicker button-text="Info" v-model="selectedTheme.colors.info" />
</v-col>
<v-col>
<ColorPicker
button-text="Warning"
v-model="selectedTheme.colors.warning"
/>
</v-col>
<v-col>
<ColorPicker
button-text="Error"
v-model="selectedTheme.colors.error"
/>
</v-col>
</v-row>
</v-card-text>
<v-card-actions>
<v-row>
<v-col> </v-col>
<v-col></v-col>
<v-col align="end">
<v-btn text color="success" @click="saveThemes">
Save Colors and Apply Theme
</v-btn>
</v-col>
</v-row>
</v-card-actions>
</v-card>
</template>
<script>
import api from "../../api";
import ColorPicker from "./ThemeUI/ColorPicker";
import NewTheme from "./ThemeUI/NewTheme";
import Confirmation from "../UI/Confirmation";
export default {
components: {
ColorPicker,
Confirmation,
NewTheme,
},
data() {
return {
selectedTheme: {},
selectedDarkMode: "system",
availableThemes: [],
};
},
async mounted() {
this.availableThemes = await api.themes.requestAll();
this.selectedTheme = this.$store.getters.getActiveTheme;
this.selectedDarkMode = this.$store.getters.getDarkMode;
console.log(this.selectedDarkMode);
},
methods: {
/**
* Open the delete confirmation.
*/
deleteSelectedThemeValidation() {
if (this.$refs.form.validate()) {
if (this.selectedTheme.name === "default") {
// Notify User Can't Delete Default
} else if (this.selectedTheme !== {}) {
this.$refs.deleteThemeConfirm.open();
}
}
},
/**
* Delete the selected Theme
*/
async deleteSelectedTheme() {
//Delete Theme from DB
await api.themes.delete(this.selectedTheme.name);
//Get the new list of available from DB
this.availableThemes = await api.themes.requestAll();
//Change to default if deleting current theme.
if (
!this.availableThemes.some(
(theme) => theme.name === this.selectedTheme.name
)
) {
await this.$store.dispatch("resetTheme");
this.selectedTheme = this.$store.getters.getActiveTheme;
}
},
/**
* Create the new Theme and select it.
*/
async appendTheme(newTheme) {
await api.themes.create(newTheme);
this.availableThemes.push(newTheme);
this.selectedTheme = newTheme;
},
themeSelected() {
//TODO Revamp Theme selection.
//console.log("this.activeTheme", this.selectedTheme);
},
setStoresDarkMode() {
console.log(this.selectedDarkMode);
this.$store.commit("setDarkMode", this.selectedDarkMode);
},
/**
* This will save the current colors and make the selected theme live.
*/
async saveThemes() {
if (this.$refs.form.validate()) {
this.$store.commit("setTheme", this.selectedTheme);
await api.themes.update(
this.selectedTheme.name,
this.selectedTheme.colors
);
}
},
},
};
</script>
<style>
</style>

View file

@ -1,70 +0,0 @@
<template>
<div>
<v-btn block :color="value" @click="dialog = true">
{{ buttonText }}
</v-btn>
<v-dialog v-model="dialog" width="400">
<v-card>
<v-card-title> {{ buttonText }} Color </v-card-title>
<v-card-text>
<v-text-field v-model="color"> </v-text-field>
<v-row>
<v-col></v-col>
<v-col>
<v-color-picker
dot-size="28"
hide-inputs
hide-mode-switch
mode="hexa"
:show-swatches="swatches"
swatches-max-height="300"
v-model="color"
@change="updateColor"
></v-color-picker>
</v-col>
<v-col></v-col>
</v-row>
</v-card-text>
<v-card-actions>
<v-btn text @click="toggleSwatches"> Swatches </v-btn>
<v-btn text @click="dialog = false"> Select </v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</div>
</template>
<script>
export default {
props: {
buttonText: String,
value: String,
},
data() {
return {
dialog: false,
swatches: false,
color: "#FF00FF",
};
},
watch: {
color() {
this.updateColor();
},
},
methods: {
toggleSwatches() {
if (this.swatches) {
this.swatches = false;
} else this.swatches = true;
},
updateColor() {
this.$emit("input", this.color);
},
},
};
</script>
<style>
</style>

View file

@ -1,73 +0,0 @@
<template>
<div>
<v-btn text color="success" @click="dialog = true"> New </v-btn>
<v-dialog v-model="dialog" width="400">
<v-card>
<v-card-title> Add a New Theme </v-card-title>
<v-card-text>
<v-text-field
label="Theme Name"
v-model="themeName"
:rules="[rules.required]"
></v-text-field>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="grey" text @click="dialog = false"> Cancel </v-btn>
<v-btn color="success" text @click="Select" :disabled="!themeName">
Create
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</div>
</template>
<script>
export default {
props: {
buttonText: String,
value: String,
},
data() {
return {
dialog: false,
themeName: "",
rules: {
required: (val) => !!val || "Required.",
},
};
},
watch: {
color() {
this.updateColor();
},
},
methods: {
randomColor() {
return "#" + Math.floor(Math.random() * 16777215).toString(16);
},
Select() {
const newTheme = {
name: this.themeName,
colors: {
primary: "#E58325",
accent: "#00457A",
secondary: "#973542",
success: "#5AB1BB",
info: "#4990BA",
warning: "#FF4081",
error: "#EF5350",
},
};
this.$emit("new-theme", newTheme);
this.dialog = false;
},
},
};
</script>
<style>
</style>

View file

@ -1,12 +0,0 @@
<template>
<v-card>
<v-card-title class="card-title mt-1"> User Settings </v-card-title>
</v-card>
</template>
<script>
export default {};
</script>
<style>
</style>

View file

@ -1,116 +0,0 @@
<template>
<v-card>
<v-card-title class="secondary white--text mt-1">
Meal Planner Webhooks
</v-card-title>
<v-card-text>
<p>
The URLs listed below will recieve webhooks containing the recipe data
for the meal plan on it's scheduled day. Currently Webhooks will execute
at <strong>{{ time }}</strong>
</p>
<v-row dense align="center">
<v-col cols="12" md="2" sm="5">
<v-switch
v-model="enabled"
inset
label="Enabled"
class="my-n3"
></v-switch>
</v-col>
<v-col cols="12" md="3" sm="5">
<TimePicker @save-time="saveTime" />
</v-col>
<v-col cols="12" md="4" sm="5">
<v-btn text color="info" @click="testWebhooks"> Test Webhooks </v-btn>
</v-col>
</v-row>
<v-row v-for="(url, index) in webhooks" :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="webhooks[index]"
label="Webhook URL"
></v-text-field>
</v-col>
</v-row>
</v-card-text>
<v-card-actions>
<v-row>
<v-col>
<v-btn icon color="success" @click="addWebhook">
<v-icon>mdi-plus</v-icon>
</v-btn>
</v-col>
<v-col> </v-col>
<v-col align="end">
<v-btn text color="success" @click="saveWebhooks">
Save Webhooks
</v-btn>
</v-col>
</v-row>
</v-card-actions>
</v-card>
</template>
<script>
import api from "../../api";
import TimePicker from "./Webhooks/TimePicker";
export default {
components: {
TimePicker,
},
data() {
return {
name: "main",
webhooks: [],
enabled: false,
time: "",
};
},
mounted() {
this.getSiteSettings();
},
methods: {
saveTime(value) {
this.time = value;
},
async getSiteSettings() {
let settings = await api.settings.requestAll();
this.webhooks = settings.webhooks.webhookURLs;
this.name = settings.name;
this.time = settings.webhooks.webhookTime;
this.enabled = settings.webhooks.enabled;
},
addWebhook() {
this.webhooks.push(" ");
},
removeWebhook(index) {
this.webhooks.splice(index, 1);
},
saveWebhooks() {
const body = {
name: this.name,
webhooks: {
webhookURLs: this.webhooks,
webhookTime: this.time,
enabled: this.enabled,
},
};
api.settings.update(body);
},
testWebhooks() {
api.settings.testWebhooks();
},
},
};
</script>
<style>
</style>

View file

@ -1,45 +0,0 @@
<template>
<v-dialog
ref="dialog"
v-model="modal2"
:return-value.sync="time"
persistent
width="290px"
>
<template v-slot:activator="{ on, attrs }">
<v-text-field
v-model="time"
label="Set New Time"
prepend-icon="mdi-clock-time-four-outline"
readonly
v-bind="attrs"
v-on="on"
></v-text-field>
</template>
<v-time-picker v-if="modal2" v-model="time" full-width>
<v-spacer></v-spacer>
<v-btn text color="primary" @click="modal2 = false"> Cancel </v-btn>
<v-btn text color="primary" @click="saveTime"> OK </v-btn>
</v-time-picker>
</v-dialog>
</template>
<script>
export default {
data() {
return {
time: null,
modal2: false,
};
},
methods: {
saveTime() {
this.$refs.dialog.save(this.time);
this.$emit("save-time", this.time);
},
},
};
</script>
<style scoped>
</style>