feature/recipe-patch-improvements (#382)

* automated docs update

* recipe rating component

* recipe partial updates - closes #25

* use Vue.delete to update store

* format

* arrow functions

* fix tests

* format

* initial context menu

* localize

* add confirmation dialog

* context menu

* fix bare exception

* update line length

* format all file with prettier

* update changelog

* download as json

* update python dependencies

* update javascript dependencies

Co-authored-by: hay-kot <hay-kot@pm.me>
This commit is contained in:
Hayden
2021-05-01 20:46:02 -08:00
committed by GitHub
parent c196445e61
commit be378cb20c
121 changed files with 18942 additions and 4765 deletions

View File

@@ -47,5 +47,4 @@ export default {
};
</script>
<style lang="scss" scoped>
</style>
<style lang="scss" scoped></style>

View File

@@ -1,12 +1,7 @@
<template>
<v-form ref="file">
<input ref="uploader" class="d-none" type="file" @change="onFileChanged" />
<v-btn
:loading="isSelecting"
@click="onButtonClick"
color="accent"
:text="textBtn"
>
<v-btn :loading="isSelecting" @click="onButtonClick" color="accent" :text="textBtn">
<v-icon left> {{ icon }}</v-icon>
{{ text ? text : defaultText }}
</v-btn>
@@ -55,7 +50,7 @@ export default {
let formData = new FormData();
formData.append(this.fileName, this.file);
if(await api.utils.uploadFile(this.url, formData)) {
if (await api.utils.uploadFile(this.url, formData)) {
this.$emit(UPLOAD_EVENT);
}
this.isSelecting = false;
@@ -81,5 +76,4 @@ export default {
};
</script>
<style>
</style>
<style></style>

View File

@@ -22,14 +22,10 @@
</template>
<v-list>
<v-list-item @click="$emit('sort-recent')">
<v-list-item-title>{{
$t("general.recent")
}}</v-list-item-title>
<v-list-item-title>{{ $t("general.recent") }}</v-list-item-title>
</v-list-item>
<v-list-item @click="$emit('sort')">
<v-list-item-title>{{
$t("general.sort-alphabetically")
}}</v-list-item-title>
<v-list-item-title>{{ $t("general.sort-alphabetically") }}</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
@@ -39,14 +35,7 @@
</v-card>
<div v-if="recipes">
<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"
>
<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"
@@ -148,10 +137,7 @@ export default {
},
methods: {
bumpList() {
const newCardLimit = Math.min(
this.cardLimit + 20,
this.effectiveHardLimit
);
const newCardLimit = Math.min(this.cardLimit + 20, this.effectiveHardLimit);
if (this.loading === false && newCardLimit > this.cardLimit) {
this.setLoader();
@@ -172,4 +158,4 @@ export default {
.transparent {
opacity: 1;
}
</style>
</style>

View File

@@ -1,11 +1,7 @@
<template>
<div>
<slot name="open" v-bind="{ open }"> </slot>
<v-dialog
v-model="dialog"
:width="modalWidth + 'px'"
:content-class="top ? 'top-dialog' : undefined"
>
<v-dialog v-model="dialog" :width="modalWidth + 'px'" :content-class="top ? 'top-dialog' : undefined">
<v-card class="pb-10" height="100%">
<v-app-bar dark :color="color" class="mt-n1 mb-2">
<v-icon large left>
@@ -14,20 +10,16 @@
<v-toolbar-title class="headline"> {{ title }} </v-toolbar-title>
<v-spacer></v-spacer>
</v-app-bar>
<v-progress-linear
v-if="loading"
indeterminate
color="primary"
></v-progress-linear>
<v-progress-linear v-if="loading" indeterminate color="primary"></v-progress-linear>
<slot> </slot>
<v-card-actions>
<slot name="card-actions">
<v-btn text color="grey" @click="dialog = false">
{{$t('general.cancel')}}
{{ $t("general.cancel") }}
</v-btn>
<v-spacer></v-spacer>
<v-btn color="success" @click="submitEvent">
{{$t('general.submit')}}
{{ $t("general.submit") }}
</v-btn>
</slot>
</v-card-actions>
@@ -84,4 +76,4 @@ export default {
.top-dialog {
align-self: flex-start;
}
</style>
</style>

View File

@@ -1,4 +1,3 @@
<template>
<v-dialog
v-model="dialog"
@@ -7,17 +6,16 @@
@click:outside="cancel"
@keydown.esc="cancel"
>
<template v-slot:activator="{}">
<slot v-bind="{ open }"> </slot>
</template>
<v-card>
<v-app-bar v-if="Boolean(title)" :color="color" dense dark>
<v-app-bar v-if="Boolean(title)" :color="color" dense dark>
<v-icon v-if="Boolean(icon)" left> {{ icon }}</v-icon>
<v-toolbar-title v-text="title" />
</v-app-bar>
<v-card-text
v-show="!!message"
class="pa-4 text--primary"
v-html="message"
/>
<v-card-text v-show="!!message" class="pa-4 text--primary" v-html="message" />
<v-card-actions>
<v-spacer></v-spacer>
@@ -35,6 +33,7 @@
<script>
const CLOSE_EVENT = "close";
const OPEN_EVENT = "open";
const CONFIRM_EVENT = "confirm";
/**
* ConfirmationDialog Component used to add a second validaion step to an action.
* @version 1.0.1
@@ -96,13 +95,9 @@ export default {
dialog: false,
}),
methods: {
/**
* Sets the modal to be visiable.
*/
open() {
this.dialog = true;
},
/**
* Cancel button handler.
*/
@@ -129,7 +124,7 @@ export default {
* @event confirm
* @property {string} content content of the first prop passed to the event
*/
this.$emit("confirm");
this.$emit(CONFIRM_EVENT);
//Hide Modal
this.dialog = false;
@@ -138,5 +133,4 @@ export default {
};
</script>
<style>
</style>
<style></style>

View File

@@ -21,12 +21,7 @@
<v-card-title> </v-card-title>
<v-form @submit.prevent="select">
<v-card-text>
<v-text-field
dense
:label="inputLabel"
v-model="itemName"
:rules="[rules.required]"
></v-text-field>
<v-text-field dense :label="inputLabel" v-model="itemName" :rules="[rules.required]"></v-text-field>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
@@ -103,5 +98,4 @@ export default {
};
</script>
<style>
</style>
<style></style>

View File

@@ -61,9 +61,7 @@ export default {
try {
this.results = this.fuse.search(this.search.trim());
} catch {
this.results = this.rawData
.map(x => ({ item: x }))
.sort((a, b) => (a.name > b.name ? 1 : -1));
this.results = this.rawData.map(x => ({ item: x })).sort((a, b) => (a.name > b.name ? 1 : -1));
}
this.$emit(RESULTS_EVENT, this.results);
@@ -75,5 +73,4 @@ export default {
};
</script>
<style scoped>
</style>
<style scoped></style>

View File

@@ -1,11 +1,5 @@
<template>
<v-menu
v-model="menuModel"
readonly
offset-y
offset-overflow
max-height="75vh"
>
<v-menu v-model="menuModel" readonly offset-y offset-overflow max-height="75vh">
<template #activator="{ attrs }">
<v-text-field
ref="searchInput"
@@ -33,12 +27,7 @@
</template>
</v-text-field>
</template>
<v-card
v-if="showResults"
max-height="75vh"
:max-width="maxWidth"
scrollable
>
<v-card v-if="showResults" max-height="75vh" :max-width="maxWidth" scrollable>
<v-card-text class="flex row mx-auto ">
<div class="mr-auto">
Results
@@ -56,22 +45,10 @@
<v-list-item-avatar>
<v-img :src="getImage(item.item.slug)"></v-img>
</v-list-item-avatar>
<v-list-item-content
@click="
showResults ? null : selected(item.item.slug, item.item.name)
"
>
<v-list-item-title v-html="highlight(item.item.name)">
</v-list-item-title>
<v-rating
dense
v-if="item.item.rating"
:value="item.item.rating"
size="12"
>
</v-rating>
<v-list-item-subtitle v-html="highlight(item.item.description)">
</v-list-item-subtitle>
<v-list-item-content @click="showResults ? null : selected(item.item.slug, item.item.name)">
<v-list-item-title v-html="highlight(item.item.name)"> </v-list-item-title>
<v-rating dense v-if="item.item.rating" :value="item.item.rating" size="12"> </v-rating>
<v-list-item-subtitle v-html="highlight(item.item.description)"> </v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
</v-list>
@@ -153,9 +130,7 @@ export default {
try {
this.result = this.fuse.search(this.search.trim());
} catch {
this.result = this.data
.map(x => ({ item: x }))
.sort((a, b) => (a.name > b.name ? 1 : -1));
this.result = this.data.map(x => ({ item: x })).sort((a, b) => (a.name > b.name ? 1 : -1));
}
this.$emit("results", this.result);
@@ -173,10 +148,7 @@ export default {
if (!this.search) {
return string;
}
return string.replace(
new RegExp(this.search, "gi"),
match => `<mark>${match}</mark>`
);
return string.replace(new RegExp(this.search, "gi"), match => `<mark>${match}</mark>`);
},
getImage(image) {
return api.recipes.recipeTinyImage(image);
@@ -221,4 +193,4 @@ export default {
&, & > *
display: flex
flex-direction: column
</style>
</style>

View File

@@ -1,12 +1,6 @@
<template>
<div class="text-center ">
<v-dialog
v-model="dialog"
width="600px"
height="0"
:fullscreen="isMobile"
content-class="top-dialog"
>
<v-dialog v-model="dialog" width="600px" height="0" :fullscreen="isMobile" content-class="top-dialog">
<v-card>
<v-app-bar dark color="primary lighten-1" rounded="0">
<SearchBar
@@ -103,4 +97,4 @@ export default {
.top-dialog {
align-self: flex-start;
}
</style>
</style>

View File

@@ -1,15 +1,7 @@
<template>
<div>
<TheSidebar ref="theSidebar" />
<v-app-bar
clipped-left
dense
app
color="primary"
dark
class="d-print-none"
:bottom="isMobile"
>
<v-app-bar clipped-left dense app color="primary" dark class="d-print-none" :bottom="isMobile">
<v-btn icon @click="openSidebar">
<v-icon> mdi-menu </v-icon>
</v-btn>
@@ -36,7 +28,7 @@
<v-btn icon @click="$refs.recipeSearch.open()">
<v-icon> mdi-magnify </v-icon>
</v-btn>
<SearchDialog ref="recipeSearch"/>
<SearchDialog ref="recipeSearch" />
</div>
<TheSiteMenu />
@@ -90,5 +82,4 @@ export default {
};
</script>
<style scoped>
</style>
<style scoped></style>

View File

@@ -6,14 +6,7 @@
<v-icon large left v-if="!processing">
mdi-link
</v-icon>
<v-progress-circular
v-else
indeterminate
color="white"
large
class="mr-2"
>
</v-progress-circular>
<v-progress-circular v-else indeterminate color="white" large class="mr-2"> </v-progress-circular>
<v-toolbar-title class="headline">
{{ $t("new-recipe.from-url") }}
@@ -54,21 +47,9 @@
</v-form>
</v-card>
</v-dialog>
<v-speed-dial
v-model="fab"
:open-on-hover="absolute"
:fixed="absolute"
:bottom="absolute"
:right="absolute"
>
<v-speed-dial v-model="fab" :open-on-hover="absolute" :fixed="absolute" :bottom="absolute" :right="absolute">
<template v-slot:activator>
<v-btn
v-model="fab"
:color="absolute ? 'accent' : 'white'"
dark
:icon="!absolute"
:fab="absolute"
>
<v-btn v-model="fab" :color="absolute ? 'accent' : 'white'" dark :icon="!absolute" :fab="absolute">
<v-icon> mdi-plus </v-icon>
</v-btn>
</template>
@@ -132,5 +113,4 @@ export default {
};
</script>
<style>
</style>
<style></style>

View File

@@ -4,11 +4,7 @@
<template v-slot:prepend>
<v-list-item two-line v-if="isLoggedIn">
<v-list-item-avatar color="accent" class="white--text">
<img
:src="userProfileImage"
v-if="!hideImage"
@error="hideImage = true"
/>
<img :src="userProfileImage" v-if="!hideImage" @error="hideImage = true" />
<div v-else>
{{ initials }}
</div>
@@ -16,21 +12,14 @@
<v-list-item-content>
<v-list-item-title> {{ user.fullName }}</v-list-item-title>
<v-list-item-subtitle>
{{ user.admin ? "Admin" : "User" }}</v-list-item-subtitle
>
<v-list-item-subtitle> {{ user.admin ? "Admin" : "User" }}</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
</template>
<v-divider></v-divider>
<v-list nav dense>
<v-list-item
v-for="nav in effectiveMenu"
:key="nav.title"
link
:to="nav.to"
>
<v-list-item v-for="nav in effectiveMenu" :key="nav.title" link :to="nav.to">
<v-list-item-icon>
<v-icon>{{ nav.icon }}</v-icon>
</v-list-item-icon>
@@ -228,15 +217,12 @@ export default {
this.showSidebar = false;
},
async getVersion() {
let response = await axios.get(
"https://api.github.com/repos/hay-kot/mealie/releases/latest",
{
headers: {
"content-type": "application/json",
Authorization: null,
},
}
);
let response = await axios.get("https://api.github.com/repos/hay-kot/mealie/releases/latest", {
headers: {
"content-type": "application/json",
Authorization: null,
},
});
this.latestVersion = response.data.tag_name;
},
@@ -250,4 +236,4 @@ export default {
bottom: 0 !important;
width: 100%;
}
</style>
</style>

View File

@@ -1,15 +1,7 @@
<template>
<div class="text-center">
<LoginDialog ref="loginDialog" />
<v-menu
transition="slide-x-transition"
bottom
right
offset-y
offset-overflow
open-on-hover
close-delay="200"
>
<v-menu transition="slide-x-transition" bottom right offset-y offset-overflow open-on-hover close-delay="200">
<template v-slot:activator="{ on, attrs }">
<v-btn v-bind="attrs" v-on="on" icon>
<v-icon>mdi-account</v-icon>
@@ -49,7 +41,7 @@ export default {
return [
{
icon: "mdi-account",
title: this.$t('user.login'),
title: this.$t("user.login"),
restricted: false,
login: true,
},
@@ -83,7 +75,7 @@ export default {
nav: "/admin",
restricted: true,
},
]
];
},
filteredItems() {
if (this.loggedIn) {
@@ -108,4 +100,4 @@ export default {
.menu-text {
text-align: left !important;
}
</style>
</style>