Add plural name for unit and food

Add an optional plural name for unit and food.
Additional options to show always the plural name for unit and food
for an ingredient is added.
This commit is contained in:
Niklas Schwarz 2022-06-06 00:53:42 +02:00
parent a8a590a942
commit 9994b6f9c2
31 changed files with 284 additions and 41 deletions

View File

@ -22,9 +22,21 @@ class IngredientObject(object):
else:
self.amount = f"<scalable-number v-bind:number='{bleach.clean(str(ingredient.amount))}' v-bind:factor='ingredient_factor'></scalable-number>"
if ingredient.unit:
if ingredient.unit.plural_name in (None, ""):
self.unit = bleach.clean(str(ingredient.unit))
else:
if ingredient.always_use_plural_unit or ingredient.amount > 1 and not ingredient.no_amount:
self.unit = bleach.clean(ingredient.unit.plural_name)
else:
self.unit = bleach.clean(str(ingredient.unit))
else:
self.unit = ""
if ingredient.food.plural_name in (None, ""):
self.food = bleach.clean(str(ingredient.food))
else:
if ingredient.always_use_plural_food or ingredient.amount > 1 and not ingredient.no_amount:
self.food = bleach.clean(str(ingredient.food.plural_name))
else:
self.food = bleach.clean(str(ingredient.food))
self.note = bleach.clean(str(ingredient.note))

View File

