Merge pull request #52 from hay-kot/frontend-refactor

Frontend Organization
This commit is contained in:
Hayden 2021-01-08 17:26:29 -09:00 committed by GitHub
commit a404788df9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
28 changed files with 80 additions and 231 deletions

View file

@ -20,7 +20,7 @@
</v-app-bar> </v-app-bar>
<v-main> <v-main>
<v-container> <v-container>
<AddRecipe /> <AddRecipeFab />
<SnackBar /> <SnackBar />
<v-expand-transition> <v-expand-transition>
<SearchHeader v-show="search" /> <SearchHeader v-show="search" />
@ -35,7 +35,7 @@
<script> <script>
import Menu from "./components/UI/Menu"; import Menu from "./components/UI/Menu";
import SearchHeader from "./components/UI/SearchHeader"; import SearchHeader from "./components/UI/SearchHeader";
import AddRecipe from "./components/AddRecipe"; import AddRecipeFab from "./components/UI/AddRecipeFab";
import SnackBar from "./components/UI/SnackBar"; import SnackBar from "./components/UI/SnackBar";
import Vuetify from "./plugins/vuetify"; import Vuetify from "./plugins/vuetify";
export default { export default {
@ -43,7 +43,7 @@ export default {
components: { components: {
Menu, Menu,
AddRecipe, AddRecipeFab,
SearchHeader, SearchHeader,
SnackBar SnackBar
}, },

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,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

@ -175,8 +175,8 @@
</template> </template>
<script> <script>
import api from "../../api"; import api from "../../../api";
import utils from "../../utils"; import utils from "../../../utils";
import BulkAdd from "./BulkAdd"; import BulkAdd from "./BulkAdd";
export default { export default {
components: { components: {

View file

@ -1,128 +0,0 @@
<template>
<v-card-text>
<v-row>
<v-col cols="4">
<h2 class="mb-4">Ingredients</h2>
<div v-for="ingredient in ingredients" :key="ingredient">
<v-row align="center">
<v-checkbox hide-details class="shrink mr-2 mt-0"></v-checkbox>
<v-text-field :value="ingredient"></v-text-field>
</v-row>
</div>
<v-btn
class="ml-n5"
color="primary"
fab`
dark
small
@click="addIngredient"
>
<v-icon>mdi-plus</v-icon>
</v-btn>
<h2 class="mt-6">Categories</h2>
<v-combobox
dense
multiple
chips
item-color="primary"
deletable-chips
:value="categories"
>
<template v-slot:selection="data">
<v-chip :selected="data.selected" close color="primary" dark>
{{ data.item }}
</v-chip>
</template>
</v-combobox>
<h2 class="mt-4">Tags</h2>
<v-combobox dense multiple chips deletable-chips :value="tags">
<template v-slot:selection="data">
<v-chip :selected="data.selected" close color="primary" dark>
{{ data.item }}
</v-chip>
</template>
</v-combobox>
</v-col>
<v-divider :vertical="true"></v-divider>
<v-col>
<h2 class="mb-4">Instructions</h2>
<div v-for="(step, index) in instructions" :key="step.text">
<v-hover v-slot="{ hover }">
<v-card
class="ma-1"
:class="[{ 'on-hover': hover }]"
:elevation="hover ? 12 : 2"
>
<v-card-title>Step: {{ index + 1 }}</v-card-title>
<v-card-text>
<v-textarea dense :value="step.text"></v-textarea>
</v-card-text>
</v-card>
</v-hover>
</div>
<v-btn color="primary" fab dark small @click="addStep">
<v-icon>mdi-plus</v-icon>
</v-btn>
</v-col>
</v-row>
</v-card-text>
</template>
<script>
export default {
props: {
form: Boolean,
ingredients: Array,
instructions: Array,
categories: Array,
tags: Array,
},
data() {
return {
disabledSteps: [],
};
},
methods: {
toggleDisabled(stepIndex) {
if (this.disabledSteps.includes(stepIndex)) {
let index = this.disabledSteps.indexOf(stepIndex);
if (index !== -1) {
this.disabledSteps.splice(index, 1);
}
} else {
this.disabledSteps.push(stepIndex);
}
},
isDisabled(stepIndex) {
if (this.disabledSteps.includes(stepIndex)) {
return "disabled-card";
} else {
return;
}
},
saveRecipe() {
this.$emit("save");
},
deleteRecipe() {
this.$emit("delete");
},
addIngredient() {
this.$emit("addingredient");
},
addStep() {
this.$emit("addstep");
},
},
};
</script>
<style>
.disabled-card {
opacity: 0.5;
}
</style>

View file

@ -62,7 +62,8 @@
</template> </template>
<script> <script>
import api from "../../api"; import api from "../../../api";
export default { export default {
data() { data() {
return { return {

View file

@ -40,7 +40,7 @@
</template> </template>
<script> <script>
import api from "../../api"; import api from "../../../api";
// import TimePicker from "./Webhooks/TimePicker"; // import TimePicker from "./Webhooks/TimePicker";
export default { export default {
data() { data() {

View file

@ -50,7 +50,7 @@
</v-select> </v-select>
</v-col> </v-col>
<v-col cols="12" sm="1"> <v-col cols="12" sm="1">
<NewTheme @new-theme="appendTheme" /> <NewThemeDialog @new-theme="appendTheme" />
</v-col> </v-col>
<v-col cols="12" sm="1"> <v-col cols="12" sm="1">
<v-btn text color="error" @click="deleteSelectedThemeValidation"> <v-btn text color="error" @click="deleteSelectedThemeValidation">
@ -69,40 +69,40 @@
</v-form> </v-form>
<v-row dense align-content="center" v-if="selectedTheme.colors"> <v-row dense align-content="center" v-if="selectedTheme.colors">
<v-col> <v-col>
<ColorPicker <ColorPickerDialog
button-text="Primary" button-text="Primary"
v-model="selectedTheme.colors.primary" v-model="selectedTheme.colors.primary"
/> />
</v-col> </v-col>
<v-col> <v-col>
<ColorPicker <ColorPickerDialog
button-text="Secondary" button-text="Secondary"
v-model="selectedTheme.colors.secondary" v-model="selectedTheme.colors.secondary"
/> />
</v-col> </v-col>
<v-col> <v-col>
<ColorPicker <ColorPickerDialog
button-text="Accent" button-text="Accent"
v-model="selectedTheme.colors.accent" v-model="selectedTheme.colors.accent"
/> />
</v-col> </v-col>
<v-col> <v-col>
<ColorPicker <ColorPickerDialog
button-text="Success" button-text="Success"
v-model="selectedTheme.colors.success" v-model="selectedTheme.colors.success"
/> />
</v-col> </v-col>
<v-col> <v-col>
<ColorPicker button-text="Info" v-model="selectedTheme.colors.info" /> <ColorPickerDialog button-text="Info" v-model="selectedTheme.colors.info" />
</v-col> </v-col>
<v-col> <v-col>
<ColorPicker <ColorPickerDialog
button-text="Warning" button-text="Warning"
v-model="selectedTheme.colors.warning" v-model="selectedTheme.colors.warning"
/> />
</v-col> </v-col>
<v-col> <v-col>
<ColorPicker <ColorPickerDialog
button-text="Error" button-text="Error"
v-model="selectedTheme.colors.error" v-model="selectedTheme.colors.error"
/> />
@ -125,16 +125,16 @@
</template> </template>
<script> <script>
import api from "../../api"; import api from "../../../api";
import ColorPicker from "./ThemeUI/ColorPicker"; import ColorPickerDialog from "./ColorPickerDialog";
import NewTheme from "./ThemeUI/NewTheme"; import NewThemeDialog from "./NewThemeDialog";
import Confirmation from "../UI/Confirmation"; import Confirmation from "../../UI/Confirmation";
export default { export default {
components: { components: {
ColorPicker, ColorPickerDialog,
Confirmation, Confirmation,
NewTheme, NewThemeDialog,
}, },
data() { data() {
return { return {
@ -186,10 +186,10 @@ export default {
/** /**
* Create the new Theme and select it. * Create the new Theme and select it.
*/ */
async appendTheme(newTheme) { async appendTheme(NewThemeDialog) {
await api.themes.create(newTheme); await api.themes.create(NewThemeDialog);
this.availableThemes.push(newTheme); this.availableThemes.push(NewThemeDialog);
this.selectedTheme = newTheme; this.selectedTheme = NewThemeDialog;
}, },
themeSelected() { themeSelected() {

View file

@ -20,7 +20,7 @@
></v-switch> ></v-switch>
</v-col> </v-col>
<v-col cols="12" md="3" sm="5"> <v-col cols="12" md="3" sm="5">
<TimePicker @save-time="saveTime" /> <TimePickerDialog @save-time="saveTime" />
</v-col> </v-col>
<v-col cols="12" md="4" sm="5"> <v-col cols="12" md="4" sm="5">
<v-btn text color="info" @click="testWebhooks"> Test Webhooks </v-btn> <v-btn text color="info" @click="testWebhooks"> Test Webhooks </v-btn>
@ -60,11 +60,11 @@
</template> </template>
<script> <script>
import api from "../../api"; import api from "../../../api";
import TimePicker from "./Webhooks/TimePicker"; import TimePickerDialog from "./TimePickerDialog";
export default { export default {
components: { components: {
TimePicker, TimePickerDialog,
}, },
data() { data() {
return { return {

View file

@ -41,7 +41,7 @@
</template> </template>
<script> <script>
import api from "../api"; import api from "../../api";
export default { export default {
data() { data() {

View file

@ -20,7 +20,7 @@
</template> </template>
<script> <script>
import RecipeCard from "./UI/RecipeCard"; import RecipeCard from "./RecipeCard";
export default { export default {
components: { components: {

View file

@ -5,7 +5,7 @@
</template> </template>
<script> <script>
import RecentRecipes from "./RecentRecipes"; import RecentRecipes from "../components/UI/RecentRecipes";
export default { export default {
components: { components: {

View file

@ -69,10 +69,10 @@
</template> </template>
<script> <script>
import api from "../../api"; import api from "../api";
import utils from "../../utils"; import utils from "../utils";
import NewMeal from "./NewMeal"; import NewMeal from "../components/MealPlan/MealPlanNew";
import EditPlan from "./EditPlan"; import EditPlan from "../components/MealPlan/MealPlanEditor";
export default { export default {
components: { components: {

View file

@ -39,8 +39,8 @@
</template> </template>
<script> <script>
import api from "../../api"; import api from "../api";
import utils from "../../utils"; import utils from "../utils";
export default { export default {
data() { data() {
return { return {

View file

@ -29,20 +29,20 @@
/> />
</div> </div>
<EditRecipe v-else v-model="recipeDetails" @upload="getImage" /> <RecipeEditor v-else v-model="recipeDetails" @upload="getImage" />
</v-card> </v-card>
</template> </template>
<script> <script>
import api from "../api"; import api from "../api";
import EditRecipe from "./RecipeEditor/EditRecipe"; import RecipeEditor from "../components/Recipe/RecipeEditor";
import VJsoneditor from "v-jsoneditor"; import VJsoneditor from "v-jsoneditor";
import ButtonRow from "./UI/ButtonRow"; import ButtonRow from "../components/UI/ButtonRow";
export default { export default {
components: { components: {
VJsoneditor, VJsoneditor,
EditRecipe, RecipeEditor,
ButtonRow, ButtonRow,
}, },
data() { data() {

View file

@ -18,7 +18,7 @@
@delete="deleteRecipe" @delete="deleteRecipe"
/> />
<ViewRecipe <RecipeViewer
v-if="!form" v-if="!form"
:name="recipeDetails.name" :name="recipeDetails.name"
:ingredients="recipeDetails.recipeIngredient" :ingredients="recipeDetails.recipeIngredient"
@ -39,7 +39,7 @@
height="1500px" height="1500px"
:options="jsonEditorOptions" :options="jsonEditorOptions"
/> />
<EditRecipe v-else v-model="recipeDetails" @upload="getImageFile" /> <RecipeEditor v-else v-model="recipeDetails" @upload="getImageFile" />
</v-card> </v-card>
</template> </template>
@ -47,16 +47,16 @@
import api from "../api"; import api from "../api";
import utils from "../utils"; import utils from "../utils";
import VJsoneditor from "v-jsoneditor"; import VJsoneditor from "v-jsoneditor";
import ViewRecipe from "./RecipeEditor/ViewRecipe"; import RecipeViewer from "../components/Recipe/RecipeViewer";
import EditRecipe from "./RecipeEditor/EditRecipe"; import RecipeEditor from "../components/Recipe/RecipeEditor";
import ButtonRow from "./UI/ButtonRow"; import ButtonRow from "../components/UI/ButtonRow";
export default { export default {
components: { components: {
VJsoneditor, VJsoneditor,
ViewRecipe, RecipeViewer,
EditRecipe, RecipeEditor,
ButtonRow ButtonRow,
}, },
data() { data() {
return { return {
@ -66,7 +66,7 @@ export default {
jsonEditorOptions: { jsonEditorOptions: {
mode: "code", mode: "code",
search: false, search: false,
mainMenuBar: false mainMenuBar: false,
}, },
// Recipe Details // // Recipe Details //
recipeDetails: { recipeDetails: {
@ -83,9 +83,9 @@ export default {
categories: [], categories: [],
dateAdded: "", dateAdded: "",
notes: [], notes: [],
rating: 0 rating: 0,
}, },
imageKey: 1 imageKey: 1,
}; };
}, },
mounted() { mounted() {
@ -93,9 +93,9 @@ export default {
}, },
watch: { watch: {
$route: function() { $route: function () {
this.getRecipeDetails(); this.getRecipeDetails();
} },
}, },
computed: { computed: {
@ -111,7 +111,7 @@ export default {
} else { } else {
return false; return false;
} }
} },
}, },
methods: { methods: {
getImageFile(fileObject) { getImageFile(fileObject) {
@ -142,8 +142,8 @@ export default {
showForm() { showForm() {
this.form = true; this.form = true;
this.jsonEditor = false; this.jsonEditor = false;
} },
} },
}; };
</script> </script>

View file

@ -27,10 +27,10 @@
</template> </template>
<script> <script>
import Backup from "./Backup"; import Backup from "../components/Settings/Backup";
import Webhooks from "./Webhooks"; import Webhooks from "../components/Settings/Webhook";
import Theme from "./Theme"; import Theme from "../components/Settings/Theme";
import Migration from "./Migration"; import Migration from "../components/Settings/Migration";
import axios from "axios"; import axios from "axios";
export default { export default {

View file

@ -1,23 +1,23 @@
import Home from "./components/Home"; import HomePage from "./pages/HomePage";
import Page404 from "./components/Page404"; import Page404 from "./pages/404Page";
import Recipe from "./components/Recipe"; import RecipePage from "./pages/RecipePage";
import NewRecipe from "./components/NewRecipe"; import RecipeNewPage from "./pages/RecipeNewPage";
import Admin from "./components/Admin/Admin"; import SettingsPage from "./pages/SettingsPage";
import MealPlanner from "./components/MealPlan/MealPlanner"; import MeaplPlanPage from "./pages/MealPlanPage";
import ThisWeek from "./components/MealPlan/ThisWeek"; import MealPlanThisWeekPage from "./pages/MealPlanThisWeekPage";
import api from "./api"; import api from "./api";
export const routes = [ export const routes = [
{ path: "/", component: Home }, { path: "/", component: HomePage },
{ path: "/mealie", component: Home }, { path: "/mealie", component: HomePage },
{ path: "/recipe/:recipe", component: Recipe }, { path: "/recipe/:recipe", component: RecipePage },
{ path: "/new/", component: NewRecipe }, { path: "/new/", component: RecipeNewPage },
{ path: "/settings/site", component: Admin }, { path: "/settings/site", component: SettingsPage },
{ path: "/meal-plan/planner", component: MealPlanner }, { path: "/meal-plan/planner", component: MeaplPlanPage },
{ path: "/meal-plan/this-week", component: ThisWeek }, { path: "/meal-plan/this-week", component: MealPlanThisWeekPage },
{ {
path: "/meal-plan/today", path: "/meal-plan/today",
beforeEnter: async (_to, _from, next) => { beforeEnter: async (_to, _from, next) => {
await todaysMealRoute().then((redirect) => { await todaysMealRoute().then((redirect) => {
next(redirect); next(redirect);
}); });

View file

@ -77,7 +77,7 @@ async def parse_recipe_url(url: RecipeURLIn):
return slug return slug
@router.post("/api/recipe/create/", tags=["Recipes"], response_model=SlugResponse) @router.post("/api/recipe/create/", tags=["Recipes"])
async def create_from_json(data: Recipe) -> str: async def create_from_json(data: Recipe) -> str:
""" Takes in a JSON string and loads data into the database as a new entry""" """ Takes in a JSON string and loads data into the database as a new entry"""
created_recipe = data.save_to_db() created_recipe = data.save_to_db()