mirror of
https://github.com/mealie-recipes/mealie.git
synced 2026-04-16 09:55:34 -04:00
fix: Search layout fixes (#7459)
This commit is contained in:
4
.github/copilot-instructions.md
vendored
4
.github/copilot-instructions.md
vendored
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
## Project Overview
|
## Project Overview
|
||||||
|
|
||||||
Mealie is a self-hosted recipe manager, meal planner, and shopping list application with a FastAPI backend (Python 3.12) and Nuxt 3 frontend (Vue 3 + TypeScript). It uses SQLAlchemy ORM with support for SQLite and PostgreSQL databases.
|
Mealie is a self-hosted recipe manager, meal planner, and shopping list application with a FastAPI backend (Python 3.12) and Nuxt 4 frontend (Vue 3 + TypeScript). It uses SQLAlchemy ORM with support for SQLite and PostgreSQL databases.
|
||||||
|
|
||||||
**Development vs Production:**
|
**Development vs Production:**
|
||||||
- **Development:** Frontend (port 3000) and backend (port 9000) run as separate processes
|
- **Development:** Frontend (port 3000) and backend (port 9000) run as separate processes
|
||||||
@@ -51,7 +51,7 @@ Mealie is a self-hosted recipe manager, meal planner, and shopping list applicat
|
|||||||
- Use `useAuthBackend()` for authentication state, `useMealieAuth()` for user management
|
- Use `useAuthBackend()` for authentication state, `useMealieAuth()` for user management
|
||||||
|
|
||||||
**State Management:**
|
**State Management:**
|
||||||
- Nuxt 3 composables for state (no Vuex)
|
- Nuxt 4 composables for state (no Vuex)
|
||||||
- Auth state via `use-mealie-auth.ts` composable
|
- Auth state via `use-mealie-auth.ts` composable
|
||||||
- Prefer composables over global state stores
|
- Prefer composables over global state stores
|
||||||
|
|
||||||
|
|||||||
@@ -7,66 +7,64 @@
|
|||||||
content-class="top-dialog"
|
content-class="top-dialog"
|
||||||
:scrollable="false"
|
:scrollable="false"
|
||||||
>
|
>
|
||||||
<v-app-bar
|
|
||||||
sticky
|
|
||||||
dark
|
|
||||||
color="primary-lighten-1 top-0 position-relative left-0"
|
|
||||||
:rounded="!$vuetify.display.xs"
|
|
||||||
style="width: 100%;"
|
|
||||||
>
|
|
||||||
<v-text-field
|
|
||||||
id="arrow-search"
|
|
||||||
v-model="search.query.value"
|
|
||||||
autofocus
|
|
||||||
variant="solo"
|
|
||||||
flat
|
|
||||||
autocomplete="off"
|
|
||||||
bg-color="primary-lighten-1"
|
|
||||||
color="white"
|
|
||||||
density="compact"
|
|
||||||
class="mx-2 arrow-search"
|
|
||||||
hide-details
|
|
||||||
single-line
|
|
||||||
:placeholder="$t('search.search')"
|
|
||||||
:prepend-inner-icon="$globals.icons.search"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<v-btn
|
|
||||||
v-if="$vuetify.display.xs"
|
|
||||||
icon
|
|
||||||
size="x-small"
|
|
||||||
@click="dialog = false"
|
|
||||||
>
|
|
||||||
<v-icon>
|
|
||||||
{{ $globals.icons.close }}
|
|
||||||
</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-app-bar>
|
|
||||||
<v-card
|
<v-card
|
||||||
class="position-relative mt-1 pa-1 scroll"
|
:rounded="!$vuetify.display.xs"
|
||||||
max-height="700px"
|
|
||||||
relative
|
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
>
|
>
|
||||||
|
<v-toolbar
|
||||||
|
dark
|
||||||
|
color="primary-lighten-1"
|
||||||
|
>
|
||||||
|
<v-text-field
|
||||||
|
id="arrow-search"
|
||||||
|
v-model="search.query.value"
|
||||||
|
autofocus
|
||||||
|
variant="solo"
|
||||||
|
flat
|
||||||
|
autocomplete="off"
|
||||||
|
bg-color="primary-lighten-1"
|
||||||
|
color="white"
|
||||||
|
density="compact"
|
||||||
|
class="mx-2 arrow-search"
|
||||||
|
hide-details
|
||||||
|
single-line
|
||||||
|
:placeholder="$t('search.search')"
|
||||||
|
:prepend-inner-icon="$globals.icons.search"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<v-btn
|
||||||
|
v-if="$vuetify.display.xs"
|
||||||
|
icon
|
||||||
|
size="x-small"
|
||||||
|
@click="dialog = false"
|
||||||
|
>
|
||||||
|
<v-icon>
|
||||||
|
{{ $globals.icons.close }}
|
||||||
|
</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
</v-toolbar>
|
||||||
|
|
||||||
<v-card-actions>
|
<v-card-actions>
|
||||||
<div class="mr-auto">
|
<div class="mr-auto">
|
||||||
{{ $t("search.results") }}
|
{{ $t("search.results") }}
|
||||||
</div>
|
</div>
|
||||||
</v-card-actions>
|
</v-card-actions>
|
||||||
|
|
||||||
<RecipeCardMobile
|
<div class="scroll pa-1" style="max-height: 700px;">
|
||||||
v-for="(recipe, index) in search.data.value"
|
<RecipeCardMobile
|
||||||
:key="index"
|
v-for="(recipe, index) in search.data.value"
|
||||||
:tabindex="index"
|
:key="index"
|
||||||
class="ma-1 arrow-nav"
|
:tabindex="index"
|
||||||
:name="recipe.name ?? ''"
|
class="ma-1 arrow-nav"
|
||||||
:description="recipe.description ?? ''"
|
:name="recipe.name ?? ''"
|
||||||
:slug="recipe.slug ?? ''"
|
:description="recipe.description ?? ''"
|
||||||
:rating="recipe.rating ?? 0"
|
:slug="recipe.slug ?? ''"
|
||||||
:image="recipe.image"
|
:rating="recipe.rating ?? 0"
|
||||||
:recipe-id="recipe.id ?? ''"
|
:image="recipe.image"
|
||||||
v-bind="$attrs.selected ? { selected: () => handleSelect(recipe) } : {}"
|
:recipe-id="recipe.id ?? ''"
|
||||||
/>
|
v-bind="$attrs.selected ? { selected: () => handleSelect(recipe) } : {}"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</v-card>
|
</v-card>
|
||||||
</v-dialog>
|
</v-dialog>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -79,7 +79,6 @@
|
|||||||
<v-virtual-scroll
|
<v-virtual-scroll
|
||||||
:items="filtered"
|
:items="filtered"
|
||||||
height="300"
|
height="300"
|
||||||
item-height="51"
|
|
||||||
>
|
>
|
||||||
<template #default="{ item }">
|
<template #default="{ item }">
|
||||||
<v-list-item
|
<v-list-item
|
||||||
@@ -108,7 +107,6 @@
|
|||||||
<v-virtual-scroll
|
<v-virtual-scroll
|
||||||
:items="filtered"
|
:items="filtered"
|
||||||
height="300"
|
height="300"
|
||||||
item-height="51"
|
|
||||||
>
|
>
|
||||||
<template #default="{ item }">
|
<template #default="{ item }">
|
||||||
<v-list-item
|
<v-list-item
|
||||||
|
|||||||
Reference in New Issue
Block a user