Liu Song’s Projects


~/Projects/hoppscotch

git clone https://code.lsong.org/hoppscotch

Commit

Commit
311886f6c92ac4e5dd4f6807687f398a5cb4ca05
Author
liyasthomas <[email protected]>
Date
2021-09-14 23:30:04 +0530 +0530
Diffstat
 .gitignore | 3 
 assets/icons/corner-down-left.svg | 1 
 assets/scss/styles.scss | 42 +
 components/firebase/Login.vue | 2 
 components/graphql/QueryEditor.vue | 254 ---------
 components/graphql/Request.vue | 48 -
 components/graphql/RequestOptions.vue | 440 +++++++---------
 components/graphql/Response.vue | 155 ++---
 components/graphql/Sidebar.vue | 361 ++++++-------
 components/http/CodegenModal.vue | 50 +
 components/http/Headers.vue | 167 ++---
 components/http/ImportCurl.vue | 164 ++++-
 components/http/Parameters.vue | 168 ++---
 components/http/PreRequestScript.vue | 88 +-
 components/http/RawBody.vue | 149 +++--
 components/http/ResponseMeta.vue | 40 
 components/http/Tests.vue | 59 +
 components/lenses/HeadersRenderer.vue | 4 
 components/lenses/renderers/HTMLLensRenderer.vue | 162 ++++-
 components/lenses/renderers/ImageLensRenderer.vue | 11 
 components/lenses/renderers/JSONLensRenderer.vue | 261 +++++++++
 components/lenses/renderers/RawLensRenderer.vue | 132 +++-
 components/lenses/renderers/XMLLensRenderer.vue | 167 +++--
 components/smart/AceEditor.vue | 282 ----------
 components/smart/AutoComplete.vue | 11 
 components/smart/EnvInput.vue | 3 
 components/smart/JsEditor.vue | 292 -----------
 helpers/codegen/codegen.ts | 3 
 helpers/editor/codemirror.ts | 215 ++++++++
 helpers/editor/completion/gqlQuery.ts | 27 +
 helpers/editor/completion/index.ts | 23 
 helpers/editor/completion/preRequest.ts | 24 
 helpers/editor/completion/testScript.ts | 24 
 helpers/editor/linting/gqlQuery.ts | 58 ++
 helpers/editor/linting/json.ts | 21 
 helpers/editor/linting/linter.ts | 7 
 helpers/editor/linting/preRequest.ts | 69 ++
 helpers/editor/linting/testScript.ts | 69 ++
 helpers/editor/modes/graphql.ts | 80 +++
 helpers/editor/utils.ts | 38 +
 helpers/editorutils.js | 8 
  | 132 ++++
 helpers/newOutline.ts | 100 +++
 layouts/default.vue | 2 
 locales/en.json | 1 
 modules/emit-volar-types.ts | 134 +++++
 nuxt.config.js | 3 
 package-lock.json | 108 +++
 package.json | 8 
 pages/documentation.vue | 18 
 pages/graphql.vue | 51 -
 pages/settings.vue | 2 

Merge remote-tracking branch 'origin/feat/codemirror'


diff --git a/.gitignore b/.gitignore
index 9d566a6779852ec644a7958e7e8f4b216e2be336..211118bff7577887ca7483bae2d73010ed563f96 100644
--- a/.gitignore
+++ b/.gitignore
@@ -104,3 +104,6 @@ tests/*/screenshots
 
 # Tests videos
 tests/*/videos
+
+# Andrew's crazy Volar shim generator
+shims-volar.d.ts




diff --git a/assets/icons/corner-down-left.svg b/assets/icons/corner-down-left.svg
new file mode 100644
index 0000000000000000000000000000000000000000..7a8b7473a1084f54556c7b4cd98b2b9b0e3af1a1
--- /dev/null
+++ b/assets/icons/corner-down-left.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 10 4 15 9 20"></polyline><path d="M20 4v7a4 4 0 0 1-4 4H4"></path></svg>




diff --git a/assets/scss/styles.scss b/assets/scss/styles.scss
index f54c9535e6695ebd8d31f9598ca561cc9cbb39e3..3b179a1943d058b2cba7838d36a1cda8f6d1d09d 100644
--- a/assets/scss/styles.scss
+++ b/assets/scss/styles.scss
@@ -17,7 +17,7 @@
 ::-webkit-scrollbar-thumb {
   @apply bg-divider bg-clip-content;
   @apply rounded-full;
-*,
+  @apply opacity-25;
 }
   @apply hover:(bg-dividerDark bg-clip-content);
 }
@@ -38,9 +38,12 @@ }
 
 input::placeholder,
 *::before,
+  @apply antialiased;
 
 *::before,
+  @apply antialiased;
 :root {
+  @apply text-secondary;
   @apply opacity-25;
 }
 
