mirror of
https://github.com/hay-kot/mealie.git
synced 2025-08-22 14:33:33 -07:00
improved search bar
This commit is contained in:
parent
757b5f8335
commit
ff6959dcb2
2 changed files with 71 additions and 41 deletions
|
@ -1,31 +1,37 @@
|
|||
<template>
|
||||
<div>
|
||||
<v-autocomplete
|
||||
:items="autoResults"
|
||||
v-model="searchSlug"
|
||||
item-value="item.slug"
|
||||
item-text="item.name"
|
||||
<v-menu v-model="menuModel" offset-y readonly max-width="450">
|
||||
<template #activator="{ attrs }">
|
||||
<v-text-field
|
||||
class="mt-6"
|
||||
v-model="search"
|
||||
v-bind="attrs"
|
||||
dense
|
||||
light
|
||||
:label="$t('search.search-mealie')"
|
||||
:search-input.sync="search"
|
||||
hide-no-data
|
||||
cache-items
|
||||
solo
|
||||
autofocus
|
||||
auto-select-first
|
||||
style="max-width: 450px;"
|
||||
@focus="onFocus"
|
||||
>
|
||||
<template
|
||||
v-if="showResults"
|
||||
v-slot:item="{ item }"
|
||||
style="max-width: 750px"
|
||||
</v-text-field>
|
||||
</template>
|
||||
<v-card v-if="showResults" max-height="500" min-width="98%" class="">
|
||||
<v-card-text class="py-1">Results</v-card-text>
|
||||
<v-divider></v-divider>
|
||||
<v-list scrollable>
|
||||
<v-list-item
|
||||
v-for="(item, index) in autoResults"
|
||||
:key="index"
|
||||
:to="showResults ? `/recipe/${item.item.slug}` : null"
|
||||
>
|
||||
<v-list-item-avatar>
|
||||
<v-img :src="getImage(item.item.image)"></v-img>
|
||||
</v-list-item-avatar>
|
||||
<v-list-item-content @click="selected(item.item.slug)">
|
||||
<v-list-item-title>
|
||||
{{ item.item.name }}
|
||||
<v-list-item-content
|
||||
@click="showResults ? null : selected(item.item.slug)"
|
||||
>
|
||||
<v-list-item-title v-html="highlight(item.item.name)">
|
||||
</v-list-item-title>
|
||||
<v-rating
|
||||
dense
|
||||
v-if="item.item.rating"
|
||||
|
@ -33,14 +39,13 @@
|
|||
size="12"
|
||||
>
|
||||
</v-rating>
|
||||
</v-list-item-title>
|
||||
<v-list-item-subtitle>
|
||||
{{ item.item.description }}
|
||||
<v-list-item-subtitle v-html="highlight(item.item.description)">
|
||||
</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
</template>
|
||||
</v-autocomplete>
|
||||
</div>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-card>
|
||||
</v-menu>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -57,6 +62,7 @@ export default {
|
|||
return {
|
||||
searchSlug: "",
|
||||
search: "",
|
||||
menuModel: false,
|
||||
data: [],
|
||||
result: [],
|
||||
autoResults: [],
|
||||
|
@ -66,9 +72,10 @@ export default {
|
|||
threshold: 0.6,
|
||||
location: 0,
|
||||
distance: 100,
|
||||
findAllMatches: true,
|
||||
maxPatternLength: 32,
|
||||
minMatchCharLength: 1,
|
||||
keys: ["name", "slug", "description"],
|
||||
minMatchCharLength: 2,
|
||||
keys: ["name", "description"],
|
||||
},
|
||||
};
|
||||
},
|
||||
|
@ -80,8 +87,15 @@ export default {
|
|||
fuse() {
|
||||
return new Fuse(this.data, this.options);
|
||||
},
|
||||
isSearching() {
|
||||
return this.search && this.search.length > 0;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
isSearching(val) {
|
||||
val ? (this.menuModel = true) : null;
|
||||
},
|
||||
|
||||
search() {
|
||||
try {
|
||||
this.result = this.fuse.search(this.search.trim());
|
||||
|
@ -101,18 +115,34 @@ export default {
|
|||
},
|
||||
},
|
||||
methods: {
|
||||
highlight(string) {
|
||||
if (!this.search) {
|
||||
return string;
|
||||
}
|
||||
return string.replace(
|
||||
new RegExp(this.search, "gi"),
|
||||
match => `<mark>${match}</mark>`
|
||||
);
|
||||
},
|
||||
getImage(image) {
|
||||
return utils.getImageURL(image);
|
||||
},
|
||||
selected(slug) {
|
||||
this.$emit("selected", slug);
|
||||
},
|
||||
async onFocus() {
|
||||
clearTimeout(this.timeout);
|
||||
this.isFocused = true;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
<style scoped>
|
||||
.color-transition {
|
||||
transition: background-color 0.3s ease;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="sass" scoped>
|
||||
</style>
|
|
@ -87,9 +87,6 @@ export default {
|
|||
},
|
||||
mounted() {},
|
||||
computed: {
|
||||
loggedIn() {
|
||||
return this.$store.getters.getIsLoggedIn;
|
||||
},
|
||||
filteredItems() {
|
||||
if (this.loggedIn) {
|
||||
return this.items.filter(x => x.restricted == true);
|
||||
|
@ -97,6 +94,9 @@ export default {
|
|||
return this.items.filter(x => x.restricted == false);
|
||||
}
|
||||
},
|
||||
loggedIn() {
|
||||
return this.$store.getters.getIsLoggedIn;
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue