-
-
Notifications
You must be signed in to change notification settings - Fork 789
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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 * 🧹
- Loading branch information
1 parent
4b55b83
commit d440d51
Showing
17 changed files
with
1,175 additions
and
98 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
106 changes: 106 additions & 0 deletions
106
...bic/versions/2023-10-19-19.22.55_ba1e4a6cfe99_added_plural_names_and_alias_tables_for_.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
"""added plural names and alias tables for foods and units | ||
Revision ID: ba1e4a6cfe99 | ||
Revises: dded3119c1fe | ||
Create Date: 2023-10-19 19:22:55.369319 | ||
""" | ||
import sqlalchemy as sa | ||
|
||
import mealie.db.migration_types | ||
from alembic import op | ||
|
||
# revision identifiers, used by Alembic. | ||
revision = "ba1e4a6cfe99" | ||
down_revision = "dded3119c1fe" | ||
branch_labels = None | ||
depends_on = None | ||
|
||
|
||
def upgrade(): | ||
# ### commands auto generated by Alembic - please adjust! ### | ||
op.create_table( | ||
"ingredient_units_aliases", | ||
sa.Column("id", mealie.db.migration_types.GUID(), nullable=False), | ||
sa.Column("unit_id", mealie.db.migration_types.GUID(), nullable=False), | ||
sa.Column("name", sa.String(), nullable=False), | ||
sa.Column("name_normalized", sa.String(), nullable=True), | ||
sa.Column("created_at", sa.DateTime(), nullable=True), | ||
sa.Column("update_at", sa.DateTime(), nullable=True), | ||
sa.ForeignKeyConstraint( | ||
["unit_id"], | ||
["ingredient_units.id"], | ||
), | ||
sa.PrimaryKeyConstraint("id", "unit_id"), | ||
) | ||
op.create_index( | ||
op.f("ix_ingredient_units_aliases_created_at"), "ingredient_units_aliases", ["created_at"], unique=False | ||
) | ||
op.create_index( | ||
op.f("ix_ingredient_units_aliases_name_normalized"), | ||
"ingredient_units_aliases", | ||
["name_normalized"], | ||
unique=False, | ||
) | ||
op.create_table( | ||
"ingredient_foods_aliases", | ||
sa.Column("id", mealie.db.migration_types.GUID(), nullable=False), | ||
sa.Column("food_id", mealie.db.migration_types.GUID(), nullable=False), | ||
sa.Column("name", sa.String(), nullable=False), | ||
sa.Column("name_normalized", sa.String(), nullable=True), | ||
sa.Column("created_at", sa.DateTime(), nullable=True), | ||
sa.Column("update_at", sa.DateTime(), nullable=True), | ||
sa.ForeignKeyConstraint( | ||
["food_id"], | ||
["ingredient_foods.id"], | ||
), | ||
sa.PrimaryKeyConstraint("id", "food_id"), | ||
) | ||
op.create_index( | ||
op.f("ix_ingredient_foods_aliases_created_at"), "ingredient_foods_aliases", ["created_at"], unique=False | ||
) | ||
op.create_index( | ||
op.f("ix_ingredient_foods_aliases_name_normalized"), | ||
"ingredient_foods_aliases", | ||
["name_normalized"], | ||
unique=False, | ||
) | ||
op.add_column("ingredient_foods", sa.Column("plural_name", sa.String(), nullable=True)) | ||
op.add_column("ingredient_foods", sa.Column("plural_name_normalized", sa.String(), nullable=True)) | ||
op.create_index( | ||
op.f("ix_ingredient_foods_plural_name_normalized"), "ingredient_foods", ["plural_name_normalized"], unique=False | ||
) | ||
op.add_column("ingredient_units", sa.Column("plural_name", sa.String(), nullable=True)) | ||
op.add_column("ingredient_units", sa.Column("plural_name_normalized", sa.String(), nullable=True)) | ||
op.create_index( | ||
op.f("ix_ingredient_units_plural_name_normalized"), "ingredient_units", ["plural_name_normalized"], unique=False | ||
) | ||
op.add_column("ingredient_units", sa.Column("plural_abbreviation", sa.String(), nullable=True)) | ||
op.add_column("ingredient_units", sa.Column("plural_abbreviation_normalized", sa.String(), nullable=True)) | ||
op.create_index( | ||
op.f("ix_ingredient_units_plural_abbreviation_normalized"), | ||
"ingredient_units", | ||
["plural_abbreviation_normalized"], | ||
unique=False, | ||
) | ||
# ### end Alembic commands ### | ||
|
||
|
||
def downgrade(): | ||
# ### commands auto generated by Alembic - please adjust! ### | ||
op.drop_index(op.f("ix_ingredient_units_plural_abbreviation_normalized"), table_name="ingredient_units") | ||
op.drop_column("ingredient_units", "plural_abbreviation_normalized") | ||
op.drop_column("ingredient_units", "plural_abbreviation") | ||
op.drop_index(op.f("ix_ingredient_units_plural_name_normalized"), table_name="ingredient_units") | ||
op.drop_column("ingredient_units", "plural_name_normalized") | ||
op.drop_column("ingredient_units", "plural_name") | ||
op.drop_index(op.f("ix_ingredient_foods_plural_name_normalized"), table_name="ingredient_foods") | ||
op.drop_column("ingredient_foods", "plural_name_normalized") | ||
op.drop_column("ingredient_foods", "plural_name") | ||
op.drop_index(op.f("ix_ingredient_foods_aliases_name_normalized"), table_name="ingredient_foods_aliases") | ||
op.drop_index(op.f("ix_ingredient_foods_aliases_created_at"), table_name="ingredient_foods_aliases") | ||
op.drop_table("ingredient_foods_aliases") | ||
op.drop_index(op.f("ix_ingredient_units_aliases_name_normalized"), table_name="ingredient_units_aliases") | ||
op.drop_index(op.f("ix_ingredient_units_aliases_created_at"), table_name="ingredient_units_aliases") | ||
op.drop_table("ingredient_units_aliases") | ||
# ### end Alembic commands ### |
141 changes: 141 additions & 0 deletions
141
frontend/components/Domain/Recipe/RecipeDataAliasManagerDialog.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
<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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.