refactor: minor ui improvements
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<i class="opacity-75 pb-2 material-icons">manage_search</i>
|
||||
<span class="text-center my-2">
|
||||
<span class="my-2 text-center">
|
||||
{{ t("state.nothing_found") }} "{{ search }}"
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -17,22 +17,22 @@
|
||||
class="bg-transparent flex flex-shrink-0 text-base text-secondaryDark p-6"
|
||||
/>
|
||||
<div
|
||||
class="flex pb-4 px-4 border-b text-tiny border-dividerLight justify-between text-secondaryLight whitespace-nowrap overflow-auto flex-shrink-0 hide-scrollbar"
|
||||
class="border-b border-dividerLight flex flex-shrink-0 text-tiny text-secondaryLight px-4 pb-4 justify-between whitespace-nowrap overflow-auto hide-scrollbar"
|
||||
>
|
||||
<div class="flex items-center">
|
||||
<kbd class="shortcut-key">↑</kbd>
|
||||
<kbd class="shortcut-key">↓</kbd>
|
||||
<span class="truncate ml-2">
|
||||
<span class="ml-2 truncate">
|
||||
{{ t("action.to_navigate") }}
|
||||
</span>
|
||||
<kbd class="shortcut-key">↩</kbd>
|
||||
<span class="truncate ml-2">
|
||||
<span class="ml-2 truncate">
|
||||
{{ t("action.to_select") }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<kbd class="shortcut-key">ESC</kbd>
|
||||
<span class="truncate ml-2">
|
||||
<span class="ml-2 truncate">
|
||||
{{ t("action.to_close") }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
<template>
|
||||
<section :id="label.toLowerCase()" class="flex flex-col flex-1 relative">
|
||||
<slot></slot>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
defineProps({
|
||||
label: {
|
||||
type: String,
|
||||
default: "Section",
|
||||
},
|
||||
})
|
||||
</script>
|
||||
@@ -1,29 +1,24 @@
|
||||
<template>
|
||||
<AppSlideOver :show="show" @close="close()">
|
||||
<template #content>
|
||||
<div
|
||||
class="bg-primary border-b border-dividerLight flex p-2 top-0 z-10 sticky items-center justify-between"
|
||||
>
|
||||
<h3 class="ml-4 heading">{{ t("app.shortcuts") }}</h3>
|
||||
<div class="flex">
|
||||
<div class="bg-primary flex flex-col top-0 z-10 sticky">
|
||||
<div
|
||||
class="border-b border-dividerLight flex p-2 items-center justify-between"
|
||||
>
|
||||
<h3 class="ml-4 heading">{{ t("app.shortcuts") }}</h3>
|
||||
<ButtonSecondary svg="x" @click.native="close()" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-primary border-b border-dividerLight">
|
||||
<div class="flex flex-col my-4 mx-6">
|
||||
<div class="border-b border-dividerLight flex flex-col py-4 px-6">
|
||||
<input
|
||||
v-model="filterText"
|
||||
type="search"
|
||||
autocomplete="off"
|
||||
class="bg-primaryLight border border-dividerLight rounded flex w-full py-2 px-4 focus-visible:border-divider"
|
||||
class="bg-primaryLight border border-dividerLight rounded flex py-2 px-4 focus-visible:border-divider"
|
||||
:placeholder="`${t('action.search')}`"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="filterText"
|
||||
class="divide-dividerLight divide-y flex flex-col flex-1 overflow-auto hide-scrollbar"
|
||||
>
|
||||
<div v-if="filterText" class="divide-dividerLight divide-y flex flex-col">
|
||||
<div
|
||||
v-for="(map, mapIndex) in searchResults"
|
||||
:key="`map-${mapIndex}`"
|
||||
@@ -43,15 +38,12 @@
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<i class="opacity-75 pb-2 material-icons">manage_search</i>
|
||||
<span class="text-center my-2">
|
||||
<span class="my-2 text-center">
|
||||
{{ t("state.nothing_found") }} "{{ filterText }}"
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="divide-dividerLight divide-y flex flex-col flex-1 overflow-auto hide-scrollbar"
|
||||
>
|
||||
<div v-else class="divide-dividerLight divide-y flex flex-col">
|
||||
<div
|
||||
v-for="(map, mapIndex) in mappings"
|
||||
:key="`map-${mapIndex}`"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
</div>
|
||||
</transition>
|
||||
<aside
|
||||
class="bg-primary flex flex-col h-full max-w-full transform transition top-0 ease-in-out right-0 w-96 z-30 duration-300 fixed overflow-auto"
|
||||
class="bg-primary flex flex-col h-full max-w-full transform transition top-0 ease-in-out right-0 w-96 z-30 duration-300 fixed overflow-auto hide-scrollbar"
|
||||
:class="show ? 'shadow-xl translate-x-0' : 'translate-x-full'"
|
||||
>
|
||||
<slot name="content"></slot>
|
||||
|
||||
@@ -140,7 +140,7 @@
|
||||
:src="`/images/states/${$colorMode.value}/pack.svg`"
|
||||
loading="lazy"
|
||||
class="flex-col object-contain object-center h-16 mb-4 w-16 inline-flex"
|
||||
:alt="$t('empty.collection')"
|
||||
:alt="`${$t('empty.collection')}`"
|
||||
/>
|
||||
<span class="text-center">
|
||||
{{ $t("empty.collection") }}
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
<template>
|
||||
<AppSection
|
||||
label="collections"
|
||||
:class="{ 'rounded border border-divider': savingMode }"
|
||||
>
|
||||
<div :class="{ 'rounded border border-divider': savingMode }">
|
||||
<div
|
||||
class="divide-dividerLight divide-y border-b border-dividerLight flex flex-col top-0 z-10 sticky"
|
||||
:class="{ 'bg-primary': !savingMode }"
|
||||
@@ -13,7 +10,7 @@
|
||||
type="search"
|
||||
autocomplete="off"
|
||||
:placeholder="$t('action.search')"
|
||||
class="bg-transparent flex w-full py-2 px-4"
|
||||
class="bg-transparent flex py-2 px-4"
|
||||
/>
|
||||
<div class="flex flex-1 justify-between">
|
||||
<ButtonSecondary
|
||||
@@ -84,7 +81,7 @@
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<i class="opacity-75 pb-2 material-icons">manage_search</i>
|
||||
<span class="text-center my-2">
|
||||
<span class="my-2 text-center">
|
||||
{{ $t("state.nothing_found") }} "{{ filterText }}"
|
||||
</span>
|
||||
</div>
|
||||
@@ -126,7 +123,7 @@
|
||||
:show="showModalImportExport"
|
||||
@hide-modal="displayModalImportExport(false)"
|
||||
/>
|
||||
</AppSection>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
<template>
|
||||
<AppSection
|
||||
label="collections"
|
||||
:class="{ 'rounded border border-divider': saveRequest }"
|
||||
>
|
||||
<div :class="{ 'rounded border border-divider': saveRequest }">
|
||||
<div
|
||||
class="divide-dividerLight divide-y bg-primary border-b border-dividerLight rounded-t flex flex-col z-10 sticky"
|
||||
:style="saveRequest ? 'top: calc(-1 * var(--font-size-body))' : 'top: 0'"
|
||||
>
|
||||
<div v-if="!saveRequest" class="search-wrappe">
|
||||
<div v-if="!saveRequest" class="flex flex-col">
|
||||
<input
|
||||
v-model="filterText"
|
||||
type="search"
|
||||
autocomplete="off"
|
||||
:placeholder="$t('action.search')"
|
||||
class="bg-transparent flex w-full py-2 pr-2 pl-4"
|
||||
class="bg-transparent py-2 pr-2 pl-4"
|
||||
/>
|
||||
</div>
|
||||
<CollectionsChooseType
|
||||
@@ -135,7 +132,7 @@
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<i class="opacity-75 pb-2 material-icons">manage_search</i>
|
||||
<span class="text-center my-2">
|
||||
<span class="my-2 text-center">
|
||||
{{ $t("state.nothing_found") }} "{{ filterText }}"
|
||||
</span>
|
||||
</div>
|
||||
@@ -181,7 +178,7 @@
|
||||
@hide-modal="displayModalImportExport(false)"
|
||||
@update-team-collections="updateTeamCollections"
|
||||
/>
|
||||
</AppSection>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
:src="`/images/states/${$colorMode.value}/blockchain.svg`"
|
||||
loading="lazy"
|
||||
class="flex-col object-contain object-center h-16 my-4 w-16 inline-flex"
|
||||
:alt="$t('empty.environments')"
|
||||
:alt="`${$t('empty.environments')}`"
|
||||
/>
|
||||
<span class="text-center pb-4">
|
||||
{{ $t("empty.environments") }}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<AppSection :label="`${$t('environment.title')}`">
|
||||
<div>
|
||||
<div class="bg-primary rounded-t flex flex-col top-0 z-10 sticky">
|
||||
<tippy ref="options" interactive trigger="click" theme="popover" arrow>
|
||||
<template #trigger>
|
||||
@@ -69,19 +69,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<EnvironmentsAdd
|
||||
:show="showModalAdd"
|
||||
@hide-modal="displayModalAdd(false)"
|
||||
/>
|
||||
<EnvironmentsEdit
|
||||
:show="showModalEdit"
|
||||
:editing-environment-index="editingEnvironmentIndex"
|
||||
@hide-modal="displayModalEdit(false)"
|
||||
/>
|
||||
<EnvironmentsImportExport
|
||||
:show="showModalImportExport"
|
||||
@hide-modal="displayModalImportExport(false)"
|
||||
/>
|
||||
<div class="flex flex-col">
|
||||
<EnvironmentsEnvironment
|
||||
environment-index="Global"
|
||||
@@ -117,7 +104,20 @@
|
||||
@click.native="displayModalAdd(true)"
|
||||
/>
|
||||
</div>
|
||||
</AppSection>
|
||||
<EnvironmentsAdd
|
||||
:show="showModalAdd"
|
||||
@hide-modal="displayModalAdd(false)"
|
||||
/>
|
||||
<EnvironmentsEdit
|
||||
:show="showModalEdit"
|
||||
:editing-environment-index="editingEnvironmentIndex"
|
||||
@hide-modal="displayModalEdit(false)"
|
||||
/>
|
||||
<EnvironmentsImportExport
|
||||
:show="showModalImportExport"
|
||||
@hide-modal="displayModalImportExport(false)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
@@ -7,56 +7,54 @@
|
||||
:selected="true"
|
||||
:indicator="gqlQueryString.length > 0"
|
||||
>
|
||||
<AppSection label="query">
|
||||
<div
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 top-upperSecondaryStickyFold pl-4 z-10 sticky items-center justify-between gqlRunQuery"
|
||||
>
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ t("request.query") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
<ButtonSecondary
|
||||
:label="`${t('request.run')}`"
|
||||
svg="play"
|
||||
class="rounded-none !text-accent !hover:text-accentDark"
|
||||
@click.native="runQuery()"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
ref="saveRequest"
|
||||
:label="`${t('request.save')}`"
|
||||
svg="save"
|
||||
class="rounded-none"
|
||||
@click.native="saveRequest"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
to="https://docs.hoppscotch.io/graphql"
|
||||
blank
|
||||
:title="t('app.wiki')"
|
||||
svg="help-circle"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('action.clear_all')"
|
||||
svg="trash-2"
|
||||
@click.native="clearGQLQuery()"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('action.prettify')"
|
||||
:svg="`${prettifyQueryIcon}`"
|
||||
@click.native="prettifyQuery"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('action.copy')"
|
||||
:svg="`${copyQueryIcon}`"
|
||||
@click.native="copyQuery"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 top-upperSecondaryStickyFold pl-4 z-10 sticky items-center justify-between gqlRunQuery"
|
||||
>
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ t("request.query") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
<ButtonSecondary
|
||||
:label="`${t('request.run')}`"
|
||||
svg="play"
|
||||
class="rounded-none !text-accent !hover:text-accentDark"
|
||||
@click.native="runQuery()"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
ref="saveRequest"
|
||||
:label="`${t('request.save')}`"
|
||||
svg="save"
|
||||
class="rounded-none"
|
||||
@click.native="saveRequest"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
to="https://docs.hoppscotch.io/graphql"
|
||||
blank
|
||||
:title="t('app.wiki')"
|
||||
svg="help-circle"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('action.clear_all')"
|
||||
svg="trash-2"
|
||||
@click.native="clearGQLQuery()"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('action.prettify')"
|
||||
:svg="`${prettifyQueryIcon}`"
|
||||
@click.native="prettifyQuery"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('action.copy')"
|
||||
:svg="`${copyQueryIcon}`"
|
||||
@click.native="copyQuery"
|
||||
/>
|
||||
</div>
|
||||
<div ref="queryEditor"></div>
|
||||
</AppSection>
|
||||
</div>
|
||||
<div ref="queryEditor"></div>
|
||||
</SmartTab>
|
||||
|
||||
<SmartTab
|
||||
@@ -64,37 +62,42 @@
|
||||
:label="`${t('tab.variables')}`"
|
||||
:indicator="variableString.length > 0"
|
||||
>
|
||||
<AppSection label="variables">
|
||||
<div
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 top-upperSecondaryStickyFold pl-4 z-10 sticky items-center justify-between"
|
||||
>
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ t("request.variables") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
to="https://docs.hoppscotch.io/graphql"
|
||||
blank
|
||||
:title="t('app.wiki')"
|
||||
svg="help-circle"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('action.clear_all')"
|
||||
svg="trash-2"
|
||||
@click.native="clearGQLVariables()"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('action.copy')"
|
||||
:svg="`${copyVariablesIcon}`"
|
||||
@click.native="copyVariables"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 top-upperSecondaryStickyFold pl-4 z-10 sticky items-center justify-between"
|
||||
>
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ t("request.variables") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
to="https://docs.hoppscotch.io/graphql"
|
||||
blank
|
||||
:title="t('app.wiki')"
|
||||
svg="help-circle"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('action.clear_all')"
|
||||
svg="trash-2"
|
||||
@click.native="clearGQLVariables()"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
ref="prettifyRequest"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('action.prettify')"
|
||||
:svg="prettifyVariablesIcon"
|
||||
@click.native="prettifyVariableString"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('action.copy')"
|
||||
:svg="`${copyVariablesIcon}`"
|
||||
@click.native="copyVariables"
|
||||
/>
|
||||
</div>
|
||||
<div ref="variableEditor"></div>
|
||||
</AppSection>
|
||||
</div>
|
||||
<div ref="variableEditor"></div>
|
||||
</SmartTab>
|
||||
|
||||
<SmartTab
|
||||
@@ -102,57 +105,56 @@
|
||||
:label="`${t('tab.headers')}`"
|
||||
:info="activeGQLHeadersCount === 0 ? null : `${activeGQLHeadersCount}`"
|
||||
>
|
||||
<AppSection label="headers">
|
||||
<div
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 top-upperSecondaryStickyFold pl-4 z-10 sticky items-center justify-between"
|
||||
>
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ t("tab.headers") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
to="https://docs.hoppscotch.io/graphql"
|
||||
blank
|
||||
:title="t('app.wiki')"
|
||||
svg="help-circle"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('action.clear_all')"
|
||||
svg="trash-2"
|
||||
@click.native="clearHeaders()"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('state.bulk_mode')"
|
||||
svg="edit"
|
||||
:class="{ '!text-accent': bulkMode }"
|
||||
@click.native="bulkMode = !bulkMode"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('add.new')"
|
||||
svg="plus"
|
||||
:disabled="bulkMode"
|
||||
@click.native="addRequestHeader"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 top-upperSecondaryStickyFold pl-4 z-10 sticky items-center justify-between"
|
||||
>
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ t("tab.headers") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
to="https://docs.hoppscotch.io/graphql"
|
||||
blank
|
||||
:title="t('app.wiki')"
|
||||
svg="help-circle"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('action.clear_all')"
|
||||
svg="trash-2"
|
||||
@click.native="clearHeaders()"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('state.bulk_mode')"
|
||||
svg="edit"
|
||||
:class="{ '!text-accent': bulkMode }"
|
||||
@click.native="bulkMode = !bulkMode"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('add.new')"
|
||||
svg="plus"
|
||||
:disabled="bulkMode"
|
||||
@click.native="addRequestHeader"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="bulkMode" ref="bulkEditor"></div>
|
||||
<div v-else>
|
||||
<div
|
||||
v-for="(header, index) in headers"
|
||||
:key="`header-${String(index)}`"
|
||||
class="divide-dividerLight divide-x border-b border-dividerLight flex"
|
||||
>
|
||||
<SmartAutoComplete
|
||||
:placeholder="`${t('count.header', { count: index + 1 })}`"
|
||||
:source="commonHeaders"
|
||||
:spellcheck="false"
|
||||
:value="header.key"
|
||||
autofocus
|
||||
styles="
|
||||
</div>
|
||||
<div v-if="bulkMode" ref="bulkEditor"></div>
|
||||
<div v-else>
|
||||
<div
|
||||
v-for="(header, index) in headers"
|
||||
:key="`header-${String(index)}`"
|
||||
class="divide-dividerLight divide-x border-b border-dividerLight flex"
|
||||
>
|
||||
<SmartAutoComplete
|
||||
:placeholder="`${t('count.header', { count: index + 1 })}`"
|
||||
:source="commonHeaders"
|
||||
:spellcheck="false"
|
||||
:value="header.key"
|
||||
autofocus
|
||||
styles="
|
||||
bg-transparent
|
||||
flex
|
||||
flex-1
|
||||
@@ -160,92 +162,90 @@
|
||||
px-4
|
||||
truncate
|
||||
"
|
||||
class="flex-1 !flex"
|
||||
@input="
|
||||
updateRequestHeader(index, {
|
||||
key: $event,
|
||||
value: header.value,
|
||||
active: header.active,
|
||||
})
|
||||
class="flex-1 !flex"
|
||||
@input="
|
||||
updateRequestHeader(index, {
|
||||
key: $event,
|
||||
value: header.value,
|
||||
active: header.active,
|
||||
})
|
||||
"
|
||||
/>
|
||||
<input
|
||||
class="bg-transparent flex flex-1 py-2 px-4"
|
||||
:placeholder="`${t('count.value', { count: index + 1 })}`"
|
||||
:name="`value ${String(index)}`"
|
||||
:value="header.value"
|
||||
autofocus
|
||||
@change="
|
||||
updateRequestHeader(index, {
|
||||
key: header.key,
|
||||
value: $event.target.value,
|
||||
active: header.active,
|
||||
})
|
||||
"
|
||||
/>
|
||||
<span>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="
|
||||
header.hasOwnProperty('active')
|
||||
? header.active
|
||||
? t('action.turn_off')
|
||||
: t('action.turn_on')
|
||||
: t('action.turn_off')
|
||||
"
|
||||
/>
|
||||
<input
|
||||
class="bg-transparent flex flex-1 py-2 px-4"
|
||||
:placeholder="`${t('count.value', { count: index + 1 })}`"
|
||||
:name="`value ${String(index)}`"
|
||||
:value="header.value"
|
||||
autofocus
|
||||
@change="
|
||||
:svg="
|
||||
header.hasOwnProperty('active')
|
||||
? header.active
|
||||
? 'check-circle'
|
||||
: 'circle'
|
||||
: 'check-circle'
|
||||
"
|
||||
color="green"
|
||||
@click.native="
|
||||
updateRequestHeader(index, {
|
||||
key: header.key,
|
||||
value: $event.target.value,
|
||||
active: header.active,
|
||||
value: header.value,
|
||||
active: !header.active,
|
||||
})
|
||||
"
|
||||
/>
|
||||
<span>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="
|
||||
header.hasOwnProperty('active')
|
||||
? header.active
|
||||
? t('action.turn_off')
|
||||
: t('action.turn_on')
|
||||
: t('action.turn_off')
|
||||
"
|
||||
:svg="
|
||||
header.hasOwnProperty('active')
|
||||
? header.active
|
||||
? 'check-circle'
|
||||
: 'circle'
|
||||
: 'check-circle'
|
||||
"
|
||||
color="green"
|
||||
@click.native="
|
||||
updateRequestHeader(index, {
|
||||
key: header.key,
|
||||
value: header.value,
|
||||
active: !header.active,
|
||||
})
|
||||
"
|
||||
/>
|
||||
</span>
|
||||
<span>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('action.remove')"
|
||||
svg="trash"
|
||||
color="red"
|
||||
@click.native="removeRequestHeader(index)"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="headers.length === 0"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/add_category.svg`"
|
||||
loading="lazy"
|
||||
class="flex-col object-contain object-center h-16 my-4 w-16 inline-flex"
|
||||
:alt="`${t('empty.headers')}`"
|
||||
/>
|
||||
<span class="text-center pb-4">
|
||||
{{ t("empty.headers") }}
|
||||
</span>
|
||||
</span>
|
||||
<span>
|
||||
<ButtonSecondary
|
||||
:label="`${t('add.new')}`"
|
||||
filled
|
||||
svg="plus"
|
||||
class="mb-4"
|
||||
@click.native="addRequestHeader"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('action.remove')"
|
||||
svg="trash"
|
||||
color="red"
|
||||
@click.native="removeRequestHeader(index)"
|
||||
/>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</AppSection>
|
||||
<div
|
||||
v-if="headers.length === 0"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/add_category.svg`"
|
||||
loading="lazy"
|
||||
class="flex-col object-contain object-center h-16 my-4 w-16 inline-flex"
|
||||
:alt="`${t('empty.headers')}`"
|
||||
/>
|
||||
<span class="text-center pb-4">
|
||||
{{ t("empty.headers") }}
|
||||
</span>
|
||||
<ButtonSecondary
|
||||
:label="`${t('add.new')}`"
|
||||
filled
|
||||
svg="plus"
|
||||
class="mb-4"
|
||||
@click.native="addRequestHeader"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</SmartTab>
|
||||
</SmartTabs>
|
||||
|
||||
<CollectionsSaveRequest
|
||||
mode="graphql"
|
||||
:show="showSaveRequestModal"
|
||||
@@ -379,8 +379,9 @@ useCodemirror(queryEditor, gqlQueryString, {
|
||||
})
|
||||
|
||||
const copyQueryIcon = ref("copy")
|
||||
const prettifyQueryIcon = ref("wand")
|
||||
const copyVariablesIcon = ref("copy")
|
||||
const prettifyQueryIcon = ref("wand")
|
||||
const prettifyVariablesIcon = ref("wand")
|
||||
|
||||
const showSaveRequestModal = ref(false)
|
||||
|
||||
@@ -511,6 +512,19 @@ const copyVariables = () => {
|
||||
setTimeout(() => (copyVariablesIcon.value = "copy"), 1000)
|
||||
}
|
||||
|
||||
const prettifyVariableString = () => {
|
||||
try {
|
||||
const jsonObj = JSON.parse(variableString.value)
|
||||
variableString.value = JSON.stringify(jsonObj, null, 2)
|
||||
prettifyVariablesIcon.value = "check"
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
prettifyVariablesIcon.value = "info"
|
||||
toast.error(`${t("error.json_prettify_invalid_body")}`)
|
||||
}
|
||||
setTimeout(() => (prettifyVariablesIcon.value = "wand"), 1000)
|
||||
}
|
||||
|
||||
const addRequestHeader = () => {
|
||||
const empty = { key: "", value: "", active: true }
|
||||
const index = headers.value.length
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<AppSection ref="response" label="response">
|
||||
<div>
|
||||
<div
|
||||
v-if="responseString === 'loading'"
|
||||
class="flex flex-col p-4 items-center justify-center"
|
||||
@@ -71,7 +71,7 @@
|
||||
reverse
|
||||
/>
|
||||
</div>
|
||||
</AppSection>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
@@ -26,125 +26,34 @@
|
||||
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 object-contain object-center h-16 my-4 w-16 inline-flex"
|
||||
:alt="`${t('empty.documentation')}`"
|
||||
<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 object-contain object-center h-16 my-4 w-16 inline-flex"
|
||||
:alt="`${t('empty.documentation')}`"
|
||||
/>
|
||||
<span class="text-center mb-4">
|
||||
{{ 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"
|
||||
/>
|
||||
<span class="text-center mb-4">
|
||||
{{ 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">
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
to="https://docs.hoppscotch.io/quickstart/graphql"
|
||||
blank
|
||||
:title="t('app.wiki')"
|
||||
svg="help-circle"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<SmartTabs
|
||||
ref="gqlTabs"
|
||||
styles="border-t border-b border-dividerLight bg-primary sticky z-10 top-sidebarPrimaryStickyFold"
|
||||
>
|
||||
<div class="gqlTabs">
|
||||
<SmartTab
|
||||
v-if="queryFields.length > 0"
|
||||
:id="'queries'"
|
||||
:label="`${t('tab.queries')}`"
|
||||
:selected="true"
|
||||
class="divide-dividerLight divide-y"
|
||||
>
|
||||
<GraphqlField
|
||||
v-for="(field, index) in filteredQueryFields"
|
||||
:key="`field-${index}`"
|
||||
:gql-field="field"
|
||||
:jump-type-callback="handleJumpToType"
|
||||
class="p-4"
|
||||
/>
|
||||
</SmartTab>
|
||||
<SmartTab
|
||||
v-if="mutationFields.length > 0"
|
||||
:id="'mutations'"
|
||||
:label="`${t('graphql.mutations')}`"
|
||||
class="divide-dividerLight divide-y"
|
||||
>
|
||||
<GraphqlField
|
||||
v-for="(field, index) in filteredMutationFields"
|
||||
:key="`field-${index}`"
|
||||
:gql-field="field"
|
||||
:jump-type-callback="handleJumpToType"
|
||||
class="p-4"
|
||||
/>
|
||||
</SmartTab>
|
||||
<SmartTab
|
||||
v-if="subscriptionFields.length > 0"
|
||||
:id="'subscriptions'"
|
||||
:label="`${t('graphql.subscriptions')}`"
|
||||
class="divide-dividerLight divide-y"
|
||||
>
|
||||
<GraphqlField
|
||||
v-for="(field, index) in filteredSubscriptionFields"
|
||||
:key="`field-${index}`"
|
||||
:gql-field="field"
|
||||
:jump-type-callback="handleJumpToType"
|
||||
class="p-4"
|
||||
/>
|
||||
</SmartTab>
|
||||
<SmartTab
|
||||
v-if="graphqlTypes.length > 0"
|
||||
:id="'types'"
|
||||
ref="typesTab"
|
||||
:label="`${t('tab.types')}`"
|
||||
class="divide-dividerLight divide-y"
|
||||
>
|
||||
<GraphqlType
|
||||
v-for="(type, index) in filteredGraphqlTypes"
|
||||
:key="`type-${index}`"
|
||||
:gql-type="type"
|
||||
:gql-types="graphqlTypes"
|
||||
:is-highlighted="isGqlTypeHighlighted(type)"
|
||||
:highlighted-fields="getGqlTypeHighlightedFields(type)"
|
||||
:jump-type-callback="handleJumpToType"
|
||||
/>
|
||||
</SmartTab>
|
||||
</div>
|
||||
</SmartTabs>
|
||||
</div>
|
||||
</AppSection>
|
||||
</SmartTab>
|
||||
|
||||
<SmartTab :id="'schema'" icon="box" :label="`${t('tab.schema')}`">
|
||||
<AppSection ref="schema" label="schema">
|
||||
<div
|
||||
v-if="schemaString"
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 pl-4 top-0 z-10 sticky items-center justify-between"
|
||||
>
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ t("graphql.schema") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
@@ -153,45 +62,132 @@
|
||||
:title="t('app.wiki')"
|
||||
svg="help-circle"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('state.linewrap')"
|
||||
:class="{ '!text-accent': linewrapEnabled }"
|
||||
svg="wrap-text"
|
||||
@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>
|
||||
<div v-if="schemaString" ref="schemaEditor"></div>
|
||||
<div
|
||||
v-else
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
<SmartTabs
|
||||
ref="gqlTabs"
|
||||
styles="border-t border-b border-dividerLight bg-primary sticky z-10 top-sidebarPrimaryStickyFold"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/blockchain.svg`"
|
||||
loading="lazy"
|
||||
class="flex-col object-contain object-center h-16 my-4 w-16 inline-flex"
|
||||
:alt="`${t('empty.schema')}`"
|
||||
<div class="gqlTabs">
|
||||
<SmartTab
|
||||
v-if="queryFields.length > 0"
|
||||
:id="'queries'"
|
||||
:label="`${t('tab.queries')}`"
|
||||
:selected="true"
|
||||
class="divide-dividerLight divide-y"
|
||||
>
|
||||
<GraphqlField
|
||||
v-for="(field, index) in filteredQueryFields"
|
||||
:key="`field-${index}`"
|
||||
:gql-field="field"
|
||||
:jump-type-callback="handleJumpToType"
|
||||
class="p-4"
|
||||
/>
|
||||
</SmartTab>
|
||||
<SmartTab
|
||||
v-if="mutationFields.length > 0"
|
||||
:id="'mutations'"
|
||||
:label="`${t('graphql.mutations')}`"
|
||||
class="divide-dividerLight divide-y"
|
||||
>
|
||||
<GraphqlField
|
||||
v-for="(field, index) in filteredMutationFields"
|
||||
:key="`field-${index}`"
|
||||
:gql-field="field"
|
||||
:jump-type-callback="handleJumpToType"
|
||||
class="p-4"
|
||||
/>
|
||||
</SmartTab>
|
||||
<SmartTab
|
||||
v-if="subscriptionFields.length > 0"
|
||||
:id="'subscriptions'"
|
||||
:label="`${t('graphql.subscriptions')}`"
|
||||
class="divide-dividerLight divide-y"
|
||||
>
|
||||
<GraphqlField
|
||||
v-for="(field, index) in filteredSubscriptionFields"
|
||||
:key="`field-${index}`"
|
||||
:gql-field="field"
|
||||
:jump-type-callback="handleJumpToType"
|
||||
class="p-4"
|
||||
/>
|
||||
</SmartTab>
|
||||
<SmartTab
|
||||
v-if="graphqlTypes.length > 0"
|
||||
:id="'types'"
|
||||
ref="typesTab"
|
||||
:label="`${t('tab.types')}`"
|
||||
class="divide-dividerLight divide-y"
|
||||
>
|
||||
<GraphqlType
|
||||
v-for="(type, index) in filteredGraphqlTypes"
|
||||
:key="`type-${index}`"
|
||||
:gql-type="type"
|
||||
:gql-types="graphqlTypes"
|
||||
:is-highlighted="isGqlTypeHighlighted(type)"
|
||||
:highlighted-fields="getGqlTypeHighlightedFields(type)"
|
||||
:jump-type-callback="handleJumpToType"
|
||||
/>
|
||||
</SmartTab>
|
||||
</div>
|
||||
</SmartTabs>
|
||||
</div>
|
||||
</SmartTab>
|
||||
|
||||
<SmartTab :id="'schema'" icon="box" :label="`${t('tab.schema')}`">
|
||||
<div
|
||||
v-if="schemaString"
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 pl-4 top-0 z-10 sticky 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')"
|
||||
svg="help-circle"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('state.linewrap')"
|
||||
:class="{ '!text-accent': linewrapEnabled }"
|
||||
svg="wrap-text"
|
||||
@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"
|
||||
/>
|
||||
<span class="text-center mb-4">
|
||||
{{ t("empty.schema") }}
|
||||
</span>
|
||||
</div>
|
||||
</AppSection>
|
||||
</div>
|
||||
<div v-if="schemaString" ref="schemaEditor"></div>
|
||||
<div
|
||||
v-else
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/blockchain.svg`"
|
||||
loading="lazy"
|
||||
class="flex-col object-contain object-center h-16 my-4 w-16 inline-flex"
|
||||
:alt="`${t('empty.schema')}`"
|
||||
/>
|
||||
<span class="text-center mb-4">
|
||||
{{ t("empty.schema") }}
|
||||
</span>
|
||||
</div>
|
||||
</SmartTab>
|
||||
</SmartTabs>
|
||||
</template>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<AppSection label="history">
|
||||
<div>
|
||||
<div class="bg-primary border-b border-dividerLight flex top-0 z-10 sticky">
|
||||
<input
|
||||
v-model="filterText"
|
||||
@@ -52,7 +52,7 @@
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<i class="opacity-75 pb-2 material-icons">manage_search</i>
|
||||
<span class="text-center my-2">
|
||||
<span class="my-2 text-center">
|
||||
{{ $t("state.nothing_found") }} "{{ filterText }}"
|
||||
</span>
|
||||
</div>
|
||||
@@ -64,7 +64,7 @@
|
||||
:src="`/images/states/${$colorMode.value}/history.svg`"
|
||||
loading="lazy"
|
||||
class="flex-col object-contain object-center h-16 my-4 w-16 inline-flex"
|
||||
:alt="$t('empty.history')"
|
||||
:alt="`${$t('empty.history')}`"
|
||||
/>
|
||||
<span class="text-center mb-4">
|
||||
{{ $t("empty.history") }}
|
||||
@@ -76,7 +76,7 @@
|
||||
@hide-modal="confirmRemove = false"
|
||||
@resolve="clearHistory"
|
||||
/>
|
||||
</AppSection>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
@@ -109,7 +109,7 @@
|
||||
:src="`/images/states/${$colorMode.value}/login.svg`"
|
||||
loading="lazy"
|
||||
class="flex-col object-contain object-center h-16 my-4 w-16 inline-flex"
|
||||
:alt="$t('empty.authorization')"
|
||||
:alt="`${$t('empty.authorization')}`"
|
||||
/>
|
||||
<span class="text-center pb-4">
|
||||
{{ $t("empty.authorization") }}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<AppSection label="bodyParameters">
|
||||
<div>
|
||||
<div
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 top-upperTertiaryStickyFold pl-4 z-10 sticky items-center justify-between"
|
||||
>
|
||||
@@ -147,7 +147,7 @@
|
||||
:src="`/images/states/${$colorMode.value}/upload_single_file.svg`"
|
||||
loading="lazy"
|
||||
class="flex-col object-contain object-center h-16 my-4 w-16 inline-flex"
|
||||
:alt="$t('empty.body')"
|
||||
:alt="`${$t('empty.body')}`"
|
||||
/>
|
||||
<span class="text-center pb-4">
|
||||
{{ $t("empty.body") }}
|
||||
@@ -160,7 +160,7 @@
|
||||
@click.native="addBodyParam"
|
||||
/>
|
||||
</div>
|
||||
</AppSection>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<AppSection label="headers">
|
||||
<div>
|
||||
<div
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 top-upperSecondaryStickyFold pl-4 z-10 sticky items-center justify-between"
|
||||
>
|
||||
@@ -145,7 +145,7 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</AppSection>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<AppSection label="parameters">
|
||||
<div>
|
||||
<div
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 top-upperSecondaryStickyFold pl-4 z-10 sticky items-center justify-between"
|
||||
>
|
||||
@@ -138,7 +138,7 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</AppSection>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<AppSection id="script" :label="`${t('preRequest.script')}`">
|
||||
<div>
|
||||
<div
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 top-upperSecondaryStickyFold pl-4 z-10 sticky items-center justify-between"
|
||||
>
|
||||
@@ -58,7 +58,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</AppSection>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
@@ -117,10 +117,11 @@ const prettifyRequestBody = () => {
|
||||
const jsonObj = JSON.parse(rawParamsBody.value)
|
||||
rawParamsBody.value = JSON.stringify(jsonObj, null, 2)
|
||||
prettifyIcon.value = "check"
|
||||
setTimeout(() => (prettifyIcon.value = "wand"), 1000)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
prettifyIcon.value = "info"
|
||||
toast.error(`${t("error.json_prettify_invalid_body")}`)
|
||||
}
|
||||
setTimeout(() => (prettifyIcon.value = "wand"), 1000)
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<template>
|
||||
<AppSection label="response">
|
||||
<div>
|
||||
<HttpResponseMeta :response="response" />
|
||||
<LensesResponseBodyRenderer
|
||||
v-if="!loading && hasResponse"
|
||||
:response="response"
|
||||
/>
|
||||
</AppSection>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<AppSection :label="`${t('test.results')}`">
|
||||
<div>
|
||||
<div
|
||||
v-if="
|
||||
testResults &&
|
||||
@@ -88,7 +88,7 @@
|
||||
class="my-4"
|
||||
/>
|
||||
</div>
|
||||
</AppSection>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<AppSection id="script" :label="`${t('test.script')}`">
|
||||
<div>
|
||||
<div
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 top-upperSecondaryStickyFold pl-4 z-10 sticky items-center justify-between"
|
||||
>
|
||||
@@ -58,7 +58,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</AppSection>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
@@ -13,63 +13,57 @@
|
||||
:size="COLUMN_LAYOUT ? 45 : 50"
|
||||
class="hide-scrollbar !overflow-auto"
|
||||
>
|
||||
<AppSection label="request">
|
||||
<div
|
||||
class="bg-primary flex flex-col space-y-4 p-4 top-0 z-10 sticky"
|
||||
>
|
||||
<div class="space-x-2 flex-1 inline-flex">
|
||||
<input
|
||||
id="mqtt-url"
|
||||
v-model="url"
|
||||
type="url"
|
||||
autocomplete="off"
|
||||
spellcheck="false"
|
||||
class="bg-primaryLight border border-divider rounded text-secondaryDark w-full py-2 px-4 hover:border-dividerDark focus-visible:bg-transparent focus-visible:border-dividerDark"
|
||||
:placeholder="$t('mqtt.url')"
|
||||
:disabled="connectionState"
|
||||
@keyup.enter="validUrl ? toggleConnection() : null"
|
||||
/>
|
||||
<ButtonPrimary
|
||||
id="connect"
|
||||
:disabled="!validUrl"
|
||||
class="w-32"
|
||||
:label="
|
||||
connectionState
|
||||
? $t('action.disconnect')
|
||||
: $t('action.connect')
|
||||
"
|
||||
:loading="connectingState"
|
||||
@click.native="toggleConnection"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex space-x-4">
|
||||
<input
|
||||
id="mqtt-username"
|
||||
v-model="username"
|
||||
type="text"
|
||||
spellcheck="false"
|
||||
class="input"
|
||||
:placeholder="$t('authorization.username')"
|
||||
/>
|
||||
<input
|
||||
id="mqtt-password"
|
||||
v-model="password"
|
||||
type="password"
|
||||
spellcheck="false"
|
||||
class="input"
|
||||
:placeholder="$t('authorization.password')"
|
||||
/>
|
||||
</div>
|
||||
<div class="bg-primary flex flex-col space-y-4 p-4 top-0 z-10 sticky">
|
||||
<div class="space-x-2 flex-1 inline-flex">
|
||||
<input
|
||||
id="mqtt-url"
|
||||
v-model="url"
|
||||
type="url"
|
||||
autocomplete="off"
|
||||
spellcheck="false"
|
||||
class="bg-primaryLight border border-divider rounded text-secondaryDark w-full py-2 px-4 hover:border-dividerDark focus-visible:bg-transparent focus-visible:border-dividerDark"
|
||||
:placeholder="$t('mqtt.url')"
|
||||
:disabled="connectionState"
|
||||
@keyup.enter="validUrl ? toggleConnection() : null"
|
||||
/>
|
||||
<ButtonPrimary
|
||||
id="connect"
|
||||
:disabled="!validUrl"
|
||||
class="w-32"
|
||||
:label="
|
||||
connectionState
|
||||
? $t('action.disconnect')
|
||||
: $t('action.connect')
|
||||
"
|
||||
:loading="connectingState"
|
||||
@click.native="toggleConnection"
|
||||
/>
|
||||
</div>
|
||||
</AppSection>
|
||||
<div class="flex space-x-4">
|
||||
<input
|
||||
id="mqtt-username"
|
||||
v-model="username"
|
||||
type="text"
|
||||
spellcheck="false"
|
||||
class="input"
|
||||
:placeholder="$t('authorization.username')"
|
||||
/>
|
||||
<input
|
||||
id="mqtt-password"
|
||||
v-model="password"
|
||||
type="password"
|
||||
spellcheck="false"
|
||||
class="input"
|
||||
:placeholder="$t('authorization.password')"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Pane>
|
||||
<Pane
|
||||
:size="COLUMN_LAYOUT ? 65 : 50"
|
||||
class="hide-scrollbar !overflow-auto"
|
||||
>
|
||||
<AppSection label="response">
|
||||
<RealtimeLog :title="$t('mqtt.log')" :log="log" />
|
||||
</AppSection>
|
||||
<RealtimeLog :title="$t('mqtt.log')" :log="log" />
|
||||
</Pane>
|
||||
</Splitpanes>
|
||||
</Pane>
|
||||
@@ -79,75 +73,73 @@
|
||||
min-size="20"
|
||||
class="hide-scrollbar !overflow-auto"
|
||||
>
|
||||
<AppSection label="messages">
|
||||
<div class="flex flex-col flex-1 p-4 inline-flex">
|
||||
<label for="pub_topic" class="font-semibold text-secondaryLight">
|
||||
{{ $t("mqtt.topic") }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="flex px-4">
|
||||
<input
|
||||
id="pub_topic"
|
||||
v-model="pub_topic"
|
||||
class="input"
|
||||
:placeholder="$t('mqtt.topic_name')"
|
||||
type="text"
|
||||
autocomplete="off"
|
||||
spellcheck="false"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-1 p-4 items-center justify-between">
|
||||
<label for="mqtt-message" class="font-semibold text-secondaryLight">
|
||||
{{ $t("mqtt.communication") }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="flex space-x-2 px-4">
|
||||
<input
|
||||
id="mqtt-message"
|
||||
v-model="msg"
|
||||
class="input"
|
||||
type="text"
|
||||
autocomplete="off"
|
||||
:placeholder="$t('mqtt.message')"
|
||||
spellcheck="false"
|
||||
/>
|
||||
<ButtonPrimary
|
||||
id="publish"
|
||||
name="get"
|
||||
:disabled="!canpublish"
|
||||
:label="$t('mqtt.publish')"
|
||||
@click.native="publish"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="border-t border-dividerLight flex flex-col flex-1 mt-4 p-4 inline-flex"
|
||||
>
|
||||
<label for="sub_topic" class="font-semibold text-secondaryLight">
|
||||
{{ $t("mqtt.topic") }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="flex space-x-2 px-4">
|
||||
<input
|
||||
id="sub_topic"
|
||||
v-model="sub_topic"
|
||||
type="text"
|
||||
autocomplete="off"
|
||||
:placeholder="$t('mqtt.topic_name')"
|
||||
spellcheck="false"
|
||||
class="input"
|
||||
/>
|
||||
<ButtonPrimary
|
||||
id="subscribe"
|
||||
name="get"
|
||||
:disabled="!cansubscribe"
|
||||
:label="
|
||||
subscriptionState ? $t('mqtt.unsubscribe') : $t('mqtt.subscribe')
|
||||
"
|
||||
reverse
|
||||
@click.native="toggleSubscription"
|
||||
/>
|
||||
</div>
|
||||
</AppSection>
|
||||
<div class="flex flex-col flex-1 p-4 inline-flex">
|
||||
<label for="pub_topic" class="font-semibold text-secondaryLight">
|
||||
{{ $t("mqtt.topic") }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="flex px-4">
|
||||
<input
|
||||
id="pub_topic"
|
||||
v-model="pub_topic"
|
||||
class="input"
|
||||
:placeholder="$t('mqtt.topic_name')"
|
||||
type="text"
|
||||
autocomplete="off"
|
||||
spellcheck="false"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-1 p-4 items-center justify-between">
|
||||
<label for="mqtt-message" class="font-semibold text-secondaryLight">
|
||||
{{ $t("mqtt.communication") }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="flex space-x-2 px-4">
|
||||
<input
|
||||
id="mqtt-message"
|
||||
v-model="msg"
|
||||
class="input"
|
||||
type="text"
|
||||
autocomplete="off"
|
||||
:placeholder="$t('mqtt.message')"
|
||||
spellcheck="false"
|
||||
/>
|
||||
<ButtonPrimary
|
||||
id="publish"
|
||||
name="get"
|
||||
:disabled="!canpublish"
|
||||
:label="$t('mqtt.publish')"
|
||||
@click.native="publish"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="border-t border-dividerLight flex flex-col flex-1 mt-4 p-4 inline-flex"
|
||||
>
|
||||
<label for="sub_topic" class="font-semibold text-secondaryLight">
|
||||
{{ $t("mqtt.topic") }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="flex space-x-2 px-4">
|
||||
<input
|
||||
id="sub_topic"
|
||||
v-model="sub_topic"
|
||||
type="text"
|
||||
autocomplete="off"
|
||||
:placeholder="$t('mqtt.topic_name')"
|
||||
spellcheck="false"
|
||||
class="input"
|
||||
/>
|
||||
<ButtonPrimary
|
||||
id="subscribe"
|
||||
name="get"
|
||||
:disabled="!cansubscribe"
|
||||
:label="
|
||||
subscriptionState ? $t('mqtt.unsubscribe') : $t('mqtt.subscribe')
|
||||
"
|
||||
reverse
|
||||
@click.native="toggleSubscription"
|
||||
/>
|
||||
</div>
|
||||
</Pane>
|
||||
</Splitpanes>
|
||||
</template>
|
||||
|
||||
@@ -13,84 +13,80 @@
|
||||
:size="COLUMN_LAYOUT ? 45 : 50"
|
||||
class="hide-scrollbar !overflow-auto"
|
||||
>
|
||||
<AppSection label="request">
|
||||
<div class="bg-primary flex p-4 top-0 z-10 sticky">
|
||||
<div class="space-x-2 flex-1 inline-flex">
|
||||
<div class="flex flex-1">
|
||||
<label for="client-version">
|
||||
<tippy
|
||||
ref="versionOptions"
|
||||
interactive
|
||||
trigger="click"
|
||||
theme="popover"
|
||||
arrow
|
||||
>
|
||||
<template #trigger>
|
||||
<span class="select-wrapper">
|
||||
<input
|
||||
id="client-version"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
title="socket.io-client version"
|
||||
class="bg-primaryLight border border-divider rounded-l cursor-pointer flex font-semibold text-secondaryDark py-2 px-4 w-26 hover:border-dividerDark focus-visible:bg-transparent focus-visible:border-dividerDark"
|
||||
:value="`Client ${clientVersion}`"
|
||||
readonly
|
||||
:disabled="connectionState"
|
||||
/>
|
||||
</span>
|
||||
</template>
|
||||
<SmartItem
|
||||
v-for="(_, version) in socketIoClients"
|
||||
:key="`client-${version}`"
|
||||
:label="`Client ${version}`"
|
||||
@click.native="onSelectVersion(version)"
|
||||
/>
|
||||
</tippy>
|
||||
</label>
|
||||
<input
|
||||
id="socketio-url"
|
||||
v-model="url"
|
||||
type="url"
|
||||
autocomplete="off"
|
||||
spellcheck="false"
|
||||
:class="{ error: !urlValid }"
|
||||
class="bg-primaryLight border border-divider flex flex-1 text-secondaryDark w-full py-2 px-4 hover:border-dividerDark focus-visible:bg-transparent focus-visible:border-dividerDark"
|
||||
:placeholder="$t('socketio.url')"
|
||||
:disabled="connectionState"
|
||||
@keyup.enter="urlValid ? toggleConnection() : null"
|
||||
/>
|
||||
<input
|
||||
id="socketio-path"
|
||||
v-model="path"
|
||||
class="bg-primaryLight border border-divider rounded-r flex flex-1 text-secondaryDark w-full py-2 px-4 hover:border-dividerDark focus-visible:bg-transparent focus-visible:border-dividerDark"
|
||||
spellcheck="false"
|
||||
:disabled="connectionState"
|
||||
@keyup.enter="urlValid ? toggleConnection() : null"
|
||||
/>
|
||||
</div>
|
||||
<ButtonPrimary
|
||||
id="connect"
|
||||
:disabled="!urlValid"
|
||||
name="connect"
|
||||
class="w-32"
|
||||
:label="
|
||||
!connectionState
|
||||
? $t('action.connect')
|
||||
: $t('action.disconnect')
|
||||
"
|
||||
:loading="connectingState"
|
||||
@click.native="toggleConnection"
|
||||
<div class="bg-primary flex p-4 top-0 z-10 sticky">
|
||||
<div class="space-x-2 flex-1 inline-flex">
|
||||
<div class="flex flex-1">
|
||||
<label for="client-version">
|
||||
<tippy
|
||||
ref="versionOptions"
|
||||
interactive
|
||||
trigger="click"
|
||||
theme="popover"
|
||||
arrow
|
||||
>
|
||||
<template #trigger>
|
||||
<span class="select-wrapper">
|
||||
<input
|
||||
id="client-version"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
title="socket.io-client version"
|
||||
class="bg-primaryLight border border-divider rounded-l cursor-pointer flex font-semibold text-secondaryDark py-2 px-4 w-26 hover:border-dividerDark focus-visible:bg-transparent focus-visible:border-dividerDark"
|
||||
:value="`Client ${clientVersion}`"
|
||||
readonly
|
||||
:disabled="connectionState"
|
||||
/>
|
||||
</span>
|
||||
</template>
|
||||
<SmartItem
|
||||
v-for="(_, version) in socketIoClients"
|
||||
:key="`client-${version}`"
|
||||
:label="`Client ${version}`"
|
||||
@click.native="onSelectVersion(version)"
|
||||
/>
|
||||
</tippy>
|
||||
</label>
|
||||
<input
|
||||
id="socketio-url"
|
||||
v-model="url"
|
||||
type="url"
|
||||
autocomplete="off"
|
||||
spellcheck="false"
|
||||
:class="{ error: !urlValid }"
|
||||
class="bg-primaryLight border border-divider flex flex-1 text-secondaryDark w-full py-2 px-4 hover:border-dividerDark focus-visible:bg-transparent focus-visible:border-dividerDark"
|
||||
:placeholder="$t('socketio.url')"
|
||||
:disabled="connectionState"
|
||||
@keyup.enter="urlValid ? toggleConnection() : null"
|
||||
/>
|
||||
<input
|
||||
id="socketio-path"
|
||||
v-model="path"
|
||||
class="bg-primaryLight border border-divider rounded-r flex flex-1 text-secondaryDark w-full py-2 px-4 hover:border-dividerDark focus-visible:bg-transparent focus-visible:border-dividerDark"
|
||||
spellcheck="false"
|
||||
:disabled="connectionState"
|
||||
@keyup.enter="urlValid ? toggleConnection() : null"
|
||||
/>
|
||||
</div>
|
||||
<ButtonPrimary
|
||||
id="connect"
|
||||
:disabled="!urlValid"
|
||||
name="connect"
|
||||
class="w-32"
|
||||
:label="
|
||||
!connectionState
|
||||
? $t('action.connect')
|
||||
: $t('action.disconnect')
|
||||
"
|
||||
:loading="connectingState"
|
||||
@click.native="toggleConnection"
|
||||
/>
|
||||
</div>
|
||||
</AppSection>
|
||||
</div>
|
||||
</Pane>
|
||||
<Pane
|
||||
:size="COLUMN_LAYOUT ? 65 : 50"
|
||||
class="hide-scrollbar !overflow-auto"
|
||||
>
|
||||
<AppSection label="response">
|
||||
<RealtimeLog :title="$t('socketio.log')" :log="log" />
|
||||
</AppSection>
|
||||
<RealtimeLog :title="$t('socketio.log')" :log="log" />
|
||||
</Pane>
|
||||
</Splitpanes>
|
||||
</Pane>
|
||||
@@ -100,74 +96,72 @@
|
||||
min-size="20"
|
||||
class="hide-scrollbar !overflow-auto"
|
||||
>
|
||||
<AppSection label="messages">
|
||||
<div class="flex flex-col flex-1 p-4 inline-flex">
|
||||
<label for="events" class="font-semibold text-secondaryLight">
|
||||
{{ $t("socketio.events") }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="flex px-4">
|
||||
<input
|
||||
id="event_name"
|
||||
v-model="communication.eventName"
|
||||
class="input"
|
||||
name="event_name"
|
||||
:placeholder="$t('socketio.event_name')"
|
||||
type="text"
|
||||
autocomplete="off"
|
||||
:disabled="!connectionState"
|
||||
<div class="flex flex-col flex-1 p-4 inline-flex">
|
||||
<label for="events" class="font-semibold text-secondaryLight">
|
||||
{{ $t("socketio.events") }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="flex px-4">
|
||||
<input
|
||||
id="event_name"
|
||||
v-model="communication.eventName"
|
||||
class="input"
|
||||
name="event_name"
|
||||
:placeholder="$t('socketio.event_name')"
|
||||
type="text"
|
||||
autocomplete="off"
|
||||
:disabled="!connectionState"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-1 p-4 items-center justify-between">
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ $t("socketio.communication") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('add.new')"
|
||||
svg="plus"
|
||||
@click.native="addCommunicationInput"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-1 p-4 items-center justify-between">
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ $t("socketio.communication") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
</div>
|
||||
<div class="flex flex-col space-y-2 px-4 pb-4">
|
||||
<div
|
||||
v-for="(input, index) of communication.inputs"
|
||||
:key="`input-${index}`"
|
||||
>
|
||||
<div class="flex space-x-2">
|
||||
<input
|
||||
v-model="communication.inputs[index]"
|
||||
class="input"
|
||||
name="message"
|
||||
:placeholder="$t('count.message', { count: index + 1 })"
|
||||
type="text"
|
||||
autocomplete="off"
|
||||
:disabled="!connectionState"
|
||||
@keyup.enter="connectionState ? sendMessage() : null"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-if="index + 1 !== communication.inputs.length"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('add.new')"
|
||||
svg="plus"
|
||||
@click.native="addCommunicationInput"
|
||||
:title="$t('action.remove')"
|
||||
svg="trash"
|
||||
color="red"
|
||||
outline
|
||||
@click.native="removeCommunicationInput({ index })"
|
||||
/>
|
||||
<ButtonPrimary
|
||||
v-if="index + 1 === communication.inputs.length"
|
||||
id="send"
|
||||
name="send"
|
||||
:disabled="!connectionState"
|
||||
:label="$t('action.send')"
|
||||
@click.native="sendMessage"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col space-y-2 px-4 pb-4">
|
||||
<div
|
||||
v-for="(input, index) of communication.inputs"
|
||||
:key="`input-${index}`"
|
||||
>
|
||||
<div class="flex space-x-2">
|
||||
<input
|
||||
v-model="communication.inputs[index]"
|
||||
class="input"
|
||||
name="message"
|
||||
:placeholder="$t('count.message', { count: index + 1 })"
|
||||
type="text"
|
||||
autocomplete="off"
|
||||
:disabled="!connectionState"
|
||||
@keyup.enter="connectionState ? sendMessage() : null"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-if="index + 1 !== communication.inputs.length"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.remove')"
|
||||
svg="trash"
|
||||
color="red"
|
||||
outline
|
||||
@click.native="removeCommunicationInput({ index })"
|
||||
/>
|
||||
<ButtonPrimary
|
||||
v-if="index + 1 === communication.inputs.length"
|
||||
id="send"
|
||||
name="send"
|
||||
:disabled="!connectionState"
|
||||
:label="$t('action.send')"
|
||||
@click.native="sendMessage"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</AppSection>
|
||||
</div>
|
||||
</Pane>
|
||||
</Splitpanes>
|
||||
</template>
|
||||
|
||||
@@ -45,14 +45,7 @@
|
||||
</div>
|
||||
</Pane>
|
||||
<Pane :size="COLUMN_LAYOUT ? 65 : 50" class="hide-scrollbar !overflow-auto">
|
||||
<AppSection label="response">
|
||||
<ul>
|
||||
<li>
|
||||
<RealtimeLog :title="$t('sse.log')" :log="log" />
|
||||
<div id="result"></div>
|
||||
</li>
|
||||
</ul>
|
||||
</AppSection>
|
||||
<RealtimeLog :title="$t('sse.log')" :log="log" />
|
||||
</Pane>
|
||||
</Splitpanes>
|
||||
</template>
|
||||
|
||||
@@ -13,135 +13,131 @@
|
||||
:size="COLUMN_LAYOUT ? 45 : 50"
|
||||
class="hide-scrollbar !overflow-auto"
|
||||
>
|
||||
<AppSection label="request">
|
||||
<div class="bg-primary flex p-4 top-0 z-10 sticky">
|
||||
<div class="space-x-2 flex-1 inline-flex">
|
||||
<input
|
||||
id="websocket-url"
|
||||
v-model="url"
|
||||
class="bg-primaryLight border border-divider rounded text-secondaryDark w-full py-2 px-4 hover:border-dividerDark focus-visible:bg-transparent focus-visible:border-dividerDark"
|
||||
type="url"
|
||||
autocomplete="off"
|
||||
spellcheck="false"
|
||||
:class="{ error: !urlValid }"
|
||||
:placeholder="$t('websocket.url')"
|
||||
:disabled="connectionState"
|
||||
@keyup.enter="urlValid ? toggleConnection() : null"
|
||||
/>
|
||||
<ButtonPrimary
|
||||
id="connect"
|
||||
:disabled="!urlValid"
|
||||
class="w-32"
|
||||
name="connect"
|
||||
:label="
|
||||
!connectionState
|
||||
? $t('action.connect')
|
||||
: $t('action.disconnect')
|
||||
"
|
||||
:loading="connectingState"
|
||||
@click.native="toggleConnection"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 top-upperPrimaryStickyFold pl-4 z-10 sticky items-center justify-between"
|
||||
>
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ $t("websocket.protocols") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.clear_all')"
|
||||
svg="trash-2"
|
||||
@click.native="clearContent"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('add.new')"
|
||||
svg="plus"
|
||||
@click.native="addProtocol"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-for="(protocol, index) of protocols"
|
||||
:key="`protocol-${index}`"
|
||||
class="divide-dividerLight divide-x border-b border-dividerLight flex"
|
||||
>
|
||||
<div class="bg-primary flex p-4 top-0 z-10 sticky">
|
||||
<div class="space-x-2 flex-1 inline-flex">
|
||||
<input
|
||||
v-model="protocol.value"
|
||||
class="bg-transparent flex flex-1 py-2 px-4"
|
||||
:placeholder="$t('count.protocol', { count: index + 1 })"
|
||||
name="message"
|
||||
type="text"
|
||||
id="websocket-url"
|
||||
v-model="url"
|
||||
class="bg-primaryLight border border-divider rounded text-secondaryDark w-full py-2 px-4 hover:border-dividerDark focus-visible:bg-transparent focus-visible:border-dividerDark"
|
||||
type="url"
|
||||
autocomplete="off"
|
||||
@change="
|
||||
spellcheck="false"
|
||||
:class="{ error: !urlValid }"
|
||||
:placeholder="$t('websocket.url')"
|
||||
:disabled="connectionState"
|
||||
@keyup.enter="urlValid ? toggleConnection() : null"
|
||||
/>
|
||||
<ButtonPrimary
|
||||
id="connect"
|
||||
:disabled="!urlValid"
|
||||
class="w-32"
|
||||
name="connect"
|
||||
:label="
|
||||
!connectionState
|
||||
? $t('action.connect')
|
||||
: $t('action.disconnect')
|
||||
"
|
||||
:loading="connectingState"
|
||||
@click.native="toggleConnection"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 top-upperPrimaryStickyFold pl-4 z-10 sticky items-center justify-between"
|
||||
>
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ $t("websocket.protocols") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.clear_all')"
|
||||
svg="trash-2"
|
||||
@click.native="clearContent"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('add.new')"
|
||||
svg="plus"
|
||||
@click.native="addProtocol"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-for="(protocol, index) of protocols"
|
||||
:key="`protocol-${index}`"
|
||||
class="divide-dividerLight divide-x border-b border-dividerLight flex"
|
||||
>
|
||||
<input
|
||||
v-model="protocol.value"
|
||||
class="bg-transparent flex flex-1 py-2 px-4"
|
||||
:placeholder="$t('count.protocol', { count: index + 1 })"
|
||||
name="message"
|
||||
type="text"
|
||||
autocomplete="off"
|
||||
@change="
|
||||
updateProtocol(index, {
|
||||
value: $event.target.value,
|
||||
active: protocol.active,
|
||||
})
|
||||
"
|
||||
/>
|
||||
<span>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="
|
||||
protocol.hasOwnProperty('active')
|
||||
? protocol.active
|
||||
? $t('action.turn_off')
|
||||
: $t('action.turn_on')
|
||||
: $t('action.turn_off')
|
||||
"
|
||||
:svg="
|
||||
protocol.hasOwnProperty('active')
|
||||
? protocol.active
|
||||
? 'check-circle'
|
||||
: 'circle'
|
||||
: 'check-circle'
|
||||
"
|
||||
color="green"
|
||||
@click.native="
|
||||
updateProtocol(index, {
|
||||
value: $event.target.value,
|
||||
active: protocol.active,
|
||||
value: protocol.value,
|
||||
active: !protocol.active,
|
||||
})
|
||||
"
|
||||
/>
|
||||
<span>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="
|
||||
protocol.hasOwnProperty('active')
|
||||
? protocol.active
|
||||
? $t('action.turn_off')
|
||||
: $t('action.turn_on')
|
||||
: $t('action.turn_off')
|
||||
"
|
||||
:svg="
|
||||
protocol.hasOwnProperty('active')
|
||||
? protocol.active
|
||||
? 'check-circle'
|
||||
: 'circle'
|
||||
: 'check-circle'
|
||||
"
|
||||
color="green"
|
||||
@click.native="
|
||||
updateProtocol(index, {
|
||||
value: protocol.value,
|
||||
active: !protocol.active,
|
||||
})
|
||||
"
|
||||
/>
|
||||
</span>
|
||||
<span>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.remove')"
|
||||
svg="trash"
|
||||
color="red"
|
||||
@click.native="deleteProtocol({ index })"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="protocols.length === 0"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/add_category.svg`"
|
||||
loading="lazy"
|
||||
class="flex-col object-contain object-center h-16 my-4 w-16 inline-flex"
|
||||
:alt="$t('empty.protocols')"
|
||||
</span>
|
||||
<span>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.remove')"
|
||||
svg="trash"
|
||||
color="red"
|
||||
@click.native="deleteProtocol({ index })"
|
||||
/>
|
||||
<span class="text-center mb-4">
|
||||
{{ $t("empty.protocols") }}
|
||||
</span>
|
||||
</div>
|
||||
</AppSection>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="protocols.length === 0"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/add_category.svg`"
|
||||
loading="lazy"
|
||||
class="flex-col object-contain object-center h-16 my-4 w-16 inline-flex"
|
||||
:alt="$t('empty.protocols')"
|
||||
/>
|
||||
<span class="text-center mb-4">
|
||||
{{ $t("empty.protocols") }}
|
||||
</span>
|
||||
</div>
|
||||
</Pane>
|
||||
<Pane
|
||||
:size="COLUMN_LAYOUT ? 65 : 50"
|
||||
class="hide-scrollbar !overflow-auto"
|
||||
>
|
||||
<AppSection label="response">
|
||||
<RealtimeLog :title="$t('websocket.log')" :log="log" />
|
||||
</AppSection>
|
||||
<RealtimeLog :title="$t('websocket.log')" :log="log" />
|
||||
</Pane>
|
||||
</Splitpanes>
|
||||
</Pane>
|
||||
@@ -151,38 +147,36 @@
|
||||
min-size="20"
|
||||
class="hide-scrollbar !overflow-auto"
|
||||
>
|
||||
<AppSection label="messages">
|
||||
<div class="flex flex-col flex-1 p-4 inline-flex">
|
||||
<label
|
||||
for="websocket-message"
|
||||
class="font-semibold text-secondaryLight"
|
||||
>
|
||||
{{ $t("websocket.communication") }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="flex space-x-2 px-4">
|
||||
<input
|
||||
id="websocket-message"
|
||||
v-model="communication.input"
|
||||
name="message"
|
||||
type="text"
|
||||
autocomplete="off"
|
||||
:disabled="!connectionState"
|
||||
:placeholder="$t('websocket.message')"
|
||||
class="input"
|
||||
@keyup.enter="connectionState ? sendMessage() : null"
|
||||
@keyup.up="connectionState ? walkHistory('up') : null"
|
||||
@keyup.down="connectionState ? walkHistory('down') : null"
|
||||
/>
|
||||
<ButtonPrimary
|
||||
id="send"
|
||||
name="send"
|
||||
:disabled="!connectionState"
|
||||
:label="$t('action.send')"
|
||||
@click.native="sendMessage"
|
||||
/>
|
||||
</div>
|
||||
</AppSection>
|
||||
<div class="flex flex-col flex-1 p-4 inline-flex">
|
||||
<label
|
||||
for="websocket-message"
|
||||
class="font-semibold text-secondaryLight"
|
||||
>
|
||||
{{ $t("websocket.communication") }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="flex space-x-2 px-4">
|
||||
<input
|
||||
id="websocket-message"
|
||||
v-model="communication.input"
|
||||
name="message"
|
||||
type="text"
|
||||
autocomplete="off"
|
||||
:disabled="!connectionState"
|
||||
:placeholder="$t('websocket.message')"
|
||||
class="input"
|
||||
@keyup.enter="connectionState ? sendMessage() : null"
|
||||
@keyup.up="connectionState ? walkHistory('up') : null"
|
||||
@keyup.down="connectionState ? walkHistory('down') : null"
|
||||
/>
|
||||
<ButtonPrimary
|
||||
id="send"
|
||||
name="send"
|
||||
:disabled="!connectionState"
|
||||
:label="$t('action.send')"
|
||||
@click.native="sendMessage"
|
||||
/>
|
||||
</div>
|
||||
</Pane>
|
||||
</Splitpanes>
|
||||
</template>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<AppSection label="teams">
|
||||
<div>
|
||||
<div class="space-y-4 p-4">
|
||||
<ButtonSecondary
|
||||
:label="`${t('team.create_new')}`"
|
||||
@@ -88,7 +88,7 @@
|
||||
:editing-team-i-d="editingTeamID"
|
||||
@hide-modal="displayModalInvite(false)"
|
||||
/>
|
||||
</AppSection>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
@@ -31,6 +31,7 @@ import { lintKeymap } from "@codemirror/lint"
|
||||
export const baseTheme = EditorView.theme({
|
||||
"&": {
|
||||
fontSize: "var(--font-size-body)",
|
||||
height: "100%",
|
||||
},
|
||||
".cm-content": {
|
||||
caretColor: "var(--secondary-light-color)",
|
||||
|
||||
@@ -13,111 +13,107 @@
|
||||
:size="COLUMN_LAYOUT ? 45 : 50"
|
||||
class="hide-scrollbar !overflow-auto"
|
||||
>
|
||||
<AppSection label="import">
|
||||
<div class="flex p-4 items-start justify-between">
|
||||
<label>
|
||||
{{ $t("documentation.generate_message") }}
|
||||
</label>
|
||||
<span
|
||||
class="bg-accentDark rounded text-accentContrast py-1 px-2 inline-flex"
|
||||
>
|
||||
BETA
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="bg-primary border-b border-dividerLight flex top-0 z-10 sticky items-start justify-between"
|
||||
<div class="flex p-4 items-start justify-between">
|
||||
<label>
|
||||
{{ $t("documentation.generate_message") }}
|
||||
</label>
|
||||
<span
|
||||
class="bg-accentDark rounded text-accentContrast py-1 px-2 inline-flex"
|
||||
>
|
||||
<label for="collectionUpload">
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
title="JSON"
|
||||
svg="folder"
|
||||
class="!rounded-none"
|
||||
:label="$t('import.collections')"
|
||||
@click.native="$refs.collectionUpload.click()"
|
||||
/>
|
||||
</label>
|
||||
<input
|
||||
ref="collectionUpload"
|
||||
class="input"
|
||||
name="collectionUpload"
|
||||
type="file"
|
||||
@change="uploadCollection"
|
||||
/>
|
||||
BETA
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="bg-primary border-b border-dividerLight flex top-0 z-10 sticky items-start justify-between"
|
||||
>
|
||||
<label for="collectionUpload">
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.clear')"
|
||||
svg="trash-2"
|
||||
@click.native="collectionJSON = '[]'"
|
||||
title="JSON"
|
||||
svg="folder"
|
||||
class="!rounded-none"
|
||||
:label="$t('import.collections')"
|
||||
@click.native="$refs.collectionUpload.click()"
|
||||
/>
|
||||
</div>
|
||||
<textarea-autosize
|
||||
id="import-curl"
|
||||
v-model="collectionJSON"
|
||||
class="bg-primary font-mono p-4"
|
||||
autofocus
|
||||
rows="8"
|
||||
</label>
|
||||
<input
|
||||
ref="collectionUpload"
|
||||
class="input"
|
||||
name="collectionUpload"
|
||||
type="file"
|
||||
@change="uploadCollection"
|
||||
/>
|
||||
<div
|
||||
class="bg-primary border-t border-b border-dividerLight flex p-4 bottom-0 z-10 sticky items-start justify-between"
|
||||
>
|
||||
<ButtonPrimary
|
||||
:label="$t('documentation.generate')"
|
||||
@click.native="getDoc"
|
||||
/>
|
||||
</div>
|
||||
</AppSection>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.clear')"
|
||||
svg="trash-2"
|
||||
@click.native="collectionJSON = '[]'"
|
||||
/>
|
||||
</div>
|
||||
<textarea-autosize
|
||||
id="import-curl"
|
||||
v-model="collectionJSON"
|
||||
class="bg-primary font-mono p-4"
|
||||
autofocus
|
||||
rows="8"
|
||||
/>
|
||||
<div
|
||||
class="bg-primary border-t border-b border-dividerLight flex p-4 bottom-0 z-10 sticky items-start justify-between"
|
||||
>
|
||||
<ButtonPrimary
|
||||
:label="$t('documentation.generate')"
|
||||
@click.native="getDoc"
|
||||
/>
|
||||
</div>
|
||||
</Pane>
|
||||
<Pane
|
||||
:size="COLUMN_LAYOUT ? 65 : 50"
|
||||
class="hide-scrollbar !overflow-auto"
|
||||
>
|
||||
<AppSection label="documentation">
|
||||
<div class="flex flex-col">
|
||||
<div
|
||||
v-if="items.length === 0"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<i class="opacity-75 pb-2 material-icons">topic</i>
|
||||
<span class="text-center">
|
||||
{{ $t("helpers.generate_documentation_first") }}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 p-4 top-0 z-10 sticky"
|
||||
>
|
||||
<span
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="
|
||||
!currentUser
|
||||
? $t('export.require_github')
|
||||
: currentUser.provider !== 'github.com'
|
||||
? $t('export.require_github')
|
||||
: 'Beta'
|
||||
"
|
||||
>
|
||||
<ButtonPrimary
|
||||
:disabled="
|
||||
!currentUser
|
||||
? true
|
||||
: currentUser.provider !== 'github.com'
|
||||
? true
|
||||
: false
|
||||
"
|
||||
:label="$t('export.create_secret_gist')"
|
||||
@click.native="createDocsGist"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
v-for="(collection, index) in items"
|
||||
:key="`collection-${index}`"
|
||||
>
|
||||
<DocsCollection :collection="collection" />
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<div
|
||||
v-if="items.length === 0"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<i class="opacity-75 pb-2 material-icons">topic</i>
|
||||
<span class="text-center">
|
||||
{{ $t("helpers.generate_documentation_first") }}
|
||||
</span>
|
||||
</div>
|
||||
</AppSection>
|
||||
<div
|
||||
v-else
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 p-4 top-0 z-10 sticky"
|
||||
>
|
||||
<span
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="
|
||||
!currentUser
|
||||
? $t('export.require_github')
|
||||
: currentUser.provider !== 'github.com'
|
||||
? $t('export.require_github')
|
||||
: 'Beta'
|
||||
"
|
||||
>
|
||||
<ButtonPrimary
|
||||
:disabled="
|
||||
!currentUser
|
||||
? true
|
||||
: currentUser.provider !== 'github.com'
|
||||
? true
|
||||
: false
|
||||
"
|
||||
:label="$t('export.create_secret_gist')"
|
||||
@click.native="createDocsGist"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
v-for="(collection, index) in items"
|
||||
:key="`collection-${index}`"
|
||||
>
|
||||
<DocsCollection :collection="collection" />
|
||||
</div>
|
||||
</div>
|
||||
</Pane>
|
||||
</Splitpanes>
|
||||
</Pane>
|
||||
|
||||
@@ -173,9 +173,7 @@
|
||||
</section>
|
||||
</SmartTab>
|
||||
<SmartTab :id="'teams'" :label="t('team.title')">
|
||||
<AppSection label="teams">
|
||||
<Teams :modal="false" />
|
||||
</AppSection>
|
||||
<Teams :modal="false" />
|
||||
</SmartTab>
|
||||
</SmartTabs>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user