@ -530,6 +530,7 @@ class Keyword(ExportModelOperationsMixin('keyword'), TreeModel, PermissionModelM
class Unit(ExportModelOperationsMixin('unit'), models.Model, PermissionModelMixin):
name = models.CharField(max_length=128, validators=[MinLengthValidator(1)])
plural_name = models.CharField(max_length=128, null=True, blank=True, default=None)
description = models.TextField(blank=True, null=True)
space = models.ForeignKey(Space, on_delete=models.CASCADE)
@ -554,6 +555,7 @@ class Food(ExportModelOperationsMixin('food'), TreeModel, PermissionModelMixin):
if SORT_TREE_BY_NAME:
node_order_by = ['name']
name = models.CharField(max_length=128, validators=[MinLengthValidator(1)])
plural_name = models.CharField(max_length=128, null=True, blank=True, default=None)
recipe = models.ForeignKey('Recipe', null=True, blank=True, on_delete=models.SET_NULL)
supermarket_category = models.ForeignKey(SupermarketCategory, null=True, blank=True, on_delete=models.SET_NULL) # inherited field
ignore_shopping = models.BooleanField(default=False) # inherited field
@ -654,6 +656,8 @@ class Ingredient(ExportModelOperationsMixin('ingredient'), models.Model, Permiss
note = models.CharField(max_length=256, null=True, blank=True)
is_header = models.BooleanField(default=False)
no_amount = models.BooleanField(default=False)
always_use_plural_unit = models.BooleanField(default=False)
always_use_plural_food = models.BooleanField(default=False)
order = models.IntegerField(default=0)
original_text = models.CharField(max_length=512, null=True, blank=True, default=None)
@ -663,7 +667,23 @@ class Ingredient(ExportModelOperationsMixin('ingredient'), models.Model, Permiss
objects = ScopedManager(space='space')
def __str__(self):
return str(self.amount) + ' ' + str(self.unit) + ' ' + str(self.food)
food = ""
unit = ""
if self.always_use_plural_food and self.food.plural_name not in (None, "") and not self.no_amount:
food = self.food.plural_name
else:
if self.amount > 1 and self.food.plural_name not in (None, "") and not self.no_amount:
food = self.food.plural_name
else:
food = str(self.food)
if self.always_use_plural_unit and self.unit.plural_name not in (None, "") and not self.no_amount:
unit = self.unit.plural_name
else:
if self.amount > 1 and self.unit.plural_name not in (None, "") and not self.no_amount:
unit = self.unit.plural_name
else:
unit = str(self.unit)
return str(self.amount) + ' ' + str(unit) + ' ' + str(food)
class Meta:
ordering = ['order', 'pk']

View File

@ -431,17 +431,22 @@ class UnitSerializer(UniqueFieldsMixin, ExtendedRecipeMixin):
def create(self, validated_data):
name = validated_data.pop('name').strip()
plural_name = validated_data.pop('plural_name', None)
if plural_name:
plural_name = plural_name.strip()
space = validated_data.pop('space', self.context['request'].space)
obj, created = Unit.objects.get_or_create(name=name, space=space, defaults=validated_data)
obj, created = Unit.objects.get_or_create(name=name, plural_name=plural_name, space=space, defaults=validated_data)
return obj
def update(self, instance, validated_data):
validated_data['name'] = validated_data['name'].strip()
if plural_name := validated_data.get('plural_name', None):
validated_data['plural_name'] = plural_name.strip()
return super(UnitSerializer, self).update(instance, validated_data)
class Meta:
model = Unit
fields = ('id', 'name', 'description', 'numrecipe', 'image')
fields = ('id', 'name', 'plural_name', 'description', 'numrecipe', 'image')
read_only_fields = ('id', 'numrecipe', 'image')
@ -499,7 +504,7 @@ class RecipeSimpleSerializer(WritableNestedModelSerializer):
class FoodSimpleSerializer(serializers.ModelSerializer):
class Meta:
model = Food
fields = ('id', 'name')
fields = ('id', 'name', 'plural_name')
class FoodSerializer(UniqueFieldsMixin, WritableNestedModelSerializer, ExtendedRecipeMixin):
@ -538,6 +543,9 @@ class FoodSerializer(UniqueFieldsMixin, WritableNestedModelSerializer, ExtendedR
def create(self, validated_data):
name = validated_data.pop('name').strip()
plural_name = validated_data.pop('plural_name', None)
if plural_name:
plural_name = plural_name.strip()
space = validated_data.pop('space', self.context['request'].space)
# supermarket category needs to be handled manually as food.get or create does not create nested serializers unlike a super.create of serializer
if 'supermarket_category' in validated_data and validated_data['supermarket_category']:
@ -562,12 +570,14 @@ class FoodSerializer(UniqueFieldsMixin, WritableNestedModelSerializer, ExtendedR
else:
validated_data['onhand_users'] = list(set(onhand_users) - set(shared_users))
obj, created = Food.objects.get_or_create(name=name, space=space, defaults=validated_data)
obj, created = Food.objects.get_or_create(name=name, plural_name=plural_name, space=space, defaults=validated_data)
return obj
def update(self, instance, validated_data):
if name := validated_data.get('name', None):
validated_data['name'] = name.strip()
if plural_name := validated_data.get('plural_name', None):
validated_data['plural_name'] = plural_name.strip()
# assuming if on hand for user also onhand for shopping_share users
onhand = validated_data.get('food_onhand', None)
reset_inherit = self.initial_data.get('reset_inherit', False)
@ -587,7 +597,7 @@ class FoodSerializer(UniqueFieldsMixin, WritableNestedModelSerializer, ExtendedR
class Meta:
model = Food
fields = (
'id', 'name', 'description', 'shopping', 'recipe', 'food_onhand', 'supermarket_category',
'id', 'name', 'plural_name', 'description', 'shopping', 'recipe', 'food_onhand', 'supermarket_category',
'image', 'parent', 'numchild', 'numrecipe', 'inherit_fields', 'full_name', 'ignore_shopping',
'substitute', 'substitute_siblings', 'substitute_children', 'substitute_onhand', 'child_inherit_fields'
)
@ -616,6 +626,7 @@ class IngredientSimpleSerializer(WritableNestedModelSerializer):
fields = (
'id', 'food', 'unit', 'amount', 'note', 'order',
'is_header', 'no_amount', 'original_text', 'used_in_recipes',
'always_use_plural_unit', 'always_use_plural_food',
)
@ -1162,7 +1173,7 @@ class SupermarketCategoryExportSerializer(SupermarketCategorySerializer):
class UnitExportSerializer(UnitSerializer):
class Meta:
model = Unit
fields = ('name', 'description')
fields = ('name', 'plural_name', 'description')
class FoodExportSerializer(FoodSerializer):
@ -1170,7 +1181,7 @@ class FoodExportSerializer(FoodSerializer):
class Meta:
model = Food
fields = ('name', 'ignore_shopping', 'supermarket_category',)
fields = ('name', 'plural_name', 'ignore_shopping', 'supermarket_category',)
class IngredientExportSerializer(WritableNestedModelSerializer):
@ -1184,7 +1195,7 @@ class IngredientExportSerializer(WritableNestedModelSerializer):
class Meta:
model = Ingredient
fields = ('food', 'unit', 'amount', 'note', 'order', 'is_header', 'no_amount')
fields = ('food', 'unit', 'amount', 'note', 'order', 'is_header', 'no_amount', 'always_use_plural_unit', 'always_use_plural_food')
class StepExportSerializer(WritableNestedModelSerializer):

File diff suppressed because one or more lines are too long

View File

@ -98,6 +98,7 @@ class SupermarketCategoryFactory(factory.django.DjangoModelFactory):
class FoodFactory(factory.django.DjangoModelFactory):
"""Food factory."""
name = factory.LazyAttribute(lambda x: faker.sentence(nb_words=3, variable_nb_words=False))
plural_name = factory.LazyAttribute(lambda x: faker.sentence(nb_words=3, variable_nb_words=False))
description = factory.LazyAttribute(lambda x: faker.sentence(nb_words=10))
supermarket_category = factory.Maybe(
factory.LazyAttribute(lambda x: x.has_category),
@ -126,7 +127,7 @@ class FoodFactory(factory.django.DjangoModelFactory):
class Meta:
model = 'cookbook.Food'
django_get_or_create = ('name', 'space',)
django_get_or_create = ('name', 'plural_name', 'space',)
@register
@ -160,12 +161,13 @@ class RecipeBookEntryFactory(factory.django.DjangoModelFactory):
class UnitFactory(factory.django.DjangoModelFactory):
"""Unit factory."""
name = factory.LazyAttribute(lambda x: faker.word())
plural_name = factory.LazyAttribute(lambda x: faker.word())
description = factory.LazyAttribute(lambda x: faker.sentence(nb_words=10))
space = factory.SubFactory(SpaceFactory)
class Meta:
model = 'cookbook.Unit'
django_get_or_create = ('name', 'space',)
django_get_or_create = ('name', 'plural_name', 'space',)
@register

View File

@ -571,6 +571,34 @@
<i class="fas fa-balance-scale-right fa-fw"></i>
{{ $t("Enable_Amount") }}
</button>
<button type="button" class="dropdown-item"
v-if="!ingredient.always_use_plural_unit"
@click="ingredient.always_use_plural_unit = true">
<i class="fas fa-filter fa-fw"></i>
{{ $t("Use_Plural_Unit_Always") }}
</button>
<button type="button" class="dropdown-item"
v-if="ingredient.always_use_plural_unit"
@click="ingredient.always_use_plural_unit = false">
<i class="fas fa-filter fa-fw"></i>
{{ $t("Use_Plural_Unit_Simple") }}
</button>
<button type="button" class="dropdown-item"
v-if="!ingredient.always_use_plural_food"
@click="ingredient.always_use_plural_food = true">
<i class="fas fa-filter fa-fw"></i>
{{ $t("Use_Plural_Food_Always") }}
</button>
<button type="button" class="dropdown-item"
v-if="ingredient.always_use_plural_food"
@click="ingredient.always_use_plural_food = false">
<i class="fas fa-filter fa-fw"></i>
{{ $t("Use_Plural_Food_Simple") }}
</button>
<button type="button" class="dropdown-item"
@click="copyTemplateReference(index, ingredient)">
<i class="fas fa-code"></i>
@ -1037,6 +1065,8 @@ export default {
order: 0,
is_header: false,
no_amount: false,
always_use_plural_unit: false,
always_use_plural_food: false,
original_text: null,
})
this.sortIngredients(step)

View File

@ -23,6 +23,7 @@
<b-card-body class="m-0 py-0">
<b-card-text class="h-100 my-0 d-flex flex-column" style="text-overflow: ellipsis">
<h5 class="m-0 mt-1 text-truncate">{{ item[title] }}</h5>
<div v-if="item[plural] !== '' && item[plural] !== null" class="m-0 text-truncate">({{ $t("plural_short") }}: {{ item[plural] }})</div>
<div class="m-0 text-truncate">{{ item[subtitle] }}</div>
<div class="m-0 text-truncate small text-muted" v-if="getFullname">{{ getFullname }}</div>
@ -146,6 +147,7 @@ export default {
item: { type: Object },
model: { type: Object },
title: { type: String, default: "name" }, // this and the following props need to be moved to model.js and made computed values
plural: { type: String, default: "plural_name" },
subtitle: { type: String, default: "description" },
child_count: { type: String, default: "numchild" },
children: { type: String, default: "children" },

View File

@ -16,14 +16,33 @@
v-html="calculateAmount(ingredient.amount)"></span>
</td>
<td @click="done">
<span v-if="ingredient.unit !== null && !ingredient.no_amount">{{ ingredient.unit.name }}</span>
<template v-if="ingredient.unit !== null && !ingredient.no_amount">
<template v-if="ingredient.unit.plural_name === '' || ingredient.unit.plural_name === null">
<span>{{ ingredient.unit.name }}
</template>
<template v-else>
<span v-if="ingredient.always_use_plural_unit">{{ ingredient.unit.plural_name}}</span>
<span v-else-if="(ingredient.amount * this.ingredient_factor) > 1">{{ ingredient.unit.plural_name }}</span>
<span v-else>{{ ingredient.unit.name }}</span>
</template>
</template>
</td>
<td @click="done">
<template v-if="ingredient.food !== null">
<a :href="resolveDjangoUrl('view_recipe', ingredient.food.recipe.id)"
v-if="ingredient.food.recipe !== null" target="_blank"
rel="noopener noreferrer">{{ ingredient.food.name }}</a>
<span v-if="ingredient.food.recipe === null">{{ ingredient.food.name }}</span>
<template v-if="ingredient.food.recipe === null">
<template v-if="ingredient.food.plural_name === '' || ingredient.food.plural_name === null">
<span>{{ ingredient.food.name }}</span>
</template>
<template v-else>
<span v-if="ingredient.always_use_plural_food">{{ ingredient.food.plural_name }}</span>
<span v-else-if="ingredient.no_amount">{{ ingredient.food.name }}</span>
<span v-else-if="(ingredient.amount * this.ingredient_factor) > 1">{{ ingredient.food.plural_name }}</span>
<span v-else>{{ ingredient.food.name }}</span>
</template>
</template>
</template>
</td>
<td v-if="detailed">

View File

@ -425,5 +425,11 @@
"New_Supermarket": "",
"New_Supermarket_Category": "",
"Are_You_Sure": "",
"Valid Until": ""
"Valid Until": "",
"Plural": "",
"plural_short": "",
"Use_Plural_Unit_Always": "",
"Use_Plural_Unit_Simple": "",
"Use_Plural_Food_Always": "",
"Use_Plural_Food_Simple": ""
}

View File

@ -410,5 +410,11 @@
"Warning_Delete_Supermarket_Category": "Изтриването на категория супермаркет ще изтрие и всички връзки с храни. Сигурен ли си?",
"New_Supermarket": "Създайте нов супермаркет",
"New_Supermarket_Category": "Създаване на нова категория супермаркет",
"Are_You_Sure": "Сигурен ли си?"
"Are_You_Sure": "Сигурен ли си?",
"Plural": "",
"plural_short": "",
"Use_Plural_Unit_Always": "",
"Use_Plural_Unit_Simple": "",
"Use_Plural_Food_Always": "",
"Use_Plural_Food_Simple": ""
}

View File

@ -458,5 +458,11 @@
"Days": "Dage",
"Message": "Besked",
"Sticky_Nav": "Fastlåst navigation",
"reset_food_inheritance": "Nulstil nedarvning"
"reset_food_inheritance": "Nulstil nedarvning",
"Plural": "",
"plural_short": "",
"Use_Plural_Unit_Always": "",
"Use_Plural_Unit_Simple": "",
"Use_Plural_Food_Always": "",
"Use_Plural_Food_Simple": ""
}

View File

@ -460,5 +460,11 @@
"Comments_setting": "Kommentare anzeigen",
"reset_food_inheritance": "Vererbung zurücksetzen",
"food_inherit_info": "Datenfelder des Lebensmittels, die standardmäßig vererbt werden sollen.",
"Are_You_Sure": "Bist du dir sicher?"
"Are_You_Sure": "Bist du dir sicher?",
"Plural": "Plural",
"plural_short": "pl.",
"Use_Plural_Unit_Always": "Pluralform der Maßeinheit immer verwenden",
"Use_Plural_Unit_Simple": "Pluralform der Maßeinheit dynamisch anpassen",
"Use_Plural_Food_Always": "Pluralform des Essens immer verwenden",
"Use_Plural_Food_Simple": "Pluralform des Essens dynamisch anpassen"
}

View File

@ -459,5 +459,11 @@
"New_Supermarket": "Create new supermarket",
"New_Supermarket_Category": "Create new supermarket category",
"Are_You_Sure": "Are you sure?",
"Valid Until": "Valid Until"
"Valid Until": "Valid Until",
"Plural": "Plural",
"plural_short": "plural",
"Use_Plural_Unit_Always": "Use plural form for unit always",
"Use_Plural_Unit_Simple": "Use plural form for unit dynamically",
"Use_Plural_Food_Always": "Use plural form for food always",
"Use_Plural_Food_Simple": "Use plural form for food dynamically"
}

View File

@ -436,5 +436,11 @@
"Default_Unit": "Unidad Predeterminada",
"Language": "Lenguaje",
"Hour": "Hora",
"Username": "Nombre de Usuario"
"Username": "Nombre de Usuario",
"Plural": "",
"plural_short": "",
"Use_Plural_Unit_Always": "",
"Use_Plural_Unit_Simple": "",
"Use_Plural_Food_Always": "",
"Use_Plural_Food_Simple": ""
}

View File

@ -212,5 +212,11 @@
"success_moving_resource": "Resurssin siirto onnistui!",
"success_merging_resource": "Resurssin yhdistäminen onnistui!",
"Search Settings": "Hakuasetukset",
"Shopping_Categories": "Ostoskategoriat"
"Shopping_Categories": "Ostoskategoriat",
"Plural": "",
"plural_short": "",
"Use_Plural_Unit_Always": "",
"Use_Plural_Unit_Simple": "",
"Use_Plural_Food_Always": "",
"Use_Plural_Food_Simple": ""
}

