property view unit conversion/edit

This commit is contained in:
vabene1111
2025-03-21 21:22:32 +01:00
parent fbab90e954
commit de5ac9181f
34 changed files with 111 additions and 38 deletions

View File

@@ -44,13 +44,17 @@ class FoodPropertyHelper:
if i.food is not None: if i.food is not None:
conversions = uch.get_conversions(i) conversions = uch.get_conversions(i)
for pt in property_types: for pt in property_types:
# if a property could be calculated with an actual value
found_property = False found_property = False
# if food has a value for the given property type (no matter if conversion is possible)
has_property_value = False
if i.food.properties_food_amount == 0 or i.food.properties_food_unit is None: # if food is configured incorrectly if i.food.properties_food_amount == 0 or i.food.properties_food_unit is None: # if food is configured incorrectly
computed_properties[pt.id]['food_values'][i.food.id] = {'id': i.food.id, 'food': i.food.name, 'value': None} computed_properties[pt.id]['food_values'][i.food.id] = {'id': i.food.id, 'food': {'id': i.food.id, 'name': i.food.name}, 'value': None}
computed_properties[pt.id]['missing_value'] = True computed_properties[pt.id]['missing_value'] = True
else: else:
for p in i.food.properties.all(): for p in i.food.properties.all():
if p.property_type == pt and p.property_amount is not None: if p.property_type == pt and p.property_amount is not None:
has_property_value = True
for c in conversions: for c in conversions:
if c.unit == i.food.properties_food_unit: if c.unit == i.food.properties_food_unit:
found_property = True found_property = True
@@ -60,10 +64,12 @@ class FoodPropertyHelper:
if not found_property: if not found_property:
if i.amount == 0: # don't count ingredients without an amount as missing if i.amount == 0: # don't count ingredients without an amount as missing
computed_properties[pt.id]['missing_value'] = computed_properties[pt.id]['missing_value'] or False # don't override if another food was already missing computed_properties[pt.id]['missing_value'] = computed_properties[pt.id]['missing_value'] or False # don't override if another food was already missing
computed_properties[pt.id]['food_values'][i.food.id] = {'id': i.food.id, 'food': i.food.name, 'value': 0} computed_properties[pt.id]['food_values'][i.food.id] = {'id': i.food.id, 'food': {'id': i.food.id, 'name': i.food.name}, 'value': 0}
else: else:
computed_properties[pt.id]['missing_value'] = True computed_properties[pt.id]['missing_value'] = True
computed_properties[pt.id]['food_values'][i.food.id] = {'id': i.food.id, 'food': i.food.name, 'value': None} computed_properties[pt.id]['food_values'][i.food.id] = {'id': i.food.id, 'food': {'id': i.food.id, 'name': i.food.name}, 'value': None}
if has_property_value and i.unit is not None:
computed_properties[pt.id]['food_values'][i.food.id]['missing_conversion'] = {'base_unit': {'id': i.unit.id, 'name': i.unit.name}, 'converted_unit': {'id': i.food.properties_food_unit.id, 'name': i.food.properties_food_unit.name}}
return computed_properties return computed_properties
@@ -74,5 +80,5 @@ class FoodPropertyHelper:
if key in d and d[key]['value']: if key in d and d[key]['value']:
d[key]['value'] += value d[key]['value'] += value
else: else:
d[key] = {'id': food.id, 'food': food.name, 'value': value} d[key] = {'id': food.id, 'food': {'id': food.id, 'name': food.name}, 'value': value}
return d return d

View File

