"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "components/graphql/Sidebar.vue" between
hoppscotch-2.0.0.tar.gz and hoppscotch-2.1.0.tar.gz

About: Hoppscotch is a light-weight, web based API development suite.

Sidebar.vue  (hoppscotch-2.0.0):Sidebar.vue  (hoppscotch-2.1.0)
<template> <template>
<aside> <SmartTabs styles="sticky bg-primary z-10 top-0" vertical>
<SmartTabs styles="sticky z-10 top-0"> <SmartTab
<SmartTab :id="'docs'" :label="`Docs`" :selected="true"> :id="'history'"
<AppSection label="docs"> icon="clock"
<div class="bg-primary flex top-sidebarPrimaryStickyFold z-10 sticky"> :label="`${$t('tab.history')}`"
<div class="search-wrapper"> :selected="true"
<input >
v-model="graphqlFieldsFilterText" <History
type="search" ref="graphqlHistoryComponent"
:placeholder="$t('action.search')" :page="'graphql'"
class="bg-transparent flex w-full py-2 pr-2 pl-10" @useHistory="handleUseHistory"
/> />
</div> </SmartTab>
<SmartTab
:id="'collections'"
icon="folder"
:label="`${$t('tab.collections')}`"
>
<CollectionsGraphql />
</SmartTab>
<SmartTab
:id="'docs'"
icon="book-open"
:label="`${$t('tab.documentation')}`"
>
<AppSection label="docs">
<div
v-if="
queryFields.length === 0 &&
mutationFields.length === 0 &&
subscriptionFields.length === 0 &&
graphqlTypes.length === 0
"
class="
flex flex-col
text-secondaryLight
p-4
items-center
justify-center
"
>
<img
:src="`/images/states/${$colorMode.value}/add_comment.svg`"
loading="lazy"
class="
flex-col
my-4
object-contain object-center
h-16
w-16
inline-flex
"
/>
<span class="text-center">
{{ $t("empty.documentation") }}
</span>
</div>
<div v-else>
<div class="bg-primary flex top-0 z-10 sticky">
<input
v-model="graphqlFieldsFilterText"
type="search"
autocomplete="off"
:placeholder="`${$t('action.search')}`"
class="bg-transparent flex w-full p-4 py-2"
/>
<div class="flex"> <div class="flex">
<ButtonSecondary <ButtonSecondary
v-tippy="{ theme: 'tooltip' }" v-tippy="{ theme: 'tooltip' }"
to="https://docs.hoppscotch.io/quickstart/graphql" to="https://docs.hoppscotch.io/quickstart/graphql"
blank blank
:title="$t('app.wiki')" :title="$t('app.wiki')"
icon="help_outline" svg="help-circle"
/> />
</div> </div>
</div> </div>
<SmartTabs <SmartTabs
ref="gqlTabs" ref="gqlTabs"
styles="border-t border-dividerLight sticky z-10 top-sidebarSecondar yStickyFold" styles="border-t border-b border-dividerLight bg-primary sticky z-10 top-sidebarPrimaryStickyFold"
> >
<div class="gqlTabs"> <div class="gqlTabs">
<SmartTab <SmartTab
v-if="queryFields.length > 0" v-if="queryFields.length > 0"
:id="'queries'" :id="'queries'"
:label="$t('tab.queries')" :label="`${$t('tab.queries')}`"
:selected="true" :selected="true"
class="divide-y divide-dividerLight" class="divide-y divide-dividerLight"
> >
<GraphqlField <GraphqlField
v-for="(field, index) in filteredQueryFields" v-for="(field, index) in filteredQueryFields"
:key="`field-${index}`" :key="`field-${index}`"
:gql-field="field" :gql-field="field"
:jump-type-callback="handleJumpToType" :jump-type-callback="handleJumpToType"
class="p-4" class="p-4"
/> />
</SmartTab> </SmartTab>
<SmartTab <SmartTab
v-if="mutationFields.length > 0" v-if="mutationFields.length > 0"
:id="'mutations'" :id="'mutations'"
:label="$t('graphql.mutations')" :label="`${$t('graphql.mutations')}`"
class="divide-y divide-dividerLight" class="divide-y divide-dividerLight"
> >
<GraphqlField <GraphqlField
v-for="(field, index) in filteredMutationFields" v-for="(field, index) in filteredMutationFields"
:key="`field-${index}`" :key="`field-${index}`"
:gql-field="field" :gql-field="field"
:jump-type-callback="handleJumpToType" :jump-type-callback="handleJumpToType"
class="p-4" class="p-4"
/> />
</SmartTab> </SmartTab>
<SmartTab <SmartTab
v-if="subscriptionFields.length > 0" v-if="subscriptionFields.length > 0"
:id="'subscriptions'" :id="'subscriptions'"
:label="$t('graphql.subscriptions')" :label="`${$t('graphql.subscriptions')}`"
class="divide-y divide-dividerLight" class="divide-y divide-dividerLight"
> >
<GraphqlField <GraphqlField
v-for="(field, index) in filteredSubscriptionFields" v-for="(field, index) in filteredSubscriptionFields"
:key="`field-${index}`" :key="`field-${index}`"
:gql-field="field" :gql-field="field"
:jump-type-callback="handleJumpToType" :jump-type-callback="handleJumpToType"
class="p-4" class="p-4"
/> />
</SmartTab> </SmartTab>
<SmartTab <SmartTab
v-if="graphqlTypes.length > 0" v-if="graphqlTypes.length > 0"
:id="'types'" :id="'types'"
ref="typesTab" ref="typesTab"
:label="$t('tab.types')" :label="`${$t('tab.types')}`"
class="divide-y divide-dividerLight" class="divide-y divide-dividerLight"
> >
<GraphqlType <GraphqlType
v-for="(type, index) in filteredGraphqlTypes" v-for="(type, index) in filteredGraphqlTypes"
:key="`type-${index}`" :key="`type-${index}`"
:gql-type="type" :gql-type="type"
:gql-types="graphqlTypes" :gql-types="graphqlTypes"
:is-highlighted="isGqlTypeHighlighted(type)" :is-highlighted="isGqlTypeHighlighted(type)"
:highlighted-fields="getGqlTypeHighlightedFields(type)" :highlighted-fields="getGqlTypeHighlightedFields(type)"
:jump-type-callback="handleJumpToType" :jump-type-callback="handleJumpToType"
/> />
</SmartTab> </SmartTab>
</div> </div>
</SmartTabs> </SmartTabs>
<div </div>
v-if=" </AppSection>
queryFields.length === 0 && </SmartTab>
mutationFields.length === 0 &&
subscriptionFields.length === 0 && <SmartTab :id="'schema'" icon="box" :label="`${$t('tab.schema')}`">
graphqlTypes.length === 0 <AppSection ref="schema" label="schema">
" <div
class=" v-if="schemaString"
flex flex-col class="
text-secondaryLight bg-primary
p-4 flex flex-1
items-center top-0
justify-center pl-4
" z-10
> sticky
<i class="opacity-75 pb-2 material-icons">link</i> items-center
<span class="text-center"> justify-between
{{ $t("empty.schema") }} border-b border-dividerLight
</span> "
>
<label class="font-semibold text-secondaryLight">
{{ $t("graphql.schema") }}
</label>
<div class="flex">
<ButtonSecondary
v-tippy="{ theme: 'tooltip' }"
to="https://docs.hoppscotch.io/quickstart/graphql"
blank
:title="$t('app.wiki')"
svg="help-circle"
/>
<ButtonSecondary
v-tippy="{ theme: 'tooltip' }"
:title="$t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }"
svg="corner-down-left"
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
/>
<ButtonSecondary
ref="downloadSchema"
v-tippy="{ theme: 'tooltip' }"
:title="$t('action.download_file')"
:svg="downloadSchemaIcon"
@click.native="downloadSchema"
/>
<ButtonSecondary
ref="copySchemaCode"
v-tippy="{ theme: 'tooltip' }"
:title="$t('action.copy')"
:svg="copySchemaIcon"
@click.native="copySchema"
/>
</div> </div>
</AppSection> </div>
</SmartTab> <div v-if="schemaString" ref="schemaEditor"></div>
<div
<SmartTab :id="'history'" :label="$t('tab.history')"> v-else
<History class="
ref="graphqlHistoryComponent" flex flex-col
:page="'graphql'" text-secondaryLight
@useHistory="handleUseHistory" p-4
/> items-center
</SmartTab> justify-center
"
<SmartTab :id="'collections'" :label="$t('tab.collections')"> >
<CollectionsGraphql /> <img
</SmartTab> :src="`/images/states/${$colorMode.value}/blockchain.svg`"
loading="lazy"
<SmartTab :id="'schema'" :label="`Schema`">
<AppSection ref="schema" label="schema">
<div
v-if="schemaString"
class=" class="
bg-primary flex-col
flex flex-1 my-4
top-sidebarPrimaryStickyFold object-contain object-center
pl-4 h-16
z-10 w-16
sticky inline-flex
items-center
justify-between
" "
>
<label class="font-semibold text-secondaryLight">
{{ $t("graphql.schema") }}
</label>
<div class="flex">
<ButtonSecondary
v-tippy="{ theme: 'tooltip' }"
to="https://docs.hoppscotch.io/quickstart/graphql"
blank
:title="$t('app.wiki')"
icon="help_outline"
/>
<ButtonSecondary
ref="downloadSchema"
v-tippy="{ theme: 'tooltip' }"
:title="$t('action.download_file')"
:icon="downloadSchemaIcon"
@click.native="downloadSchema"
/>
<ButtonSecondary
ref="copySchemaCode"
v-tippy="{ theme: 'tooltip' }"
:title="$t('action.copy')"
:icon="copySchemaIcon"
@click.native="copySchema"
/>
</div>
</div>
<SmartAceEditor
v-if="schemaString"
v-model="schemaString"
:lang="'graphqlschema'"
:options="{
maxLines: Infinity,
minLines: 16,
autoScrollEditorIntoView: true,
readOnly: true,
showPrintMargin: false,
useWorker: false,
}"
styles="border-b border-dividerLight"
/> />
<div <span class="text-center">
v-else {{ $t("empty.schema") }}
class=" </span>
flex flex-col </div>
text-secondaryLight </AppSection>
p-4 </SmartTab>
items-center </SmartTabs>
justify-center
"
>
<i class="opacity-75 pb-2 material-icons">link</i>
<span class="text-center">
{{ $t("empty.schema") }}
</span>
</div>
</AppSection>
</SmartTab>
</SmartTabs>
</aside>
</template> </template>
<script lang="ts"> <script setup lang="ts">
import { import {
computed, computed,
defineComponent,
nextTick, nextTick,
PropType, reactive,
ref, ref,
useContext, useContext,
} from "@nuxtjs/composition-api" } from "@nuxtjs/composition-api"
import { GraphQLField, GraphQLType } from "graphql" import { GraphQLField, GraphQLType } from "graphql"
import { map } from "rxjs/operators" import { map } from "rxjs/operators"
import { useCodemirror } from "~/helpers/editor/codemirror"
import { GQLConnection } from "~/helpers/GQLConnection" import { GQLConnection } from "~/helpers/GQLConnection"
import { GQLHeader } from "~/helpers/types/HoppGQLRequest" import { GQLHeader } from "~/helpers/types/HoppGQLRequest"
import { copyToClipboard } from "~/helpers/utils/clipboard" import { copyToClipboard } from "~/helpers/utils/clipboard"
import { useReadonlyStream } from "~/helpers/utils/composables" import { useReadonlyStream } from "~/helpers/utils/composables"
import { import {
setGQLHeaders, setGQLHeaders,
setGQLQuery, setGQLQuery,
setGQLResponse, setGQLResponse,
setGQLURL, setGQLURL,
setGQLVariables, setGQLVariables,
} from "~/newstore/GQLSession" } from "~/newstore/GQLSession"
import "~/helpers/editor/modes/graphql"
function isTextFoundInGraphqlFieldObject( function isTextFoundInGraphqlFieldObject(
text: string, text: string,
field: GraphQLField<any, any> field: GraphQLField<any, any>
) { ) {
const normalizedText = text.toLowerCase() const normalizedText = text.toLowerCase()
const isFilterTextFoundInDescription = field.description const isFilterTextFoundInDescription = field.description
? field.description.toLowerCase().includes(normalizedText) ? field.description.toLowerCase().includes(normalizedText)
: false : false
skipping to change at line 289 skipping to change at line 319
} }
type GQLHistoryEntry = { type GQLHistoryEntry = {
url: string url: string
headers: GQLHeader[] headers: GQLHeader[]
query: string query: string
response: string response: string
variables: string variables: string
} }
export default defineComponent({ const props = defineProps<{
props: { conn: GQLConnection
conn: { }>()
type: Object as PropType<GQLConnection>,
required: true, const {
}, $toast,
}, app: { i18n },
setup(props) { } = useContext()
const { const t = i18n.t.bind(i18n)
$toast,
app: { i18n }, const queryFields = useReadonlyStream(
} = useContext() props.conn.queryFields$.pipe(map((x) => x ?? [])),
const t = i18n.t.bind(i18n) []
)
const queryFields = useReadonlyStream(
props.conn.queryFields$.pipe(map((x) => x ?? [])), const mutationFields = useReadonlyStream(
[] props.conn.mutationFields$.pipe(map((x) => x ?? [])),
) []
const mutationFields = useReadonlyStream( )
props.conn.mutationFields$.pipe(map((x) => x ?? [])),
[] const subscriptionFields = useReadonlyStream(
) props.conn.subscriptionFields$.pipe(map((x) => x ?? [])),
const subscriptionFields = useReadonlyStream( []
props.conn.subscriptionFields$.pipe(map((x) => x ?? [])), )
[]
) const graphqlTypes = useReadonlyStream(
const graphqlTypes = useReadonlyStream( props.conn.graphqlTypes$.pipe(map((x) => x ?? [])),
props.conn.graphqlTypes$.pipe(map((x) => x ?? [])), []
[] )
)
const downloadSchemaIcon = ref("download")
const copySchemaIcon = ref("copy")
const graphqlFieldsFilterText = ref("")
const gqlTabs = ref<any | null>(null)
const typesTab = ref<any | null>(null)
const filteredQueryFields = computed(() => {
return getFilteredGraphqlFields(
graphqlFieldsFilterText.value,
queryFields.value as any
)
})
const downloadSchemaIcon = ref("save_alt") const filteredMutationFields = computed(() => {
const copySchemaIcon = ref("content_copy") return getFilteredGraphqlFields(
graphqlFieldsFilterText.value,
mutationFields.value as any
)
})
const graphqlFieldsFilterText = ref("") const filteredSubscriptionFields = computed(() => {
return getFilteredGraphqlFields(
graphqlFieldsFilterText.value,
subscriptionFields.value as any
)
})
const gqlTabs = ref<any | null>(null) const filteredGraphqlTypes = computed(() => {
const typesTab = ref<any | null>(null) return getFilteredGraphqlTypes(
graphqlFieldsFilterText.value,
graphqlTypes.value as any
)
})
const filteredQueryFields = computed(() => { const isGqlTypeHighlighted = (gqlType: GraphQLType) => {
return getFilteredGraphqlFields( if (!graphqlFieldsFilterText.value) return false
graphqlFieldsFilterText.value,
queryFields.value as any
)
})
const filteredMutationFields = computed(() => {
return getFilteredGraphqlFields(
graphqlFieldsFilterText.value,
mutationFields.value as any
)
})
const filteredSubscriptionFields = computed(() => {
return getFilteredGraphqlFields(
graphqlFieldsFilterText.value,
subscriptionFields.value as any
)
})
const filteredGraphqlTypes = computed(() => {
return getFilteredGraphqlTypes(
graphqlFieldsFilterText.value,
graphqlTypes.value as any
)
})
const isGqlTypeHighlighted = (gqlType: GraphQLType) => {
if (!graphqlFieldsFilterText.value) return false
return isTextFoundInGraphqlFieldObject(
graphqlFieldsFilterText.value,
gqlType as any
)
}
const getGqlTypeHighlightedFields = (gqlType: GraphQLType) => { return isTextFoundInGraphqlFieldObject(
if (!graphqlFieldsFilterText.value) return [] graphqlFieldsFilterText.value,
gqlType as any
)
}
const fields = Object.values((gqlType as any)._fields || {}) const getGqlTypeHighlightedFields = (gqlType: GraphQLType) => {
if (!fields || fields.length === 0) return [] if (!graphqlFieldsFilterText.value) return []
return fields.filter((field) => const fields = Object.values((gqlType as any)._fields || {})
isTextFoundInGraphqlFieldObject( if (!fields || fields.length === 0) return []
graphqlFieldsFilterText.value,
field as any
)
)
}
const handleJumpToType = async (type: GraphQLType) => { return fields.filter((field) =>
gqlTabs.value.selectTab(typesTab.value) isTextFoundInGraphqlFieldObject(graphqlFieldsFilterText.value, field as any)
await nextTick() )
}
const rootTypeName = resolveRootType(type).name
const target = document.getElementById(`type_${rootTypeName}`)
if (target) {
gqlTabs.value.$el
.querySelector(".gqlTabs")
.scrollTo({ top: target.offsetTop, behavior: "smooth" })
}
}
const schemaString = useReadonlyStream(
props.conn.schemaString$.pipe(map((x) => x ?? "")),
""
)
const downloadSchema = () => { const handleJumpToType = async (type: GraphQLType) => {
const dataToWrite = JSON.stringify(schemaString.value, null, 2) gqlTabs.value.selectTab(typesTab.value)
const file = new Blob([dataToWrite], { type: "application/graphql" }) await nextTick()
const a = document.createElement("a")
const url = URL.createObjectURL(file) const rootTypeName = resolveRootType(type).name
a.href = url
a.download = `${ const target = document.getElementById(`type_${rootTypeName}`)
url.split("/").pop()!.split("#")[0].split("?")[0] if (target) {
}.graphql` gqlTabs.value.$el
document.body.appendChild(a) .querySelector(".gqlTabs")
a.click() .scrollTo({ top: target.offsetTop, behavior: "smooth" })
downloadSchemaIcon.value = "done" }
$toast.success(t("state.download_started").toString(), { }
icon: "downloading",
})
setTimeout(() => {
document.body.removeChild(a)
URL.revokeObjectURL(url)
downloadSchemaIcon.value = "save_alt"
}, 1000)
}
const copySchema = () => { const schemaString = useReadonlyStream(
if (!schemaString.value) return props.conn.schemaString$.pipe(map((x) => x ?? "")),
""
)
const schemaEditor = ref<any | null>(null)
const linewrapEnabled = ref(true)
useCodemirror(
schemaEditor,
schemaString,
reactive({
extendedEditorConfig: {
mode: "graphql",
readOnly: true,
lineWrapping: linewrapEnabled,
},
linter: null,
completer: null,
})
)
copyToClipboard(schemaString.value) const downloadSchema = () => {
copySchemaIcon.value = "done" const dataToWrite = JSON.stringify(schemaString.value, null, 2)
setTimeout(() => (copySchemaIcon.value = "content_copy"), 1000) const file = new Blob([dataToWrite], { type: "application/graphql" })
} const a = document.createElement("a")
const url = URL.createObjectURL(file)
a.href = url
a.download = `${url.split("/").pop()!.split("#")[0].split("?")[0]}.graphql`
document.body.appendChild(a)
a.click()
downloadSchemaIcon.value = "check"
$toast.success(`${t("state.download_started")}`, {
icon: "downloading",
})
setTimeout(() => {
document.body.removeChild(a)
URL.revokeObjectURL(url)
downloadSchemaIcon.value = "download"
}, 1000)
}
const handleUseHistory = (entry: GQLHistoryEntry) => { const copySchema = () => {
const url = entry.url if (!schemaString.value) return
const headers = entry.headers
const gqlQueryString = entry.query
const variableString = entry.variables
const responseText = entry.response
setGQLURL(url)
setGQLHeaders(headers)
setGQLQuery(gqlQueryString)
setGQLVariables(variableString)
setGQLResponse(responseText)
props.conn.reset()
}
return { copyToClipboard(schemaString.value)
queryFields, copySchemaIcon.value = "check"
mutationFields, setTimeout(() => (copySchemaIcon.value = "copy"), 1000)
subscriptionFields, }
graphqlTypes,
schemaString, const handleUseHistory = (entry: GQLHistoryEntry) => {
const url = entry.url
graphqlFieldsFilterText, const headers = entry.headers
const gqlQueryString = entry.query
filteredQueryFields, const variableString = entry.variables
filteredMutationFields, const responseText = entry.response
filteredSubscriptionFields,
filteredGraphqlTypes, setGQLURL(url)
setGQLHeaders(headers)
isGqlTypeHighlighted, setGQLQuery(gqlQueryString)
getGqlTypeHighlightedFields, setGQLVariables(variableString)
setGQLResponse(responseText)
gqlTabs, props.conn.reset()
typesTab, }
handleJumpToType,
downloadSchema,
downloadSchemaIcon,
copySchemaIcon,
copySchema,
handleUseHistory,
}
},
})
</script> </script>
 End of changes. 31 change blocks. 
297 lines changed or deleted 309 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)