View File

@ -402,5 +402,11 @@
"Comments_setting": "Montrer les commentaires",
"import_duplicates": "Pour éviter les doublons, les recettes de même nom seront ignorées. Cocher la case pour tout importer.",
"Account": "Compte",
"Change_Password": "Modifier le mot de passe"
"Change_Password": "Modifier le mot de passe",
"Plural": "",
"plural_short": "",
"Use_Plural_Unit_Always": "",
"Use_Plural_Unit_Simple": "",
"Use_Plural_Food_Always": "",
"Use_Plural_Food_Simple": ""
}

View File

@ -412,5 +412,11 @@
"Warning_Delete_Supermarket_Category": "",
"New_Supermarket": "",
"New_Supermarket_Category": "",
"Are_You_Sure": ""
"Are_You_Sure": "",
"Plural": "",
"plural_short": "",
"Use_Plural_Unit_Always": "",
"Use_Plural_Unit_Simple": "",
"Use_Plural_Food_Always": "",
"Use_Plural_Food_Simple": ""
}

View File

@ -122,5 +122,11 @@
"Save_and_View": "Պահպանել և Դիտել",
"Select_File": "Ընտրել Ֆայլ",
"Edit_Keyword": "Խմբագրել բանալի բառը",
"Hide_Recipes": "Թաքցնել բաղադրատոմսերը"
"Hide_Recipes": "Թաքցնել բաղադրատոմսերը",
"Plural": "",
"plural_short": "",
"Use_Plural_Unit_Always": "",
"Use_Plural_Unit_Simple": "",
"Use_Plural_Food_Always": "",
"Use_Plural_Food_Simple": ""
}

