mirror of
https://github.com/hay-kot/mealie.git
synced 2025-08-22 14:33:33 -07:00
meal-plan search redesign
This commit is contained in:
parent
7394cfc640
commit
a8ce091712
2 changed files with 60 additions and 50 deletions
|
@ -1,34 +1,38 @@
|
||||||
<template>
|
<template>
|
||||||
<v-menu v-model="menuModel" offset-y readonly max-width="450">
|
<v-menu v-model="menuModel" offset-y readonly :max-width="maxWidth">
|
||||||
<template #activator="{ attrs }">
|
<template #activator="{ attrs }">
|
||||||
<v-text-field
|
<v-text-field
|
||||||
class="mt-6"
|
class="mt-6"
|
||||||
v-model="search"
|
v-model="search"
|
||||||
v-bind="attrs"
|
v-bind="attrs"
|
||||||
dense
|
:dense="dense"
|
||||||
light
|
light
|
||||||
:label="$t('search.search-mealie')"
|
:label="$t('search.search-mealie')"
|
||||||
solo
|
|
||||||
autofocus
|
autofocus
|
||||||
style="max-width: 450px;"
|
:solo="solo"
|
||||||
|
:style="`max-width: ${maxWidth};`"
|
||||||
@focus="onFocus"
|
@focus="onFocus"
|
||||||
|
autocomplete="off"
|
||||||
>
|
>
|
||||||
</v-text-field>
|
</v-text-field>
|
||||||
</template>
|
</template>
|
||||||
<v-card v-if="showResults" max-height="500" min-width="98%" class="">
|
<v-card v-if="showResults" max-height="500" :max-width="maxWidth">
|
||||||
<v-card-text class="py-1">Results</v-card-text>
|
<v-card-text class="py-1">Results</v-card-text>
|
||||||
<v-divider></v-divider>
|
<v-divider></v-divider>
|
||||||
<v-list scrollable>
|
<v-list scrollable>
|
||||||
<v-list-item
|
<v-list-item
|
||||||
v-for="(item, index) in autoResults"
|
v-for="(item, index) in autoResults"
|
||||||
:key="index"
|
:key="index"
|
||||||
:to="showResults ? `/recipe/${item.item.slug}` : null"
|
:to="navOnClick ? `/recipe/${item.item.slug}` : null"
|
||||||
|
@click="navOnClick ? null : selected(item.item.slug, item.item.name)"
|
||||||
>
|
>
|
||||||
<v-list-item-avatar>
|
<v-list-item-avatar>
|
||||||
<v-img :src="getImage(item.item.image)"></v-img>
|
<v-img :src="getImage(item.item.image)"></v-img>
|
||||||
</v-list-item-avatar>
|
</v-list-item-avatar>
|
||||||
<v-list-item-content
|
<v-list-item-content
|
||||||
@click="showResults ? null : selected(item.item.slug)"
|
@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-html="highlight(item.item.name)">
|
||||||
</v-list-item-title>
|
</v-list-item-title>
|
||||||
|
@ -57,6 +61,21 @@ export default {
|
||||||
showResults: {
|
showResults: {
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
maxWidth: {
|
||||||
|
default: "450px",
|
||||||
|
},
|
||||||
|
dense: {
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
navOnClick: {
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
resetSearch: {
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
solo: {
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -65,7 +84,7 @@ export default {
|
||||||
menuModel: false,
|
menuModel: false,
|
||||||
data: [],
|
data: [],
|
||||||
result: [],
|
result: [],
|
||||||
autoResults: [],
|
fuseResults: [],
|
||||||
isDark: false,
|
isDark: false,
|
||||||
options: {
|
options: {
|
||||||
shouldSort: true,
|
shouldSort: true,
|
||||||
|
@ -84,6 +103,9 @@ export default {
|
||||||
this.data = this.$store.getters.getRecentRecipes;
|
this.data = this.$store.getters.getRecentRecipes;
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
autoResults() {
|
||||||
|
return this.fuseResults.length > 1 ? this.fuseResults : this.results;
|
||||||
|
},
|
||||||
fuse() {
|
fuse() {
|
||||||
return new Fuse(this.data, this.options);
|
return new Fuse(this.data, this.options);
|
||||||
},
|
},
|
||||||
|
@ -96,6 +118,10 @@ export default {
|
||||||
val ? (this.menuModel = true) : null;
|
val ? (this.menuModel = true) : null;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
resetSearch(val) {
|
||||||
|
val ? (this.search = "") : null;
|
||||||
|
},
|
||||||
|
|
||||||
search() {
|
search() {
|
||||||
try {
|
try {
|
||||||
this.result = this.fuse.search(this.search.trim());
|
this.result = this.fuse.search(this.search.trim());
|
||||||
|
@ -107,7 +133,7 @@ export default {
|
||||||
this.$emit("results", this.result);
|
this.$emit("results", this.result);
|
||||||
|
|
||||||
if (this.showResults === true) {
|
if (this.showResults === true) {
|
||||||
this.autoResults = this.result;
|
this.fuseResults = this.result;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
searchSlug() {
|
searchSlug() {
|
||||||
|
@ -127,8 +153,9 @@ export default {
|
||||||
getImage(image) {
|
getImage(image) {
|
||||||
return utils.getImageURL(image);
|
return utils.getImageURL(image);
|
||||||
},
|
},
|
||||||
selected(slug) {
|
selected(slug, name) {
|
||||||
this.$emit("selected", slug);
|
console.log("Selected", slug, name);
|
||||||
|
this.$emit("selected", slug, name);
|
||||||
},
|
},
|
||||||
async onFocus() {
|
async onFocus() {
|
||||||
clearTimeout(this.timeout);
|
clearTimeout(this.timeout);
|
||||||
|
|
|
@ -1,41 +1,21 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<v-dialog v-model="dialog" height="100%" max-width="1200">
|
<v-dialog v-model="dialog" width="600px" height="0">
|
||||||
<v-card min-height="725" height="100%">
|
<v-card>
|
||||||
|
<v-app-bar dark color="primary">
|
||||||
|
<v-toolbar-title class="headline">Search a Recipe</v-toolbar-title>
|
||||||
|
</v-app-bar>
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
<v-card-title></v-card-title>
|
<SearchBar
|
||||||
<v-row justify="center">
|
@results="updateResults"
|
||||||
<v-col cols="1"> </v-col>
|
@selected="emitSelect"
|
||||||
<v-col>
|
:show-results="true"
|
||||||
<SearchBar @results="updateResults" :show-results="false" />
|
max-width="550px"
|
||||||
</v-col>
|
:dense="false"
|
||||||
<v-col cols="2">
|
:nav-on-click="false"
|
||||||
<v-btn icon>
|
:reset-search="dialog"
|
||||||
<v-icon large> mdi-filter </v-icon>
|
:solo="false"
|
||||||
</v-btn>
|
/>
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
|
|
||||||
<v-row v-if="searchResults">
|
|
||||||
<v-col
|
|
||||||
:sm="6"
|
|
||||||
:md="6"
|
|
||||||
:lg="4"
|
|
||||||
:xl="3"
|
|
||||||
v-for="item in searchResults.slice(0, 24)"
|
|
||||||
:key="item.item.name"
|
|
||||||
>
|
|
||||||
<RecipeCard
|
|
||||||
:route="false"
|
|
||||||
:name="item.item.name"
|
|
||||||
:description="item.item.description"
|
|
||||||
:slug="item.item.slug"
|
|
||||||
:rating="item.item.rating"
|
|
||||||
:image="item.item.image"
|
|
||||||
@click="emitSelect(item.item.name, item.item.slug)"
|
|
||||||
/>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
</v-card>
|
</v-card>
|
||||||
</v-dialog>
|
</v-dialog>
|
||||||
|
@ -44,11 +24,9 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import SearchBar from "./SearchBar";
|
import SearchBar from "./SearchBar";
|
||||||
import RecipeCard from "../../Recipe/RecipeCard";
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
SearchBar,
|
SearchBar,
|
||||||
RecipeCard,
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -60,7 +38,7 @@ export default {
|
||||||
updateResults(results) {
|
updateResults(results) {
|
||||||
this.searchResults = results;
|
this.searchResults = results;
|
||||||
},
|
},
|
||||||
emitSelect(name, slug) {
|
emitSelect(slug, name) {
|
||||||
this.$emit("select", name, slug);
|
this.$emit("select", name, slug);
|
||||||
this.dialog = false;
|
this.dialog = false;
|
||||||
},
|
},
|
||||||
|
@ -72,4 +50,9 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
.v-dialog__content {
|
||||||
|
margin-top: 10%;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
Loading…
Add table
Add a link
Reference in a new issue