mirror of
https://github.com/mealie-recipes/mealie.git
synced 2026-05-06 18:13:31 -04:00
fix: restore create-item button in recipe dropdowns (categories, tags, tools) (#7564)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -88,7 +88,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #append-item>
|
<template #append-item>
|
||||||
<div class="px-2">
|
<div v-if="showCreateUnit" class="px-2">
|
||||||
<BaseButton
|
<BaseButton
|
||||||
block
|
block
|
||||||
size="small"
|
size="small"
|
||||||
@@ -147,7 +147,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #append-item>
|
<template #append-item>
|
||||||
<div class="px-2">
|
<div v-if="showCreateFood" class="px-2">
|
||||||
<BaseButton
|
<BaseButton
|
||||||
block
|
block
|
||||||
size="small"
|
size="small"
|
||||||
@@ -344,6 +344,11 @@ const foodData = useFoodData();
|
|||||||
const foodAutocomplete = ref<HTMLInputElement>();
|
const foodAutocomplete = ref<HTMLInputElement>();
|
||||||
const { search: foodSearch, filtered: filteredFoods } = useSearch(foodStore.store);
|
const { search: foodSearch, filtered: filteredFoods } = useSearch(foodStore.store);
|
||||||
|
|
||||||
|
const showCreateFood = computed(() =>
|
||||||
|
!!foodSearch.value
|
||||||
|
&& !filteredFoods.value.some((f: any) => (f.name ?? "").toLowerCase() === foodSearch.value.toLowerCase()),
|
||||||
|
);
|
||||||
|
|
||||||
async function createAssignFood() {
|
async function createAssignFood() {
|
||||||
foodData.data.name = foodSearch.value;
|
foodData.data.name = foodSearch.value;
|
||||||
model.value.food = await foodStore.actions.createOne(foodData.data) || undefined;
|
model.value.food = await foodStore.actions.createOne(foodData.data) || undefined;
|
||||||
@@ -376,6 +381,11 @@ const unitsData = useUnitData();
|
|||||||
const unitAutocomplete = ref<HTMLInputElement>();
|
const unitAutocomplete = ref<HTMLInputElement>();
|
||||||
const { search: unitSearch, filtered: filteredUnits } = useSearch(unitStore.store);
|
const { search: unitSearch, filtered: filteredUnits } = useSearch(unitStore.store);
|
||||||
|
|
||||||
|
const showCreateUnit = computed(() =>
|
||||||
|
!!unitSearch.value
|
||||||
|
&& !filteredUnits.value.some((u: any) => (u.name ?? "").toLowerCase() === unitSearch.value.toLowerCase()),
|
||||||
|
);
|
||||||
|
|
||||||
async function createAssignUnit() {
|
async function createAssignUnit() {
|
||||||
unitsData.data.name = unitSearch.value;
|
unitsData.data.name = unitSearch.value;
|
||||||
model.value.unit = await unitStore.actions.createOne(unitsData.data) || undefined;
|
model.value.unit = await unitStore.actions.createOne(unitsData.data) || undefined;
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
class="pa-0 ma-0"
|
class="pa-0 ma-0"
|
||||||
@update:model-value="resetSearchInput"
|
@update:model-value="resetSearchInput"
|
||||||
@click:append="dialog = true"
|
@click:append="dialog = true"
|
||||||
|
@keyup.enter="handleEnter"
|
||||||
>
|
>
|
||||||
<template #chip="{ item, index }">
|
<template #chip="{ item, index }">
|
||||||
<v-chip
|
<v-chip
|
||||||
@@ -32,6 +33,26 @@
|
|||||||
@click:close="removeByIndex(index)"
|
@click:close="removeByIndex(index)"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
<template
|
||||||
|
v-if="showAdd"
|
||||||
|
#no-data
|
||||||
|
>
|
||||||
|
<div class="caption text-center pb-2">
|
||||||
|
{{ $t("recipe.press-enter-to-create") }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template
|
||||||
|
v-if="showAdd && searchInput"
|
||||||
|
#append-item
|
||||||
|
>
|
||||||
|
<div class="px-2">
|
||||||
|
<BaseButton
|
||||||
|
block
|
||||||
|
size="small"
|
||||||
|
@click="createItem()"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
<template
|
<template
|
||||||
v-if="showAdd"
|
v-if="showAdd"
|
||||||
#append
|
#append
|
||||||
@@ -180,6 +201,32 @@ function appendCreated(item: any) {
|
|||||||
selected.value = [...selected.value, item];
|
selected.value = [...selected.value, item];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleEnter() {
|
||||||
|
if (!searchInput.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const exactMatch = items.value.some(
|
||||||
|
(item: any) => (item.name ?? "").toLowerCase() === searchInput.value.toLowerCase(),
|
||||||
|
);
|
||||||
|
if (!exactMatch) {
|
||||||
|
createItem();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createItem() {
|
||||||
|
if (!searchInput.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const actions = storeMap[props.selectorType].actions;
|
||||||
|
// @ts-expect-error different organizer types have different required fields
|
||||||
|
const newItem = await actions.createOne({ name: searchInput.value });
|
||||||
|
if (newItem) {
|
||||||
|
appendCreated(newItem);
|
||||||
|
}
|
||||||
|
searchInput.value = "";
|
||||||
|
}
|
||||||
|
|
||||||
const dialog = ref(false);
|
const dialog = ref(false);
|
||||||
|
|
||||||
const searchInput = ref("");
|
const searchInput = ref("");
|
||||||
|
|||||||
Reference in New Issue
Block a user