View File

@ -346,5 +346,11 @@
"csv_delim_help": "Delimitatore usato per le esportazioni CSV.",
"csv_prefix_label": "Prefisso lista",
"not": "not",
"Keyword": "Parola chiave"
"Keyword": "Parola chiave",
"Plural": "",
"plural_short": "",
"Use_Plural_Unit_Always": "",
"Use_Plural_Unit_Simple": "",
"Use_Plural_Food_Always": "",
"Use_Plural_Food_Simple": ""
}

View File

@ -461,5 +461,11 @@
"Valid Until": "Geldig tot",
"warning_space_delete": "Je kunt jouw space verwijderen inclusief alle recepten, boodschappenlijstjes, maaltijdplannen en alles wat je verder aangemaakt hebt. Dit kan niet ongedaan worden gemaakt! Weet je het zeker?",
"food_inherit_info": "Voedselvelden die standaard geërfd worden.",
"facet_count_info": "Geef receptenaantal bij zoekfilters weer."
"facet_count_info": "Geef receptenaantal bij zoekfilters weer.",
"Plural": "",
"plural_short": "",
"Use_Plural_Unit_Always": "",
"Use_Plural_Unit_Simple": "",
"Use_Plural_Food_Always": "",
"Use_Plural_Food_Simple": ""
}

