mealie/frontend/components/Domain/Recipe/RecipeDataAliasManagerDialog.vue
Michael Genson d440d51ffe
feat: plural foods and units, and aliases (#2674)
* added plural names and alias tables to foods/units

* updated models to include plural names and aliases

* updated parser to include plural and aliases

* fixed migrations

* fixed recursive models

* added plural abbreviation to migration

* updated parser and display prop

* update displays to use plurals

* fix display edgecase and remove print

* added/updated display tests

* fixed model bug and added parser tests

* added tests for aliases

* added new plural options to data management page

* removed unique constraint

* made base dialog more customizable

* added alias management to food and unit data pages

* removed unused awaits

* 🧹
2023-11-14 06:39:07 -09:00

142 lines
3.4 KiB
Vue

<template>
<div>
<BaseDialog
v-model="dialog"
:title="$t('data-pages.manage-aliases')"
:icon="$globals.icons.edit"
:submit-icon="$globals.icons.check"
:submit-text="$tc('general.confirm')"
@submit="saveAliases"
@cancel="$emit('cancel')"
>
<v-card-text>
<v-container>
<v-row v-for="alias, i in aliases" :key="i">
<v-col cols="10">
<v-text-field
v-model="alias.name"
:label="$t('general.name')"
:rules="[validators.required]"
/>
</v-col>
<v-col cols="2">
<BaseButtonGroup
:buttons="[
{
icon: $globals.icons.delete,
text: $tc('general.delete'),
event: 'delete'
}
]"
@delete="deleteAlias(i)"
/>
</v-col>
</v-row>
</v-container>
</v-card-text>
<template #custom-card-action>
<BaseButton edit @click="createAlias">{{ $t('data-pages.create-alias') }}
<template #icon>
{{ $globals.icons.create }}
</template>
</BaseButton>
</template>
</BaseDialog>
</div>
</template>
<script lang="ts">
import { computed, defineComponent, ref } from "@nuxtjs/composition-api";
import { whenever } from "@vueuse/core";
import { validators } from "~/composables/use-validators";
import { IngredientFood, IngredientUnit } from "~/lib/api/types/recipe";
export interface GenericAlias {
name: string;
}
export default defineComponent({
props: {
value: {
type: Boolean,
default: false,
},
data: {
type: Object as () => IngredientFood | IngredientUnit,
required: true,
},
},
setup(props, context) {
// V-Model Support
const dialog = computed({
get: () => {
return props.value;
},
set: (val) => {
context.emit("input", val);
},
});
function createAlias() {
aliases.value.push({
"name": "",
})
}
function deleteAlias(index: number) {
aliases.value.splice(index, 1);
}
const aliases = ref<GenericAlias[]>(props.data.aliases || []);
function initAliases() {
aliases.value = [...props.data.aliases || []];
if (!aliases.value.length) {
createAlias();
}
}
initAliases();
whenever(
() => props.value,
() => {
initAliases();
},
)
function saveAliases() {
const seenAliasNames: string[] = [];
const keepAliases: GenericAlias[] = [];
aliases.value.forEach((alias) => {
if (
!alias.name
|| alias.name === props.data.name
|| alias.name === props.data.pluralName
// @ts-ignore only applies to units
|| alias.name === props.data.abbreviation
// @ts-ignore only applies to units
|| alias.name === props.data.pluralAbbreviation
|| seenAliasNames.includes(alias.name)
) {
return;
}
keepAliases.push(alias);
seenAliasNames.push(alias.name);
})
aliases.value = keepAliases;
context.emit("submit", keepAliases);
}
return {
aliases,
createAlias,
dialog,
deleteAlias,
saveAliases,
validators,
}
},
});
</script>