feat(frontend): add debugger to creation page (#750)

* feat(frontend):  add debugger to creation page

* styling

Co-authored-by: Hayden <hay-kot@pm.me>
This commit is contained in:
Hayden 2021-10-19 18:45:03 -08:00 committed by GitHub
parent 89da1a2654
commit 7e3a36f2dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 308 additions and 125 deletions

View File

@ -82,6 +82,10 @@ export class RecipeAPI extends BaseCRUDAPI<Recipe, CreateRecipe> {
return this.requests.post(routes.recipesRecipeSlugImage(slug), { url });
}
async testCreateOneUrl(url: string) {
return await this.requests.post<Recipe | null>(routes.recipesTestScrapeUrl, { url });
}
async createOneByUrl(url: string) {
return await this.requests.post(routes.recipesCreateUrl, { url });
}

View File

@ -8,7 +8,7 @@
}
.narrow-container {
max-width: 700px !important;
max-width: 800px !important;
}
.theme--dark.v-application {

View File

@ -8,6 +8,7 @@
:outlined="btnStyle.outlined"
:text="btnStyle.text"
:to="to"
v-bind="$attrs"
v-on="$listeners"
@click="download ? downloadFile() : undefined"
>

View File

@ -10,6 +10,9 @@
<slot> </slot>
</h3>
</section>
<section class="d-flex">
<slot name="content"></slot>
</section>
<v-divider v-if="divider" class="my-4"></v-divider>
</div>
</template>

View File

@ -27,6 +27,7 @@
"date-fns": "^2.23.0",
"fuse.js": "^6.4.6",
"nuxt": "^2.15.7",
"v-jsoneditor": "^1.4.5",
"vuedraggable": "^2.24.3",
"vuetify": "^2.5.5"
},

View File