View File

@ -460,5 +460,11 @@
"First_name": "Imię",
"Last_name": "Nazwisko",
"Disabled": "Wyłączone",
"Disable": "Wyłączyć"
"Disable": "Wyłączyć",
"Plural": "",
"plural_short": "",
"Use_Plural_Unit_Always": "",
"Use_Plural_Unit_Simple": "",
"Use_Plural_Food_Always": "",
"Use_Plural_Food_Simple": ""
}

View File

@ -382,5 +382,11 @@
"err_deleting_protected_resource": "O objeto que você está tentando deletar ainda está sendo utilizado, portanto não pode ser deletado.",
"food_inherit_info": "Campos no alimento que devem ser herdados por padrão.",
"warning_space_delete": "Você pode deletar seu espaço, inclusive todas as receitas, listas de mercado, planos de comida e tudo mais que você criou. Esta ação não poderá ser desfeita! Você tem certeza que quer fazer isto?",
"facet_count_info": "Mostrar quantidade de receitas nos filtros de busca."
"facet_count_info": "Mostrar quantidade de receitas nos filtros de busca.",
"Plural": "",
"plural_short": "",
"Use_Plural_Unit_Always": "",
"Use_Plural_Unit_Simple": "",
"Use_Plural_Food_Always": "",
"Use_Plural_Food_Simple": ""
}

