mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2026-01-11 09:07:12 -05:00
working filter for food/keyword/book
This commit is contained in:
37
vue3/src/components/display/RandomIcon.vue
Normal file
37
vue3/src/components/display/RandomIcon.vue
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
<template>
|
||||||
|
<v-icon :icon="icon"></v-icon>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import {computed} from "vue";
|
||||||
|
|
||||||
|
const icon = computed(() => {
|
||||||
|
let icons = [
|
||||||
|
'fa-solid fa-fw fa-hamburger',
|
||||||
|
'fa-solid fa-fw fa-utensils',
|
||||||
|
'fa-solid fa-fw fa-apple-alt',
|
||||||
|
'fa-solid fa-fw fa-bacon',
|
||||||
|
'fa-solid fa-fw fa-bread-slice',
|
||||||
|
'fa-solid fa-fw fa-candy-cane',
|
||||||
|
'fa-solid fa-fw fa-carrot',
|
||||||
|
'fa-solid fa-fw fa-cheese',
|
||||||
|
'fa-solid fa-fw fa-cookie',
|
||||||
|
'fa-solid fa-fw fa-drumstick-bite',
|
||||||
|
'fa-solid fa-fw fa-egg',
|
||||||
|
'fa-solid fa-fw fa-fish',
|
||||||
|
'fa-solid fa-fw fa-hotdog',
|
||||||
|
'fa-solid fa-fw fa-ice-cream',
|
||||||
|
'fa-solid fa-fw fa-lemon',
|
||||||
|
'fa-solid fa-fw fa-pepper-hot',
|
||||||
|
'fa-solid fa-fw fa-pizza-slice',
|
||||||
|
'fa-solid fa-fw fa-cookie-bite'
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
return icons[Math.floor(Math.random() * icons.length)];
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -124,7 +124,6 @@ onBeforeMount(() => {
|
|||||||
* @param query input to search for on the API
|
* @param query input to search for on the API
|
||||||
*/
|
*/
|
||||||
function search(query: string) {
|
function search(query: string) {
|
||||||
console.log('search called')
|
|
||||||
loading.value = true
|
loading.value = true
|
||||||
return modelClass.value.list({query: query, page: 1, pageSize: 25}).then((r: any) => {
|
return modelClass.value.list({query: query, page: 1, pageSize: 25}).then((r: any) => {
|
||||||
if (modelClass.value.model.isPaginated) {
|
if (modelClass.value.model.isPaginated) {
|
||||||
|
|||||||
@@ -3,11 +3,11 @@
|
|||||||
<v-row>
|
<v-row>
|
||||||
<v-col cols="12" md="6" offset-md="3">
|
<v-col cols="12" md="6" offset-md="3">
|
||||||
<v-text-field :label="$t('Search')"
|
<v-text-field :label="$t('Search')"
|
||||||
v-model="search_query"
|
v-model="query"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
@submit="searchRecipes({page: 1})"
|
@submit="searchRecipes({page: 1})"
|
||||||
@keydown.enter="searchRecipes({page: 1})"
|
@keydown.enter="searchRecipes({page: 1})"
|
||||||
@click:clear="search_query = ''"
|
@click:clear="query = ''"
|
||||||
clearable hide-details>
|
clearable hide-details>
|
||||||
<template v-slot:append>
|
<template v-slot:append>
|
||||||
<v-btn @click="panel ='search' " v-if="panel == ''" color="primary" icon><i class="fa-solid fa-caret-down"></i></v-btn>
|
<v-btn @click="panel ='search' " v-if="panel == ''" color="primary" icon><i class="fa-solid fa-caret-down"></i></v-btn>
|
||||||
@@ -23,47 +23,20 @@
|
|||||||
<v-expansion-panel-text>
|
<v-expansion-panel-text>
|
||||||
<v-form :disabled="loading" class="mt-4">
|
<v-form :disabled="loading" class="mt-4">
|
||||||
|
|
||||||
<model-select model="Keyword" mode="tags" v-model="search_keywords" density="compact" :object="false" search-on-load
|
<template v-for="filter in Object.values(filters)">
|
||||||
v-if="filters.keywords.enabled" :hint="filters.keywords.help">
|
<component :="filter" :is="filter.is" density="compact" v-model="filter.modelValue" v-if="isFilterVisible(filter)">
|
||||||
<template #append>
|
<template #append>
|
||||||
<v-btn icon="fa-solid fa-times" size="small" variant="plain" @click="search_keywords = []; filters.keywords.enabled = false"></v-btn>
|
<v-btn icon="fa-solid fa-times" size="small" variant="plain"
|
||||||
|
@click="filter.enabled = false; filter.modelValue = filter.default"></v-btn>
|
||||||
</template>
|
</template>
|
||||||
</model-select>
|
</component>
|
||||||
|
|
||||||
<model-select model="Keyword" mode="tags" v-model="search_keywords_and" density="compact" :object="false" search-on-load
|
|
||||||
v-if="filters.keywords_and.enabled">
|
|
||||||
<template #append>
|
|
||||||
<v-btn icon="fa-solid fa-times" size="small" variant="plain" @click="search_keywords_and = []; filters.keywords_and.enabled = false"></v-btn>
|
|
||||||
</template>
|
</template>
|
||||||
</model-select>
|
|
||||||
<model-select model="Keyword" mode="tags" v-model="search_keywords_or_not" density="compact" :object="false" search-on-load
|
|
||||||
v-if="filters.keywords_or_not.enabled">
|
|
||||||
<template #append>
|
|
||||||
<v-btn icon="fa-solid fa-times" size="small" variant="plain" @click="search_keywords_or_not = []; filters.keywords_or_not.enabled = false"></v-btn>
|
|
||||||
</template>
|
|
||||||
</model-select>
|
|
||||||
<model-select model="Keyword" mode="tags" v-model="search_keywords_and_not" density="compact" :object="false" search-on-load
|
|
||||||
v-if="filters.keywords_and_not.enabled">
|
|
||||||
<template #append>
|
|
||||||
<v-btn icon="fa-solid fa-times" size="small" variant="plain" @click="search_keywords_and_not = []; filters.keywords_and_not.enabled = false"></v-btn>
|
|
||||||
</template>
|
|
||||||
</model-select>
|
|
||||||
|
|
||||||
<v-divider class="mt-2 mb-2"></v-divider>
|
<v-divider class="mt-2 mb-2"></v-divider>
|
||||||
|
|
||||||
<v-autocomplete :items="availableFilters" @update:model-value="(item:string) =>{ filters[item].enabled = true; nextTick(() => {addFilterSelect = ''})}" density="compact" :label="$t('AddFilter')" v-model="addFilterSelect"></v-autocomplete>
|
<v-autocomplete :items="availableFilters"
|
||||||
|
@update:model-value="(item:string) =>{ filters[item].enabled = true; nextTick(() => {addFilterSelect = null})}" density="compact"
|
||||||
<!-- <model-select model="Food" mode="tags" v-model="urlSearchParams.foods" density="compact" :object="false"></model-select>-->
|
:label="$t('AddFilter')" v-model="addFilterSelect"></v-autocomplete>
|
||||||
<!-- <model-select model="Unit" mode="tags" v-model="urlSearchParams.units" density="compact" :object="false"></model-select>-->
|
|
||||||
<!-- <model-select model="RecipeBook" mode="tags" v-model="urlSearchParams.books" density="compact" :object="false"></model-select>-->
|
|
||||||
|
|
||||||
<!-- <v-number-input :label="$t('times_cooked')" v-model="searchParameters.timescooked" clearable></v-number-input>-->
|
|
||||||
<!-- <v-date-input :label="$t('last_cooked')" v-model="searchParameters.cookedon" clearable></v-date-input>-->
|
|
||||||
<!-- <v-date-input :label="$t('last_viewed')" v-model="searchParameters.viewedon" clearable></v-date-input>-->
|
|
||||||
<!-- <v-date-input :label="$t('created_on')" v-model="searchParameters.createdon" clearable></v-date-input>-->
|
|
||||||
<!-- <v-date-input :label="$t('updatedon')" v-model="searchParameters.updatedon" clearable></v-date-input>-->
|
|
||||||
|
|
||||||
<!-- <v-checkbox :label="$t('make_now')" v-model="urlSearchParams.makenow" density="compact"></v-checkbox>-->
|
|
||||||
|
|
||||||
<model-select model="CustomFilter" v-model="selectedCustomFilter" density="compact">
|
<model-select model="CustomFilter" v-model="selectedCustomFilter" density="compact">
|
||||||
<template #append>
|
<template #append>
|
||||||
@@ -79,7 +52,7 @@
|
|||||||
:items="[{title: $t('Table'), value: 'table'}, {title: $t('Cards'), value: 'grid'},]" density="compact"></v-select>
|
:items="[{title: $t('Table'), value: 'table'}, {title: $t('Cards'), value: 'grid'},]" density="compact"></v-select>
|
||||||
</v-col>
|
</v-col>
|
||||||
<v-col cols="6">
|
<v-col cols="6">
|
||||||
<v-select class="float-right" :label="$t('PerPage')" v-model="search_pageSize" :items="[10,25,50,100]" density="compact"
|
<v-select class="float-right" :label="$t('PerPage')" v-model="pageSize" :items="[10,25,50,100]" density="compact"
|
||||||
width="100%"></v-select>
|
width="100%"></v-select>
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
@@ -87,7 +60,7 @@
|
|||||||
</v-expansion-panel-text>
|
</v-expansion-panel-text>
|
||||||
|
|
||||||
<v-card-actions v-if="panel == 'search'">
|
<v-card-actions v-if="panel == 'search'">
|
||||||
<!-- <v-btn @click="reset()" prepend-icon="fa-solid fa-circle-xmark" :disabled="Object.keys(urlSearchParams).length == 0">{{ $t('Reset') }}</v-btn>-->
|
<v-btn @click="reset()" prepend-icon="fa-solid fa-circle-xmark">{{ $t('Reset') }}</v-btn>
|
||||||
<v-btn @click="searchRecipes({page: 1})" prepend-icon="$search">{{ $t('Search') }}</v-btn>
|
<v-btn @click="searchRecipes({page: 1})" prepend-icon="$search">{{ $t('Search') }}</v-btn>
|
||||||
</v-card-actions>
|
</v-card-actions>
|
||||||
</v-expansion-panel>
|
</v-expansion-panel>
|
||||||
@@ -104,8 +77,8 @@
|
|||||||
:loading="loading"
|
:loading="loading"
|
||||||
:items="recipes"
|
:items="recipes"
|
||||||
:headers="tableHeaders"
|
:headers="tableHeaders"
|
||||||
:page="search_page"
|
:page="page"
|
||||||
:items-per-page="search_pageSize"
|
:items-per-page="pageSize"
|
||||||
:items-length="tableItemCount"
|
:items-length="tableItemCount"
|
||||||
@click:row="handleRowClick"
|
@click:row="handleRowClick"
|
||||||
disable-sort
|
disable-sort
|
||||||
@@ -113,7 +86,8 @@
|
|||||||
hide-default-footer
|
hide-default-footer
|
||||||
>
|
>
|
||||||
<template #item.image="{item}">
|
<template #item.image="{item}">
|
||||||
<v-avatar :image="item.image" size="x-large" class="mt-1 mb-1"></v-avatar>
|
<v-avatar :image="item.image" size="x-large" class="mt-1 mb-1" v-if="item.image"></v-avatar>
|
||||||
|
<v-avatar color="primary" variant="tonal" size="x-large" class="mt-1 mb-1" v-else><random-icon></random-icon></v-avatar>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #item.keywords="{item}">
|
<template #item.keywords="{item}">
|
||||||
@@ -139,8 +113,8 @@
|
|||||||
</template>
|
</template>
|
||||||
<v-row>
|
<v-row>
|
||||||
<v-col cols="12" md="6" offset-md="3">
|
<v-col cols="12" md="6" offset-md="3">
|
||||||
<v-pagination v-model="search_page" :length="Math.ceil(tableItemCount/search_pageSize)"
|
<v-pagination v-model="page" :length="Math.ceil(tableItemCount/pageSize)"
|
||||||
@update:modelValue="searchRecipes({page: search_page})" class="ms-2 me-2" size="small"
|
@update:modelValue="searchRecipes({page: page})" class="ms-2 me-2" size="small"
|
||||||
></v-pagination>
|
></v-pagination>
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
@@ -179,39 +153,187 @@ import {useDisplay} from "vuetify";
|
|||||||
import {useUserPreferenceStore} from "@/stores/UserPreferenceStore";
|
import {useUserPreferenceStore} from "@/stores/UserPreferenceStore";
|
||||||
import {useRouteQuery} from "@vueuse/router";
|
import {useRouteQuery} from "@vueuse/router";
|
||||||
import {toNumberArray} from "@/utils/utils";
|
import {toNumberArray} from "@/utils/utils";
|
||||||
|
import RandomIcon from "@/components/display/RandomIcon.vue";
|
||||||
|
|
||||||
const {t} = useI18n()
|
const {t} = useI18n()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const {mdAndUp} = useDisplay()
|
const {mdAndUp} = useDisplay()
|
||||||
|
|
||||||
const search_query = useRouteQuery('query', "",)
|
const query = useRouteQuery('query', "",)
|
||||||
const search_page = useRouteQuery('page', 1, {transform: Number})
|
const page = useRouteQuery('page', 1, {transform: Number})
|
||||||
const search_pageSize = useRouteQuery('pageSize', useUserPreferenceStore().deviceSettings.general_tableItemsPerPage, {transform: Number})
|
const pageSize = useRouteQuery('pageSize', useUserPreferenceStore().deviceSettings.general_tableItemsPerPage, {transform: Number})
|
||||||
|
|
||||||
const search_keywords = useRouteQuery('keywords', [], {transform: toNumberArray})
|
|
||||||
const search_keywords_or_not = useRouteQuery('keywords_or_not', [], {transform: toNumberArray})
|
|
||||||
const search_keywords_and = useRouteQuery('keywords_and', [], {transform: toNumberArray})
|
|
||||||
const search_keywords_and_not = useRouteQuery('keywords_and_not', [], {transform: toNumberArray})
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* all filters available to enable
|
* all filters available to enable
|
||||||
*/
|
*/
|
||||||
const filters = ref({
|
const filters = ref({
|
||||||
keywords: {value: 'keywords', title: 'Keywords', help: 'Any of the keywords', enabled: false, default: []},
|
keywords: {
|
||||||
keywords_and: {value: 'keywords_and', title: 'Keywords And', help: 'All of the keywords', enabled: false, default: []},
|
value: 'keywords',
|
||||||
keywords_or_not: {value: 'keywords_or_not', title: 'Keywords Or Not', help: 'None of the given keywords', enabled: false, default: []},
|
label: 'Keyword (any)',
|
||||||
keywords_and_not: {value: 'keywords_and_not', title: 'Keywords And Not', help: 'Not all of the given keywords', enabled: false, default: []},
|
hint: 'Any of the given keywords',
|
||||||
|
enabled: false,
|
||||||
|
default: [],
|
||||||
|
is: ModelSelect,
|
||||||
|
model: 'Keyword',
|
||||||
|
modelValue: useRouteQuery('keywords', [], {transform: toNumberArray}),
|
||||||
|
mode: 'tags',
|
||||||
|
object: false,
|
||||||
|
searchOnLoad: true
|
||||||
|
},
|
||||||
|
keywordsAnd: {
|
||||||
|
value: 'keywordsAnd',
|
||||||
|
label: 'Keyword (all)',
|
||||||
|
hint: 'All of the given keywords',
|
||||||
|
enabled: false,
|
||||||
|
default: [],
|
||||||
|
is: ModelSelect,
|
||||||
|
model: 'Keyword',
|
||||||
|
modelValue: useRouteQuery('keywordsAnd', [], {transform: toNumberArray}),
|
||||||
|
mode: 'tags',
|
||||||
|
object: false,
|
||||||
|
searchOnLoad: true
|
||||||
|
},
|
||||||
|
keywordsOrNot: {
|
||||||
|
value: 'keywordsOrNot',
|
||||||
|
label: 'Keyword exclude (any)',
|
||||||
|
hint: 'Exclude recipes with any of the given keywords',
|
||||||
|
enabled: false,
|
||||||
|
default: [],
|
||||||
|
is: ModelSelect,
|
||||||
|
model: 'Keyword',
|
||||||
|
modelValue: useRouteQuery('keywordsOrNot ', [], {transform: toNumberArray}),
|
||||||
|
mode: 'tags',
|
||||||
|
object: false,
|
||||||
|
searchOnLoad: true
|
||||||
|
},
|
||||||
|
keywordsAndNot: {
|
||||||
|
value: 'keywordsAndNot',
|
||||||
|
label: 'Keyword exclude (all)',
|
||||||
|
hint: 'Exclude recipes with all of the given keywords',
|
||||||
|
enabled: false,
|
||||||
|
default: [],
|
||||||
|
is: ModelSelect,
|
||||||
|
model: 'Keyword',
|
||||||
|
modelValue: useRouteQuery('keywordsAndNot ', [], {transform: toNumberArray}),
|
||||||
|
mode: 'tags',
|
||||||
|
object: false,
|
||||||
|
searchOnLoad: true
|
||||||
|
},
|
||||||
|
foods: {
|
||||||
|
value: 'foods',
|
||||||
|
label: 'Foods (any)',
|
||||||
|
hint: 'Any of the given foods',
|
||||||
|
enabled: false,
|
||||||
|
default: [],
|
||||||
|
is: ModelSelect,
|
||||||
|
model: 'Food',
|
||||||
|
modelValue: useRouteQuery('foods', [], {transform: toNumberArray}),
|
||||||
|
mode: 'tags',
|
||||||
|
object: false,
|
||||||
|
searchOnLoad: true
|
||||||
|
},
|
||||||
|
foodsAnd: {
|
||||||
|
value: 'foodsAnd',
|
||||||
|
label: 'Food (all)',
|
||||||
|
hint: 'All of the given foods',
|
||||||
|
enabled: false,
|
||||||
|
default: [],
|
||||||
|
is: ModelSelect,
|
||||||
|
model: 'Food',
|
||||||
|
modelValue: useRouteQuery('foodsAnd', [], {transform: toNumberArray}),
|
||||||
|
mode: 'tags',
|
||||||
|
object: false,
|
||||||
|
searchOnLoad: true
|
||||||
|
},
|
||||||
|
foodsOrNot: {
|
||||||
|
value: 'foodsOrNot',
|
||||||
|
label: 'Food exclude (any)',
|
||||||
|
hint: 'Exclude recipes with any of the given foods',
|
||||||
|
enabled: false,
|
||||||
|
default: [],
|
||||||
|
is: ModelSelect,
|
||||||
|
model: 'Food',
|
||||||
|
modelValue: useRouteQuery('foodsOrNot ', [], {transform: toNumberArray}),
|
||||||
|
mode: 'tags',
|
||||||
|
object: false,
|
||||||
|
searchOnLoad: true
|
||||||
|
},
|
||||||
|
foodsAndNot: {
|
||||||
|
value: 'foodsAndNot',
|
||||||
|
label: 'Food exclude (all)',
|
||||||
|
hint: 'Exclude recipes with all of the given foods',
|
||||||
|
enabled: false,
|
||||||
|
default: [],
|
||||||
|
is: ModelSelect,
|
||||||
|
model: 'Food',
|
||||||
|
modelValue: useRouteQuery('foodsAndNot ', [], {transform: toNumberArray}),
|
||||||
|
mode: 'tags',
|
||||||
|
object: false,
|
||||||
|
searchOnLoad: true
|
||||||
|
},
|
||||||
|
books: {
|
||||||
|
value: 'books',
|
||||||
|
label: 'Book (any)',
|
||||||
|
hint: 'Recipes that are in any of the given books',
|
||||||
|
enabled: false,
|
||||||
|
default: [],
|
||||||
|
is: ModelSelect,
|
||||||
|
model: 'RecipeBook',
|
||||||
|
modelValue: useRouteQuery('books', [], {transform: toNumberArray}),
|
||||||
|
mode: 'tags',
|
||||||
|
object: false,
|
||||||
|
searchOnLoad: true
|
||||||
|
},
|
||||||
|
booksAnd: {
|
||||||
|
value: 'booksAnd',
|
||||||
|
label: 'Book (all)',
|
||||||
|
hint: 'Recipes that are in all of the given books',
|
||||||
|
enabled: false,
|
||||||
|
default: [],
|
||||||
|
is: ModelSelect,
|
||||||
|
model: 'RecipeBook',
|
||||||
|
modelValue: useRouteQuery('booksAnd', [], {transform: toNumberArray}),
|
||||||
|
mode: 'tags',
|
||||||
|
object: false,
|
||||||
|
searchOnLoad: true
|
||||||
|
},
|
||||||
|
booksOrNot: {
|
||||||
|
value: 'booksOrNot',
|
||||||
|
label: 'Book exclude (any)',
|
||||||
|
hint: 'Exclude recipes with any of the given books',
|
||||||
|
enabled: false,
|
||||||
|
default: [],
|
||||||
|
is: ModelSelect,
|
||||||
|
model: 'RecipeBook',
|
||||||
|
modelValue: useRouteQuery('booksOrNot ', [], {transform: toNumberArray}),
|
||||||
|
mode: 'tags',
|
||||||
|
object: false,
|
||||||
|
searchOnLoad: true
|
||||||
|
},
|
||||||
|
booksAndNot: {
|
||||||
|
value: 'booksAndNot',
|
||||||
|
label: 'Book exclude (all)',
|
||||||
|
hint: 'Exclude recipes with all of the given books',
|
||||||
|
enabled: false,
|
||||||
|
default: [],
|
||||||
|
is: ModelSelect,
|
||||||
|
model: 'RecipeBook',
|
||||||
|
modelValue: useRouteQuery('booksAndNot ', [], {transform: toNumberArray}),
|
||||||
|
mode: 'tags',
|
||||||
|
object: false,
|
||||||
|
searchOnLoad: true
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* filters that are not yet enabled
|
* filters that are not yet enabled
|
||||||
*/
|
*/
|
||||||
const availableFilters = computed(() => {
|
const availableFilters = computed(() => {
|
||||||
let f = []
|
let f: Array<{value: string, title: string}> = []
|
||||||
Object.entries(filters.value).forEach((entry) => {
|
Object.entries(filters.value).forEach((entry) => {
|
||||||
let [key, value] = entry
|
let [key, filter] = entry
|
||||||
if (!value.enabled) {
|
if (!isFilterVisible(filter)) {
|
||||||
f.push({value: value.value, title: value.title})
|
f.push({value: filter.value, title: filter.label})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return f
|
return f
|
||||||
@@ -220,7 +342,7 @@ const availableFilters = computed(() => {
|
|||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const dialog = ref(false)
|
const dialog = ref(false)
|
||||||
const panel = ref('')
|
const panel = ref('')
|
||||||
const addFilterSelect = ref('')
|
const addFilterSelect = ref<string | null>(null)
|
||||||
|
|
||||||
const tableHeaders = computed(() => {
|
const tableHeaders = computed(() => {
|
||||||
let headers = [
|
let headers = [
|
||||||
@@ -246,7 +368,7 @@ const newFilterName = ref('')
|
|||||||
* handle query updates when using the GlobalSearchDialog on the search page directly
|
* handle query updates when using the GlobalSearchDialog on the search page directly
|
||||||
*/
|
*/
|
||||||
// TODO this also makes the search update on every stroke, do we want this?
|
// TODO this also makes the search update on every stroke, do we want this?
|
||||||
watch(() => search_query.value, () => {
|
watch(() => query.value, () => {
|
||||||
searchRecipes({page: 1})
|
searchRecipes({page: 1})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -254,7 +376,7 @@ watch(() => search_query.value, () => {
|
|||||||
* perform initial search on mounted
|
* perform initial search on mounted
|
||||||
*/
|
*/
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
searchRecipes({page: search_page.value})
|
searchRecipes({page: page.value})
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -265,20 +387,16 @@ function searchRecipes(options: VDataTableUpdateOptions) {
|
|||||||
let api = new ApiApi()
|
let api = new ApiApi()
|
||||||
loading.value = true
|
loading.value = true
|
||||||
|
|
||||||
search_page.value = options.page
|
|
||||||
if (options.itemsPerPage) {
|
|
||||||
search_pageSize.value = options.itemsPerPage
|
|
||||||
}
|
|
||||||
|
|
||||||
let searchParameters = {
|
let searchParameters = {
|
||||||
query: search_query.value,
|
query: query.value,
|
||||||
page: search_page.value,
|
page: page.value,
|
||||||
pageSize: search_pageSize.value,
|
pageSize: pageSize.value,
|
||||||
keywords: search_keywords.value,
|
|
||||||
foods: search_keywords.value,
|
|
||||||
books: search_keywords.value,
|
|
||||||
} as ApiRecipeListRequest
|
} as ApiRecipeListRequest
|
||||||
|
|
||||||
|
Object.values(filters.value).forEach((filter) => {
|
||||||
|
searchParameters[filter.value] = filter.modelValue
|
||||||
|
})
|
||||||
|
|
||||||
api.apiRecipeList(searchParameters).then((r) => {
|
api.apiRecipeList(searchParameters).then((r) => {
|
||||||
recipes.value = r.results
|
recipes.value = r.results
|
||||||
tableItemCount.value = r.count
|
tableItemCount.value = r.count
|
||||||
@@ -290,13 +408,25 @@ function searchRecipes(options: VDataTableUpdateOptions) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reset all search parameters and perform emtpy searchj
|
||||||
|
*/
|
||||||
function reset() {
|
function reset() {
|
||||||
Object.keys(urlSearchParams).forEach(key => {
|
page.value = 1
|
||||||
delete urlSearchParams[key]
|
query.value = ''
|
||||||
|
Object.values(filters.value).forEach((filter) => {
|
||||||
|
filter.enabled = false
|
||||||
|
filter.modelValue = filter.default
|
||||||
})
|
})
|
||||||
recipes.value = []
|
recipes.value = []
|
||||||
|
searchRecipes({page: 1})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* handle clicking a table row by opening the selected recipe
|
||||||
|
* @param event
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
function handleRowClick(event: PointerEvent, data: any) {
|
function handleRowClick(event: PointerEvent, data: any) {
|
||||||
router.push({name: 'RecipeViewPage', params: {id: recipes.value[data.index].id}})
|
router.push({name: 'RecipeViewPage', params: {id: recipes.value[data.index].id}})
|
||||||
}
|
}
|
||||||
@@ -322,6 +452,19 @@ function saveCustomFilter() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* determines if the filter should be visible because its either enabled or not the default value
|
||||||
|
* @param filter
|
||||||
|
*/
|
||||||
|
function isFilterVisible(filter: any) {
|
||||||
|
if (!filter.enabled && filter.modelValue.length > 0) {
|
||||||
|
filter.enabled = true
|
||||||
|
}
|
||||||
|
return filter.enabled
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO temporary function to convert old saved search format, either make proper db table or convert to native new format
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* create new filter
|
* create new filter
|
||||||
*/
|
*/
|
||||||
@@ -347,8 +490,6 @@ function loadCustomFilter() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO temporary function to convert old saved search format, either make proper db table or convert to native new format
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* turn data in the format of a CustomFilter into the format needed for api request
|
* turn data in the format of a CustomFilter into the format needed for api request
|
||||||
* @param customFilterParams
|
* @param customFilterParams
|
||||||
|
|||||||
Reference in New Issue
Block a user