@ -1,34 +1,47 @@
<template>
<v-container class="narrow-container flex-column">
<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">
<BaseOverflowButton v-model="tab" rounded outlined :items="tabs"> </BaseOverflowButton>
</div>
</template>
</BasePageTitle>
<BaseOverflowButton v-model="tab" rounded class="mx-2" outlined :items="tabs"> </BaseOverflowButton>
<section>
<v-tabs-items v-model="tab" class="mt-10">
<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 outlined>
<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')"
validate-on-blur
autofocus
class="rounded-lg my-auto"
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>
<v-spacer></v-spacer>
<BaseButton type="submit" :loading="loading" />
<v-card-actions class="justify-center">
<div style="width: 250px">
<BaseButton rounded block type="submit" :loading="loading" />
</div>
</v-card-actions>
</v-card>
</v-form>
@ -59,75 +72,142 @@
{{ $t("new-recipe.recipe-markup-specification") }}
</a>
</div>
<div class="d-flex justify-end">
<v-btn
dark
outlined
:to="{ path: '/recipes/debugger', query: { test_url: recipeUrl } }"
@click="addRecipe = false"
>
<v-icon left> {{ $globals.icons.externalLink }} </v-icon>
{{ $t("new-recipe.view-scraped-data") }}
</v-btn>
</div>
</v-alert>
</v-expand-transition>
</v-tab-item>
<!-- Create By Name -->
<v-tab-item value="new" eager>
<v-card outlined>
<v-card flat>
<v-card-title class="headline"> Create Recipe </v-card-title>
<v-card-text>
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')"
validate-on-blur
autofocus
class="rounded-lg my-auto"
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>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<BaseButton :loading="loading" @click="createByName(newRecipeName)" />
<v-card-actions class="justify-center">
<div style="width: 250px">
<BaseButton rounded block :loading="loading" @click="createByName(newRecipeName)" />
</div>
</v-card-actions>
</v-card>
</v-tab-item>
<!-- Create By Zip -->
<v-tab-item value="zip" eager>
<v-form>
<v-card outlined>
<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"
placeholder="Select your files"
label="File input"
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="$globals.icons.zip"
prepend-icon=""
:prepend-inner-icon="$globals.icons.zip"
>
</v-file-input>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<BaseButton :loading="loading" @click="createByZip" />
<v-card-actions class="justify-center">
<div style="width: 250px">
<BaseButton large rounded block :loading="loading" @click="createByZip" />
</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>
<v-card-title class="headline"> Recipe Debugger</v-card-title>
<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
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">
<BaseButton rounded block type="submit" color="info" :loading="loading">
<template #icon>
{{ $globals.icons.robot }}
</template>
Debug
</BaseButton>
</div>
</v-card-actions>
</v-card>
</v-form>
</v-tab-item>
</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>
</v-container>
</div>
</template>
<script lang="ts">
import { defineComponent, reactive, toRefs, ref, useRouter, useContext } from "@nuxtjs/composition-api";
// @ts-ignore No Types for v-jsoneditor
import VJsoneditor from "v-jsoneditor";
import { useApiSingleton } from "~/composables/use-api";
import { validators } from "~/composables/use-validators";
import { Recipe } from "~/types/api-types/recipe";
export default defineComponent({
components: { VJsoneditor },
setup() {
const state = reactive({
error: false,
@ -138,21 +218,26 @@ export default defineComponent({
const { $globals } = useContext();
const tabs = [
{
icon: $globals.icons.edit,
text: "Create Recipe",
value: "new",
},
{
icon: $globals.icons.link,
text: "Import with URL",
value: "url",
},
{
icon: $globals.icons.edit,
text: "Create Recipe",
value: "new",
},
{
icon: $globals.icons.zip,
text: "Import with .zip",
value: "zip",
},
{
icon: $globals.icons.robot,
text: "Debug Scraper",
value: "debug",
},
];
const api = useApiSingleton();
@ -168,6 +253,23 @@ export default defineComponent({
router.push(`/recipe/${response.data}`);
}
// ===================================================
// 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;
}
// ===================================================
// Recipe URL Import
// @ts-ignore
@ -221,11 +323,14 @@ export default defineComponent({
}
return {
debugTreeView,
tabs,
domCreateByName,
domUrlForm,
newRecipeName,
newRecipeZip,
debugUrl,
debugData,
createByName,
createByUrl,
createByZip,

View File

@ -20,7 +20,7 @@
</v-btn>
</template>
<template #default="{ state }">
<v-slide-x-transition>
<v-slide-x-transition leave-absolute hide-on-leave>
<div v-if="!state" key="personal-info">
<BaseCardSectionTitle class="mt-10" title="Personal Information"> </BaseCardSectionTitle>
<v-card tag="article" outlined>

View File

@ -1563,6 +1563,11 @@
estree-walker "^2.0.1"
picomatch "^2.2.2"
"@sphinxxxx/color-conversion@^2.2.2":
version "2.2.2"
resolved "https://registry.yarnpkg.com/@sphinxxxx/color-conversion/-/color-conversion-2.2.2.tgz#03ecc29279e3c0c832f6185a5bfa3497858ac8ca"
integrity sha512-XExJS3cLqgrmNBIP3bBw6+1oQ1ksGjFh0+oClDKFYpCCqx/hlqwWO5KO/S63fzUo67SxI9dMrF0y5T/Ey7h8Zw==
"@types/anymatch@*":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-3.0.0.tgz#c95ff14401dbb2869913afac3935af4ad0d37f1a"
@ -2332,6 +2337,11 @@ accepts@~1.3.5:
mime-types "~2.1.24"
negotiator "0.6.2"
ace-builds@^1.4.12:
version "1.4.13"
resolved "https://registry.yarnpkg.com/ace-builds/-/ace-builds-1.4.13.tgz#186f42d3849ebcc6a48b93088a058489897514c1"
integrity sha512-SOLzdaQkY6ecPKYRDDg+MY1WoGgXA34cIvYJNNoBMGGUswHmlauU2Hy0UL96vW0Fs/LgFbMUjD+6vqzWTldIYQ==
acorn-jsx@^5.2.0, acorn-jsx@^5.3.1:
version "5.3.2"
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
@ -2375,7 +2385,7 @@ ajv-keywords@^3.1.0, ajv-keywords@^3.4.1, ajv-keywords@^3.5.2:
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d"
integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==
ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.2, ajv@^6.12.4, ajv@^6.12.5:
ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.2, ajv@^6.12.4, ajv@^6.12.5, ajv@^6.12.6:
version "6.12.6"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
@ -6272,6 +6282,11 @@ isobject@^3.0.0, isobject@^3.0.1:
resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8=
javascript-natural-sort@^0.7.1:
version "0.7.1"
resolved "https://registry.yarnpkg.com/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz#f9e2303d4507f6d74355a73664d1440fb5a0ef59"
integrity sha1-+eIwPUUH9tdDVac2ZNFED7Wg71k=
jest-worker@^26.5.0, jest-worker@^26.6.2:
version "26.6.2"
resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed"
@ -6291,6 +6306,11 @@ jiti@^1.9.2:
resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.11.0.tgz#64120a30d97b9bf37b8b032cf4564dfadc28984c"
integrity sha512-/2c7e61hxxTIN34UeHBB0LCJ5Tq64kgJDV7GR+++e8XRxCKRIKmB8tH6ww1W+Z6Kgd6By+C3RSCu1lXjbPT68A==
jmespath@^0.15.0:
version "0.15.0"
resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217"
integrity sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=
js-cookie@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-3.0.1.tgz#9e39b4c6c2f56563708d7d31f6f5f21873a92414"
@ -6344,6 +6364,11 @@ json-schema-traverse@^1.0.0:
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2"
integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==
json-source-map@^0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/json-source-map/-/json-source-map-0.6.1.tgz#e0b1f6f4ce13a9ad57e2ae165a24d06e62c79a0f"
integrity sha512-1QoztHPsMQqhDq0hlXY5ZqcEdUzxQEIxgFkKl4WUp2pgShObl+9ovi4kRh2TfvAfxAoHOJ9vIMEqk3k4iex7tg==
json-stable-stringify-without-jsonify@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
@ -6363,6 +6388,21 @@ json5@^2.1.1, json5@^2.1.2:
dependencies:
minimist "^1.2.5"
jsoneditor@^9.5.3:
version "9.5.6"
resolved "https://registry.yarnpkg.com/jsoneditor/-/jsoneditor-9.5.6.tgz#b2abca2aeb34bb5291025d0eeddcb2845e0d90a9"
integrity sha512-smu4CKCOeJiizGGGYQ7ZAvCclnuJP7gX/wcoHw/DWiJMUZq+3KjJNDhYnVTRgi+Zk0UlPngA4egmuJre/H2mXg==
dependencies:
ace-builds "^1.4.12"
ajv "^6.12.6"
javascript-natural-sort "^0.7.1"
jmespath "^0.15.0"
json-source-map "^0.6.1"
jsonrepair "^2.2.1"
mobius1-selectr "^2.4.13"
picomodal "^3.0.0"
vanilla-picker "^2.11.2"
jsonfile@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
@ -6379,6 +6419,11 @@ jsonfile@^6.0.1:
optionalDependencies:
graceful-fs "^4.1.6"
jsonrepair@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/jsonrepair/-/jsonrepair-2.2.1.tgz#7c6257c36550a310150c41ab7d5d4cab71828456"
integrity sha512-o9Je8TceILo872uQC9fIBJm957j1Io7z8Ca1iWIqY6S5S65HGE9XN7XEEw7+tUviB9Vq4sygV89MVTxl+rhZyg==
jwt-decode@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/jwt-decode/-/jwt-decode-3.1.2.tgz#3fb319f3675a2df0c2895c8f5e9fa4b67b04ed59"
@ -7020,6 +7065,11 @@ mkdirp@^1.0.3, mkdirp@^1.0.4:
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
mobius1-selectr@^2.4.13:
version "2.4.13"
resolved "https://registry.yarnpkg.com/mobius1-selectr/-/mobius1-selectr-2.4.13.tgz#0019dfd9f984840d6e40f70683ab3ec78ce3b5df"
integrity sha512-Mk9qDrvU44UUL0EBhbAA1phfQZ7aMZPjwtL7wkpiBzGh8dETGqfsh50mWoX9EkjDlkONlErWXArHCKfoxVg0Bw==
move-concurrently@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92"
@ -7671,6 +7721,11 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.2.3:
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972"
integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==
picomodal@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/picomodal/-/picomodal-3.0.0.tgz#facd30f4fbf34a809c1e04ea525f004f399c0b82"
integrity sha1-+s0w9PvzSoCcHgTqUl8ATzmcC4I=
pify@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
@ -10261,6 +10316,13 @@ utils-merge@1.0.1:
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=
v-jsoneditor@^1.4.5:
version "1.4.5"
resolved "https://registry.yarnpkg.com/v-jsoneditor/-/v-jsoneditor-1.4.5.tgz#e6164c17a9f7c36fb591d907c0c32f4375409fae"
integrity sha512-xrfCsvu/BC1UV/phzqWOjBqxEOPg8hWg3sntQYihmJUs4fdJjSXI6nGBatvntO9nrqSGLlKsS6RGV+FbhZsERg==
dependencies:
jsoneditor "^9.5.3"
v8-compile-cache@^2.0.3:
version "2.3.0"
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
@ -10274,6 +10336,13 @@ validate-npm-package-license@^3.0.1:
spdx-correct "^3.0.0"
spdx-expression-parse "^3.0.0"
vanilla-picker@^2.11.2:
version "2.11.2"
resolved "https://registry.yarnpkg.com/vanilla-picker/-/vanilla-picker-2.11.2.tgz#eaa24efa68c27e7ee9e0776df55d6913b855f133"
integrity sha512-2cP7LlUnxHxwOf06ReUVtd2RFJMnJGaxN2s0p8wzBH3In5b00Le7fFZ9VrIoBE0svZkSq/BC/Pwq/k/9n+AA2g==
dependencies:
"@sphinxxxx/color-conversion" "^2.2.2"
vary@^1.1.2, vary@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"