mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2026-01-01 04:10:06 -05:00
WIP search page
This commit is contained in:
@@ -49,7 +49,11 @@ class RecipeSearch():
|
||||
self._search_prefs = SearchPreference()
|
||||
self._string = self._params.get('query').strip(
|
||||
) if self._params.get('query', None) else None
|
||||
|
||||
self._rating = self._params.get('rating', None)
|
||||
self._rating_gte = self._params.get('rating_gte', None)
|
||||
self._rating_lte = self._params.get('rating_lte', None)
|
||||
|
||||
self._keywords = {
|
||||
'or': self._params.get('keywords_or', None) or self._params.get('keywords', None),
|
||||
'and': self._params.get('keywords_and', None),
|
||||
@@ -140,7 +144,7 @@ class RecipeSearch():
|
||||
self.keyword_filters(**self._keywords)
|
||||
self.food_filters(**self._foods)
|
||||
self.book_filters(**self._books)
|
||||
self.rating_filter(rating=self._rating)
|
||||
self.rating_filter()
|
||||
self.internal_filter(internal=self._internal)
|
||||
self.step_filters(steps=self._steps)
|
||||
self.unit_filters(units=self._units)
|
||||
@@ -413,25 +417,16 @@ class RecipeSearch():
|
||||
units = [units]
|
||||
self._queryset = self._queryset.filter(steps__ingredients__unit__in=units)
|
||||
|
||||
def rating_filter(self, rating=None):
|
||||
if rating or self._sort_includes('rating'):
|
||||
lessthan = '-' in (rating or [])
|
||||
reverse = 'rating' in (self._sort_order or []) and '-rating' not in (self._sort_order or [])
|
||||
if lessthan or reverse:
|
||||
default = 100
|
||||
else:
|
||||
default = 0
|
||||
# TODO make ratings a settings user-only vs all-users
|
||||
self._queryset = self._queryset.annotate(rating=Round(Avg(Case(When(cooklog__created_by=self._request.user, then='cooklog__rating'), default=default))))
|
||||
if rating is None:
|
||||
return
|
||||
def rating_filter(self):
|
||||
if self._rating or self._rating_lte or self._rating_gte or self._sort_includes('rating'):
|
||||
self._queryset = self._queryset.annotate(rating=Round(Avg(Case(When(cooklog__created_by=self._request.user, then='cooklog__rating'), default=0))))
|
||||
|
||||
if rating == '0':
|
||||
self._queryset = self._queryset.filter(rating=0)
|
||||
elif lessthan:
|
||||
self._queryset = self._queryset.filter(rating__lte=int(rating[1:])).exclude(rating=0)
|
||||
else:
|
||||
self._queryset = self._queryset.filter(rating__gte=int(rating))
|
||||
if self._rating:
|
||||
self._queryset = self._queryset.filter(rating=round(int(self._rating)))
|
||||
elif self._rating_gte:
|
||||
self._queryset = self._queryset.filter(rating__gte=int(self._rating_gte))
|
||||
elif self._rating_lte:
|
||||
self._queryset = self._queryset.filter(rating__gte=int(self._rating_lte)).exclude(rating=0)
|
||||
|
||||
def internal_filter(self, internal=None):
|
||||
if not internal:
|
||||
|
||||
@@ -1110,9 +1110,6 @@ class RecipePagination(PageNumberPagination):
|
||||
OpenApiParameter(name='foods_and_not',
|
||||
description=_('Food IDs, repeat for multiple. Exclude recipes with all of the foods.'), type=int,
|
||||
many=True),
|
||||
OpenApiParameter(name='units', description=_('ID of unit a recipe should have.'), type=int),
|
||||
OpenApiParameter(name='rating', description=_(
|
||||
'Rating a recipe should have or greater. [0 - 5] Negative value filters rating less than.'), type=int),
|
||||
OpenApiParameter(name='books', description=_('ID of book a recipe should be in. For multiple repeat parameter.'),
|
||||
type=int, many=True),
|
||||
OpenApiParameter(name='books_or',
|
||||
@@ -1127,9 +1124,15 @@ class RecipePagination(PageNumberPagination):
|
||||
OpenApiParameter(name='books_and_not',
|
||||
description=_('Book IDs, repeat for multiple. Exclude recipes with all of the books.'), type=int,
|
||||
many=True),
|
||||
OpenApiParameter(name='units', description=_('ID of unit a recipe should have.'), type=int),
|
||||
OpenApiParameter(name='internal',
|
||||
description=_('If only internal recipes should be returned. [''true''/''<b>false</b>'']'),
|
||||
type=bool),
|
||||
|
||||
OpenApiParameter(name='rating', description=_( 'Exact rating of recipe'), type=int),
|
||||
OpenApiParameter(name='rating_gte', description=_( 'Rating a recipe should have or greater. '), type=int),
|
||||
OpenApiParameter(name='rating_lte', description=_( 'Rating a recipe should have or smaller.'), type=int),
|
||||
|
||||
OpenApiParameter(name='random',
|
||||
description=_('Returns the results in randomized order. [''true''/''<b>false</b>'']')),
|
||||
OpenApiParameter(name='new',
|
||||
|
||||
26
vue3/src/components/inputs/RatingField.vue
Normal file
26
vue3/src/components/inputs/RatingField.vue
Normal file
@@ -0,0 +1,26 @@
|
||||
<template>
|
||||
<v-input label="Test" hint="Test hint" persistent-hint>
|
||||
<template #prepend v-if="$slots.prepend">
|
||||
<slot name="prepend">
|
||||
</slot>
|
||||
</template>
|
||||
|
||||
<v-rating v-model="model"></v-rating>
|
||||
|
||||
<template #append v-if="$slots.append">
|
||||
<slot name="append">
|
||||
</slot>
|
||||
</template>
|
||||
</v-input>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
const model = defineModel<boolean>({required: true})
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -1217,6 +1217,8 @@ export interface ApiRecipeListRequest {
|
||||
query?: string;
|
||||
random?: string;
|
||||
rating?: number;
|
||||
ratingGte?: number;
|
||||
ratingLte?: number;
|
||||
timescooked?: number;
|
||||
units?: number;
|
||||
updatedon?: string;
|
||||
@@ -8880,6 +8882,14 @@ export class ApiApi extends runtime.BaseAPI {
|
||||
queryParameters['rating'] = requestParameters['rating'];
|
||||
}
|
||||
|
||||
if (requestParameters['ratingGte'] != null) {
|
||||
queryParameters['rating_gte'] = requestParameters['ratingGte'];
|
||||
}
|
||||
|
||||
if (requestParameters['ratingLte'] != null) {
|
||||
queryParameters['rating_lte'] = requestParameters['ratingLte'];
|
||||
}
|
||||
|
||||
if (requestParameters['timescooked'] != null) {
|
||||
queryParameters['timescooked'] = requestParameters['timescooked'];
|
||||
}
|
||||
|
||||
@@ -154,12 +154,14 @@ import {useUserPreferenceStore} from "@/stores/UserPreferenceStore";
|
||||
import {useRouteQuery} from "@vueuse/router";
|
||||
import {toNumberArray} from "@/utils/utils";
|
||||
import RandomIcon from "@/components/display/RandomIcon.vue";
|
||||
import {VRating, VSelect} from "vuetify/components";
|
||||
import RatingField from "@/components/inputs/RatingField.vue";
|
||||
|
||||
const {t} = useI18n()
|
||||
const router = useRouter()
|
||||
const {mdAndUp} = useDisplay()
|
||||
|
||||
const query = useRouteQuery('query', "",)
|
||||
const query = useRouteQuery('query', "")
|
||||
const page = useRouteQuery('page', 1, {transform: Number})
|
||||
const pageSize = useRouteQuery('pageSize', useUserPreferenceStore().deviceSettings.general_tableItemsPerPage, {transform: Number})
|
||||
|
||||
@@ -323,6 +325,56 @@ const filters = ref({
|
||||
object: false,
|
||||
searchOnLoad: true
|
||||
},
|
||||
units: {
|
||||
value: 'units',
|
||||
label: 'Unit (any)',
|
||||
hint: 'Recipes that contain any of the given units',
|
||||
enabled: false,
|
||||
default: [],
|
||||
is: ModelSelect,
|
||||
model: 'Unit',
|
||||
modelValue: useRouteQuery('units', [], {transform: toNumberArray}),
|
||||
mode: 'tags',
|
||||
object: false,
|
||||
searchOnLoad: true
|
||||
},
|
||||
internal: {
|
||||
value: 'internal',
|
||||
label: 'Hide External',
|
||||
hint: 'Hide external recipes',
|
||||
enabled: false,
|
||||
default: [],
|
||||
is: VSelect,
|
||||
items: [{value: true, title: 'Yes'}, {value: false, title: 'No'}],
|
||||
modelValue: useRouteQuery('internal ', "false"),
|
||||
},
|
||||
rating: {
|
||||
value: 'rating',
|
||||
label: 'Rating (exact)',
|
||||
hint: 'Recipes with the exact rating',
|
||||
enabled: false,
|
||||
default: 0,
|
||||
is: RatingField,
|
||||
modelValue: useRouteQuery('rating ', 0),
|
||||
},
|
||||
rating_gte: {
|
||||
value: 'rating_gte',
|
||||
label: 'Rating (>=)',
|
||||
hint: 'Recipes with the given or a greater rating',
|
||||
enabled: false,
|
||||
default: 0,
|
||||
is: RatingField,
|
||||
modelValue: useRouteQuery('rating_gte ', 0),
|
||||
},
|
||||
rating_lte: {
|
||||
value: 'rating_lte',
|
||||
label: 'Rating (<=)',
|
||||
hint: 'Recipes with the given or a smaller rating',
|
||||
enabled: false,
|
||||
default: 0,
|
||||
is: RatingField,
|
||||
modelValue: useRouteQuery('rating_lte ', 0),
|
||||
},
|
||||
})
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user