View File

@ -387,5 +387,11 @@
"Copy Token": "Copiar Token",
"warning_space_delete": "Você pode deletar seu espaço, inclusive todas as receitas, listas de mercado, planos de comida e tudo mais que você criou. Esta ação não poderá ser desfeita! Você tem certeza que quer fazer isto?",
"food_inherit_info": "Campos no alimento que devem ser herdados por padrão.",
"facet_count_info": "Mostrar quantidade de receitas nos filtros de busca."
"facet_count_info": "Mostrar quantidade de receitas nos filtros de busca.",
"Plural": "",
"plural_short": "",
"Use_Plural_Unit_Always": "",
"Use_Plural_Unit_Simple": "",
"Use_Plural_Food_Always": "",
"Use_Plural_Food_Simple": ""
}

View File

@ -206,5 +206,11 @@
"Auto_Planner": "",
"New_Cookbook": "",
"Hide_Keyword": "",
"Clear": ""
"Clear": "",
"Plural": "",
"plural_short": "",
"Use_Plural_Unit_Always": "",
"Use_Plural_Unit_Simple": "",
"Use_Plural_Food_Always": "",
"Use_Plural_Food_Simple": ""
}

View File

@ -342,5 +342,11 @@
"IgnoreThis": "Никогда не добавлять {food} в список покупок автоматически",
"DelayFor": "Отложить на {hours} часов",
"New_Entry": "Новая запись",
"GroupBy": "Сгруппировать по"
"GroupBy": "Сгруппировать по",
"Plural": "",
"plural_short": "",
"Use_Plural_Unit_Always": "",
"Use_Plural_Unit_Simple": "",
"Use_Plural_Food_Always": "",
"Use_Plural_Food_Simple": ""
}

