| 
									
										
										
										
											2021-10-02 11:37:04 -08:00
										 |  |  | <template> | 
					
						
							| 
									
										
										
										
											2021-10-19 18:45:03 -08:00
										 |  |  |   <div> | 
					
						
							|  |  |  |     <v-container class="narrow-container flex-column pa-0"> | 
					
						
							|  |  |  |       <BasePageTitle divider> | 
					
						
							|  |  |  |         <template #header> | 
					
						
							|  |  |  |           <v-img max-height="175" max-width="175" :src="require('~/static/svgs/recipes-create.svg')"></v-img> | 
					
						
							|  |  |  |         </template> | 
					
						
							|  |  |  |         <template #title> Recipe Creation </template> | 
					
						
							|  |  |  |         Select one of the various ways to create a recipe | 
					
						
							|  |  |  |         <template #content> | 
					
						
							|  |  |  |           <div class="ml-auto"> | 
					
						
							| 
									
										
										
										
											2021-11-05 15:48:10 -08:00
										 |  |  |             <BaseOverflowButton v-model="tab" rounded :items="tabs"> </BaseOverflowButton> | 
					
						
							| 
									
										
										
										
											2021-10-19 18:45:03 -08:00
										 |  |  |           </div> | 
					
						
							|  |  |  |         </template> | 
					
						
							|  |  |  |       </BasePageTitle> | 
					
						
							| 
									
										
										
										
											2021-10-02 11:37:04 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-19 18:45:03 -08:00
										 |  |  |       <section> | 
					
						
							|  |  |  |         <v-tabs-items v-model="tab" class="mt-2"> | 
					
						
							|  |  |  |           <!-- Create From URL --> | 
					
						
							|  |  |  |           <v-tab-item value="url" eager> | 
					
						
							|  |  |  |             <v-form ref="domUrlForm" @submit.prevent="createByUrl(recipeUrl)"> | 
					
						
							|  |  |  |               <v-card flat> | 
					
						
							|  |  |  |                 <v-card-title class="headline"> Scrape Recipe </v-card-title> | 
					
						
							|  |  |  |                 <v-card-text> | 
					
						
							|  |  |  |                   Scrape a recipe by url. Provide the url for the site you want to scrape, and Mealie will attempt to | 
					
						
							|  |  |  |                   scrape the recipe from that site and add it to your collection. | 
					
						
							|  |  |  |                   <v-text-field | 
					
						
							|  |  |  |                     v-model="recipeUrl" | 
					
						
							|  |  |  |                     :label="$t('new-recipe.recipe-url')" | 
					
						
							| 
									
										
										
										
											2021-10-30 15:46:44 -08:00
										 |  |  |                     :prepend-inner-icon="$globals.icons.link" | 
					
						
							| 
									
										
										
										
											2021-10-19 18:45:03 -08:00
										 |  |  |                     validate-on-blur | 
					
						
							|  |  |  |                     autofocus | 
					
						
							|  |  |  |                     filled | 
					
						
							|  |  |  |                     clearable | 
					
						
							|  |  |  |                     class="rounded-lg mt-2" | 
					
						
							|  |  |  |                     rounded | 
					
						
							|  |  |  |                     :rules="[validators.url]" | 
					
						
							|  |  |  |                     :hint="$t('new-recipe.url-form-hint')" | 
					
						
							|  |  |  |                     persistent-hint | 
					
						
							|  |  |  |                   ></v-text-field> | 
					
						
							|  |  |  |                 </v-card-text> | 
					
						
							|  |  |  |                 <v-card-actions class="justify-center"> | 
					
						
							|  |  |  |                   <div style="width: 250px"> | 
					
						
							| 
									
										
										
										
											2021-10-30 15:46:44 -08:00
										 |  |  |                     <BaseButton :disabled="recipeUrl === null" rounded block type="submit" :loading="loading" /> | 
					
						
							| 
									
										
										
										
											2021-10-19 18:45:03 -08:00
										 |  |  |                   </div> | 
					
						
							|  |  |  |                 </v-card-actions> | 
					
						
							|  |  |  |               </v-card> | 
					
						
							|  |  |  |             </v-form> | 
					
						
							|  |  |  |             <v-expand-transition> | 
					
						
							|  |  |  |               <v-alert v-show="error" color="error" class="mt-6 white--text"> | 
					
						
							|  |  |  |                 <v-card-title class="ma-0 pa-0"> | 
					
						
							|  |  |  |                   <v-icon left color="white" x-large> {{ $globals.icons.robot }} </v-icon> | 
					
						
							|  |  |  |                   {{ $t("new-recipe.error-title") }} | 
					
						
							|  |  |  |                 </v-card-title> | 
					
						
							|  |  |  |                 <v-divider class="my-3 mx-2"></v-divider> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 <p> | 
					
						
							|  |  |  |                   {{ $t("new-recipe.error-details") }} | 
					
						
							|  |  |  |                 </p> | 
					
						
							|  |  |  |                 <div class="d-flex row justify-space-around my-3 force-white"> | 
					
						
							|  |  |  |                   <a | 
					
						
							|  |  |  |                     class="dark" | 
					
						
							|  |  |  |                     href="https://developers.google.com/search/docs/data-types/recipe" | 
					
						
							|  |  |  |                     target="_blank" | 
					
						
							|  |  |  |                     rel="noreferrer nofollow" | 
					
						
							|  |  |  |                   > | 
					
						
							|  |  |  |                     {{ $t("new-recipe.google-ld-json-info") }} | 
					
						
							|  |  |  |                   </a> | 
					
						
							|  |  |  |                   <a href="https://github.com/hay-kot/mealie/issues" target="_blank" rel="noreferrer nofollow"> | 
					
						
							|  |  |  |                     {{ $t("new-recipe.github-issues") }} | 
					
						
							|  |  |  |                   </a> | 
					
						
							|  |  |  |                   <a href="https://schema.org/Recipe" target="_blank" rel="noreferrer nofollow"> | 
					
						
							|  |  |  |                     {{ $t("new-recipe.recipe-markup-specification") }} | 
					
						
							|  |  |  |                   </a> | 
					
						
							|  |  |  |                 </div> | 
					
						
							|  |  |  |               </v-alert> | 
					
						
							|  |  |  |             </v-expand-transition> | 
					
						
							|  |  |  |           </v-tab-item> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           <!-- Create By Name --> | 
					
						
							|  |  |  |           <v-tab-item value="new" eager> | 
					
						
							|  |  |  |             <v-card flat> | 
					
						
							|  |  |  |               <v-card-title class="headline"> Create Recipe </v-card-title> | 
					
						
							| 
									
										
										
										
											2021-10-02 11:37:04 -08:00
										 |  |  |               <v-card-text> | 
					
						
							| 
									
										
										
										
											2021-10-19 18:45:03 -08:00
										 |  |  |                 Create a recipe by providing the name. All recipes must have unique names. | 
					
						
							|  |  |  |                 <v-form ref="domCreateByName"> | 
					
						
							|  |  |  |                   <v-text-field | 
					
						
							|  |  |  |                     v-model="newRecipeName" | 
					
						
							|  |  |  |                     :label="$t('recipe.recipe-name')" | 
					
						
							| 
									
										
										
										
											2021-10-30 15:46:44 -08:00
										 |  |  |                     :prepend-inner-icon="$globals.icons.primary" | 
					
						
							| 
									
										
										
										
											2021-10-19 18:45:03 -08:00
										 |  |  |                     validate-on-blur | 
					
						
							|  |  |  |                     autofocus | 
					
						
							|  |  |  |                     filled | 
					
						
							|  |  |  |                     clearable | 
					
						
							|  |  |  |                     class="rounded-lg mt-2" | 
					
						
							|  |  |  |                     rounded | 
					
						
							|  |  |  |                     :rules="[validators.required]" | 
					
						
							|  |  |  |                     hint="New recipe names must be unique" | 
					
						
							|  |  |  |                     persistent-hint | 
					
						
							|  |  |  |                   ></v-text-field> | 
					
						
							|  |  |  |                 </v-form> | 
					
						
							| 
									
										
										
										
											2021-10-02 11:37:04 -08:00
										 |  |  |               </v-card-text> | 
					
						
							| 
									
										
										
										
											2021-10-19 18:45:03 -08:00
										 |  |  |               <v-card-actions class="justify-center"> | 
					
						
							|  |  |  |                 <div style="width: 250px"> | 
					
						
							| 
									
										
										
										
											2021-10-30 15:46:44 -08:00
										 |  |  |                   <BaseButton | 
					
						
							|  |  |  |                     :disabled="newRecipeName === ''" | 
					
						
							|  |  |  |                     rounded | 
					
						
							|  |  |  |                     block | 
					
						
							|  |  |  |                     :loading="loading" | 
					
						
							|  |  |  |                     @click="createByName(newRecipeName)" | 
					
						
							|  |  |  |                   /> | 
					
						
							| 
									
										
										
										
											2021-10-19 18:45:03 -08:00
										 |  |  |                 </div> | 
					
						
							| 
									
										
										
										
											2021-10-02 11:37:04 -08:00
										 |  |  |               </v-card-actions> | 
					
						
							|  |  |  |             </v-card> | 
					
						
							| 
									
										
										
										
											2021-10-19 18:45:03 -08:00
										 |  |  |           </v-tab-item> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           <!-- Create By Zip --> | 
					
						
							|  |  |  |           <v-tab-item value="zip" eager> | 
					
						
							|  |  |  |             <v-form> | 
					
						
							|  |  |  |               <v-card> | 
					
						
							|  |  |  |                 <v-card-title class="headline"> Import from Zip </v-card-title> | 
					
						
							|  |  |  |                 <v-card-text> | 
					
						
							|  |  |  |                   Import a single recipe that was exported from another Mealie instance. | 
					
						
							|  |  |  |                   <v-file-input | 
					
						
							|  |  |  |                     v-model="newRecipeZip" | 
					
						
							|  |  |  |                     accept=".zip" | 
					
						
							|  |  |  |                     label=".zip" | 
					
						
							|  |  |  |                     filled | 
					
						
							|  |  |  |                     clearable | 
					
						
							|  |  |  |                     class="rounded-lg mt-2" | 
					
						
							|  |  |  |                     rounded | 
					
						
							|  |  |  |                     truncate-length="100" | 
					
						
							|  |  |  |                     hint=".zip files must have been exported from Mealie" | 
					
						
							|  |  |  |                     persistent-hint | 
					
						
							|  |  |  |                     prepend-icon="" | 
					
						
							|  |  |  |                     :prepend-inner-icon="$globals.icons.zip" | 
					
						
							|  |  |  |                   > | 
					
						
							|  |  |  |                   </v-file-input> | 
					
						
							|  |  |  |                 </v-card-text> | 
					
						
							|  |  |  |                 <v-card-actions class="justify-center"> | 
					
						
							|  |  |  |                   <div style="width: 250px"> | 
					
						
							| 
									
										
										
										
											2021-10-30 15:46:44 -08:00
										 |  |  |                     <BaseButton | 
					
						
							|  |  |  |                       :disabled="newRecipeZip === null" | 
					
						
							|  |  |  |                       large | 
					
						
							|  |  |  |                       rounded | 
					
						
							|  |  |  |                       block | 
					
						
							|  |  |  |                       :loading="loading" | 
					
						
							|  |  |  |                       @click="createByZip" | 
					
						
							|  |  |  |                     /> | 
					
						
							| 
									
										
										
										
											2021-10-19 18:45:03 -08:00
										 |  |  |                   </div> | 
					
						
							|  |  |  |                 </v-card-actions> | 
					
						
							|  |  |  |               </v-card> | 
					
						
							|  |  |  |             </v-form> | 
					
						
							|  |  |  |           </v-tab-item> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           <!-- Create By Zip --> | 
					
						
							|  |  |  |           <v-tab-item value="debug" eager> | 
					
						
							|  |  |  |             <v-form ref="domUrlForm" @submit.prevent="debugUrl(recipeUrl)"> | 
					
						
							|  |  |  |               <v-card flat> | 
					
						
							| 
									
										
										
										
											2021-10-30 15:46:44 -08:00
										 |  |  |                 <v-card-title class="headline"> Recipe Debugger </v-card-title> | 
					
						
							| 
									
										
										
										
											2021-10-19 18:45:03 -08:00
										 |  |  |                 <v-card-text> | 
					
						
							|  |  |  |                   Grab the URL of the recipe you want to debug and paste it here. The URL will be scraped by the recipe | 
					
						
							|  |  |  |                   scraper and the results will be displayed. If you don't see any data returned, the site you are trying | 
					
						
							|  |  |  |                   to scrape is not supported by Mealie or it's scraper library. | 
					
						
							|  |  |  |                   <v-text-field | 
					
						
							|  |  |  |                     v-model="recipeUrl" | 
					
						
							|  |  |  |                     :label="$t('new-recipe.recipe-url')" | 
					
						
							|  |  |  |                     validate-on-blur | 
					
						
							| 
									
										
										
										
											2021-10-30 15:46:44 -08:00
										 |  |  |                     :prepend-inner-icon="$globals.icons.link" | 
					
						
							| 
									
										
										
										
											2021-10-19 18:45:03 -08:00
										 |  |  |                     autofocus | 
					
						
							|  |  |  |                     filled | 
					
						
							|  |  |  |                     clearable | 
					
						
							|  |  |  |                     rounded | 
					
						
							|  |  |  |                     class="rounded-lg mt-2" | 
					
						
							|  |  |  |                     :rules="[validators.url]" | 
					
						
							|  |  |  |                     :hint="$t('new-recipe.url-form-hint')" | 
					
						
							|  |  |  |                     persistent-hint | 
					
						
							|  |  |  |                   ></v-text-field> | 
					
						
							|  |  |  |                 </v-card-text> | 
					
						
							|  |  |  |                 <v-card-actions class="justify-center"> | 
					
						
							|  |  |  |                   <div style="width: 250px"> | 
					
						
							| 
									
										
										
										
											2021-10-30 15:46:44 -08:00
										 |  |  |                     <BaseButton | 
					
						
							|  |  |  |                       :disabled="recipeUrl === null" | 
					
						
							|  |  |  |                       rounded | 
					
						
							|  |  |  |                       block | 
					
						
							|  |  |  |                       type="submit" | 
					
						
							|  |  |  |                       color="info" | 
					
						
							|  |  |  |                       :loading="loading" | 
					
						
							|  |  |  |                     > | 
					
						
							| 
									
										
										
										
											2021-10-19 18:45:03 -08:00
										 |  |  |                       <template #icon> | 
					
						
							|  |  |  |                         {{ $globals.icons.robot }} | 
					
						
							|  |  |  |                       </template> | 
					
						
							|  |  |  |                       Debug | 
					
						
							|  |  |  |                     </BaseButton> | 
					
						
							|  |  |  |                   </div> | 
					
						
							|  |  |  |                 </v-card-actions> | 
					
						
							|  |  |  |               </v-card> | 
					
						
							|  |  |  |             </v-form> | 
					
						
							|  |  |  |           </v-tab-item> | 
					
						
							| 
									
										
										
										
											2021-10-28 19:28:33 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |           <v-tab-item value="bulk" eager> | 
					
						
							|  |  |  |             <v-card flat> | 
					
						
							|  |  |  |               <v-card-title class="headline"> Recipe Bulk Importer </v-card-title> | 
					
						
							|  |  |  |               <v-card-text> | 
					
						
							|  |  |  |                 The Bulk recipe importer allows you to import multiple recipes at once by queing the sites on the | 
					
						
							|  |  |  |                 backend and running the task in the background. This can be useful when initially migrating to Mealie, | 
					
						
							|  |  |  |                 or when you want to import a large number of recipes. | 
					
						
							|  |  |  |               </v-card-text> | 
					
						
							|  |  |  |             </v-card> | 
					
						
							|  |  |  |           </v-tab-item> | 
					
						
							| 
									
										
										
										
											2021-10-19 18:45:03 -08:00
										 |  |  |         </v-tabs-items> | 
					
						
							|  |  |  |       </section> | 
					
						
							|  |  |  |       <v-divider class="mt-5"></v-divider> | 
					
						
							|  |  |  |     </v-container> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     <v-container tag="section"> | 
					
						
							|  |  |  |       <!--  Debug Extras --> | 
					
						
							|  |  |  |       <section v-if="debugData && tab === 'debug'"> | 
					
						
							|  |  |  |         <v-checkbox v-model="debugTreeView" label="Tree View"></v-checkbox> | 
					
						
							|  |  |  |         <VJsoneditor | 
					
						
							|  |  |  |           v-model="debugData" | 
					
						
							|  |  |  |           class="primary" | 
					
						
							|  |  |  |           :options="{ | 
					
						
							|  |  |  |             mode: debugTreeView ? 'tree' : 'code', | 
					
						
							|  |  |  |             search: false, | 
					
						
							|  |  |  |             indentation: 4, | 
					
						
							|  |  |  |             mainMenuBar: false, | 
					
						
							|  |  |  |           }" | 
					
						
							|  |  |  |           height="700px" | 
					
						
							|  |  |  |         /> | 
					
						
							|  |  |  |       </section> | 
					
						
							| 
									
										
										
										
											2021-10-28 19:28:33 -08:00
										 |  |  |       <!--  Debug Extras --> | 
					
						
							|  |  |  |       <section v-else-if="tab === 'bulk'" class="mt-2"> | 
					
						
							|  |  |  |         <v-row v-for="(bulkUrl, idx) in bulkUrls" :key="'bulk-url' + idx" class="my-1" dense> | 
					
						
							|  |  |  |           <v-col cols="12" xs="12" sm="12" md="12"> | 
					
						
							|  |  |  |             <v-text-field | 
					
						
							|  |  |  |               v-model="bulkUrls[idx].url" | 
					
						
							|  |  |  |               :label="$t('new-recipe.recipe-url')" | 
					
						
							|  |  |  |               dense | 
					
						
							|  |  |  |               single-line | 
					
						
							|  |  |  |               validate-on-blur | 
					
						
							|  |  |  |               autofocus | 
					
						
							|  |  |  |               filled | 
					
						
							|  |  |  |               hide-details | 
					
						
							|  |  |  |               clearable | 
					
						
							|  |  |  |               :prepend-inner-icon="$globals.icons.link" | 
					
						
							|  |  |  |               rounded | 
					
						
							|  |  |  |               class="rounded-lg" | 
					
						
							|  |  |  |             > | 
					
						
							|  |  |  |               <template #append> | 
					
						
							|  |  |  |                 <v-btn color="error" icon x-small @click="bulkUrls.splice(idx, 1)"> | 
					
						
							|  |  |  |                   <v-icon> | 
					
						
							|  |  |  |                     {{ $globals.icons.delete }} | 
					
						
							|  |  |  |                   </v-icon> | 
					
						
							|  |  |  |                 </v-btn> | 
					
						
							|  |  |  |               </template> | 
					
						
							|  |  |  |             </v-text-field> | 
					
						
							|  |  |  |           </v-col> | 
					
						
							|  |  |  |           <v-col cols="12" xs="12" sm="6"> | 
					
						
							|  |  |  |             <RecipeCategoryTagSelector | 
					
						
							|  |  |  |               v-model="bulkUrls[idx].categories" | 
					
						
							|  |  |  |               validate-on-blur | 
					
						
							|  |  |  |               autofocus | 
					
						
							|  |  |  |               single-line | 
					
						
							|  |  |  |               filled | 
					
						
							|  |  |  |               hide-details | 
					
						
							|  |  |  |               dense | 
					
						
							|  |  |  |               clearable | 
					
						
							|  |  |  |               rounded | 
					
						
							|  |  |  |               class="rounded-lg" | 
					
						
							|  |  |  |             ></RecipeCategoryTagSelector> | 
					
						
							|  |  |  |           </v-col> | 
					
						
							|  |  |  |           <v-col cols="12" xs="12" sm="6"> | 
					
						
							|  |  |  |             <RecipeCategoryTagSelector | 
					
						
							|  |  |  |               v-model="bulkUrls[idx].tags" | 
					
						
							|  |  |  |               validate-on-blur | 
					
						
							|  |  |  |               autofocus | 
					
						
							|  |  |  |               tag-selector | 
					
						
							|  |  |  |               hide-details | 
					
						
							|  |  |  |               filled | 
					
						
							|  |  |  |               dense | 
					
						
							|  |  |  |               single-line | 
					
						
							|  |  |  |               clearable | 
					
						
							|  |  |  |               rounded | 
					
						
							|  |  |  |               class="rounded-lg" | 
					
						
							|  |  |  |             ></RecipeCategoryTagSelector> | 
					
						
							|  |  |  |           </v-col> | 
					
						
							|  |  |  |         </v-row> | 
					
						
							|  |  |  |         <v-card-actions class="justify-end"> | 
					
						
							| 
									
										
										
										
											2021-11-04 18:15:23 -08:00
										 |  |  |           <BaseButton | 
					
						
							|  |  |  |             delete | 
					
						
							|  |  |  |             @click=" | 
					
						
							|  |  |  |               bulkUrls = []; | 
					
						
							|  |  |  |               lockBulkImport = false; | 
					
						
							|  |  |  |             " | 
					
						
							|  |  |  |           > | 
					
						
							|  |  |  |             Clear | 
					
						
							|  |  |  |           </BaseButton> | 
					
						
							| 
									
										
										
										
											2021-10-28 19:28:33 -08:00
										 |  |  |           <v-spacer></v-spacer> | 
					
						
							|  |  |  |           <BaseButton color="info" @click="bulkUrls.push({ url: '', categories: [], tags: [] })"> | 
					
						
							|  |  |  |             <template #icon> {{ $globals.icons.createAlt }} </template> New | 
					
						
							|  |  |  |           </BaseButton> | 
					
						
							| 
									
										
										
										
											2021-11-04 18:15:23 -08:00
										 |  |  |           <BaseButton :disabled="bulkUrls.length === 0 || lockBulkImport" @click="bulkCreate"> | 
					
						
							| 
									
										
										
										
											2021-10-28 19:28:33 -08:00
										 |  |  |             <template #icon> {{ $globals.icons.check }} </template> Submit | 
					
						
							|  |  |  |           </BaseButton> | 
					
						
							|  |  |  |         </v-card-actions> | 
					
						
							|  |  |  |       </section> | 
					
						
							| 
									
										
										
										
											2021-10-19 18:45:03 -08:00
										 |  |  |     </v-container> | 
					
						
							| 
									
										
										
										
											2021-12-09 19:52:53 -09:00
										 |  |  | 
 | 
					
						
							|  |  |  |     <v-container v-if="$auth.user.advanced" class="narrow-container d-flex justify-end"> | 
					
						
							|  |  |  |       <v-btn outlined rounded to="/user/group/data/migrations"> Looking For Migrations? </v-btn> | 
					
						
							|  |  |  |     </v-container> | 
					
						
							| 
									
										
										
										
											2021-10-19 18:45:03 -08:00
										 |  |  |   </div> | 
					
						
							| 
									
										
										
										
											2021-10-02 11:37:04 -08:00
										 |  |  | </template> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <script lang="ts"> | 
					
						
							| 
									
										
										
										
											2021-10-16 16:06:13 -08:00
										 |  |  | import { defineComponent, reactive, toRefs, ref, useRouter, useContext } from "@nuxtjs/composition-api"; | 
					
						
							| 
									
										
										
										
											2021-10-19 18:45:03 -08:00
										 |  |  | // @ts-ignore No Types for v-jsoneditor
 | 
					
						
							|  |  |  | import VJsoneditor from "v-jsoneditor"; | 
					
						
							| 
									
										
										
										
											2021-11-06 11:28:47 -08:00
										 |  |  | import { useUserApi } from "~/composables/api"; | 
					
						
							| 
									
										
										
										
											2021-10-28 19:28:33 -08:00
										 |  |  | import RecipeCategoryTagSelector from "~/components/Domain/Recipe/RecipeCategoryTagSelector.vue"; | 
					
						
							| 
									
										
										
										
											2021-10-02 11:37:04 -08:00
										 |  |  | import { validators } from "~/composables/use-validators"; | 
					
						
							| 
									
										
										
										
											2021-10-19 18:45:03 -08:00
										 |  |  | import { Recipe } from "~/types/api-types/recipe"; | 
					
						
							| 
									
										
										
										
											2021-10-28 19:28:33 -08:00
										 |  |  | import { alert } from "~/composables/use-toast"; | 
					
						
							| 
									
										
										
										
											2021-10-02 11:37:04 -08:00
										 |  |  | export default defineComponent({ | 
					
						
							| 
									
										
										
										
											2021-10-28 19:28:33 -08:00
										 |  |  |   components: { VJsoneditor, RecipeCategoryTagSelector }, | 
					
						
							| 
									
										
										
										
											2021-10-02 11:37:04 -08:00
										 |  |  |   setup() { | 
					
						
							|  |  |  |     const state = reactive({ | 
					
						
							|  |  |  |       error: false, | 
					
						
							|  |  |  |       loading: false, | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-16 16:06:13 -08:00
										 |  |  |     // @ts-ignore - $globals not found in type definition
 | 
					
						
							|  |  |  |     const { $globals } = useContext(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const tabs = [ | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         icon: $globals.icons.link, | 
					
						
							|  |  |  |         text: "Import with URL", | 
					
						
							|  |  |  |         value: "url", | 
					
						
							|  |  |  |       }, | 
					
						
							| 
									
										
										
										
											2021-10-19 18:45:03 -08:00
										 |  |  |       { | 
					
						
							|  |  |  |         icon: $globals.icons.edit, | 
					
						
							|  |  |  |         text: "Create Recipe", | 
					
						
							|  |  |  |         value: "new", | 
					
						
							|  |  |  |       }, | 
					
						
							| 
									
										
										
										
											2021-10-16 16:06:13 -08:00
										 |  |  |       { | 
					
						
							|  |  |  |         icon: $globals.icons.zip, | 
					
						
							|  |  |  |         text: "Import with .zip", | 
					
						
							|  |  |  |         value: "zip", | 
					
						
							|  |  |  |       }, | 
					
						
							| 
									
										
										
										
											2021-10-28 19:28:33 -08:00
										 |  |  |       { | 
					
						
							|  |  |  |         icon: $globals.icons.link, | 
					
						
							|  |  |  |         text: "Bulk URL Import", | 
					
						
							|  |  |  |         value: "bulk", | 
					
						
							|  |  |  |       }, | 
					
						
							| 
									
										
										
										
											2021-10-19 18:45:03 -08:00
										 |  |  |       { | 
					
						
							|  |  |  |         icon: $globals.icons.robot, | 
					
						
							|  |  |  |         text: "Debug Scraper", | 
					
						
							|  |  |  |         value: "debug", | 
					
						
							|  |  |  |       }, | 
					
						
							| 
									
										
										
										
											2021-10-16 16:06:13 -08:00
										 |  |  |     ]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-06 11:28:47 -08:00
										 |  |  |     const api = useUserApi(); | 
					
						
							| 
									
										
										
										
											2021-10-02 11:37:04 -08:00
										 |  |  |     const router = useRouter(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-04 18:15:23 -08:00
										 |  |  |     function handleResponse(response: any, edit: Boolean = false) { | 
					
						
							| 
									
										
										
										
											2021-10-02 11:37:04 -08:00
										 |  |  |       if (response?.status !== 201) { | 
					
						
							|  |  |  |         state.error = true; | 
					
						
							|  |  |  |         state.loading = false; | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-11-04 18:15:23 -08:00
										 |  |  |       router.push(`/recipe/${response.data}?edit=${edit}`); | 
					
						
							| 
									
										
										
										
											2021-10-02 11:37:04 -08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-19 18:45:03 -08:00
										 |  |  |     // ===================================================
 | 
					
						
							|  |  |  |     // Recipe Debug URL Scraper
 | 
					
						
							|  |  |  |     // @ts-ignore
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const debugTreeView = ref(false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const debugData = ref<Recipe | null>(null); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     async function debugUrl(url: string) { | 
					
						
							|  |  |  |       state.loading = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const { data } = await api.recipes.testCreateOneUrl(url); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       state.loading = false; | 
					
						
							|  |  |  |       debugData.value = data; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-02 11:37:04 -08:00
										 |  |  |     // ===================================================
 | 
					
						
							|  |  |  |     // Recipe URL Import
 | 
					
						
							|  |  |  |     // @ts-ignore
 | 
					
						
							|  |  |  |     const domUrlForm = ref<VForm>(null); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     async function createByUrl(url: string) { | 
					
						
							|  |  |  |       if (!domUrlForm.value.validate() || url === "") { | 
					
						
							| 
									
										
										
										
											2021-11-04 18:15:23 -08:00
										 |  |  |         console.log("Invalid URL", url); | 
					
						
							| 
									
										
										
										
											2021-10-02 11:37:04 -08:00
										 |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       state.loading = true; | 
					
						
							|  |  |  |       const { response } = await api.recipes.createOneByUrl(url); | 
					
						
							|  |  |  |       if (response?.status !== 201) { | 
					
						
							| 
									
										
										
										
											2021-11-04 18:15:23 -08:00
										 |  |  |         // @ts-ignore
 | 
					
						
							|  |  |  |         if (!response?.error?.response?.data?.detail?.message) { | 
					
						
							|  |  |  |           state.error = true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-02 11:37:04 -08:00
										 |  |  |         state.loading = false; | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       handleResponse(response); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // ===================================================
 | 
					
						
							|  |  |  |     // Recipe Create By Name
 | 
					
						
							|  |  |  |     const newRecipeName = ref(""); | 
					
						
							|  |  |  |     // @ts-ignore
 | 
					
						
							|  |  |  |     const domCreateByName = ref<VForm>(null); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     async function createByName(name: string) { | 
					
						
							|  |  |  |       if (!domCreateByName.value.validate() || name === "") { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       const { response } = await api.recipes.createOne({ name }); | 
					
						
							| 
									
										
										
										
											2021-11-04 18:15:23 -08:00
										 |  |  |       handleResponse(response, true); | 
					
						
							| 
									
										
										
										
											2021-10-02 11:37:04 -08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // ===================================================
 | 
					
						
							|  |  |  |     // Recipe Import From Zip File
 | 
					
						
							|  |  |  |     // @ts-ignore
 | 
					
						
							|  |  |  |     const newRecipeZip = ref<File>(null); | 
					
						
							|  |  |  |     const newRecipeZipFileName = "archive"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     async function createByZip() { | 
					
						
							|  |  |  |       if (!newRecipeZip.value) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       const formData = new FormData(); | 
					
						
							|  |  |  |       formData.append(newRecipeZipFileName, newRecipeZip.value); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const { response } = await api.upload.file("/api/recipes/create-from-zip", formData); | 
					
						
							|  |  |  |       handleResponse(response); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-28 19:28:33 -08:00
										 |  |  |     // ===================================================
 | 
					
						
							|  |  |  |     // Bulk Importer
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const bulkUrls = ref([{ url: "", categories: [], tags: [] }]); | 
					
						
							| 
									
										
										
										
											2021-11-04 18:15:23 -08:00
										 |  |  |     const lockBulkImport = ref(false); | 
					
						
							| 
									
										
										
										
											2021-10-28 19:28:33 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     async function bulkCreate() { | 
					
						
							|  |  |  |       if (bulkUrls.value.length === 0) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const { response } = await api.recipes.createManyByUrl({ imports: bulkUrls.value }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (response?.status === 202) { | 
					
						
							|  |  |  |         alert.success("Bulk Import process has started"); | 
					
						
							| 
									
										
										
										
											2021-11-04 18:15:23 -08:00
										 |  |  |         lockBulkImport.value = true; | 
					
						
							| 
									
										
										
										
											2021-10-28 19:28:33 -08:00
										 |  |  |       } else { | 
					
						
							|  |  |  |         alert.error("Bulk import process has failed"); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-02 11:37:04 -08:00
										 |  |  |     return { | 
					
						
							| 
									
										
										
										
											2021-10-28 19:28:33 -08:00
										 |  |  |       bulkCreate, | 
					
						
							|  |  |  |       bulkUrls, | 
					
						
							| 
									
										
										
										
											2021-11-04 18:15:23 -08:00
										 |  |  |       lockBulkImport, | 
					
						
							| 
									
										
										
										
											2021-10-19 18:45:03 -08:00
										 |  |  |       debugTreeView, | 
					
						
							| 
									
										
										
										
											2021-10-16 16:06:13 -08:00
										 |  |  |       tabs, | 
					
						
							| 
									
										
										
										
											2021-10-02 11:37:04 -08:00
										 |  |  |       domCreateByName, | 
					
						
							|  |  |  |       domUrlForm, | 
					
						
							|  |  |  |       newRecipeName, | 
					
						
							|  |  |  |       newRecipeZip, | 
					
						
							| 
									
										
										
										
											2021-10-19 18:45:03 -08:00
										 |  |  |       debugUrl, | 
					
						
							|  |  |  |       debugData, | 
					
						
							| 
									
										
										
										
											2021-10-02 11:37:04 -08:00
										 |  |  |       createByName, | 
					
						
							|  |  |  |       createByUrl, | 
					
						
							|  |  |  |       createByZip, | 
					
						
							|  |  |  |       ...toRefs(state), | 
					
						
							|  |  |  |       validators, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   }, | 
					
						
							| 
									
										
										
										
											2021-10-07 09:39:47 -08:00
										 |  |  |   head() { | 
					
						
							|  |  |  |     return { | 
					
						
							|  |  |  |       title: this.$t("general.create") as string, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   }, | 
					
						
							| 
									
										
										
										
											2021-10-02 11:37:04 -08:00
										 |  |  |   // Computed State is used because of the limitation of vue-composition-api in v2.0
 | 
					
						
							|  |  |  |   computed: { | 
					
						
							|  |  |  |     tab: { | 
					
						
							|  |  |  |       set(tab) { | 
					
						
							| 
									
										
										
										
											2021-10-19 20:55:09 -08:00
										 |  |  |         // @ts-ignore
 | 
					
						
							| 
									
										
										
										
											2021-10-02 11:37:04 -08:00
										 |  |  |         this.$router.replace({ query: { ...this.$route.query, tab } }); | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       get() { | 
					
						
							| 
									
										
										
										
											2021-10-19 20:55:09 -08:00
										 |  |  |         // @ts-ignore
 | 
					
						
							| 
									
										
										
										
											2021-10-02 11:37:04 -08:00
										 |  |  |         return this.$route.query.tab; | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     recipeUrl: { | 
					
						
							|  |  |  |       set(recipe_import_url) { | 
					
						
							| 
									
										
										
										
											2021-10-19 20:55:09 -08:00
										 |  |  |         // @ts-ignore
 | 
					
						
							| 
									
										
										
										
											2021-10-02 11:37:04 -08:00
										 |  |  |         this.$router.replace({ query: { ...this.$route.query, recipe_import_url } }); | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       get() { | 
					
						
							| 
									
										
										
										
											2021-10-19 20:55:09 -08:00
										 |  |  |         // @ts-ignore
 | 
					
						
							| 
									
										
										
										
											2021-10-02 11:37:04 -08:00
										 |  |  |         return this.$route.query.recipe_import_url; | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | </script> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <style> | 
					
						
							|  |  |  | .force-white > a { | 
					
						
							|  |  |  |   color: white !important; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | </style> |