mirror of
				https://github.com/mealie-recipes/mealie.git
				synced 2025-10-27 00:04:23 -04:00 
			
		
		
		
	add food and unit seeding UI (#1206)
This commit is contained in:
		| @@ -519,6 +519,12 @@ | ||||
|       "merge-food-example": "Merging {food1} into {food2}", | ||||
|       "seed-dialog-text": "Seed the database with foods based on your local language. This will create 200+ common foods that can be used to organize your database. Foods are translated via a community effort.", | ||||
|       "seed-dialog-warning": "You have already have some items in your database. This action will not reconcile duplicates, you will have to manage them manually." | ||||
|     }, | ||||
|     "units": { | ||||
|       "seed-dialog-text": "Seed the database with common units based on your local language." | ||||
|     }, | ||||
|     "labels": { | ||||
|       "seed-dialog-text": "Seed the database with common labels based on your local language." | ||||
|     } | ||||
|   }, | ||||
|   "user-registration": { | ||||
|   | ||||
| @@ -42,6 +42,43 @@ | ||||
|       </v-card-text> | ||||
|     </BaseDialog> | ||||
|  | ||||
|     <!-- Seed Dialog--> | ||||
|     <BaseDialog | ||||
|       v-model="seedDialog" | ||||
|       :icon="$globals.icons.foods" | ||||
|       :title="$tc('data-pages.seed-data')" | ||||
|       @confirm="seedDatabase" | ||||
|     > | ||||
|       <v-card-text> | ||||
|         <div class="pb-2"> | ||||
|           {{ $t("data-pages.labels.seed-dialog-text") }} | ||||
|         </div> | ||||
|         <v-autocomplete | ||||
|           v-model="locale" | ||||
|           :items="locales" | ||||
|           item-text="name" | ||||
|           label="Select Language" | ||||
|           class="my-3" | ||||
|           hide-details | ||||
|           outlined | ||||
|           offset | ||||
|         > | ||||
|           <template #item="{ item }"> | ||||
|             <v-list-item-content> | ||||
|               <v-list-item-title v-text="item.name"></v-list-item-title> | ||||
|               <v-list-item-subtitle> | ||||
|                 {{ item.progress }}% {{ $tc("language-dialog.translated") }} | ||||
|               </v-list-item-subtitle> | ||||
|             </v-list-item-content> | ||||
|           </template> | ||||
|         </v-autocomplete> | ||||
|  | ||||
|         <v-alert v-if="labels.length > 0" type="error" class="mb-0 text-body-2"> | ||||
|           {{ $t("data-pages.foods.seed-dialog-warning") }} | ||||
|         </v-alert> | ||||
|       </v-card-text> | ||||
|     </BaseDialog> | ||||
|  | ||||
|     <!-- Recipe Data Table --> | ||||
|     <BaseCardSectionTitle :icon="$globals.icons.tags" section title="Labels"> </BaseCardSectionTitle> | ||||
|     <CrudTable | ||||
| @@ -55,7 +92,7 @@ | ||||
|       <template #button-row> | ||||
|         <BaseButton create @click="state.createDialog = true"> | ||||
|           <template #icon> {{ $globals.icons.tags }} </template> | ||||
|           Create | ||||
|           {{ $t("general.create") }} | ||||
|         </BaseButton> | ||||
|       </template> | ||||
|       <template #item.name="{ item }"> | ||||
| @@ -63,16 +100,24 @@ | ||||
|           {{ item.name }} | ||||
|         </MultiPurposeLabel> | ||||
|       </template> | ||||
|       <template #button-bottom> | ||||
|         <BaseButton @click="seedDialog = true"> | ||||
|           <template #icon> {{ $globals.icons.database }} </template> | ||||
|           Seed | ||||
|         </BaseButton> | ||||
|       </template> | ||||
|     </CrudTable> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script lang="ts"> | ||||
| import { defineComponent, reactive, ref } from "@nuxtjs/composition-api"; | ||||
| import { defineComponent, onMounted, reactive, ref } from "@nuxtjs/composition-api"; | ||||
| import type { LocaleObject } from "@nuxtjs/i18n"; | ||||
| import { validators } from "~/composables/use-validators"; | ||||
| import { useUserApi } from "~/composables/api"; | ||||
| import MultiPurposeLabel from "~/components/Domain/ShoppingList/MultiPurposeLabel.vue"; | ||||
| import { MultiPurposeLabelSummary } from "~/types/api-types/labels"; | ||||
| import { useLocales } from "~/composables/use-locales"; | ||||
|  | ||||
| export default defineComponent({ | ||||
|   components: { MultiPurposeLabel }, | ||||
| @@ -178,6 +223,30 @@ export default defineComponent({ | ||||
|  | ||||
|     refreshLabels(); | ||||
|  | ||||
|     // ============================================================ | ||||
|     // Seed | ||||
|  | ||||
|     const seedDialog = ref(false); | ||||
|     const locale = ref(""); | ||||
|  | ||||
|     const { locales: LOCALES, locale: currentLocale, i18n } = useLocales(); | ||||
|  | ||||
|     onMounted(() => { | ||||
|       locale.value = currentLocale.value; | ||||
|     }); | ||||
|  | ||||
|     const locales = LOCALES.filter((locale) => | ||||
|       (i18n.locales as LocaleObject[]).map((i18nLocale) => i18nLocale.code).includes(locale.value) | ||||
|     ); | ||||
|  | ||||
|     async function seedDatabase() { | ||||
|       const { data } = await userApi.seeders.labels({ locale: locale.value }); | ||||
|  | ||||
|       if (data) { | ||||
|         refreshLabels(); | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     return { | ||||
|       state, | ||||
|       tableConfig, | ||||
| @@ -192,6 +261,12 @@ export default defineComponent({ | ||||
|       editSaveLabel, | ||||
|       createLabel, | ||||
|       createLabelData, | ||||
|  | ||||
|       // Seed | ||||
|       seedDatabase, | ||||
|       locales, | ||||
|       locale, | ||||
|       seedDialog, | ||||
|     }; | ||||
|   }, | ||||
| }); | ||||
|   | ||||
| @@ -46,6 +46,43 @@ | ||||
|       </v-card-text> | ||||
|     </BaseDialog> | ||||
|  | ||||
|     <!-- Seed Dialog--> | ||||
|     <BaseDialog | ||||
|       v-model="seedDialog" | ||||
|       :icon="$globals.icons.foods" | ||||
|       :title="$tc('data-pages.seed-data')" | ||||
|       @confirm="seedDatabase" | ||||
|     > | ||||
|       <v-card-text> | ||||
|         <div class="pb-2"> | ||||
|           {{ $t("data-pages.units.seed-dialog-text") }} | ||||
|         </div> | ||||
|         <v-autocomplete | ||||
|           v-model="locale" | ||||
|           :items="locales" | ||||
|           item-text="name" | ||||
|           label="Select Language" | ||||
|           class="my-3" | ||||
|           hide-details | ||||
|           outlined | ||||
|           offset | ||||
|         > | ||||
|           <template #item="{ item }"> | ||||
|             <v-list-item-content> | ||||
|               <v-list-item-title v-text="item.name"></v-list-item-title> | ||||
|               <v-list-item-subtitle> | ||||
|                 {{ item.progress }}% {{ $tc("language-dialog.translated") }} | ||||
|               </v-list-item-subtitle> | ||||
|             </v-list-item-content> | ||||
|           </template> | ||||
|         </v-autocomplete> | ||||
|  | ||||
|         <v-alert v-if="units.length > 0" type="error" class="mb-0 text-body-2"> | ||||
|           {{ $t("data-pages.foods.seed-dialog-warning") }} | ||||
|         </v-alert> | ||||
|       </v-card-text> | ||||
|     </BaseDialog> | ||||
|  | ||||
|     <!-- Recipe Data Table --> | ||||
|     <BaseCardSectionTitle :icon="$globals.icons.units" section title="Unit Data"> </BaseCardSectionTitle> | ||||
|     <CrudTable | ||||
| @@ -67,16 +104,24 @@ | ||||
|           {{ item.fraction ? $globals.icons.check : $globals.icons.close }} | ||||
|         </v-icon> | ||||
|       </template> | ||||
|       <template #button-bottom> | ||||
|         <BaseButton @click="seedDialog = true"> | ||||
|           <template #icon> {{ $globals.icons.database }} </template> | ||||
|           Seed | ||||
|         </BaseButton> | ||||
|       </template> | ||||
|     </CrudTable> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script lang="ts"> | ||||
| import { computed, defineComponent, onMounted, ref } from "@nuxtjs/composition-api"; | ||||
| import type { LocaleObject } from "@nuxtjs/i18n"; | ||||
| import { validators } from "~/composables/use-validators"; | ||||
| import { useUserApi } from "~/composables/api"; | ||||
| import { IngredientUnit } from "~/types/api-types/recipe"; | ||||
| import { MultiPurposeLabelSummary } from "~/types/api-types/labels"; | ||||
| import { useLocales } from "~/composables/use-locales"; | ||||
|  | ||||
| export default defineComponent({ | ||||
|   setup() { | ||||
| @@ -190,6 +235,31 @@ export default defineComponent({ | ||||
|     } | ||||
|  | ||||
|     refreshLabels(); | ||||
|  | ||||
|     // ============================================================ | ||||
|     // Seed | ||||
|  | ||||
|     const seedDialog = ref(false); | ||||
|     const locale = ref(""); | ||||
|  | ||||
|     const { locales: LOCALES, locale: currentLocale, i18n } = useLocales(); | ||||
|  | ||||
|     onMounted(() => { | ||||
|       locale.value = currentLocale.value; | ||||
|     }); | ||||
|  | ||||
|     const locales = LOCALES.filter((locale) => | ||||
|       (i18n.locales as LocaleObject[]).map((i18nLocale) => i18nLocale.code).includes(locale.value) | ||||
|     ); | ||||
|  | ||||
|     async function seedDatabase() { | ||||
|       const { data } = await userApi.seeders.units({ locale: locale.value }); | ||||
|  | ||||
|       if (data) { | ||||
|         refreshUnits(); | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     return { | ||||
|       tableConfig, | ||||
|       tableHeaders, | ||||
| @@ -211,6 +281,12 @@ export default defineComponent({ | ||||
|       mergeDialog, | ||||
|       fromUnit, | ||||
|       toUnit, | ||||
|  | ||||
|       // Seed | ||||
|       seedDatabase, | ||||
|       locales, | ||||
|       locale, | ||||
|       seedDialog, | ||||
|     }; | ||||
|   }, | ||||
| }); | ||||
|   | ||||
| @@ -14,7 +14,6 @@ from mealie.db.fixes.fix_slug_foods import fix_slug_food_names | ||||
| from mealie.repos.all_repositories import get_repositories | ||||
| from mealie.repos.repository_factory import AllRepositories | ||||
| from mealie.repos.seed.init_users import default_user_init | ||||
| from mealie.repos.seed.seeders import IngredientUnitsSeeder, MultiPurposeLabelSeeder | ||||
| from mealie.schema.user.user import GroupBase | ||||
| from mealie.services.group_services.group_service import GroupService | ||||
|  | ||||
| @@ -24,20 +23,9 @@ logger = root_logger.get_logger("init_db") | ||||
|  | ||||
|  | ||||
| def init_db(db: AllRepositories) -> None: | ||||
|     # TODO: Port other seed data to use abstract seeder class | ||||
|     default_group_init(db) | ||||
|     default_user_init(db) | ||||
|  | ||||
|     group_id = db.groups.get_all()[0].id | ||||
|  | ||||
|     seeders = [ | ||||
|         MultiPurposeLabelSeeder(db, group_id=group_id), | ||||
|         IngredientUnitsSeeder(db, group_id=group_id), | ||||
|     ] | ||||
|  | ||||
|     for seeder in seeders: | ||||
|         seeder.seed() | ||||
|  | ||||
|  | ||||
| def default_group_init(db: AllRepositories): | ||||
|     settings = get_app_settings() | ||||
|   | ||||
		Reference in New Issue
	
	Block a user