| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  | <template> | 
					
						
							|  |  |  |   <div> | 
					
						
							| 
									
										
										
										
											2022-04-09 19:08:48 -08:00
										 |  |  |     <!-- Merge Dialog --> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |     <BaseDialog | 
					
						
							|  |  |  |       v-model="mergeDialog" | 
					
						
							|  |  |  |       :icon="$globals.icons.foods" | 
					
						
							|  |  |  |       :title="$t('data-pages.foods.combine-food')" | 
					
						
							|  |  |  |       can-confirm | 
					
						
							|  |  |  |       @confirm="mergeFoods" | 
					
						
							|  |  |  |     > | 
					
						
							| 
									
										
										
										
											2022-04-09 19:08:48 -08:00
										 |  |  |       <v-card-text> | 
					
						
							| 
									
										
										
										
											2022-05-01 12:45:50 -08:00
										 |  |  |         <div> | 
					
						
							|  |  |  |           {{ $t("data-pages.foods.merge-dialog-text") }} | 
					
						
							|  |  |  |         </div> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |         <v-autocomplete | 
					
						
							|  |  |  |           v-model="fromFood" | 
					
						
							|  |  |  |           return-object | 
					
						
							|  |  |  |           :items="foods" | 
					
						
							|  |  |  |           item-title="name" | 
					
						
							|  |  |  |           :label="$t('data-pages.foods.source-food')" | 
					
						
							|  |  |  |         /> | 
					
						
							|  |  |  |         <v-autocomplete | 
					
						
							|  |  |  |           v-model="toFood" | 
					
						
							|  |  |  |           return-object | 
					
						
							|  |  |  |           :items="foods" | 
					
						
							|  |  |  |           item-title="name" | 
					
						
							|  |  |  |           :label="$t('data-pages.foods.target-food')" | 
					
						
							|  |  |  |         /> | 
					
						
							| 
									
										
										
										
											2022-04-09 19:08:48 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         <template v-if="canMerge && fromFood && toFood"> | 
					
						
							| 
									
										
										
										
											2022-05-01 12:45:50 -08:00
										 |  |  |           <div class="text-center"> | 
					
						
							|  |  |  |             {{ $t("data-pages.foods.merge-food-example", { food1: fromFood.name, food2: toFood.name }) }} | 
					
						
							|  |  |  |           </div> | 
					
						
							| 
									
										
										
										
											2022-04-09 19:08:48 -08:00
										 |  |  |         </template> | 
					
						
							|  |  |  |       </v-card-text> | 
					
						
							|  |  |  |     </BaseDialog> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |     <!-- Seed Dialog --> | 
					
						
							| 
									
										
										
										
											2022-05-01 12:45:50 -08:00
										 |  |  |     <BaseDialog | 
					
						
							|  |  |  |       v-model="seedDialog" | 
					
						
							|  |  |  |       :icon="$globals.icons.foods" | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |       :title="$t('data-pages.seed-data')" | 
					
						
							|  |  |  |       can-confirm | 
					
						
							| 
									
										
										
										
											2022-05-01 12:45:50 -08:00
										 |  |  |       @confirm="seedDatabase" | 
					
						
							|  |  |  |     > | 
					
						
							|  |  |  |       <v-card-text> | 
					
						
							|  |  |  |         <div class="pb-2"> | 
					
						
							|  |  |  |           {{ $t("data-pages.foods.seed-dialog-text") }} | 
					
						
							|  |  |  |         </div> | 
					
						
							|  |  |  |         <v-autocomplete | 
					
						
							|  |  |  |           v-model="locale" | 
					
						
							|  |  |  |           :items="locales" | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |           item-title="name" | 
					
						
							| 
									
										
										
										
											2023-01-29 02:39:51 +01:00
										 |  |  |           :label="$t('data-pages.select-language')" | 
					
						
							| 
									
										
										
										
											2022-05-01 12:45:50 -08:00
										 |  |  |           class="my-3" | 
					
						
							|  |  |  |           hide-details | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |           variant="outlined" | 
					
						
							| 
									
										
										
										
											2022-05-01 12:45:50 -08:00
										 |  |  |           offset | 
					
						
							|  |  |  |         > | 
					
						
							|  |  |  |           <template #item="{ item }"> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |             <v-list-item-title> {{ item.raw.name }} </v-list-item-title> | 
					
						
							|  |  |  |             <v-list-item-subtitle> | 
					
						
							|  |  |  |               {{ item.raw.progress }}% {{ $t("language-dialog.translated") }} | 
					
						
							|  |  |  |             </v-list-item-subtitle> | 
					
						
							| 
									
										
										
										
											2022-05-01 12:45:50 -08:00
										 |  |  |           </template> | 
					
						
							|  |  |  |         </v-autocomplete> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |         <v-alert | 
					
						
							|  |  |  |           v-if="foods && foods.length > 0" | 
					
						
							|  |  |  |           type="error" | 
					
						
							|  |  |  |           class="mb-0 text-body-2" | 
					
						
							|  |  |  |         > | 
					
						
							| 
									
										
										
										
											2022-05-01 12:45:50 -08:00
										 |  |  |           {{ $t("data-pages.foods.seed-dialog-warning") }} | 
					
						
							|  |  |  |         </v-alert> | 
					
						
							|  |  |  |       </v-card-text> | 
					
						
							|  |  |  |     </BaseDialog> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-31 15:31:20 -05:00
										 |  |  |     <!-- Create Dialog --> | 
					
						
							|  |  |  |     <BaseDialog | 
					
						
							|  |  |  |       v-model="createDialog" | 
					
						
							|  |  |  |       :icon="$globals.icons.foods" | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |       :title="$t('data-pages.foods.create-food')" | 
					
						
							| 
									
										
										
										
											2023-11-14 09:39:07 -06:00
										 |  |  |       :submit-icon="$globals.icons.save" | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |       :submit-text="$t('general.save')" | 
					
						
							|  |  |  |       can-submit | 
					
						
							| 
									
										
										
										
											2022-07-31 15:31:20 -05:00
										 |  |  |       @submit="createFood" | 
					
						
							|  |  |  |     > | 
					
						
							|  |  |  |       <v-card-text> | 
					
						
							|  |  |  |         <v-form ref="domNewFoodForm"> | 
					
						
							|  |  |  |           <v-text-field | 
					
						
							|  |  |  |             v-model="createTarget.name" | 
					
						
							|  |  |  |             autofocus | 
					
						
							| 
									
										
										
										
											2023-01-29 02:39:51 +01:00
										 |  |  |             :label="$t('general.name')" | 
					
						
							| 
									
										
										
										
											2023-11-14 09:39:07 -06:00
										 |  |  |             :hint="$t('data-pages.foods.example-food-singular')" | 
					
						
							| 
									
										
										
										
											2022-07-31 15:31:20 -05:00
										 |  |  |             :rules="[validators.required]" | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |           /> | 
					
						
							| 
									
										
										
										
											2023-11-14 09:39:07 -06:00
										 |  |  |           <v-text-field | 
					
						
							|  |  |  |             v-model="createTarget.pluralName" | 
					
						
							|  |  |  |             :label="$t('general.plural-name')" | 
					
						
							|  |  |  |             :hint="$t('data-pages.foods.example-food-plural')" | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |           /> | 
					
						
							|  |  |  |           <v-text-field | 
					
						
							|  |  |  |             v-model="createTarget.description" | 
					
						
							|  |  |  |             :label="$t('recipe.description')" | 
					
						
							|  |  |  |           /> | 
					
						
							| 
									
										
										
										
											2022-07-31 15:31:20 -05:00
										 |  |  |           <v-autocomplete | 
					
						
							|  |  |  |             v-model="createTarget.labelId" | 
					
						
							|  |  |  |             clearable | 
					
						
							|  |  |  |             :items="allLabels" | 
					
						
							|  |  |  |             item-value="id" | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |             item-title="name" | 
					
						
							| 
									
										
										
										
											2023-01-29 02:39:51 +01:00
										 |  |  |             :label="$t('data-pages.foods.food-label')" | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |           /> | 
					
						
							| 
									
										
										
										
											2024-06-29 01:16:04 +10:00
										 |  |  |           <v-checkbox | 
					
						
							|  |  |  |             v-model="createTarget.onHand" | 
					
						
							|  |  |  |             hide-details | 
					
						
							|  |  |  |             :label="$t('tool.on-hand')" | 
					
						
							|  |  |  |           /> | 
					
						
							|  |  |  |           <p class="text-caption mt-1"> | 
					
						
							|  |  |  |             {{ $t("data-pages.foods.on-hand-checkbox-label") }} | 
					
						
							|  |  |  |           </p> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |         </v-form> | 
					
						
							|  |  |  |       </v-card-text> | 
					
						
							|  |  |  |     </BaseDialog> | 
					
						
							| 
									
										
										
										
											2022-07-31 15:31:20 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-14 09:39:07 -06:00
										 |  |  |     <!-- Alias Sub-Dialog --> | 
					
						
							|  |  |  |     <RecipeDataAliasManagerDialog | 
					
						
							|  |  |  |       v-if="editTarget" | 
					
						
							|  |  |  |       :value="aliasManagerDialog" | 
					
						
							|  |  |  |       :data="editTarget" | 
					
						
							|  |  |  |       @submit="updateFoodAlias" | 
					
						
							|  |  |  |       @cancel="aliasManagerDialog = false" | 
					
						
							|  |  |  |     /> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  |     <!-- Edit Dialog --> | 
					
						
							|  |  |  |     <BaseDialog | 
					
						
							|  |  |  |       v-model="editDialog" | 
					
						
							|  |  |  |       :icon="$globals.icons.foods" | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |       :title="$t('data-pages.foods.edit-food')" | 
					
						
							| 
									
										
										
										
											2023-11-14 09:39:07 -06:00
										 |  |  |       :submit-icon="$globals.icons.save" | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |       :submit-text="$t('general.save')" | 
					
						
							|  |  |  |       can-submit | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  |       @submit="editSaveFood" | 
					
						
							|  |  |  |     > | 
					
						
							|  |  |  |       <v-card-text v-if="editTarget"> | 
					
						
							| 
									
										
										
										
											2022-08-14 00:44:11 -05:00
										 |  |  |         <v-form ref="domEditFoodForm"> | 
					
						
							| 
									
										
										
										
											2023-11-14 09:39:07 -06:00
										 |  |  |           <v-text-field | 
					
						
							|  |  |  |             v-model="editTarget.name" | 
					
						
							|  |  |  |             :label="$t('general.name')" | 
					
						
							|  |  |  |             :hint="$t('data-pages.foods.example-food-singular')" | 
					
						
							|  |  |  |             :rules="[validators.required]" | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |           /> | 
					
						
							| 
									
										
										
										
											2023-11-14 09:39:07 -06:00
										 |  |  |           <v-text-field | 
					
						
							|  |  |  |             v-model="editTarget.pluralName" | 
					
						
							|  |  |  |             :label="$t('general.plural-name')" | 
					
						
							|  |  |  |             :hint="$t('data-pages.foods.example-food-plural')" | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |           /> | 
					
						
							| 
									
										
										
										
											2023-11-14 09:39:07 -06:00
										 |  |  |           <v-text-field | 
					
						
							|  |  |  |             v-model="editTarget.description" | 
					
						
							|  |  |  |             :label="$t('recipe.description')" | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |           /> | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  |           <v-autocomplete | 
					
						
							|  |  |  |             v-model="editTarget.labelId" | 
					
						
							|  |  |  |             clearable | 
					
						
							|  |  |  |             :items="allLabels" | 
					
						
							|  |  |  |             item-value="id" | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |             item-title="name" | 
					
						
							| 
									
										
										
										
											2023-01-29 02:39:51 +01:00
										 |  |  |             :label="$t('data-pages.foods.food-label')" | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |           /> | 
					
						
							| 
									
										
										
										
											2024-06-29 01:16:04 +10:00
										 |  |  |           <v-checkbox | 
					
						
							|  |  |  |             v-model="editTarget.onHand" | 
					
						
							|  |  |  |             hide-details | 
					
						
							|  |  |  |             :label="$t('tool.on-hand')" | 
					
						
							|  |  |  |           /> | 
					
						
							|  |  |  |           <p class="text-caption mt-1"> | 
					
						
							|  |  |  |             {{ $t("data-pages.foods.on-hand-checkbox-label") }} | 
					
						
							|  |  |  |           </p> | 
					
						
							| 
									
										
										
										
											2023-11-14 09:39:07 -06:00
										 |  |  |         </v-form> | 
					
						
							|  |  |  |       </v-card-text> | 
					
						
							|  |  |  |       <template #custom-card-action> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |         <BaseButton | 
					
						
							|  |  |  |           edit | 
					
						
							|  |  |  |           @click="aliasManagerEventHandler" | 
					
						
							|  |  |  |         > | 
					
						
							|  |  |  |           {{ $t('data-pages.manage-aliases') }} | 
					
						
							|  |  |  |         </BaseButton> | 
					
						
							| 
									
										
										
										
											2023-11-14 09:39:07 -06:00
										 |  |  |       </template> | 
					
						
							|  |  |  |     </BaseDialog> | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     <!-- Delete Dialog --> | 
					
						
							|  |  |  |     <BaseDialog | 
					
						
							|  |  |  |       v-model="deleteDialog" | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |       :title="$t('general.confirm')" | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  |       :icon="$globals.icons.alertCircle" | 
					
						
							|  |  |  |       color="error" | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |       can-confirm | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  |       @confirm="deleteFood" | 
					
						
							|  |  |  |     > | 
					
						
							|  |  |  |       <v-card-text> | 
					
						
							| 
									
										
										
										
											2023-11-21 15:22:36 +00:00
										 |  |  |         {{ $t("general.confirm-delete-generic") }} | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |         <p | 
					
						
							|  |  |  |           v-if="deleteTarget" | 
					
						
							|  |  |  |           class="mt-4 ml-4" | 
					
						
							|  |  |  |         > | 
					
						
							|  |  |  |           {{ deleteTarget.name }} | 
					
						
							|  |  |  |         </p> | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  |       </v-card-text> | 
					
						
							|  |  |  |     </BaseDialog> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-04 19:55:14 +01:00
										 |  |  |     <!-- Bulk Delete Dialog --> | 
					
						
							|  |  |  |     <BaseDialog | 
					
						
							|  |  |  |       v-model="bulkDeleteDialog" | 
					
						
							|  |  |  |       width="650px" | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |       :title="$t('general.confirm')" | 
					
						
							| 
									
										
										
										
											2024-02-04 19:55:14 +01:00
										 |  |  |       :icon="$globals.icons.alertCircle" | 
					
						
							|  |  |  |       color="error" | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |       can-confirm | 
					
						
							| 
									
										
										
										
											2024-02-04 19:55:14 +01:00
										 |  |  |       @confirm="deleteSelected" | 
					
						
							|  |  |  |     > | 
					
						
							|  |  |  |       <v-card-text> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |         <p class="h4"> | 
					
						
							|  |  |  |           {{ $t('general.confirm-delete-generic-items') }} | 
					
						
							|  |  |  |         </p> | 
					
						
							|  |  |  |         <v-card variant="outlined"> | 
					
						
							|  |  |  |           <v-virtual-scroll | 
					
						
							|  |  |  |             height="400" | 
					
						
							|  |  |  |             item-height="25" | 
					
						
							|  |  |  |             :items="bulkDeleteTarget" | 
					
						
							|  |  |  |           > | 
					
						
							| 
									
										
										
										
											2024-02-04 19:55:14 +01:00
										 |  |  |             <template #default="{ item }"> | 
					
						
							|  |  |  |               <v-list-item class="pb-2"> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |                 <v-list-item-title>{{ item.name }}</v-list-item-title> | 
					
						
							| 
									
										
										
										
											2024-02-04 19:55:14 +01:00
										 |  |  |               </v-list-item> | 
					
						
							|  |  |  |             </template> | 
					
						
							|  |  |  |           </v-virtual-scroll> | 
					
						
							|  |  |  |         </v-card> | 
					
						
							|  |  |  |       </v-card-text> | 
					
						
							|  |  |  |     </BaseDialog> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-13 10:19:49 -06:00
										 |  |  |     <!-- Bulk Assign Labels Dialog --> | 
					
						
							| 
									
										
										
										
											2024-06-21 00:42:42 +02:00
										 |  |  |     <BaseDialog | 
					
						
							|  |  |  |       v-model="bulkAssignLabelDialog" | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |       :title="$t('data-pages.labels.assign-label')" | 
					
						
							| 
									
										
										
										
											2024-06-21 00:42:42 +02:00
										 |  |  |       :icon="$globals.icons.tags" | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |       can-confirm | 
					
						
							| 
									
										
										
										
											2024-06-21 00:42:42 +02:00
										 |  |  |       @confirm="assignSelected" | 
					
						
							|  |  |  |     > | 
					
						
							|  |  |  |       <v-card-text> | 
					
						
							|  |  |  |         <v-card class="mb-4"> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |           <v-card-title>{{ $t("general.caution") }}</v-card-title> | 
					
						
							|  |  |  |           <v-card-text>{{ $t("data-pages.foods.label-overwrite-warning") }}</v-card-text> | 
					
						
							| 
									
										
										
										
											2024-06-21 00:42:42 +02:00
										 |  |  |         </v-card> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         <v-autocomplete | 
					
						
							|  |  |  |           v-model="bulkAssignLabelId" | 
					
						
							|  |  |  |           clearable | 
					
						
							|  |  |  |           :items="allLabels" | 
					
						
							|  |  |  |           item-value="id" | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |           item-title="name" | 
					
						
							|  |  |  |           :label="$t('data-pages.foods.food-label')" | 
					
						
							| 
									
										
										
										
											2024-06-21 00:42:42 +02:00
										 |  |  |         /> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |         <v-card variant="outlined"> | 
					
						
							|  |  |  |           <v-virtual-scroll | 
					
						
							|  |  |  |             height="400" | 
					
						
							|  |  |  |             item-height="25" | 
					
						
							|  |  |  |             :items="bulkAssignTarget" | 
					
						
							|  |  |  |           > | 
					
						
							| 
									
										
										
										
											2024-06-21 00:42:42 +02:00
										 |  |  |             <template #default="{ item }"> | 
					
						
							|  |  |  |               <v-list-item class="pb-2"> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |                 <v-list-item-title>{{ item.name }}</v-list-item-title> | 
					
						
							| 
									
										
										
										
											2024-06-21 00:42:42 +02:00
										 |  |  |               </v-list-item> | 
					
						
							|  |  |  |             </template> | 
					
						
							|  |  |  |           </v-virtual-scroll> | 
					
						
							|  |  |  |         </v-card> | 
					
						
							|  |  |  |       </v-card-text> | 
					
						
							|  |  |  |     </BaseDialog> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-21 14:44:41 +00:00
										 |  |  |     <!-- Data Table --> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |     <BaseCardSectionTitle | 
					
						
							|  |  |  |       :icon="$globals.icons.foods" | 
					
						
							|  |  |  |       section | 
					
						
							|  |  |  |       :title="$t('data-pages.foods.food-data')" | 
					
						
							|  |  |  |     /> | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  |     <CrudTable | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |       v-model:headers="tableHeaders" | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  |       :table-config="tableConfig" | 
					
						
							| 
									
										
										
										
											2022-05-29 17:29:59 -08:00
										 |  |  |       :data="foods || []" | 
					
						
							| 
									
										
										
										
											2024-06-21 00:42:42 +02:00
										 |  |  |       :bulk-actions="[ | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |         { icon: $globals.icons.delete, text: $t('general.delete'), event: 'delete-selected' }, | 
					
						
							|  |  |  |         { icon: $globals.icons.tags, text: $t('data-pages.labels.assign-label'), event: 'assign-selected' }, | 
					
						
							| 
									
										
										
										
											2024-06-21 00:42:42 +02:00
										 |  |  |       ]" | 
					
						
							| 
									
										
										
										
											2024-09-22 09:59:20 -05:00
										 |  |  |       initial-sort="createdAt" | 
					
						
							|  |  |  |       initial-sort-desc | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  |       @delete-one="deleteEventHandler" | 
					
						
							|  |  |  |       @edit-one="editEventHandler" | 
					
						
							| 
									
										
										
										
											2022-07-31 15:31:20 -05:00
										 |  |  |       @create-one="createEventHandler" | 
					
						
							| 
									
										
										
										
											2024-02-04 19:55:14 +01:00
										 |  |  |       @delete-selected="bulkDeleteEventHandler" | 
					
						
							| 
									
										
										
										
											2024-06-21 00:42:42 +02:00
										 |  |  |       @assign-selected="bulkAssignEventHandler" | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  |     > | 
					
						
							|  |  |  |       <template #button-row> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |         <BaseButton | 
					
						
							|  |  |  |           create | 
					
						
							|  |  |  |           @click="createDialog = true" | 
					
						
							|  |  |  |         /> | 
					
						
							| 
									
										
										
										
											2022-04-09 19:08:48 -08:00
										 |  |  |         <BaseButton @click="mergeDialog = true"> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |           <template #icon> | 
					
						
							|  |  |  |             {{ $globals.icons.externalLink }} | 
					
						
							|  |  |  |           </template> | 
					
						
							| 
									
										
										
										
											2023-03-21 20:45:27 +01:00
										 |  |  |           {{ $t('data-pages.combine') }} | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  |         </BaseButton> | 
					
						
							|  |  |  |       </template> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |       <template #[`item.label`]="{ item }"> | 
					
						
							|  |  |  |         <MultiPurposeLabel | 
					
						
							|  |  |  |           v-if="item.label" | 
					
						
							|  |  |  |           :label="item.label" | 
					
						
							|  |  |  |         > | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  |           {{ item.label.name }} | 
					
						
							|  |  |  |         </MultiPurposeLabel> | 
					
						
							|  |  |  |       </template> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |       <template #[`item.onHand`]="{ item }"> | 
					
						
							| 
									
										
										
										
											2024-06-29 01:16:04 +10:00
										 |  |  |         <v-icon :color="item.onHand ? 'success' : undefined"> | 
					
						
							|  |  |  |           {{ item.onHand ? $globals.icons.check : $globals.icons.close }} | 
					
						
							|  |  |  |         </v-icon> | 
					
						
							|  |  |  |       </template> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |       <template #[`item.createdAt`]="{ item }"> | 
					
						
							| 
									
										
										
										
											2024-09-22 09:59:20 -05:00
										 |  |  |         {{ formatDate(item.createdAt) }} | 
					
						
							|  |  |  |       </template> | 
					
						
							| 
									
										
										
										
											2022-05-01 12:45:50 -08:00
										 |  |  |       <template #button-bottom> | 
					
						
							|  |  |  |         <BaseButton @click="seedDialog = true"> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |           <template #icon> | 
					
						
							|  |  |  |             {{ $globals.icons.database }} | 
					
						
							|  |  |  |           </template> | 
					
						
							| 
									
										
										
										
											2023-03-21 20:45:27 +01:00
										 |  |  |           {{ $t('data-pages.seed') }} | 
					
						
							| 
									
										
										
										
											2022-05-01 12:45:50 -08:00
										 |  |  |         </BaseButton> | 
					
						
							|  |  |  |       </template> | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  |     </CrudTable> | 
					
						
							|  |  |  |   </div> | 
					
						
							|  |  |  | </template> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <script lang="ts"> | 
					
						
							| 
									
										
										
										
											2022-05-01 12:45:50 -08:00
										 |  |  | import type { LocaleObject } from "@nuxtjs/i18n"; | 
					
						
							| 
									
										
										
										
											2023-11-14 09:39:07 -06:00
										 |  |  | import RecipeDataAliasManagerDialog from "~/components/Domain/Recipe/RecipeDataAliasManagerDialog.vue"; | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  | import { validators } from "~/composables/use-validators"; | 
					
						
							|  |  |  | import { useUserApi } from "~/composables/api"; | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  | import type { CreateIngredientFood, IngredientFood, IngredientFoodAlias } from "~/lib/api/types/recipe"; | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  | import MultiPurposeLabel from "~/components/Domain/ShoppingList/MultiPurposeLabel.vue"; | 
					
						
							| 
									
										
										
										
											2022-05-01 12:45:50 -08:00
										 |  |  | import { useLocales } from "~/composables/use-locales"; | 
					
						
							| 
									
										
										
										
											2022-05-29 17:29:59 -08:00
										 |  |  | import { useFoodStore, useLabelStore } from "~/composables/store"; | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  | import type { MultiPurposeLabelOut } from "~/lib/api/types/labels"; | 
					
						
							|  |  |  | import type { VForm } from "~/types/auto-forms"; | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-13 10:19:49 -06:00
										 |  |  | interface CreateIngredientFoodWithOnHand extends CreateIngredientFood { | 
					
						
							|  |  |  |   onHand: boolean; | 
					
						
							|  |  |  |   householdsWithIngredientFood: string[]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | interface IngredientFoodWithOnHand extends IngredientFood { | 
					
						
							|  |  |  |   onHand: boolean; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  | export default defineNuxtComponent({ | 
					
						
							| 
									
										
										
										
											2023-11-14 09:39:07 -06:00
										 |  |  |   components: { MultiPurposeLabel, RecipeDataAliasManagerDialog }, | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  |   setup() { | 
					
						
							|  |  |  |     const userApi = useUserApi(); | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |     const i18n = useI18n(); | 
					
						
							|  |  |  |     const $auth = useMealieAuth(); | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  |     const tableConfig = { | 
					
						
							|  |  |  |       hideColumns: true, | 
					
						
							|  |  |  |       canExport: true, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     const tableHeaders = [ | 
					
						
							|  |  |  |       { | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |         text: i18n.t("general.id"), | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  |         value: "id", | 
					
						
							|  |  |  |         show: false, | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       { | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |         text: i18n.t("general.name"), | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  |         value: "name", | 
					
						
							|  |  |  |         show: true, | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |         sortable: true, | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  |       }, | 
					
						
							| 
									
										
										
										
											2023-11-14 09:39:07 -06:00
										 |  |  |       { | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |         text: i18n.t("general.plural-name"), | 
					
						
							| 
									
										
										
										
											2023-11-14 09:39:07 -06:00
										 |  |  |         value: "pluralName", | 
					
						
							|  |  |  |         show: true, | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |         sortable: true, | 
					
						
							| 
									
										
										
										
											2023-11-14 09:39:07 -06:00
										 |  |  |       }, | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  |       { | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |         text: i18n.t("recipe.description"), | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  |         value: "description", | 
					
						
							|  |  |  |         show: true, | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       { | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |         text: i18n.t("shopping-list.label"), | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  |         value: "label", | 
					
						
							|  |  |  |         show: true, | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |         sortable: true, | 
					
						
							| 
									
										
										
										
											2024-12-10 08:10:07 -06:00
										 |  |  |         sort: (label1: MultiPurposeLabelOut | null, label2: MultiPurposeLabelOut | null) => { | 
					
						
							|  |  |  |           const label1Name = label1?.name || ""; | 
					
						
							|  |  |  |           const label2Name = label2?.name || ""; | 
					
						
							|  |  |  |           return label1Name.localeCompare(label2Name); | 
					
						
							|  |  |  |         }, | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  |       }, | 
					
						
							| 
									
										
										
										
											2024-06-29 01:16:04 +10:00
										 |  |  |       { | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |         text: i18n.t("tool.on-hand"), | 
					
						
							| 
									
										
										
										
											2024-06-29 01:16:04 +10:00
										 |  |  |         value: "onHand", | 
					
						
							|  |  |  |         show: true, | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |         sortable: true, | 
					
						
							| 
									
										
										
										
											2024-06-29 01:16:04 +10:00
										 |  |  |       }, | 
					
						
							| 
									
										
										
										
											2024-09-22 09:59:20 -05:00
										 |  |  |       { | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |         text: i18n.t("general.date-added"), | 
					
						
							| 
									
										
										
										
											2024-09-22 09:59:20 -05:00
										 |  |  |         value: "createdAt", | 
					
						
							|  |  |  |         show: false, | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |         sortable: true, | 
					
						
							|  |  |  |       }, | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  |     ]; | 
					
						
							| 
									
										
										
										
											2022-05-29 17:29:59 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-22 09:59:20 -05:00
										 |  |  |     function formatDate(date: string) { | 
					
						
							|  |  |  |       try { | 
					
						
							|  |  |  |         return i18n.d(Date.parse(date), "medium"); | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |       } | 
					
						
							|  |  |  |       catch { | 
					
						
							| 
									
										
										
										
											2024-09-22 09:59:20 -05:00
										 |  |  |         return ""; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |     const userHousehold = computed(() => $auth.user.value?.householdSlug || ""); | 
					
						
							| 
									
										
										
										
											2022-05-29 17:29:59 -08:00
										 |  |  |     const foodStore = useFoodStore(); | 
					
						
							| 
									
										
										
										
											2025-01-13 10:19:49 -06:00
										 |  |  |     const foods = computed(() => foodStore.store.value.map((food) => { | 
					
						
							|  |  |  |       const onHand = food.householdsWithIngredientFood?.includes(userHousehold.value) || false; | 
					
						
							|  |  |  |       return { ...food, onHand } as IngredientFoodWithOnHand; | 
					
						
							|  |  |  |     })); | 
					
						
							| 
									
										
										
										
											2022-05-29 17:29:59 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-31 15:31:20 -05:00
										 |  |  |     // ===============================================================
 | 
					
						
							|  |  |  |     // Food Creator
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const domNewFoodForm = ref<VForm>(); | 
					
						
							|  |  |  |     const createDialog = ref(false); | 
					
						
							| 
									
										
										
										
											2025-01-13 10:19:49 -06:00
										 |  |  |     const createTarget = ref<CreateIngredientFoodWithOnHand>({ | 
					
						
							| 
									
										
										
										
											2022-07-31 15:31:20 -05:00
										 |  |  |       name: "", | 
					
						
							| 
									
										
										
										
											2025-01-13 10:19:49 -06:00
										 |  |  |       onHand: false, | 
					
						
							|  |  |  |       householdsWithIngredientFood: [], | 
					
						
							| 
									
										
										
										
											2022-07-31 15:31:20 -05:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function createEventHandler() { | 
					
						
							|  |  |  |       createDialog.value = true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     async function createFood() { | 
					
						
							|  |  |  |       if (!createTarget.value || !createTarget.value.name) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-13 10:19:49 -06:00
										 |  |  |       if (createTarget.value.onHand) { | 
					
						
							|  |  |  |         createTarget.value.householdsWithIngredientFood = [userHousehold.value]; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-31 15:31:20 -05:00
										 |  |  |       // @ts-expect-error the createOne function erroneously expects an id because it uses the IngredientFood type
 | 
					
						
							|  |  |  |       await foodStore.actions.createOne(createTarget.value); | 
					
						
							|  |  |  |       createDialog.value = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       domNewFoodForm.value?.reset(); | 
					
						
							|  |  |  |       createTarget.value = { | 
					
						
							|  |  |  |         name: "", | 
					
						
							| 
									
										
										
										
											2025-01-13 10:19:49 -06:00
										 |  |  |         onHand: false, | 
					
						
							|  |  |  |         householdsWithIngredientFood: [], | 
					
						
							| 
									
										
										
										
											2022-07-31 15:31:20 -05:00
										 |  |  |       }; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-29 17:29:59 -08:00
										 |  |  |     // ===============================================================
 | 
					
						
							|  |  |  |     // Food Editor
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  |     const editDialog = ref(false); | 
					
						
							| 
									
										
										
										
											2025-01-13 10:19:49 -06:00
										 |  |  |     const editTarget = ref<IngredientFoodWithOnHand | null>(null); | 
					
						
							| 
									
										
										
										
											2022-05-29 17:29:59 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-13 10:19:49 -06:00
										 |  |  |     function editEventHandler(item: IngredientFoodWithOnHand) { | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  |       editTarget.value = item; | 
					
						
							| 
									
										
										
										
											2025-01-13 10:19:49 -06:00
										 |  |  |       editTarget.value.onHand = item.householdsWithIngredientFood?.includes(userHousehold.value) || false; | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  |       editDialog.value = true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-05-29 17:29:59 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  |     async function editSaveFood() { | 
					
						
							|  |  |  |       if (!editTarget.value) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2025-01-13 10:19:49 -06:00
										 |  |  |       if (editTarget.value.onHand && !editTarget.value.householdsWithIngredientFood?.includes(userHousehold.value)) { | 
					
						
							|  |  |  |         if (!editTarget.value.householdsWithIngredientFood) { | 
					
						
							|  |  |  |           editTarget.value.householdsWithIngredientFood = [userHousehold.value]; | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							| 
									
										
										
										
											2025-01-13 10:19:49 -06:00
										 |  |  |           editTarget.value.householdsWithIngredientFood.push(userHousehold.value); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |       } | 
					
						
							|  |  |  |       else if (!editTarget.value.onHand && editTarget.value.householdsWithIngredientFood?.includes(userHousehold.value)) { | 
					
						
							| 
									
										
										
										
											2025-01-13 10:19:49 -06:00
										 |  |  |         editTarget.value.householdsWithIngredientFood = editTarget.value.householdsWithIngredientFood.filter( | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |           household => household !== userHousehold.value, | 
					
						
							| 
									
										
										
										
											2025-01-13 10:19:49 -06:00
										 |  |  |         ); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-29 17:29:59 -08:00
										 |  |  |       await foodStore.actions.updateOne(editTarget.value); | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  |       editDialog.value = false; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-05-29 17:29:59 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // ===============================================================
 | 
					
						
							|  |  |  |     // Food Delete
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  |     const deleteDialog = ref(false); | 
					
						
							| 
									
										
										
										
											2025-01-13 10:19:49 -06:00
										 |  |  |     const deleteTarget = ref<IngredientFoodWithOnHand | null>(null); | 
					
						
							|  |  |  |     function deleteEventHandler(item: IngredientFoodWithOnHand) { | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  |       deleteTarget.value = item; | 
					
						
							|  |  |  |       deleteDialog.value = true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     async function deleteFood() { | 
					
						
							|  |  |  |       if (!deleteTarget.value) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-29 17:29:59 -08:00
										 |  |  |       await foodStore.actions.deleteOne(deleteTarget.value.id); | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  |       deleteDialog.value = false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-04 19:55:14 +01:00
										 |  |  |     const bulkDeleteDialog = ref(false); | 
					
						
							| 
									
										
										
										
											2025-01-13 10:19:49 -06:00
										 |  |  |     const bulkDeleteTarget = ref<IngredientFoodWithOnHand[]>([]); | 
					
						
							| 
									
										
										
										
											2024-02-04 19:55:14 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-13 10:19:49 -06:00
										 |  |  |     function bulkDeleteEventHandler(selection: IngredientFoodWithOnHand[]) { | 
					
						
							| 
									
										
										
										
											2024-02-04 19:55:14 +01:00
										 |  |  |       bulkDeleteTarget.value = selection; | 
					
						
							|  |  |  |       bulkDeleteDialog.value = true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     async function deleteSelected() { | 
					
						
							|  |  |  |       for (const item of bulkDeleteTarget.value) { | 
					
						
							|  |  |  |         await foodStore.actions.deleteOne(item.id); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       bulkDeleteTarget.value = []; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-14 09:39:07 -06:00
										 |  |  |     // ============================================================
 | 
					
						
							|  |  |  |     // Alias Manager
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const aliasManagerDialog = ref(false); | 
					
						
							|  |  |  |     function aliasManagerEventHandler() { | 
					
						
							|  |  |  |       aliasManagerDialog.value = true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function updateFoodAlias(newAliases: IngredientFoodAlias[]) { | 
					
						
							|  |  |  |       if (!editTarget.value) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       editTarget.value.aliases = newAliases; | 
					
						
							|  |  |  |       aliasManagerDialog.value = false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-09 19:08:48 -08:00
										 |  |  |     // ============================================================
 | 
					
						
							|  |  |  |     // Merge Foods
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const mergeDialog = ref(false); | 
					
						
							| 
									
										
										
										
											2025-01-13 10:19:49 -06:00
										 |  |  |     const fromFood = ref<IngredientFoodWithOnHand | null>(null); | 
					
						
							|  |  |  |     const toFood = ref<IngredientFoodWithOnHand | null>(null); | 
					
						
							| 
									
										
										
										
											2022-04-09 19:08:48 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     const canMerge = computed(() => { | 
					
						
							|  |  |  |       return fromFood.value && toFood.value && fromFood.value.id !== toFood.value.id; | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     async function mergeFoods() { | 
					
						
							|  |  |  |       if (!canMerge.value || !fromFood.value || !toFood.value) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const { data } = await userApi.foods.merge(fromFood.value.id, toFood.value.id); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (data) { | 
					
						
							| 
									
										
										
										
											2022-05-29 17:29:59 -08:00
										 |  |  |         foodStore.actions.refresh(); | 
					
						
							| 
									
										
										
										
											2022-04-09 19:08:48 -08:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  |     // ============================================================
 | 
					
						
							|  |  |  |     // Labels
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-22 09:59:20 -05:00
										 |  |  |     const { store: allLabels } = useLabelStore(); | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-01 12:45:50 -08:00
										 |  |  |     // ============================================================
 | 
					
						
							|  |  |  |     // Seed
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const seedDialog = ref(false); | 
					
						
							|  |  |  |     const locale = ref(""); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-29 02:39:51 +01:00
										 |  |  |     const { locales: LOCALES, locale: currentLocale } = useLocales(); | 
					
						
							| 
									
										
										
										
											2022-05-01 12:45:50 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     onMounted(() => { | 
					
						
							|  |  |  |       locale.value = currentLocale.value; | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |     const locales = LOCALES.filter(locale => | 
					
						
							|  |  |  |       (i18n.locales.value as LocaleObject[]).map(i18nLocale => i18nLocale.code).includes(locale.value as any), | 
					
						
							| 
									
										
										
										
											2022-05-01 12:45:50 -08:00
										 |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     async function seedDatabase() { | 
					
						
							|  |  |  |       const { data } = await userApi.seeders.foods({ locale: locale.value }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (data) { | 
					
						
							| 
									
										
										
										
											2022-05-29 17:29:59 -08:00
										 |  |  |         foodStore.actions.refresh(); | 
					
						
							| 
									
										
										
										
											2022-05-01 12:45:50 -08:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-21 00:42:42 +02:00
										 |  |  |     // ============================================================
 | 
					
						
							|  |  |  |     // Bulk Assign Labels
 | 
					
						
							|  |  |  |     const bulkAssignLabelDialog = ref(false); | 
					
						
							| 
									
										
										
										
											2025-01-13 10:19:49 -06:00
										 |  |  |     const bulkAssignTarget = ref<IngredientFoodWithOnHand[]>([]); | 
					
						
							| 
									
										
										
										
											2024-06-21 00:42:42 +02:00
										 |  |  |     const bulkAssignLabelId = ref<string | undefined>(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-13 10:19:49 -06:00
										 |  |  |     function bulkAssignEventHandler(selection: IngredientFoodWithOnHand[]) { | 
					
						
							| 
									
										
										
										
											2024-06-21 00:42:42 +02:00
										 |  |  |       bulkAssignTarget.value = selection; | 
					
						
							|  |  |  |       bulkAssignLabelDialog.value = true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     async function assignSelected() { | 
					
						
							|  |  |  |       if (!bulkAssignLabelId.value) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       for (const item of bulkAssignTarget.value) { | 
					
						
							|  |  |  |         item.labelId = bulkAssignLabelId.value; | 
					
						
							|  |  |  |         await foodStore.actions.updateOne(item); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       bulkAssignTarget.value = []; | 
					
						
							|  |  |  |       bulkAssignLabelId.value = undefined; | 
					
						
							|  |  |  |       foodStore.actions.refresh(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  |     return { | 
					
						
							|  |  |  |       tableConfig, | 
					
						
							|  |  |  |       tableHeaders, | 
					
						
							| 
									
										
										
										
											2025-01-13 10:19:49 -06:00
										 |  |  |       foods, | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  |       allLabels, | 
					
						
							|  |  |  |       validators, | 
					
						
							| 
									
										
										
										
											2024-09-22 09:59:20 -05:00
										 |  |  |       formatDate, | 
					
						
							| 
									
										
										
										
											2022-07-31 15:31:20 -05:00
										 |  |  |       // Create
 | 
					
						
							|  |  |  |       createDialog, | 
					
						
							| 
									
										
										
										
											2022-08-14 00:44:11 -05:00
										 |  |  |       domNewFoodForm, | 
					
						
							| 
									
										
										
										
											2022-07-31 15:31:20 -05:00
										 |  |  |       createEventHandler, | 
					
						
							|  |  |  |       createFood, | 
					
						
							|  |  |  |       createTarget, | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  |       // Edit
 | 
					
						
							|  |  |  |       editDialog, | 
					
						
							|  |  |  |       editEventHandler, | 
					
						
							|  |  |  |       editSaveFood, | 
					
						
							|  |  |  |       editTarget, | 
					
						
							|  |  |  |       // Delete
 | 
					
						
							|  |  |  |       deleteEventHandler, | 
					
						
							|  |  |  |       deleteDialog, | 
					
						
							|  |  |  |       deleteFood, | 
					
						
							| 
									
										
										
										
											2023-11-20 17:09:16 +00:00
										 |  |  |       deleteTarget, | 
					
						
							| 
									
										
										
										
											2024-02-04 19:55:14 +01:00
										 |  |  |       bulkDeleteDialog, | 
					
						
							|  |  |  |       bulkDeleteTarget, | 
					
						
							|  |  |  |       bulkDeleteEventHandler, | 
					
						
							|  |  |  |       deleteSelected, | 
					
						
							| 
									
										
										
										
											2023-11-14 09:39:07 -06:00
										 |  |  |       // Alias Manager
 | 
					
						
							|  |  |  |       aliasManagerDialog, | 
					
						
							|  |  |  |       aliasManagerEventHandler, | 
					
						
							|  |  |  |       updateFoodAlias, | 
					
						
							| 
									
										
										
										
											2022-04-09 19:08:48 -08:00
										 |  |  |       // Merge
 | 
					
						
							|  |  |  |       canMerge, | 
					
						
							|  |  |  |       mergeFoods, | 
					
						
							|  |  |  |       mergeDialog, | 
					
						
							|  |  |  |       fromFood, | 
					
						
							|  |  |  |       toFood, | 
					
						
							| 
									
										
										
										
											2022-05-01 12:45:50 -08:00
										 |  |  |       // Seed Data
 | 
					
						
							|  |  |  |       locale, | 
					
						
							|  |  |  |       locales, | 
					
						
							|  |  |  |       seedDialog, | 
					
						
							|  |  |  |       seedDatabase, | 
					
						
							| 
									
										
										
										
											2024-06-21 00:42:42 +02:00
										 |  |  |       // Bulk Assign Labels
 | 
					
						
							|  |  |  |       bulkAssignLabelDialog, | 
					
						
							|  |  |  |       bulkAssignTarget, | 
					
						
							|  |  |  |       bulkAssignLabelId, | 
					
						
							|  |  |  |       bulkAssignEventHandler, | 
					
						
							|  |  |  |       assignSelected, | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  |     }; | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | </script> |