@@ -21,11 +21,12 @@
</thead> </thead>
<tbody> <tbody>
<tr v-for="p in propertyList" :key="p.id"> <tr v-for="p in propertyList" :key="p.id">
<td>{{p.name}}</td> <td>{{ p.name }}</td>
<td>{{$n(p.propertyAmountPerServing)}} {{p.unit}}</td> <td>{{ $n(p.propertyAmountPerServing) }} {{ p.unit }}</td>
<td>{{$n(p.propertyAmountTotal)}} {{p.unit}}</td> <td>{{ $n(p.propertyAmountTotal) }} {{ p.unit }}</td>
<td v-if="sourceSelectedToShow == 'food'"> <td v-if="sourceSelectedToShow == 'food'">
<v-btn @click="dialogProperty = p; dialog = true" variant="plain" color="warning" icon="fa-solid fa-triangle-exclamation" size="small" v-if="p.missingValue"></v-btn> <v-btn @click="dialogProperty = p; dialog = true" variant="plain" color="warning" icon="fa-solid fa-triangle-exclamation" size="small"
v-if="p.missingValue"></v-btn>
<v-btn @click="dialogProperty = p; dialog = true" variant="plain" icon="fa-solid fa-circle-info" size="small" v-if="!p.missingValue"></v-btn> <v-btn @click="dialogProperty = p; dialog = true" variant="plain" icon="fa-solid fa-circle-info" size="small" v-if="!p.missingValue"></v-btn>
</td> </td>
</tr> </tr>
@@ -36,25 +37,39 @@
<v-dialog max-width="900px" v-model="dialog"> <v-dialog max-width="900px" v-model="dialog">
<v-card v-if="dialogProperty"> <v-card v-if="dialogProperty">
<v-closable-card-title :title="`${dialogProperty.propertyAmountTotal} ${dialogProperty.unit} ${dialogProperty.name}`" :sub-title="$t('total')" icon="$properties" v-model="dialog"></v-closable-card-title> <v-closable-card-title :title="`${dialogProperty.propertyAmountTotal} ${dialogProperty.unit} ${dialogProperty.name}`" :sub-title="$t('total')" icon="$properties"
v-model="dialog"></v-closable-card-title>
<v-card-text> <v-card-text>
<v-list> <v-list>
<v-list-item border v-for="fv in dialogProperty.foodValues"> <v-list-item border v-for="fv in dialogProperty.foodValues" :key="`${dialogProperty.id}_${fv.id}`">
<template #prepend> <template #prepend>
<v-progress-circular size="55" width="5" :model-value="(fv.value/dialogProperty.propertyAmountTotal)*100" :color="colorScale((fv.value/dialogProperty.propertyAmountTotal)*100)" v-if="fv.value != null">{{Math.round((fv.value/dialogProperty.propertyAmountTotal)*100)}}%</v-progress-circular> <v-progress-circular size="55" width="5" :model-value="(fv.value/dialogProperty.propertyAmountTotal)*100"
:color="colorScale((fv.value/dialogProperty.propertyAmountTotal)*100)" v-if="fv.value != null">
{{ Math.round((fv.value / dialogProperty.propertyAmountTotal) * 100) }}%
</v-progress-circular>
<v-progress-circular size="55" width="5" v-if="fv.value == null">?</v-progress-circular> <v-progress-circular size="55" width="5" v-if="fv.value == null">?</v-progress-circular>
</template> </template>
<span class="ms-2"> <span class="ms-2">
{{ fv.food }} {{ fv.food.name }}
</span> </span>
<template #append> <template #append>
<v-chip v-if="fv.value">{{$n(fv.value)}} {{dialogProperty.unit}}</v-chip> <v-chip v-if="fv.value != undefined">{{ $n(fv.value) }} {{ dialogProperty.unit }}</v-chip>
<v-chip color="create" v-else-if="fv.missing_conversion" class="cursor-pointer" prepend-icon="$create">
{{ $t('Conversion') }}: {{ fv.missing_conversion.base_unit.name }} <i class="fa-solid fa-arrow-right me-1 ms-1"></i>
{{ fv.missing_conversion.converted_unit.name }}
<model-edit-dialog model="UnitConversion" @create="refreshRecipe()"
:item-defaults="{baseAmount: 1, baseUnit: fv.missing_conversion.base_unit, convertedUnit: fv.missing_conversion.converted_unit, food: fv.food}"></model-edit-dialog>
</v-chip>
<v-chip color="error" prepend-icon="$edit" class="cursor-pointer" v-else>
{{ $t('Edit') }}
<model-edit-dialog model="Food" :item-id="fv.food.id" @update:model-value="refreshRecipe()"></model-edit-dialog>
</v-chip>
</template> </template>
</v-list-item> </v-list-item>
</v-list> </v-list>
</v-card-text> </v-card-text>
<v-card-actions> <v-card-actions>
<v-btn :to="{ name: 'PropertyEditorPage', query: {recipe: recipe.id} }">{{$t('Property_Editor')}}</v-btn> <v-btn :to="{ name: 'PropertyEditorPage', query: {recipe: recipe.id} }">{{ $t('Property_Editor') }}</v-btn>
</v-card-actions> </v-card-actions>
</v-card> </v-card>
</v-dialog> </v-dialog>
@@ -63,9 +78,11 @@
<script setup lang="ts"> <script setup lang="ts">
import {computed, onMounted, PropType, ref} from "vue"; import {computed, nextTick, onMounted, ref} from "vue";
import {PropertyType, Recipe} from "@/openapi"; import {ApiApi, PropertyType, Recipe} from "@/openapi";
import VClosableCardTitle from "@/components/dialogs/VClosableCardTitle.vue"; import VClosableCardTitle from "@/components/dialogs/VClosableCardTitle.vue";
import ModelEditDialog from "@/components/dialogs/ModelEditDialog.vue";
import {ErrorMessageType, useMessageStore} from "@/stores/MessageStore";
type PropertyWrapper = { type PropertyWrapper = {
id: number, id: number,
@@ -80,15 +97,16 @@ type PropertyWrapper = {
} }
const props = defineProps({ const props = defineProps({
recipe: {type: {} as PropType<Recipe>, required: true}, servings: {type: Number, required: true,},
servings: { type: Number, required: true, },
}) })
const recipe = defineModel<Recipe>({required: true})
/** /**
* determines if the recipe has properties on the recipe directly * determines if the recipe has properties on the recipe directly
*/ */
const hasRecipeProperties = computed(() => { const hasRecipeProperties = computed(() => {
return props.recipe.properties != undefined && props.recipe.properties.length > 0 return recipe.value.properties != undefined && recipe.value.properties.length > 0
}) })
/** /**
@@ -96,7 +114,7 @@ const hasRecipeProperties = computed(() => {
*/ */
const hasFoodProperties = computed(() => { const hasFoodProperties = computed(() => {
let propertiesFound = false let propertiesFound = false
for (const [key, fp] of Object.entries(props.recipe.foodProperties)) { for (const [key, fp] of Object.entries(recipe.value.foodProperties)) {
if (fp.total_value !== 0) { if (fp.total_value !== 0) {
propertiesFound = true propertiesFound = true
} }
@@ -111,7 +129,8 @@ const propertyList = computed(() => {
let ptList = [] as PropertyWrapper[] let ptList = [] as PropertyWrapper[]
if (sourceSelectedToShow.value == 'recipe') { if (sourceSelectedToShow.value == 'recipe') {
if (hasRecipeProperties.value) { if (hasRecipeProperties.value) {
props.recipe.properties.forEach(rp => { recipe.value.properties.forEach(rp => {
ptList.push( ptList.push(
{ {
id: rp.propertyType.id!, id: rp.propertyType.id!,
@@ -119,7 +138,7 @@ const propertyList = computed(() => {
description: rp.propertyType.description, description: rp.propertyType.description,
foodValues: [], foodValues: [],
propertyAmountPerServing: rp.propertyAmount, propertyAmountPerServing: rp.propertyAmount,
propertyAmountTotal: rp.propertyAmount * props.recipe.servings * (props.servings / props.recipe.servings), propertyAmountTotal: rp.propertyAmount * recipe.value.servings * (props.servings / recipe.value.servings),
missingValue: false, missingValue: false,
unit: rp.propertyType.unit, unit: rp.propertyType.unit,
type: rp.propertyType, type: rp.propertyType,
@@ -128,7 +147,7 @@ const propertyList = computed(() => {
}) })
} }
} else { } else {
for (const [key, fp] of Object.entries(props.recipe.foodProperties)) { for (const [key, fp] of Object.entries(recipe.value.foodProperties)) {
ptList.push( ptList.push(
{ {
id: fp.id, id: fp.id,
@@ -136,8 +155,8 @@ const propertyList = computed(() => {
description: fp.description, description: fp.description,
icon: fp.icon, icon: fp.icon,
foodValues: fp.food_values, foodValues: fp.food_values,
propertyAmountPerServing: fp.total_value / props.recipe.servings, propertyAmountPerServing: fp.total_value / recipe.value.servings,
propertyAmountTotal: fp.total_value * (props.servings / props.recipe.servings), propertyAmountTotal: fp.total_value * (props.servings / recipe.value.servings),
missingValue: fp.missing_value, missingValue: fp.missing_value,
unit: fp.unit, unit: fp.unit,
type: fp, type: fp,
@@ -161,7 +180,7 @@ const propertyList = computed(() => {
const sourceSelectedToShow = ref<'recipe' | 'food'>("food") const sourceSelectedToShow = ref<'recipe' | 'food'>("food")
const dialog = ref(false) const dialog = ref(false)
const dialogProperty = ref<undefined|PropertyWrapper>(undefined) const dialogProperty = ref<undefined | PropertyWrapper>(undefined)
onMounted(() => { onMounted(() => {
if (!hasFoodProperties) { if (!hasFoodProperties) {
@@ -169,19 +188,42 @@ onMounted(() => {
} }
}) })
/**
* refresh recipe data to pull updated conversions/properties
*/
function refreshRecipe() {
let api = new ApiApi()
api.apiRecipeRetrieve({id: recipe.value.id!}).then(r => {
recipe.value = r
nextTick(() => {
if(dialogProperty.value != undefined && dialog.value){
propertyList.value.forEach(pLE => {
if (dialogProperty.value.id == pLE.id) {
dialogProperty.value = pLE
}
})
}
})
}).catch(err => {
useMessageStore().addError(ErrorMessageType.FETCH_ERROR, err)
})
}
/** /**
* return a color based on the given number * return a color based on the given number
* used to color the percentage of each food contributing to the total value of a property * used to color the percentage of each food contributing to the total value of a property
* @param percentage * @param percentage
*/ */
function colorScale(percentage: number){ function colorScale(percentage: number) {
if(percentage > 80){ if (percentage > 80) {
return 'error' return 'error'
} }
if(percentage > 50){ if (percentage > 50) {
return 'warning' return 'warning'
} }
if(percentage > 30){ if (percentage > 30) {
return 'info' return 'info'
} }
return 'success' return 'success'

View File

@@ -72,15 +72,9 @@
</v-card> </v-card>
</template> </template>
<property-view :recipe="recipe" :servings="servings"></property-view> <property-view v-model="recipe" :servings="servings"></property-view>
<v-expansion-panels class="mt-2"> <v-expansion-panels class="mt-2">
<v-expansion-panel>
<v-expansion-panel-title><v-icon icon="$properties" class="me-2"></v-icon> {{ $t('Properties') }}</v-expansion-panel-title>
<v-expansion-panel-text>
<property-view :recipe="recipe" :ingredient-factor="ingredientFactor"></property-view>
</v-expansion-panel-text>
</v-expansion-panel>
<v-expansion-panel> <v-expansion-panel>
<v-expansion-panel-title><v-icon icon="fa-solid fa-circle-info" class="me-2"></v-icon> {{ $t('Information') }}</v-expansion-panel-title> <v-expansion-panel-title><v-icon icon="fa-solid fa-circle-info" class="me-2"></v-icon> {{ $t('Information') }}</v-expansion-panel-title>

View File

@@ -199,6 +199,7 @@
"Message": "", "Message": "",
"Messages": "", "Messages": "",
"Miscellaneous": "", "Miscellaneous": "",
"MissingConversion": "",
"Monday": "", "Monday": "",
"Month": "", "Month": "",
"More": "", "More": "",

View File

@@ -193,6 +193,7 @@
"Merge_Keyword": "Обединяване на ключова дума", "Merge_Keyword": "Обединяване на ключова дума",
"Messages": "", "Messages": "",
"Miscellaneous": "", "Miscellaneous": "",
"MissingConversion": "",
"Monday": "", "Monday": "",
"Month": "Месец", "Month": "Месец",
"More": "", "More": "",

View File

@@ -249,6 +249,7 @@
"Message": "", "Message": "",
"Messages": "", "Messages": "",
"Miscellaneous": "", "Miscellaneous": "",
"MissingConversion": "",
"Monday": "", "Monday": "",
"Month": "", "Month": "",
"More": "", "More": "",

View File

@@ -248,6 +248,7 @@
"Message": "Zpráva", "Message": "Zpráva",
"Messages": "", "Messages": "",
"Miscellaneous": "", "Miscellaneous": "",
"MissingConversion": "",
"Monday": "", "Monday": "",
"Month": "Měsíc", "Month": "Měsíc",
"More": "", "More": "",

View File

@@ -235,6 +235,7 @@
"Message": "Besked", "Message": "Besked",
"Messages": "", "Messages": "",
"Miscellaneous": "", "Miscellaneous": "",
"MissingConversion": "",
"Monday": "", "Monday": "",
"Month": "Måned", "Month": "Måned",
"More": "", "More": "",

View File

@@ -252,6 +252,7 @@
"Message": "Nachricht", "Message": "Nachricht",
"Messages": "Nachrichten", "Messages": "Nachrichten",
"Miscellaneous": "Sonstige", "Miscellaneous": "Sonstige",
"MissingConversion": "Fehlende Umrechnung",
"Monday": "Montag", "Monday": "Montag",
"Month": "Monat", "Month": "Monat",
"More": "Mehr", "More": "Mehr",

View File

@@ -230,6 +230,7 @@
"Message": "Μήνυμα", "Message": "Μήνυμα",
"Messages": "", "Messages": "",
"Miscellaneous": "", "Miscellaneous": "",
"MissingConversion": "",
"Monday": "", "Monday": "",
"Month": "Μήνας", "Month": "Μήνας",
"More": "", "More": "",

View File

@@ -250,6 +250,7 @@
"Message": "Message", "Message": "Message",
"Messages": "Messages", "Messages": "Messages",
"Miscellaneous": "Miscellaneous", "Miscellaneous": "Miscellaneous",
"MissingConversion": "Missing Conversion",
"Monday": "Monday", "Monday": "Monday",
"Month": "Month", "Month": "Month",
"More": "More", "More": "More",

View File

@@ -250,6 +250,7 @@
"Message": "Mensaje", "Message": "Mensaje",
"Messages": "", "Messages": "",
"Miscellaneous": "", "Miscellaneous": "",
"MissingConversion": "",
"Monday": "", "Monday": "",
"Month": "Mes", "Month": "Mes",
"More": "", "More": "",

View File

@@ -148,6 +148,7 @@
"Merge_Keyword": "Yhdistä Avainsana", "Merge_Keyword": "Yhdistä Avainsana",
"Messages": "", "Messages": "",
"Miscellaneous": "", "Miscellaneous": "",
"MissingConversion": "",
"Monday": "", "Monday": "",
"Month": "Kuukausi", "Month": "Kuukausi",
"More": "", "More": "",

View File

@@ -249,6 +249,7 @@
"Message": "Message", "Message": "Message",
"Messages": "", "Messages": "",
"Miscellaneous": "", "Miscellaneous": "",
"MissingConversion": "",
"Monday": "", "Monday": "",
"Month": "Mois", "Month": "Mois",
"More": "", "More": "",

View File

@@ -250,6 +250,7 @@
"Message": "הודעה", "Message": "הודעה",
"Messages": "", "Messages": "",
"Miscellaneous": "", "Miscellaneous": "",
"MissingConversion": "",
"Monday": "", "Monday": "",
"Month": "חודש", "Month": "חודש",
"More": "", "More": "",

View File

@@ -231,6 +231,7 @@
"Message": "Üzenet", "Message": "Üzenet",
"Messages": "", "Messages": "",
"Miscellaneous": "", "Miscellaneous": "",
"MissingConversion": "",
"Monday": "", "Monday": "",
"Month": "Hónap", "Month": "Hónap",
"More": "", "More": "",

View File

@@ -113,6 +113,7 @@
"Merge_Keyword": "Միացնել բանալի բառը", "Merge_Keyword": "Միացնել բանալի բառը",
"Messages": "", "Messages": "",
"Miscellaneous": "", "Miscellaneous": "",
"MissingConversion": "",
"Monday": "", "Monday": "",
"More": "", "More": "",
"Move": "Տեղափոխել", "Move": "Տեղափոխել",

View File

@@ -216,6 +216,7 @@
"Message": "", "Message": "",
"Messages": "", "Messages": "",
"Miscellaneous": "", "Miscellaneous": "",
"MissingConversion": "",
"Monday": "", "Monday": "",
"Month": "", "Month": "",
"More": "", "More": "",

View File

@@ -249,6 +249,7 @@
"Message": "", "Message": "",
"Messages": "", "Messages": "",
"Miscellaneous": "", "Miscellaneous": "",
"MissingConversion": "",
"Monday": "", "Monday": "",
"Month": "", "Month": "",
"More": "", "More": "",

View File

@@ -221,6 +221,7 @@
"Message": "Messaggio", "Message": "Messaggio",
"Messages": "", "Messages": "",
"Miscellaneous": "", "Miscellaneous": "",
"MissingConversion": "",
"Monday": "", "Monday": "",
"Month": "Mese", "Month": "Mese",
"More": "", "More": "",

View File

@@ -233,6 +233,7 @@
"Message": "", "Message": "",
"Messages": "", "Messages": "",
"Miscellaneous": "", "Miscellaneous": "",
"MissingConversion": "",
"Monday": "", "Monday": "",
"Month": "", "Month": "",
"More": "", "More": "",

View File

@@ -228,6 +228,7 @@
"Message": "Melding", "Message": "Melding",
"Messages": "", "Messages": "",
"Miscellaneous": "", "Miscellaneous": "",
"MissingConversion": "",
"Monday": "", "Monday": "",
"Month": "Måned", "Month": "Måned",
"More": "", "More": "",

View File

@@ -232,6 +232,7 @@
"Message": "Bericht", "Message": "Bericht",
"Messages": "", "Messages": "",
"Miscellaneous": "", "Miscellaneous": "",
"MissingConversion": "",
"Monday": "", "Monday": "",
"Month": "Maand", "Month": "Maand",
"More": "", "More": "",

View File

@@ -251,6 +251,7 @@
"Message": "Wiadomość", "Message": "Wiadomość",
"Messages": "", "Messages": "",
"Miscellaneous": "", "Miscellaneous": "",
"MissingConversion": "",
"Monday": "", "Monday": "",
"Month": "Miesiąc", "Month": "Miesiąc",
"More": "", "More": "",

View File

@@ -190,6 +190,7 @@
"Merge_Keyword": "Unir palavra-chave", "Merge_Keyword": "Unir palavra-chave",
"Messages": "", "Messages": "",
"Miscellaneous": "", "Miscellaneous": "",
"MissingConversion": "",
"Monday": "", "Monday": "",
"Month": "Mês", "Month": "Mês",
"More": "", "More": "",

View File

@@ -243,6 +243,7 @@
"Message": "Mensagem", "Message": "Mensagem",
"Messages": "", "Messages": "",
"Miscellaneous": "", "Miscellaneous": "",
"MissingConversion": "",
"Monday": "", "Monday": "",
"Month": "Mês", "Month": "Mês",
"More": "", "More": "",

View File

@@ -225,6 +225,7 @@
"Message": "Mesaj", "Message": "Mesaj",
"Messages": "", "Messages": "",
"Miscellaneous": "", "Miscellaneous": "",
"MissingConversion": "",
"Monday": "", "Monday": "",
"Month": "Lună", "Month": "Lună",
"More": "", "More": "",

View File

@@ -179,6 +179,7 @@
"Merge_Keyword": "Объеденить ключевые слова", "Merge_Keyword": "Объеденить ключевые слова",
"Messages": "", "Messages": "",
"Miscellaneous": "", "Miscellaneous": "",
"MissingConversion": "",
"Monday": "", "Monday": "",
"Month": "Месяц", "Month": "Месяц",
"More": "", "More": "",

View File

@@ -175,6 +175,7 @@
"Merge_Keyword": "Združi ključno besedo", "Merge_Keyword": "Združi ključno besedo",
"Messages": "", "Messages": "",
"Miscellaneous": "", "Miscellaneous": "",
"MissingConversion": "",
"Monday": "", "Monday": "",
"Month": "Mesec", "Month": "Mesec",
"More": "", "More": "",

View File

@@ -251,6 +251,7 @@
"Message": "Meddelande", "Message": "Meddelande",
"Messages": "", "Messages": "",
"Miscellaneous": "", "Miscellaneous": "",
"MissingConversion": "",
"Monday": "", "Monday": "",
"Month": "Månad", "Month": "Månad",
"More": "", "More": "",

View File

@@ -250,6 +250,7 @@
"Message": "Mesaj", "Message": "Mesaj",
"Messages": "", "Messages": "",
"Miscellaneous": "", "Miscellaneous": "",
"MissingConversion": "",
"Monday": "", "Monday": "",
"Month": "Ay", "Month": "Ay",
"More": "", "More": "",

View File

@@ -204,6 +204,7 @@
"Merge_Keyword": "Об'єднати Ключове слово", "Merge_Keyword": "Об'єднати Ключове слово",
"Messages": "", "Messages": "",
"Miscellaneous": "", "Miscellaneous": "",
"MissingConversion": "",
"Monday": "", "Monday": "",
"Month": "Місяць", "Month": "Місяць",
"More": "", "More": "",

View File

@@ -246,6 +246,7 @@
"Message": "信息", "Message": "信息",
"Messages": "", "Messages": "",
"Miscellaneous": "", "Miscellaneous": "",
"MissingConversion": "",
"Monday": "", "Monday": "",
"Month": "月份", "Month": "月份",
"More": "", "More": "",

View File

@@ -96,6 +96,7 @@
"MergeAutomateHelp": "", "MergeAutomateHelp": "",
"Messages": "", "Messages": "",
"Miscellaneous": "", "Miscellaneous": "",
"MissingConversion": "",
"Monday": "", "Monday": "",
"More": "", "More": "",
"New": "", "New": "",