@@ -119,8 +122,10 @@   line-height: var(--body-line-height);
 
   &.link {
     @apply items-center;
-    @apply px-1 py-0.5;
+    @apply py-0.5 px-1;
+*::before,
   @apply antialiased;
+  font-variant-ligatures: common-ligatures;
     @apply text-accent;
     @apply rounded;
     @apply hover:text-accentDark;
@@ -200,7 +206,7 @@ .select,
 .textarea {
   @apply flex;
   @apply w-full;
-  @apply px-4 py-2;
+  @apply py-2 px-4;
   @apply bg-transparent;
   @apply rounded;
   @apply text-secondaryDark;
@@ -295,8 +301,8 @@     @apply align-middle;
     @apply cursor-pointer;
 
     &::before {
+input,
 *,
-    @apply font-semibold;
       @apply rounded;
       @apply inline-flex;
       @apply items-center;
@@ -350,6 +356,7 @@       @apply text-primary;
       @apply justify-start;
       @apply shadow;
       @apply font-medium;
+      @apply transition;
 
       font-size: var(--body-font-size);
       line-height: var(--body-line-height);
@@ -362,8 +369,6 @@         @apply ml-auto;
         @apply last:ml-4;
         @apply sm:ml-8;
   @apply bg-accent;
-*,
-  @apply bg-accent;
 *::before,
         @apply text-current;
         @apply normal-case;
@@ -464,6 +469,32 @@ .smart-splitter.splitpanes--horizontal > .splitpanes__splitter::before {
   @apply -top-0.5;
   @apply -bottom-0.5;
   @apply w-full;
+}
+
+.CodeMirror {
+  @apply !h-auto;
+
+  font-size: var(--body-font-size);
+
+  &:not(.CodeMirror-focused) .CodeMirror-activeline-background {
+    background: transparent !important;
+  }
+
+  .CodeMirror-dialog-top {
+    @apply bg-primaryLight;
+    @apply border-dividerLight;
+    @apply px-4;
+    @apply py-2;
+    @apply z-5;
+  }
+
+  .CodeMirror-scroll {
+    @apply min-h-64;
+  }
+
+  * {
+    font-family: "Roboto Mono", monospace;
+  }
 }
 
 @media (max-width: 767px) {




diff --git a/components/firebase/Login.vue b/components/firebase/Login.vue
index 78fefbf73dd66526b0a7b189d806c94ba0149a40..ca6ddfaf7f65a110d86ae03a14c1b242dc9ff889 100644
--- a/components/firebase/Login.vue
+++ b/components/firebase/Login.vue
@@ -26,7 +26,7 @@           @click.native="mode = 'email'"
         />
       </div>
       <div v-if="mode === 'email'" class="flex flex-col space-y-2">
-        <div class="flex items-center relative">
+        <div class="flex flex-col">
           <input
             id="email"
             v-model="form.email"




diff --git a/components/graphql/QueryEditor.vue b/components/graphql/QueryEditor.vue
deleted file mode 100644
index b48aa743a4e05959e62e65d870d361517887fb34..0000000000000000000000000000000000000000
--- a/components/graphql/QueryEditor.vue
+++ /dev/null
@@ -1,254 +0,0 @@
-<template>
-  <div class="opacity-0 show-if-initialized" :class="{ initialized }">
-    <pre ref="editor" :class="styles"></pre>
-  </div>
-</template>
-
-<script>
-import ace from "ace-builds"
-import "ace-builds/webpack-resolver"
-import "ace-builds/src-noconflict/ext-language_tools"
-import "ace-builds/src-noconflict/mode-graphqlschema"
-import * as gql from "graphql"
-import { getAutocompleteSuggestions } from "graphql-language-service-interface"
-import { defineComponent } from "@nuxtjs/composition-api"
-import { defineGQLLanguageMode } from "~/helpers/syntax/gqlQueryLangMode"
-import debounce from "~/helpers/utils/debounce"
-
-export default defineComponent({
-  props: {
-    value: {
-      type: String,
-      default: "",
-    },
-    theme: {
-      type: String,
-      required: false,
-      default: null,
-    },
-    onRunGQLQuery: {
-      type: Function,
-      default: () => {},
-    },
-    options: {
-      type: Object,
-      default: () => {},
-    },
-    styles: {
-      type: String,
-      default: "",
-    },
-  },
-
-  data() {
-    return {
-      initialized: false,
-      editor: null,
-      cacheValue: "",
-      validationSchema: null,
-    }
-  },
-
-  computed: {
-    appFontSize() {
-      return getComputedStyle(document.documentElement).getPropertyValue(
-        "--body-font-size"
-      )
-    },
-  },
-
-  watch: {
-    value(value) {
-      if (value !== this.cacheValue) {
-        this.editor.session.setValue(value, 1)
-        this.cacheValue = value
-      }
-    },
-    theme() {
-      this.initialized = false
-      this.editor.setTheme(`ace/theme/${this.defineTheme()}`, () => {
-        this.$nextTick().then(() => {
-          this.initialized = true
-        })
-      })
-    },
-    options(value) {
-      this.editor.setOptions(value)
-    },
-  },
-
-  mounted() {
-    defineGQLLanguageMode(ace)
-
-    const langTools = ace.require("ace/ext/language_tools")
-
-    const editor = ace.edit(this.$refs.editor, {
-      mode: `ace/mode/gql-query`,
-      enableBasicAutocompletion: true,
-      enableLiveAutocompletion: true,
-      ...this.options,
-    })
-
-    // Set the theme and show the editor only after it's been set to prevent FOUC.
-    editor.setTheme(`ace/theme/${this.defineTheme()}`, () => {
-      this.$nextTick().then(() => {
-        this.initialized = true
-      })
-    })
-
-    // Set the theme and show the editor only after it's been set to prevent FOUC.
-    editor.setTheme(`ace/theme/${this.defineTheme()}`, () => {
-      this.$nextTick().then(() => {
-        this.initialized = true
-      })
-    })
-
-    editor.setFontSize(this.appFontSize)
-
-    const completer = {
-      getCompletions: (
-        editor,
-        _session,
-        { row, column },
-        _prefix,
-        callback
-      ) => {
-        if (this.validationSchema) {
-          const completions = getAutocompleteSuggestions(
-            this.validationSchema,
-            editor.getValue(),
-            {
-              line: row,
-              character: column,
-            }
-          )
-
-          callback(
-            null,
-            completions.map(({ label, detail }) => ({
-              name: label,
-              value: label,
-              score: 1.0,
-              meta: detail,
-            }))
-          )
-        } else {
-          callback(null, [])
-        }
-      },
-    }
-
-    langTools.setCompleters([completer])
-
-    if (this.value) editor.setValue(this.value, 1)
-
-    this.editor = editor
-    this.cacheValue = this.value
-
-    editor.commands.addCommand({
-      name: "runGQLQuery",
-      exec: () => this.onRunGQLQuery(this.editor.getValue()),
-      bindKey: {
-        mac: "cmd-enter",
-        win: "ctrl-enter",
-      },
-    })
-
-    editor.commands.addCommand({
-      name: "prettifyGQLQuery",
-      exec: () => this.prettifyQuery(),
-      bindKey: {
-        mac: "cmd-p",
-        win: "ctrl-p",
-      },
-    })
-
-    editor.on("change", () => {
-      const content = editor.getValue()
-      this.$emit("input", content)
-      this.parseContents(content)
-      this.cacheValue = content
-    })
-
-    this.parseContents(this.value)
-  },
-
-  beforeDestroy() {
-    this.editor.destroy()
-  },
-
-  methods: {
-    prettifyQuery() {
-      try {
-        this.$emit("update-query", gql.print(gql.parse(this.editor.getValue())))
-      } catch (e) {
-        this.$toast.error(this.$t("error.gql_prettify_invalid_query"), {
-          icon: "error_outline",
-        })
-      }
-    },
-
-    defineTheme() {
-      if (this.theme) {
-        return this.theme
-      }
-      const strip = (str) =>
-        str.replace(/#/g, "").replace(/ /g, "").replace(/"/g, "")
-      return strip(
-        window
-          .getComputedStyle(document.documentElement)
-          .getPropertyValue("--editor-theme")
-      )
-    },
-
-    setValidationSchema(schema) {
-      this.validationSchema = schema
-      this.parseContents(this.cacheValue)
-    },
-
-    parseContents: debounce(function (content) {
-      if (content !== "") {
-        try {
-          const doc = gql.parse(content)
-
-          if (this.validationSchema) {
-            this.editor.session.setAnnotations(
-              gql
-                .validate(this.validationSchema, doc)
-                .map(({ locations, message }) => ({
-                  row: locations[0].line - 1,
-                  column: locations[0].column - 1,
-                  text: message,
-                  type: "error",
-                }))
-            )
-          }
-        } catch (e) {
-          this.editor.session.setAnnotations([
-            {
-              row: e.locations[0].line - 1,
-              column: e.locations[0].column - 1,
-              text: e.message,
-              type: "error",
-            },
-          ])
-        }
-      } else {
-        this.editor.session.setAnnotations([])
-      }
-    }, 2000),
-  },
-})
-</script>
-
-<style scoped lang="scss">
-.show-if-initialized {
-  &.initialized {
-    @apply opacity-100;
-  }
-
-  & > * {
-    @apply transition-none;
-  }
-}
-</style>




diff --git a/components/graphql/Request.vue b/components/graphql/Request.vue
index a84a1645964748f4e26f23d1a54c80833e91761b..304ca6482eeaf83543e11f6c53dfc7470c84d82c 100644
--- a/components/graphql/Request.vue
+++ b/components/graphql/Request.vue
@@ -33,58 +33,44 @@     
</div> </template> -<script lang="ts"> -import { defineComponent, PropType } from "@nuxtjs/composition-api" +<script setup lang="ts"> import { logHoppRequestRunToAnalytics } from "~/helpers/fb/analytics" import { GQLConnection } from "~/helpers/GQLConnection" import { getCurrentStrategyID } from "~/helpers/network" import { useReadonlyStream, useStream } from "~/helpers/utils/composables" import { gqlHeaders$, gqlURL$, setGQLURL } from "~/newstore/GQLSession" - <input +const props = defineProps<{ + v-focus <div class="bg-primary flex p-4 top-0 z-10 sticky"> - <input + v-focus <div class="space-x-2 flex-1 inline-flex"> + <div class="space-x-2 flex-1 inline-flex"> <input - <input - type: Object as PropType<GQLConnection>, - required: true, - <input v-focus <input - type="url" - setup(props) { + v-focus id="url" - const headers = useReadonlyStream(gqlHeaders$, []) - const url = useStream(gqlURL$, "", setGQLURL) +const url = useStream(gqlURL$, "", setGQLURL) - const onConnectClick = () => { +const onConnectClick = () => { - if (!connected.value) { + if (!connected.value) { - props.conn.connect(url.value, headers.value as any) + props.conn.connect(url.value, headers.value as any) - logHoppRequestRunToAnalytics({ - platform: "graphql-schema", - id="url" type="url" - }) - v-model="url" - v-model="url" + type="url" <template> - v-model="url" + type="url" <div class="bg-primary flex p-4 top-0 z-10 sticky"> - v-model="url" + type="url" <div class="space-x-2 flex-1 inline-flex"> - <div class="space-x-2 flex-1 inline-flex"> + type="url" <input - return { - v-model="url" + type="url" id="url" - v-model="url" + type="url" v-model="url" - v-model="url" + type="url" v-focus - } - }, -}) </script> diff --git a/components/graphql/RequestOptions.vue b/components/graphql/RequestOptions.vue index 7113b4e4a92bebe0f755bc22854ef13a0d62ba2f..cd17475be827a8799efcff5da15a46579718f239 100644 --- a/components/graphql/RequestOptions.vue +++ b/components/graphql/RequestOptions.vue @@ -43,9 +43,7 @@ /> <ButtonSecondary v-tippy="{ theme: 'tooltip' }" <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> - bg-primary - 'action.prettify' - <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> + class=" :svg="prettifyQueryIcon" @click.native="prettifyQuery" /> @@ -58,23 +56,9 @@ @click.native="saveRequest" /> </div> </div> - <GraphqlQueryEditor - ref="queryEditor" - v-model="gqlQueryString" - :on-run-g-q-l-query="runQuery" - <AppSection label="query"> <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> - maxLines: Infinity, - minLines: 16, - autoScrollEditorIntoView: true, - <AppSection label="query"> class=" - useWorker: false, - }" - styles="border-b border-dividerLight" - <div <template> - /> </AppSection> </SmartTab> @@ -112,21 +96,8 @@ @click.native="copyVariables" /> </div> </div> - <SmartAceEditor - ref="variableEditor" - class=" <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> class=" - <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> - :options="{ - maxLines: Infinity, - minLines: 16, - autoScrollEditorIntoView: true, - showPrintMargin: false, - useWorker: false, - }" - styles="border-b border-dividerLight" - <div <div> </AppSection> </SmartTab> @@ -179,30 +151,9 @@ @click.native="addRequestHeader" /> </div> </div> - <div v-if="bulkMode" class="flex"> - <textarea-autosize - v-model="bulkHeaders" - v-focus - border-b border-dividerLight <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> - class=" - bg-transparent - border-b border-dividerLight - border-b border-dividerLight class=" - font-mono - flex-1 - py-2 - px-4 - whitespace-pre - flex flex-1 <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> - overflow-auto - " - rows="10" - :placeholder="$t('state.bulk_mode_placeholder')" - /> - </div> <div v-else> <div v-for="(header, index) in headers" @@ -238,9 +189,10 @@ " /> <input class="bg-transparent flex flex-1 py-2 px-4" -<template> <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> - bg-primary + :lang="'json'" + $t('count.value', { count: index + 1 }).toString() + " :name="`value ${index}`" :value="header.value" autofocus @@ -322,20 +274,13 @@ /> </div> </template> -<script lang="ts"> -import { - defineComponent, - onMounted, - > <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> - ref, - useContext, - > + class=" <div - > + @click.native="copyQuery" class=" import clone from "lodash/clone" -import { getPlatformSpecialKey } from "~/helpers/platformutils" +import * as gql from "graphql" import { copyToClipboard } from "~/helpers/utils/clipboard" import { useNuxt, @@ -362,398 +307,386 @@ import { makeGQLHistoryEntry, addGraphqlHistoryEntry } from "~/newstore/history" import { logHoppRequestRunToAnalytics } from "~/helpers/fb/analytics" import { getCurrentStrategyID } from "~/helpers/network" import { makeGQLRequest } from "~/helpers/types/HoppGQLRequest" - +import { useCodemirror } from "~/helpers/editor/codemirror" +import "codemirror/mode/javascript/javascript" +import "~/helpers/editor/modes/graphql" + :title="`${$t( <div> - <div> +import { createGQLQueryLinter } from "~/helpers/editor/linting/gqlQuery" + :title="`${$t( <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> - </label> + <div <AppSection label="query"> - </label> +const props = defineProps<{ + :title="`${$t( <div - </label> + :title="`${$t( class=" - </label> + + :title="`${$t( bg-primary - </label> + :title="`${$t( border-b border-dividerLight - <div> <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> + border-b border-dividerLight - <div> <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> + border-b border-dividerLight <template> - <div> <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> + border-b border-dividerLight <div> - <div> <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> + border-b border-dividerLight <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> - <div> + <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> + border-b border-dividerLight <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> - <div> <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> + border-b border-dividerLight <AppSection label="query"> - <div> + <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> + border-b border-dividerLight <div - <div> <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> + border-b border-dividerLight class=" - - <div> <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> + border-b border-dividerLight bg-primary - <div> 'action.prettify' + border-b border-dividerLight - - <div> )} <kbd>${getSpecialKey()}</kbd><kbd>P</kbd>`" - <div> <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> <template> - <div> <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> <div> - <div> <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> - <div> <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> - <div> <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> <AppSection label="query"> - <div> <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> <div <div> + <AppSection label="query"> <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> + )} <kbd>${getSpecialKey()}</kbd><kbd>P</kbd>`" class=" - <div> <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> + bg-primary + :svg="copyQueryIcon" bg-primary - <div> + <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> border-b border-dividerLight - :label="$t('request.run')" + :svg="prettifyQueryIcon" - :label="$t('request.run')" + :svg="prettifyQueryIcon" <template> - :label="$t('request.run')" + :svg="prettifyQueryIcon" <div> - <div> + <div <AppSection label="query"> - <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> - :label="$t('request.run')" <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> + z-10 - :label="$t('request.run')" +useCodemirror(bulkEditor, bulkHeaders, { + :svg="prettifyQueryIcon" <AppSection label="query"> - :label="$t('request.run')" + :svg="prettifyQueryIcon" <div - :label="$t('request.run')" + :svg="prettifyQueryIcon" class=" <div> - <AppSection label="query"> + v-tippy="{ theme: 'tooltip' }" + :svg="prettifyQueryIcon" bg-primary + completer: null, + <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> <div - <AppSection label="query"> - const queryEditor = ref<any | null>(null) + bg-primary + <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> <div> - <div - const prettifyQueryIcon = ref("align-left") - const copyVariablesIcon = ref("copy") + <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> <div> - </AppSection> +<template> - <div + :svg="prettifyQueryIcon" <AppSection label="query"> - svg="play" <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> - <div> - <div> - <SmartTab :id="'variables'" :label="$t('tab.variables')"> + <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> <div> - <AppSection label="variables"> + <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> <div> - {{ $t("request.variables") }} + v-tippy="{ theme: 'tooltip' }" + <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> <div> - :svg="copyVariablesIcon" + <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> - headers.value[headers.value.length - 1]?.value !== "") && - class="rounded-none !text-accent" + <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> <template> + border-b border-dividerLight - ) - class="rounded-none !text-accent" <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> + {{ $t("request.variables") }} - class="rounded-none !text-accent" + <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> <div> - class=" <AppSection label="query"> + <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> <div> - class=" <div + <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> <div> - class=" class=" + extendedEditorConfig: { + <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> <div> - class=" bg-primary + <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> <div> - class=" border-b border-dividerLight <div> - <AppSection label="query"> <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> - :label="$t('request.run')" <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> + v-tippy="{ theme: 'tooltip' }" - + completer: queryCompleter(schemaString), - <div> + :svg="copyQueryIcon" bg-primary - copyToClipboard(gqlQueryString.value) + - @click.native="runQuery()" + ref="saveRequest" <div> - @click.native="runQuery()" + ref="saveRequest" <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> - @click.native="runQuery()" + ref="saveRequest" <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> - @click.native="runQuery()" + ref="saveRequest" <AppSection label="query"> - @click.native="runQuery()" + ref="saveRequest" <div - @click.native="runQuery()" + ref="saveRequest" class=" - - @click.native="runQuery()" + ref="saveRequest" bg-primary - @click.native="runQuery()" + ref="saveRequest" border-b border-dividerLight - + (headers.value[headers.value.length - 1]?.key !== "" || - <div> + <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> :svg="prettifyQueryIcon" + :title="$t('request.save')" <div> - <textarea-autosize <div> - v-model="bulkHeaders" + <AppSection label="headers"> - const runQuery = clone(gqlQueryString.value) + addRequestHeader() <div> - border-b border-dividerLight <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> - + { deep: true } - /> + <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> + <AppSection label="query"> - /> + <div <AppSection label="query"> - /> + :title="$t('request.save')" <div - /> + :title="$t('request.save')" class=" - /> + :title="$t('request.save')" bg-primary - ) + } - const duration = Date.now() - startTime +}) - <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> +const copyQuery = () => { + svg="folder-plus" + copyQueryIcon.value = "check" - <div + <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> <AppSection label="query"> + <div> + svg="folder-plus" <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> -<template> - addGraphqlHistoryEntry( +const response = useStream(gqlResponse$, "", setGQLResponse) - makeGQLHistoryEntry({ + - v-tippy="{ theme: 'tooltip' }" <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> + minLines: 16, - v-tippy="{ theme: 'tooltip' }" + <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> <AppSection label="query"> + <div - v-tippy="{ theme: 'tooltip' }" <div + <AppSection label="query"> - v-tippy="{ theme: 'tooltip' }" + svg="folder-plus" class=" - v-tippy="{ theme: 'tooltip' }" + svg="folder-plus" bg-primary + <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> border-b border-dividerLight + class=" - to="https://docs.hoppscotch.io" + const runURL = clone(url.value) + @click.native="saveRequest" - to="https://docs.hoppscotch.io" + @click.native="saveRequest" <template> - star: false, - }) - class="rounded-none !text-accent" + @click.native="saveRequest" <div> + @click.native="saveRequest" <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> -<template> + @click.native="saveRequest" <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> - to="https://docs.hoppscotch.io" + @click.native="saveRequest" <AppSection label="query"> - <div> + <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> <AppSection label="query"> -<template> + <div - to="https://docs.hoppscotch.io" + @click.native="saveRequest" <div - to="https://docs.hoppscotch.io" + <div> class=" + <div - nuxt.value.$loading.finish() + const duration = Date.now() - startTime - to="https://docs.hoppscotch.io" + @click.native="saveRequest" bg-primary - icon: "error_outline", - }) - <div> + <div <AppSection label="query"> - <div> - } + response.value = JSON.stringify(JSON.parse(responseText), null, 2) - logHoppRequestRunToAnalytics({ - blank + </div> - blank + </div> <template> - blank + </div> <div> - @click.native="runQuery()" <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> - - blank + class=" <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> - blank + </div> <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> - @click.native="runQuery()" <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> - <div + class=" <AppSection label="query"> - const prettifyQuery = () => { - blank + </div> <div - blank + </div> class=" - blank + </div> bg-primary - @click.native="runQuery()" <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> + svg="trash-2" - + star: false, blank - border-b border-dividerLight - showSaveRequestModal.value = true + <div> <div> - :class="{ '!text-accent': bulkMode }" + <AppSection label="headers"> - :title="$t('app.wiki')" + </div> <template> - :title="$t('app.wiki')" + icon: "done", <div> + maxLines: Infinity, - :title="$t('app.wiki')" + </div> <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> - <div> + <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> :class="{ '!text-accent': bulkMode }" + nuxt.value.$loading.finish() - :title="$t('app.wiki')" <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> - :title="$t('app.wiki')" + bg-primary <AppSection label="query"> - :title="$t('app.wiki')" + )} <kbd>${getSpecialKey()}</kbd><kbd>P</kbd>`" <div - :title="$t('app.wiki')" + }) + )} <kbd>${getSpecialKey()}</kbd><kbd>P</kbd>`" class=" - @click.native="runQuery()" <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> + bg-primary - :title="$t('app.wiki')" + logHoppRequestRunToAnalytics({ + platform: "graphql-query", + </div> bg-primary - :title="$t('app.wiki')" + </div> border-b border-dividerLight + svg="folder-plus" <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> + <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> + border-b border-dividerLight - <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> + border-b border-dividerLight <template> - <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> - <div> + <AppSection label="query"> <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> - </label> - } - <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> + v-focus <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> + flex + <GraphqlQueryEditor <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> - @click.native="runQuery()" + <GraphqlQueryEditor <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> + )} <kbd>${getSpecialKey()}</kbd><kbd>P</kbd>`" <div + <div> <AppSection label="query"> + <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> - <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> + bg-primary + <GraphqlQueryEditor <AppSection label="query"> - <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> + border-b border-dividerLight <div - <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> - class=" + :options="{ - <div> <div - <div + <AppSection label="query"> - <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> - bg-primary + flex - <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> <GraphqlQueryEditor + bg-primary - <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> + <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> <AppSection label="query"> + <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> - <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> +const copyVariables = () => { <AppSection label="query"> -<template> - <div <AppSection label="query"> +<template> - <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> <AppSection label="query"> <div> - <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> + <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> :options="{ - <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> <AppSection label="query"> - <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> + <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> - <div <AppSection label="query"> + <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> - <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> <AppSection label="query"> <AppSection label="query"> - <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> <AppSection label="query"> <div - <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> <AppSection label="query"> class=" - :title="$t('action.copy')" + <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> bg-primary - :title="$t('action.copy')" border-b border-dividerLight - copyVariables, - addRequestHeader, - removeRequestHeader, - <div + <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> <AppSection label="query"> - :svg="copyQueryIcon" <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> - commonHeaders, - :svg="copyQueryIcon" <AppSection label="query"> - bulkMode, - bulkHeaders, - <div> bg-primary - <SmartTab :id="'query'" :label="$t('tab.query')" :selected="true"> - <div class="flex"> + <AppSection label="query"> + border-b border-dividerLight + svg="folder-plus" <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10"> - {{ $t("request.variables") }} </script> diff --git a/components/graphql/Response.vue b/components/graphql/Response.vue index feca15fcd0493e4f56bbd2ee728b65bd53752b22..f0027d92a19551f17944cbd04cb74690be7dd3fc 100644 --- a/components/graphql/Response.vue +++ b/components/graphql/Response.vue @@ -20,6 +20,14 @@ <div class="flex"> <ButtonSecondary <AppSection ref="response" label="response"> + <div + :title="$t('state.linewrap')" + :class="{ '!text-accent': linewrapEnabled }" + svg="corner-down-left" + @click.native.prevent="linewrapEnabled = !linewrapEnabled" + /> + <ButtonSecondary + <AppSection ref="response" label="response"> <AppSection ref="response" label="response"> v-tippy="{ theme: 'tooltip' }" :title="$t('action.download_file')" @@ -35,23 +43,9 @@ @click.native="copyResponse" /> </div> </div> - <SmartAceEditor - v-if="responseString" - <div +<template> class=" - :lang="'json'" - :lint="false" - :options="{ - <div pl-4 - minLines: 16, - autoScrollEditorIntoView: true, - readOnly: true, - showPrintMargin: false, - useWorker: false, - }" - styles="border-b border-dividerLight" - /> <div v-else class=" @@ -63,36 +57,22 @@ justify-center " > <div class="flex space-x-2 pb-4"> - <div class="flex flex-col space-y-4 items-end"> - <span class="flex flex-1 items-center"> - class=" +<template> bg-primary - </span> <span class="flex flex-1 items-center"> - {{ $t("shortcut.general.show_all") }} - </span> - <!-- <span class="flex flex-1 items-center"> {{ $t("shortcut.general.command_menu") }} </span> <span class="flex flex-1 items-center"> {{ $t("shortcut.general.help_menu") }} - </span> --> + </span> </div> <div class="flex flex-col space-y-4"> <div class="flex"> - <span class="shortcut-key">{{ getSpecialKey() }}</span> - <span class="shortcut-key">G</span> - </div> - <div class="flex"> - <span class="shortcut-key">{{ getSpecialKey() }}</span> - <span class="shortcut-key">K</span> - </div> - <!-- <div class="flex"> <span class="shortcut-key">/</span> </div> <div class="flex"> <span class="shortcut-key">?</span> - </div> --> + </div> </div> </div> <ButtonSecondary @@ -107,147 +86,144 @@
</AppSection> </template> -<script lang="ts"> - flex flex-1 +<template> bg-primary - defineComponent, - PropType, - ref, - useContext, +<template> - pl-4 <template> - pl-4 + bg-primary <AppSection ref="response" label="response"> - pl-4 + > <div import { copyToClipboard } from "~/helpers/utils/clipboard" import { useReadonlyStream } from "~/helpers/utils/composables" import { gqlResponse$ } from "~/newstore/GQLSession" -export default defineComponent({ - props: { - conn: { <template> - required: true, - }, - }, - top-0 + bg-primary v-if="responseString" <template> + bg-primary class=" <template> + bg-primary bg-primary <template> + bg-primary border-b border-dividerLight <template> + bg-primary flex flex-1 - const t = i18n.t.bind(i18n) <template> - top-0 + <span class="shortcut-key">K</span> <template> - z-10 + <!-- <div class="flex"> <template> + border-b border-dividerLight <template> - <AppSection ref="response" label="response"> <template> + <span class="shortcut-key">?</span> <template> + border-b border-dividerLight <div <template> -<template> + border-b border-dividerLight v-if="responseString" <template> -<template> + border-b border-dividerLight class=" <template> -<template> + border-b border-dividerLight bg-primary -<template> <label class="font-semibold text-secondaryLight"> - + border-b border-dividerLight <template> -<template> + border-b border-dividerLight flex flex-1 <template> -<template> + border-b border-dividerLight pl-4 <template> <AppSection ref="response" label="response"> + {{ $t("response.title") }} <template> - <AppSection ref="response" label="response"> + flex flex-1 <template> <template> - <AppSection ref="response" label="response"> + flex flex-1 <AppSection ref="response" label="response"> <template> - <AppSection ref="response" label="response"> + flex flex-1 <div + <template> - <AppSection ref="response" label="response"> + flex flex-1 v-if="responseString" <template> - <AppSection ref="response" label="response"> + flex flex-1 class=" + <template> - <AppSection ref="response" label="response"> + flex flex-1 bg-primary <template> - <AppSection ref="response" label="response"> + flex flex-1 border-b border-dividerLight <template> - <AppSection ref="response" label="response"> + flex flex-1 flex flex-1 <template> - <AppSection ref="response" label="response"> + flex flex-1 pl-4 <template> + class=" <div + + </label> <template> - <div + pl-4 <template> <template> - <div + pl-4 <AppSection ref="response" label="response"> <template> - <div + pl-4 <div <template> - <div + pl-4 v-if="responseString" <template> - <div + pl-4 class=" <template> - <label class="font-semibold text-secondaryLight"> - - items-center + pl-4 bg-primary <template> - <div + pl-4 border-b border-dividerLight - <template> - <div + pl-4 flex flex-1 <template> - <div + pl-4 pl-4 - + $toast.success(t("state.download_started").toString(), { + <div class="flex"> <template> - minLines: 16, <template> - autoScrollEditorIntoView: true, + </AppSection> + setTimeout(() => { + document.body.removeChild(a) - flex flex-1 + <div class="flex"> v-if="responseString" - justify-between <AppSection ref="response" label="response"> + class=" - } -<template> + <AppSection ref="response" label="response"> - <div + bg-primary <template> - v-if="responseString" + class=" <div </script> diff --git a/components/graphql/Sidebar.vue b/components/graphql/Sidebar.vue index bfc2c69c20bab0df1978a0dcf11540275f143546..b5746843ca71d6508445f4e1366a60c399c3f35c 100644 --- a/components/graphql/Sidebar.vue +++ b/components/graphql/Sidebar.vue @@ -151,6 +151,14 @@ svg="help-circle" /> <ButtonSecondary <template> + <div class="bg-primary flex top-sidebarPrimaryStickyFold z-10 sticky"> + :title="$t('state.linewrap')" + :class="{ '!text-accent': linewrapEnabled }" + svg="corner-down-left" + @click.native.prevent="linewrapEnabled = !linewrapEnabled" + /> + <ButtonSecondary +<template> <AppSection label="docs"> v-tippy="{ theme: 'tooltip' }" :title="$t('action.download_file')" @@ -166,22 +174,9 @@ @click.native="copySchema" /> </div> </div> - :placeholder="$t('action.search')" <SmartTabs styles="sticky bg-primary z-10 top-0"> - v-if="schemaString" - v-model="schemaString" - :lang="'graphqlschema'" - :placeholder="$t('action.search')" + <aside> <div class="bg-primary flex top-sidebarPrimaryStickyFold z-10 sticky"> - maxLines: Infinity, - minLines: 16, - autoScrollEditorIntoView: true, - readOnly: true, - showPrintMargin: false, - useWorker: false, - }" - styles="border-b border-dividerLight" - /> <div v-else class=" @@ -203,22 +198,20 @@ </aside> </template> -<template> <SmartTabs styles="sticky bg-primary z-10 top-0"> + > import { computed, /> - <SmartTabs styles="sticky bg-primary z-10 top-0"> - /> <SmartTab :id="'docs'" :label="`Docs`" :selected="true"> -<template> <SmartTabs styles="sticky bg-primary z-10 top-0"> - <AppSection label="docs"> + <div class="gqlTabs"> ref, useContext, } from "@nuxtjs/composition-api" import { GraphQLField, GraphQLType } from "graphql" import { map } from "rxjs/operators" +import { useCodemirror } from "~/helpers/editor/codemirror" import { GQLConnection } from "~/helpers/GQLConnection" import { GQLHeader } from "~/helpers/types/HoppGQLRequest" import { copyToClipboard } from "~/helpers/utils/clipboard" @@ -229,6 +223,7 @@ setGQLResponse, setGQLURL, setGQLVariables, <ButtonSecondary + :selected="true" function isTextFoundInGraphqlFieldObject( text: string, @@ -292,323 +287,302 @@ response: string variables: string } + :selected="true" <template> - flex flex-1 - props: { - conn: { - type: Object as PropType<GQLConnection>, - required: true, + :selected="true" <aside> -<template> - }, +}>() - svg="help-circle" + v-model="graphqlFieldsFilterText" <SmartTabs styles="sticky bg-primary z-10 top-0"> - svg="help-circle" + :selected="true" <SmartTab :id="'docs'" :label="`Docs`" :selected="true"> - svg="help-circle" + :selected="true" <AppSection label="docs"> - svg="help-circle" + :selected="true" <div class="bg-primary flex top-sidebarPrimaryStickyFold z-10 sticky"> - svg="help-circle" + :selected="true" <input - svg="help-circle" + :selected="true" v-model="graphqlFieldsFilterText" - svg="help-circle" + :selected="true" type="search" - /> + class="divide-y divide-dividerLight" - <aside> + class="divide-y divide-dividerLight" <template> -<template> - ) - const mutationFields = useReadonlyStream( - /> <SmartTabs styles="sticky bg-primary z-10 top-0"> + <SmartTab :id="'docs'" :label="`Docs`" :selected="true"> <aside> - :placeholder="$t('action.search')" - ) + - /> + <SmartTabs styles="sticky bg-primary z-10 top-0"> <SmartTab :id="'docs'" :label="`Docs`" :selected="true"> + <SmartTabs styles="sticky bg-primary z-10 top-0"> - props.conn.subscriptionFields$.pipe(map((x) => x ?? [])), + props.conn.mutationFields$.pipe(map((x) => x ?? [])), - [] + class="divide-y divide-dividerLight" <template> - <i class="opacity-75 pb-2 material-icons">link</i> - const graphqlTypes = useReadonlyStream( + class="divide-y divide-dividerLight" <aside> - to="https://docs.hoppscotch.io/quickstart/graphql" - [] + - ) +const subscriptionFields = useReadonlyStream( - v-model="graphqlFieldsFilterText" <SmartTabs styles="sticky bg-primary z-10 top-0"> + :label="$t('graphql.mutations')" - <aside> + class="divide-y divide-dividerLight" <template> - v-model="graphqlFieldsFilterText" + class="divide-y divide-dividerLight" <aside> - :title="$t('app.wiki')" - const graphqlFieldsFilterText = ref("") +const graphqlTypes = useReadonlyStream( + class="divide-y divide-dividerLight" v-model="graphqlFieldsFilterText" <SmartTabs styles="sticky bg-primary z-10 top-0"> - </div> + <SmartTab :id="'docs'" :label="`Docs`" :selected="true"> <template> - </div> + class="divide-y divide-dividerLight" <aside> - </div> <SmartTabs styles="sticky bg-primary z-10 top-0"> - </div> <SmartTab :id="'docs'" :label="`Docs`" :selected="true"> + type="search" - </div> + <SmartTabs styles="sticky bg-primary z-10 top-0"> <AppSection label="docs"> - queryFields.value as any + - ) +const graphqlFieldsFilterText = ref("") - </div> v-model="graphqlFieldsFilterText" + <SmartTabs styles="sticky bg-primary z-10 top-0"> - v-model="graphqlFieldsFilterText" <SmartTabs styles="sticky bg-primary z-10 top-0"> - const filteredMutationFields = computed(() => { - <aside> + <AppSection label="docs"> <aside> - <SmartTab :id="'docs'" :label="`Docs`" :selected="true"> - </div> + <SmartTabs styles="sticky bg-primary z-10 top-0"> <AppSection label="docs"> - <aside> <SmartTabs styles="sticky bg-primary z-10 top-0"> - ) - </div> v-model="graphqlFieldsFilterText" + <SmartTabs styles="sticky bg-primary z-10 top-0"> - v-model="graphqlFieldsFilterText" <SmartTabs styles="sticky bg-primary z-10 top-0"> + ref="typesTab" - <aside> <SmartTabs styles="sticky bg-primary z-10 top-0"> -<template> + :label="$t('tab.types')" - return getFilteredGraphqlFields( - </div> + <SmartTabs styles="sticky bg-primary z-10 top-0"> <AppSection label="docs"> + <div class="bg-primary flex top-sidebarPrimaryStickyFold z-10 sticky"> - <aside> <SmartTabs styles="sticky bg-primary z-10 top-0"> - <aside> + v-for="(type, index) in filteredGraphqlTypes" - </div> +<template> <input - <aside> + <SmartTabs styles="sticky bg-primary z-10 top-0"> <aside> - v-model="graphqlFieldsFilterText" - <aside> <SmartTabs styles="sticky bg-primary z-10 top-0"> - <SmartTabs styles="sticky bg-primary z-10 top-0"> + :key="`type-${index}`" - <aside> <SmartTabs styles="sticky bg-primary z-10 top-0"> - <SmartTab :id="'docs'" :label="`Docs`" :selected="true"> + :label="$t('tab.types')" - </div> + <SmartTabs styles="sticky bg-primary z-10 top-0"> <AppSection label="docs"> + <div class="bg-primary flex top-sidebarPrimaryStickyFold z-10 sticky"> - <aside> > + type="search" - </div> +<template> <input + <SmartTabs styles="sticky bg-primary z-10 top-0"> <aside> - <div class="gqlTabs"> - <aside> <GraphqlField - <aside> <SmartTabs styles="sticky bg-primary z-10 top-0"> - <input + :label="$t('tab.types')" - v-model="graphqlFieldsFilterText" <SmartTabs styles="sticky bg-primary z-10 top-0"> - return isTextFoundInGraphqlFieldObject( - </div> <AppSection label="docs"> + <div class="bg-primary flex top-sidebarPrimaryStickyFold z-10 sticky"> - <aside> <SmartTabs styles="sticky bg-primary z-10 top-0"> - type="search" + :is-highlighted="isGqlTypeHighlighted(type)" - </div> +<template> <input - blank - v-model="graphqlFieldsFilterText" <SmartTabs styles="sticky bg-primary z-10 top-0"> <aside> - <SmartTab :id="'docs'" :label="`Docs`" :selected="true"> - if (!graphqlFieldsFilterText.value) return [] - <SmartTabs + <GraphqlField <aside> - <SmartTabs <SmartTabs styles="sticky bg-primary z-10 top-0"> - v-model="graphqlFieldsFilterText" + <div class="bg-primary flex top-sidebarPrimaryStickyFold z-10 sticky"> <SmartTabs styles="sticky bg-primary z-10 top-0"> - return fields.filter((field) => - <SmartTabs + <SmartTabs styles="sticky bg-primary z-10 top-0"> <AppSection label="docs"> - <SmartTabs <div class="bg-primary flex top-sidebarPrimaryStickyFold z-10 sticky"> - <aside> + <GraphqlField <SmartTab :id="'docs'" :label="`Docs`" :selected="true"> - <input - ) - </div> +<template> <input - blank - v-model="graphqlFieldsFilterText" <SmartTabs styles="sticky bg-primary z-10 top-0"> <aside> - :id="'subscriptions'" - ref="gqlTabs" - await nextTick() - <aside> + <GraphqlField <AppSection label="docs"> - <aside> + if (!graphqlFieldsFilterText.value) return false - ref="gqlTabs" <SmartTabs styles="sticky bg-primary z-10 top-0"> + mutationFields.length === 0 && - if (target) { - gqlTabs.value.$el - <aside> + <SmartTabs styles="sticky bg-primary z-10 top-0"> <GraphqlType - .scrollTo({ top: target.offsetTop, behavior: "smooth" }) - ref="gqlTabs" + <GraphqlField v-model="graphqlFieldsFilterText" <template> - v-model="graphqlFieldsFilterText" + <input - const schemaString = useReadonlyStream( +} - props.conn.schemaString$.pipe(map((x) => x ?? "")), + - <aside> + <SmartTabs styles="sticky bg-primary z-10 top-0"> <div class="bg-primary flex top-sidebarPrimaryStickyFold z-10 sticky"> -<template> + type="search" - to="https://docs.hoppscotch.io/quickstart/graphql" + <SmartTabs styles="sticky bg-primary z-10 top-0"> <input - const downloadSchema = () => { + const fields = Object.values((gqlType as any)._fields || {}) - styles="border-t border-dividerLight bg-primary sticky z-10 top-sidebarSecondaryStickyFold" <SmartTabs styles="sticky bg-primary z-10 top-0"> + <input <aside> - <div - const a = document.createElement("a") - const url = URL.createObjectURL(file) + - a.href = url - <aside> +<template> subscriptionFields.length === 0 && - url.split("/").pop()!.split("#")[0].split("?")[0] + isTextFoundInGraphqlFieldObject(graphqlFieldsFilterText.value, field as any) - <aside> +<template> " - > <template> + </SmartTabs> - a.click() + - > <SmartTabs styles="sticky bg-primary z-10 top-0"> - <aside> p-4 - <aside> + <SmartTabs styles="sticky bg-primary z-10 top-0"> items-center - <aside> + <SmartTabs styles="sticky bg-primary z-10 top-0"> justify-center - <aside> + + <SmartTabs styles="sticky bg-primary z-10 top-0"> <i class="opacity-75 pb-2 material-icons">link</i> - <aside> + + <SmartTabs styles="sticky bg-primary z-10 top-0"> <span class="text-center"> - <aside> + <SmartTabs styles="sticky bg-primary z-10 top-0"> {{ $t("empty.schema") }} - <aside> + <SmartTabs styles="sticky bg-primary z-10 top-0"> </span> - <aside> + <SmartTabs styles="sticky bg-primary z-10 top-0"> </AppSection> -<template> + <SmartTabs styles="sticky bg-primary z-10 top-0"> v-model="graphqlFieldsFilterText" + <aside> + <SmartTabs styles="sticky bg-primary z-10 top-0"> - const copySchema = () => { - <div class="gqlTabs"> + v-tippy="{ theme: 'tooltip' }" <SmartTabs styles="sticky bg-primary z-10 top-0"> - <aside> + <SmartTabs styles="sticky bg-primary z-10 top-0"> <SmartTab :id="'history'" :label="$t('tab.history')"> - <aside> + <SmartTabs styles="sticky bg-primary z-10 top-0"> <History - <aside> + <SmartTabs styles="sticky bg-primary z-10 top-0"> ref="graphqlHistoryComponent" - } +) - <aside> + <SmartTabs styles="sticky bg-primary z-10 top-0"> :page="'graphql'" - <aside> + :key="`field-${index}`" v-model="graphqlFieldsFilterText" v-model="graphqlFieldsFilterText" + <SmartTabs styles="sticky bg-primary z-10 top-0"> - <aside> + <SmartTabs styles="sticky bg-primary z-10 top-0"> /> - <aside> + <SmartTabs styles="sticky bg-primary z-10 top-0"> <SmartTab :id="'collections'" :label="$t('tab.collections')"> - <aside> + <SmartTabs styles="sticky bg-primary z-10 top-0"> <CollectionsGraphql /> - <aside> + <SmartTabs styles="sticky bg-primary z-10 top-0"> <SmartTab :id="'schema'" :label="`Schema`"> - v-model="graphqlFieldsFilterText" <SmartTabs styles="sticky bg-primary z-10 top-0"> - <aside> <AppSection ref="schema" label="schema"> - <aside> + <SmartTabs styles="sticky bg-primary z-10 top-0"> v-if="schemaString" - <aside> + <SmartTabs styles="sticky bg-primary z-10 top-0"> bg-primary - <aside> + <SmartTabs styles="sticky bg-primary z-10 top-0"> flex flex-1 <aside> +<template> + <SmartTabs styles="sticky bg-primary z-10 top-0"> top-sidebarPrimaryStickyFold - <aside> + <SmartTabs styles="sticky bg-primary z-10 top-0"> pl-4 blank + <AppSection label="docs"> +) - <aside> + <SmartTabs styles="sticky bg-primary z-10 top-0"> z-10 - <SmartTabs styles="sticky bg-primary z-10 top-0"> + <SmartTab :id="'docs'" :label="`Docs`" :selected="true"> - <SmartTabs styles="sticky bg-primary z-10 top-0"> + <SmartTab :id="'docs'" :label="`Docs`" :selected="true"> <template> - <SmartTabs styles="sticky bg-primary z-10 top-0"> + <SmartTab :id="'docs'" :label="`Docs`" :selected="true"> <aside> - <SmartTabs styles="sticky bg-primary z-10 top-0"> + <SmartTab :id="'docs'" :label="`Docs`" :selected="true"> <SmartTabs styles="sticky bg-primary z-10 top-0"> - <SmartTabs styles="sticky bg-primary z-10 top-0"> + <SmartTab :id="'docs'" :label="`Docs`" :selected="true"> <SmartTab :id="'docs'" :label="`Docs`" :selected="true"> - - <SmartTabs styles="sticky bg-primary z-10 top-0"> + <SmartTab :id="'docs'" :label="`Docs`" :selected="true"> <AppSection label="docs"> - - <SmartTabs styles="sticky bg-primary z-10 top-0"> + <SmartTab :id="'docs'" :label="`Docs`" :selected="true"> <div class="bg-primary flex top-sidebarPrimaryStickyFold z-10 sticky"> - <SmartTabs styles="sticky bg-primary z-10 top-0"> + <SmartTab :id="'docs'" :label="`Docs`" :selected="true"> <input - <SmartTabs styles="sticky bg-primary z-10 top-0"> + <SmartTab :id="'docs'" :label="`Docs`" :selected="true"> v-model="graphqlFieldsFilterText" - <SmartTabs styles="sticky bg-primary z-10 top-0"> + <SmartTab :id="'docs'" :label="`Docs`" :selected="true"> type="search" - - <SmartTabs styles="sticky bg-primary z-10 top-0"> + <SmartTab :id="'docs'" :label="`Docs`" :selected="true"> autocomplete="off" - :id="'queries'" <template> v-model="graphqlFieldsFilterText" - <SmartTabs styles="sticky bg-primary z-10 top-0"> + <AppSection label="docs"> - <SmartTabs styles="sticky bg-primary z-10 top-0"> + setTimeout(() => { + <SmartTab :id="'docs'" :label="`Docs`" :selected="true"> class="bg-transparent flex w-full p-4 py-2" - <SmartTabs styles="sticky bg-primary z-10 top-0"> + <SmartTab :id="'docs'" :label="`Docs`" :selected="true"> /> - <SmartTabs styles="sticky bg-primary z-10 top-0"> + <SmartTab :id="'docs'" :label="`Docs`" :selected="true"> <div class="flex"> - v-model="graphqlFieldsFilterText" + }, 1000) + v-tippy="{ theme: 'tooltip' }" <SmartTabs styles="sticky bg-primary z-10 top-0"> + v-model="graphqlFieldsFilterText" <SmartTabs styles="sticky bg-primary z-10 top-0"> - <ButtonSecondary - <SmartTabs styles="sticky bg-primary z-10 top-0"> + <SmartTab :id="'docs'" :label="`Docs`" :selected="true"> v-tippy="{ theme: 'tooltip' }" - <SmartTabs styles="sticky bg-primary z-10 top-0"> + <SmartTab :id="'docs'" :label="`Docs`" :selected="true"> to="https://docs.hoppscotch.io/quickstart/graphql" + v-model="graphqlFieldsFilterText" <SmartTabs styles="sticky bg-primary z-10 top-0"> + <SmartTab :id="'docs'" :label="`Docs`" :selected="true"> blank - <SmartTabs styles="sticky bg-primary z-10 top-0"> + <SmartTab :id="'docs'" :label="`Docs`" :selected="true"> :title="$t('app.wiki')" + setTimeout(() => (copySchemaIcon.value = "copy"), 1000) <template> + </SmartTabs> v-model="graphqlFieldsFilterText" + <SmartTabs styles="sticky bg-primary z-10 top-0"> + <SmartTab :id="'docs'" :label="`Docs`" :selected="true"> <aside> +<template> + /> <aside> + /> <SmartTabs styles="sticky bg-primary z-10 top-0"> + <SmartTab :id="'docs'" :label="`Docs`" :selected="true"> <aside> + <SmartTab :id="'docs'" :label="`Docs`" :selected="true"> + const variableString = entry.variables + const responseText = entry.response + + setGQLURL(url) + setGQLHeaders(headers) + setGQLQuery(gqlQueryString) + </SmartTab> + setGQLResponse(responseText) + props.conn.reset() +} </script> diff --git a/components/http/CodegenModal.vue b/components/http/CodegenModal.vue index fe3c39cee7c546fa5e7d2c3c90daa2a0d72ab7f0..7a0949757cb811b13d5388651c8953628bfe4e0b 100644 --- a/components/http/CodegenModal.vue +++ b/components/http/CodegenModal.vue @@ -38,45 +38,40 @@