View File

@ -284,5 +284,11 @@
"sql_debug": "SQL razhroščevanje",
"remember_search": "Zapomni si iskanje",
"remember_hours": "Ure, ki si jih zapomni",
"tree_select": "Uporabi drevesno označbo"
"tree_select": "Uporabi drevesno označbo",
"Plural": "",
"plural_short": "",
"Use_Plural_Unit_Always": "",
"Use_Plural_Unit_Simple": "",
"Use_Plural_Food_Always": "",
"Use_Plural_Food_Simple": ""
}

View File

@ -380,5 +380,11 @@
"create_food_desc": "Skapa ett livsmedel och länka det till det här receptet.",
"additional_options": "Ytterligare alternativ",
"remember_hours": "Timmar att komma ihåg",
"tree_select": "Använd trädval"
"tree_select": "Använd trädval",
"Plural": "",
"plural_short": "",
"Use_Plural_Unit_Always": "",
"Use_Plural_Unit_Simple": "",
"Use_Plural_Food_Always": "",
"Use_Plural_Food_Simple": ""
}

View File

@ -412,5 +412,11 @@
"Warning_Delete_Supermarket_Category": "",
"New_Supermarket": "",
"New_Supermarket_Category": "",
"Are_You_Sure": ""
"Are_You_Sure": "",
"Plural": "",
"plural_short": "",
"Use_Plural_Unit_Always": "",
"Use_Plural_Unit_Simple": "",
"Use_Plural_Food_Always": "",
"Use_Plural_Food_Simple": ""
}

View File

@ -459,5 +459,11 @@
"reset_children_help": "用继承字段中的值覆盖所有子项。 继承的子字段将设置为继承,除非它们已设置为继承。",
"substitute_siblings": "代替品",
"book_filter_help": "除手动选择的食谱外,还包括筛选中的食谱。",
"Internal": "内部"
"Internal": "内部",
"Plural": "",
"plural_short": "",
"Use_Plural_Unit_Always": "",
"Use_Plural_Unit_Simple": "",
"Use_Plural_Food_Always": "",
"Use_Plural_Food_Simple": ""
}

View File

@ -77,5 +77,11 @@
"and": "",
"Information": "",
"Download": "",
"Create": ""
"Create": "",
"Plural": "",
"plural_short": "",
"Use_Plural_Unit_Always": "",
"Use_Plural_Unit_Simple": "",
"Use_Plural_Food_Always": "",
"Use_Plural_Food_Simple": ""
}

View File

@ -78,6 +78,7 @@ export class Models {
params: [
[
"name",
"plural_name",
"description",
"recipe",
"food_onhand",
@ -103,6 +104,13 @@ export class Models {
placeholder: "", // form.placeholder always translated
subtitle_field: "full_name",
},
plural_name: {
form_field: true,
type: "text",
field: "plural_name",
label: "Plural",
placeholder: "",
},
description: {
form_field: true,
type: "text",
@ -261,7 +269,7 @@ export class Models {
apiName: "Unit",
paginated: true,
create: {
params: [["name", "description"]],
params: [["name", "plural_name", "description",]],
form: {
name: {
form_field: true,
@ -270,6 +278,13 @@ export class Models {
label: "Name",
placeholder: "",
},
plural_name: {
form_field: true,
type: "text",
field: "plural_name",
label: "Plural name",
placeholder: "",
},
description: {
form_field: true,
type: "text",