debounce search

This commit is contained in:
hay-kot 2021-04-26 16:56:43 -08:00
commit 2f59c72400
5 changed files with 82 additions and 40 deletions

View file

@ -5,22 +5,19 @@
:width="modalWidth + 'px'"
:content-class="top ? 'top-dialog' : undefined"
>
<v-card class="pb-10" :loading="loading" height="100%">
<v-card class="pb-10" height="100%">
<v-app-bar dark :color="color" class="mt-n1 mb-2">
<v-icon large left v-if="!loading">
<v-icon large left>
{{ titleIcon }}
</v-icon>
<v-progress-circular
v-else
indeterminate
color="white"
large
class="mr-2"
>
</v-progress-circular>
<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>
<slot> </slot>
<v-card-actions>
<slot name="card-actions">
@ -33,6 +30,7 @@
</v-btn>
</slot>
</v-card-actions>
<slot name="below-actions"> </slot>
</v-card>
</v-dialog>

View file

@ -221,7 +221,13 @@
},
"toolbox": {
"toolbox": "Toolbox",
"new-name": "New Name"
"new-name": "New Name",
"recipes-effected": "Recipes Effected",
"title-case-all": "Title Case All",
"no-unused-items": "No Unused Items",
"remove-unused": "Remove Unused",
"assign-all": "Assign All",
"bulk-assign": "Bulk Assign"
}
},
"user": {

View file

@ -28,7 +28,7 @@
</v-card-text>
<template slot="card-actions">
<v-btn text color="grey" @click="closeDialog">
Cancel
{{ $t("general.cancel") }}
</v-btn>
<v-spacer></v-spacer>
<v-btn
@ -37,7 +37,7 @@
:loading="loading"
:disabled="results.length < 1"
>
Assign All
{{ $t("settings.toolbox.assign-all") }}
</v-btn>
</template>
<template slot="below-actions">
@ -53,7 +53,7 @@
</base-dialog>
<v-btn @click="openDialog" small color="success" class="mr-1">
Bulk Assign
{{ $t("settings.toolbox.bulk-assign") }}
</v-btn>
</div>
</template>
@ -76,6 +76,7 @@ export default {
},
data() {
return {
results: [],
search: "",
loading: false,
assignTargetRecipes: [],
@ -86,20 +87,25 @@ export default {
mounted() {
this.$store.dispatch("requestAllRecipes");
},
watch: {
search() {
this.getResults();
},
},
computed: {
allRecipes() {
return this.$store.getters.getRecentRecipes;
},
results() {
if (this.search === null || this.search === "") {
return [];
}
return this.allRecipes.filter(x => {
return (
this.checkForKeywords(x.name) || this.checkForKeywords(x.description)
);
});
},
// results() {
// if (this.search === null || this.search === "") {
// return [];
// }
// return this.allRecipes.filter(x => {
// return (
// this.checkForKeywords(x.name) || this.checkForKeywords(x.description)
// );
// });
// },
keywords() {
const lowered = this.search.toLowerCase();
return lowered.split(" ");
@ -123,6 +129,7 @@ export default {
await api.recipes.patch(element);
});
this.loading = false;
this.closeDialog();
},
closeDialog() {
this.$refs.assignDialog.close();
@ -131,6 +138,27 @@ export default {
this.$refs.assignDialog.open();
this.reset();
},
getResults() {
this.loading = true;
// cancel pending call
clearTimeout(this._timerId);
this._timerId = setTimeout(() => {
this.results = this.filterResults();
}, 300);
this.loading = false;
// delay new call 500ms
},
filterResults() {
if (this.search === null || this.search === "") {
return [];
}
return this.allRecipes.filter(x => {
return (
this.checkForKeywords(x.name) || this.checkForKeywords(x.description)
);
});
},
checkForKeywords(str) {
const searchStr = str.toLowerCase();
return this.keywords.some(x => searchStr.includes(x));

View file

@ -4,7 +4,11 @@
ref="deleteDialog"
title-icon="mdi-tag"
color="error"
:title="title"
:title="
$t('general.delete') +
' ' +
(isTags ? $t('recipe.tags') : $t('recipe.categories'))
"
:loading="loading"
modal-width="400"
>
@ -16,11 +20,11 @@
</v-list-item>
</v-list>
<v-card-text v-else class=" mt-4 text-center">
No Unused Items
{{ $t("settings.toolbox.no-unused-items") }}
</v-card-text>
<template slot="card-actions">
<v-btn text color="grey" @click="closeDialog">
Cancel
{{ $t("general.cancel") }}
</v-btn>
<v-spacer></v-spacer>
<v-btn
@ -29,13 +33,13 @@
:loading="loading"
:disabled="deleteList.length < 1"
>
Delete
{{ $t("general.delete") }}
</v-btn>
</template>
</base-dialog>
<v-btn @click="openDialog" small color="error" class="mr-1">
Remove Unused
{{ $t("settings.toolbox.remove-unused") }}
</v-btn>
</div>
</template>
@ -58,11 +62,6 @@ export default {
loading: false,
};
},
computed: {
title() {
return this.isTags ? "Delete Tags" : "Delete Categories";
},
},
methods: {
closeDialog() {
this.$refs.deleteDialog.close();

View file

@ -18,7 +18,8 @@
</v-form>
<template slot="below-actions">
<v-card-title class="headline">
{{ renameTarget.recipes.length || 0 }} Recipes Effected
{{ renameTarget.recipes.length || 0 }}
{{ $t("settings.toolbox.recipes-effected") }}
</v-card-title>
<MobileRecipeCard
class="ml-2 mr-2 mt-2 mb-2"
@ -41,12 +42,18 @@
class="mr-1"
>
<v-btn @click="openNewDialog" small color="success">
New
{{ $t("general.create") }}
</v-btn>
</new-category-tag-dialog>
<BulkAssign isTags="isTags" />
<v-btn @click="titleCaseAll" class="mr-1" small color="success">
Title Case All
<v-btn
@click="titleCaseAll"
class="mr-1"
small
color="success"
:loading="loadingTitleCase"
>
{{ $t("settings.toolbox.title-case-all") }}
</v-btn>
<RemoveUnused :isTags="isTags" />
<v-spacer> </v-spacer>
@ -125,6 +132,7 @@ export default {
},
data() {
return {
loadingTitleCase: false,
searchString: "",
searchResults: [],
renameTarget: {
@ -181,10 +189,11 @@ export default {
await api.categories.delete(name);
}
},
renameFromDialog(name, newName) {
async renameFromDialog(name, newName) {
if (this.$refs.renameForm.validate()) {
this.rename(name, newName);
await this.rename(name, newName);
}
this.$refs.renameDialog.close();
},
async rename(name, newName) {
if (this.isTags) {
@ -197,6 +206,7 @@ export default {
return lowerName.replace(/(?:^|\s|-)\S/g, x => x.toUpperCase());
},
async titleCaseAll() {
this.loadingTitleCase = true;
const renameList = this.allItems.map(x => ({
slug: x.slug,
name: x.name,
@ -216,6 +226,7 @@ export default {
});
this.$store.dispatch("requestCategories");
}
this.loadingTitleCase = false;
},
},
};