refactor: use pane layout component in pages
This commit is contained in:
55
packages/hoppscotch-app/components/app/PaneLayout.vue
Normal file
55
packages/hoppscotch-app/components/app/PaneLayout.vue
Normal file
@@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<Splitpanes
|
||||
class="smart-splitter"
|
||||
:rtl="SIDEBAR_ON_LEFT && mdAndLarger"
|
||||
:class="{
|
||||
'!flex-row-reverse': SIDEBAR_ON_LEFT && mdAndLarger,
|
||||
}"
|
||||
:horizontal="!mdAndLarger"
|
||||
>
|
||||
<Pane
|
||||
size="75"
|
||||
min-size="65"
|
||||
class="hide-scrollbar !overflow-auto flex flex-col"
|
||||
>
|
||||
<Splitpanes class="smart-splitter" :horizontal="COLUMN_LAYOUT">
|
||||
<Pane
|
||||
:size="COLUMN_LAYOUT ? 45 : 50"
|
||||
class="hide-scrollbar !overflow-auto flex flex-col"
|
||||
>
|
||||
<slot name="primary" />
|
||||
</Pane>
|
||||
<Pane
|
||||
:size="COLUMN_LAYOUT ? 65 : 50"
|
||||
class="flex flex-col hide-scrollbar !overflow-auto"
|
||||
>
|
||||
<slot name="secondary" />
|
||||
</Pane>
|
||||
</Splitpanes>
|
||||
</Pane>
|
||||
<Pane
|
||||
v-if="SIDEBAR"
|
||||
size="25"
|
||||
min-size="20"
|
||||
class="hide-scrollbar !overflow-auto flex flex-col"
|
||||
>
|
||||
<slot name="sidebar" />
|
||||
</Pane>
|
||||
</Splitpanes>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Splitpanes, Pane } from "splitpanes"
|
||||
import "splitpanes/dist/splitpanes.css"
|
||||
import { breakpointsTailwind, useBreakpoints } from "@vueuse/core"
|
||||
import { useSetting } from "~/newstore/settings"
|
||||
|
||||
const SIDEBAR_ON_LEFT = useSetting("SIDEBAR_ON_LEFT")
|
||||
|
||||
const breakpoints = useBreakpoints(breakpointsTailwind)
|
||||
const mdAndLarger = breakpoints.greater("md")
|
||||
|
||||
const COLUMN_LAYOUT = useSetting("COLUMN_LAYOUT")
|
||||
|
||||
const SIDEBAR = useSetting("SIDEBAR")
|
||||
</script>
|
||||
@@ -1,84 +1,56 @@
|
||||
<template>
|
||||
<Splitpanes
|
||||
class="smart-splitter"
|
||||
:rtl="SIDEBAR_ON_LEFT && mdAndLarger"
|
||||
:class="{
|
||||
'!flex-row-reverse': SIDEBAR_ON_LEFT && mdAndLarger,
|
||||
}"
|
||||
:horizontal="!mdAndLarger"
|
||||
>
|
||||
<Pane
|
||||
size="75"
|
||||
min-size="65"
|
||||
class="hide-scrollbar !overflow-auto flex flex-col"
|
||||
>
|
||||
<Splitpanes class="smart-splitter" :horizontal="COLUMN_LAYOUT">
|
||||
<Pane
|
||||
:size="COLUMN_LAYOUT ? 45 : 50"
|
||||
class="hide-scrollbar !overflow-auto flex flex-col"
|
||||
>
|
||||
<div
|
||||
class="sticky top-0 z-10 flex flex-shrink-0 p-4 overflow-x-auto space-x-2 bg-primary hide-scrollbar"
|
||||
>
|
||||
<div class="inline-flex flex-1 space-x-2">
|
||||
<input
|
||||
id="mqtt-url"
|
||||
v-model="url"
|
||||
type="url"
|
||||
autocomplete="off"
|
||||
spellcheck="false"
|
||||
class="w-full px-4 py-2 border rounded bg-primaryLight border-divider text-secondaryDark"
|
||||
: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>
|
||||
</Pane>
|
||||
<Pane
|
||||
:size="COLUMN_LAYOUT ? 65 : 50"
|
||||
class="hide-scrollbar !overflow-auto flex flex-col"
|
||||
>
|
||||
<RealtimeLog :title="$t('mqtt.log')" :log="log" />
|
||||
</Pane>
|
||||
</Splitpanes>
|
||||
</Pane>
|
||||
<Pane
|
||||
v-if="SIDEBAR"
|
||||
size="25"
|
||||
min-size="20"
|
||||
class="hide-scrollbar !overflow-auto flex flex-col"
|
||||
>
|
||||
<AppPaneLayout>
|
||||
<template #primary>
|
||||
<div
|
||||
class="sticky top-0 z-10 flex flex-shrink-0 p-4 overflow-x-auto space-x-2 bg-primary hide-scrollbar"
|
||||
>
|
||||
<div class="inline-flex flex-1 space-x-2">
|
||||
<input
|
||||
id="mqtt-url"
|
||||
v-model="url"
|
||||
type="url"
|
||||
autocomplete="off"
|
||||
spellcheck="false"
|
||||
class="w-full px-4 py-2 border rounded bg-primaryLight border-divider text-secondaryDark"
|
||||
: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>
|
||||
</template>
|
||||
<template #secondary>
|
||||
<RealtimeLog :title="$t('mqtt.log')" :log="log" />
|
||||
</template>
|
||||
<template #sidebar>
|
||||
<div class="flex items-center justify-between p-4">
|
||||
<label for="pub_topic" class="font-semibold text-secondaryLight">
|
||||
{{ $t("mqtt.topic") }}
|
||||
@@ -146,19 +118,15 @@
|
||||
@click.native="toggleSubscription"
|
||||
/>
|
||||
</div>
|
||||
</Pane>
|
||||
</Splitpanes>
|
||||
</template>
|
||||
</AppPaneLayout>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from "@nuxtjs/composition-api"
|
||||
import { Splitpanes, Pane } from "splitpanes"
|
||||
import "splitpanes/dist/splitpanes.css"
|
||||
import Paho from "paho-mqtt"
|
||||
import debounce from "lodash/debounce"
|
||||
import { breakpointsTailwind, useBreakpoints } from "@vueuse/core"
|
||||
import { logHoppRequestRunToAnalytics } from "~/helpers/fb/analytics"
|
||||
import { useSetting } from "~/newstore/settings"
|
||||
import {
|
||||
MQTTEndpoint$,
|
||||
setMQTTEndpoint,
|
||||
@@ -177,16 +145,8 @@ import {
|
||||
import { useStream } from "~/helpers/utils/composables"
|
||||
|
||||
export default defineComponent({
|
||||
components: { Splitpanes, Pane },
|
||||
setup() {
|
||||
const breakpoints = useBreakpoints(breakpointsTailwind)
|
||||
const mdAndLarger = breakpoints.greater("md")
|
||||
|
||||
return {
|
||||
mdAndLarger,
|
||||
SIDEBAR: useSetting("SIDEBAR"),
|
||||
COLUMN_LAYOUT: useSetting("COLUMN_LAYOUT"),
|
||||
SIDEBAR_ON_LEFT: useSetting("SIDEBAR_ON_LEFT"),
|
||||
url: useStream(MQTTEndpoint$, "", setMQTTEndpoint),
|
||||
connectionState: useStream(
|
||||
MQTTConnectionState$,
|
||||
|
||||
@@ -1,103 +1,14 @@
|
||||
<template>
|
||||
<Splitpanes
|
||||
class="smart-splitter"
|
||||
:rtl="SIDEBAR_ON_LEFT && mdAndLarger"
|
||||
:class="{
|
||||
'!flex-row-reverse': SIDEBAR_ON_LEFT && mdAndLarger,
|
||||
}"
|
||||
:horizontal="!mdAndLarger"
|
||||
>
|
||||
<Pane
|
||||
size="75"
|
||||
min-size="65"
|
||||
class="hide-scrollbar !overflow-auto flex flex-col"
|
||||
>
|
||||
<Splitpanes class="smart-splitter" :horizontal="COLUMN_LAYOUT">
|
||||
<Pane
|
||||
:size="COLUMN_LAYOUT ? 45 : 50"
|
||||
class="hide-scrollbar !overflow-auto flex flex-col"
|
||||
>
|
||||
<div
|
||||
class="sticky top-0 z-10 flex flex-shrink-0 p-4 overflow-x-auto space-x-2 bg-primary hide-scrollbar"
|
||||
>
|
||||
<div class="inline-flex flex-1 space-x-2">
|
||||
<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="flex px-4 py-2 font-semibold border rounded-l cursor-pointer bg-primaryLight border-divider text-secondaryDark w-26"
|
||||
:value="`Client ${clientVersion}`"
|
||||
readonly
|
||||
:disabled="connectionState"
|
||||
/>
|
||||
</span>
|
||||
</template>
|
||||
<div class="flex flex-col" role="menu">
|
||||
<SmartItem
|
||||
v-for="(_, version) in socketIoClients"
|
||||
:key="`client-${version}`"
|
||||
:label="`Client ${version}`"
|
||||
@click.native="onSelectVersion(version)"
|
||||
/>
|
||||
</div>
|
||||
</tippy>
|
||||
</label>
|
||||
<input
|
||||
id="socketio-url"
|
||||
v-model="url"
|
||||
type="url"
|
||||
autocomplete="off"
|
||||
spellcheck="false"
|
||||
:class="{ error: !urlValid }"
|
||||
class="flex flex-1 w-full px-4 py-2 border bg-primaryLight border-divider text-secondaryDark"
|
||||
:placeholder="$t('socketio.url')"
|
||||
:disabled="connectionState"
|
||||
@keyup.enter="urlValid ? toggleConnection() : null"
|
||||
/>
|
||||
<input
|
||||
id="socketio-path"
|
||||
v-model="path"
|
||||
class="flex flex-1 w-full px-4 py-2 border rounded-r bg-primaryLight border-divider text-secondaryDark"
|
||||
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>
|
||||
</div>
|
||||
<div
|
||||
class="sticky z-10 flex items-center justify-between pl-4 border-b bg-primary border-dividerLight top-upperPrimaryStickyFold"
|
||||
>
|
||||
<span class="flex items-center">
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ $t("authorization.type") }}
|
||||
</label>
|
||||
<AppPaneLayout>
|
||||
<template #primary>
|
||||
<div
|
||||
class="sticky top-0 z-10 flex flex-shrink-0 p-4 overflow-x-auto space-x-2 bg-primary hide-scrollbar"
|
||||
>
|
||||
<div class="inline-flex flex-1 space-x-2">
|
||||
<div class="flex flex-1">
|
||||
<label for="client-version">
|
||||
<tippy
|
||||
ref="authTypeOptions"
|
||||
ref="versionOptions"
|
||||
interactive
|
||||
trigger="click"
|
||||
theme="popover"
|
||||
@@ -105,132 +16,193 @@
|
||||
>
|
||||
<template #trigger>
|
||||
<span class="select-wrapper">
|
||||
<ButtonSecondary
|
||||
class="pr-8 ml-2 rounded-none"
|
||||
:label="authType"
|
||||
<input
|
||||
id="client-version"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
title="socket.io-client version"
|
||||
class="flex px-4 py-2 font-semibold border rounded-l cursor-pointer bg-primaryLight border-divider text-secondaryDark w-26"
|
||||
:value="`Client ${clientVersion}`"
|
||||
readonly
|
||||
:disabled="connectionState"
|
||||
/>
|
||||
</span>
|
||||
</template>
|
||||
<div class="flex flex-col" role="menu">
|
||||
<SmartItem
|
||||
label="None"
|
||||
:icon="
|
||||
authType === 'None'
|
||||
? 'radio_button_checked'
|
||||
: 'radio_button_unchecked'
|
||||
"
|
||||
:active="authType === 'None'"
|
||||
@click.native="
|
||||
() => {
|
||||
authType = 'None'
|
||||
authTypeOptions.tippy().hide()
|
||||
}
|
||||
"
|
||||
/>
|
||||
<SmartItem
|
||||
label="Bearer Token"
|
||||
:icon="
|
||||
authType === 'Bearer'
|
||||
? 'radio_button_checked'
|
||||
: 'radio_button_unchecked'
|
||||
"
|
||||
:active="authType === 'Bearer'"
|
||||
@click.native="
|
||||
() => {
|
||||
authType = 'Bearer'
|
||||
authTypeOptions.tippy().hide()
|
||||
}
|
||||
"
|
||||
v-for="(_, version) in socketIoClients"
|
||||
:key="`client-${version}`"
|
||||
:label="`Client ${version}`"
|
||||
@click.native="onSelectVersion(version)"
|
||||
/>
|
||||
</div>
|
||||
</tippy>
|
||||
</span>
|
||||
<div class="flex">
|
||||
<SmartCheckbox
|
||||
:on="authActive"
|
||||
class="px-2"
|
||||
@change="authActive = !authActive"
|
||||
>
|
||||
{{ $t("state.enabled") }}
|
||||
</SmartCheckbox>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
to="https://docs.hoppscotch.io/features/authorization"
|
||||
blank
|
||||
:title="$t('app.wiki')"
|
||||
svg="help-circle"
|
||||
</label>
|
||||
<input
|
||||
id="socketio-url"
|
||||
v-model="url"
|
||||
type="url"
|
||||
autocomplete="off"
|
||||
spellcheck="false"
|
||||
:class="{ error: !urlValid }"
|
||||
class="flex flex-1 w-full px-4 py-2 border bg-primaryLight border-divider text-secondaryDark"
|
||||
:placeholder="$t('socketio.url')"
|
||||
:disabled="connectionState"
|
||||
@keyup.enter="urlValid ? toggleConnection() : null"
|
||||
/>
|
||||
<input
|
||||
id="socketio-path"
|
||||
v-model="path"
|
||||
class="flex flex-1 w-full px-4 py-2 border rounded-r bg-primaryLight border-divider text-secondaryDark"
|
||||
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>
|
||||
</div>
|
||||
<div
|
||||
class="sticky z-10 flex items-center justify-between pl-4 border-b bg-primary border-dividerLight top-upperPrimaryStickyFold"
|
||||
>
|
||||
<span class="flex items-center">
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ $t("authorization.type") }}
|
||||
</label>
|
||||
<tippy
|
||||
ref="authTypeOptions"
|
||||
interactive
|
||||
trigger="click"
|
||||
theme="popover"
|
||||
arrow
|
||||
>
|
||||
<template #trigger>
|
||||
<span class="select-wrapper">
|
||||
<ButtonSecondary
|
||||
class="pr-8 ml-2 rounded-none"
|
||||
:label="authType"
|
||||
/>
|
||||
</span>
|
||||
</template>
|
||||
<div class="flex flex-col" role="menu">
|
||||
<SmartItem
|
||||
label="None"
|
||||
:icon="
|
||||
authType === 'None'
|
||||
? 'radio_button_checked'
|
||||
: 'radio_button_unchecked'
|
||||
"
|
||||
:active="authType === 'None'"
|
||||
@click.native="
|
||||
() => {
|
||||
authType = 'None'
|
||||
authTypeOptions.tippy().hide()
|
||||
}
|
||||
"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.clear')"
|
||||
svg="trash-2"
|
||||
@click.native="clearContent"
|
||||
<SmartItem
|
||||
label="Bearer Token"
|
||||
:icon="
|
||||
authType === 'Bearer'
|
||||
? 'radio_button_checked'
|
||||
: 'radio_button_unchecked'
|
||||
"
|
||||
:active="authType === 'Bearer'"
|
||||
@click.native="
|
||||
() => {
|
||||
authType = 'Bearer'
|
||||
authTypeOptions.tippy().hide()
|
||||
}
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="authType === 'None'"
|
||||
class="flex flex-col items-center justify-center p-4 text-secondaryLight"
|
||||
</tippy>
|
||||
</span>
|
||||
<div class="flex">
|
||||
<SmartCheckbox
|
||||
:on="authActive"
|
||||
class="px-2"
|
||||
@change="authActive = !authActive"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/login.svg`"
|
||||
loading="lazy"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
||||
:alt="$t('empty.authorization')"
|
||||
/>
|
||||
<span class="pb-4 text-center">
|
||||
This SocketIO connection does not use any authentication.
|
||||
</span>
|
||||
<ButtonSecondary
|
||||
outline
|
||||
:label="$t('app.documentation')"
|
||||
{{ $t("state.enabled") }}
|
||||
</SmartCheckbox>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
to="https://docs.hoppscotch.io/features/authorization"
|
||||
blank
|
||||
:title="$t('app.wiki')"
|
||||
svg="help-circle"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.clear')"
|
||||
svg="trash-2"
|
||||
@click.native="clearContent"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="authType === 'None'"
|
||||
class="flex flex-col items-center justify-center p-4 text-secondaryLight"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/login.svg`"
|
||||
loading="lazy"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
||||
:alt="$t('empty.authorization')"
|
||||
/>
|
||||
<span class="pb-4 text-center">
|
||||
This SocketIO connection does not use any authentication.
|
||||
</span>
|
||||
<ButtonSecondary
|
||||
outline
|
||||
:label="$t('app.documentation')"
|
||||
to="https://docs.hoppscotch.io/features/authorization"
|
||||
blank
|
||||
svg="external-link"
|
||||
reverse
|
||||
class="mb-4"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-if="authType === 'Bearer'"
|
||||
class="flex flex-1 border-b border-dividerLight"
|
||||
>
|
||||
<div class="w-2/3 border-r border-dividerLight">
|
||||
<div class="flex flex-1 border-b border-dividerLight">
|
||||
<SmartEnvInput v-model="bearerToken" placeholder="Token" />
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="sticky h-full p-4 overflow-auto bg-primary top-upperTertiaryStickyFold min-w-46 max-w-1/3 z-9"
|
||||
>
|
||||
<div class="p-2">
|
||||
<div class="pb-2 text-secondaryLight">
|
||||
{{ $t("helpers.authorization") }}
|
||||
</div>
|
||||
<SmartAnchor
|
||||
class="link"
|
||||
:label="`${$t('authorization.learn')} \xA0 →`"
|
||||
to="https://docs.hoppscotch.io/features/authorization"
|
||||
blank
|
||||
svg="external-link"
|
||||
reverse
|
||||
class="mb-4"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-if="authType === 'Bearer'"
|
||||
class="flex flex-1 border-b border-dividerLight"
|
||||
>
|
||||
<div class="w-2/3 border-r border-dividerLight">
|
||||
<div class="flex flex-1 border-b border-dividerLight">
|
||||
<SmartEnvInput v-model="bearerToken" placeholder="Token" />
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="sticky h-full p-4 overflow-auto bg-primary top-upperTertiaryStickyFold min-w-46 max-w-1/3 z-9"
|
||||
>
|
||||
<div class="p-2">
|
||||
<div class="pb-2 text-secondaryLight">
|
||||
{{ $t("helpers.authorization") }}
|
||||
</div>
|
||||
<SmartAnchor
|
||||
class="link"
|
||||
:label="`${$t('authorization.learn')} \xA0 →`"
|
||||
to="https://docs.hoppscotch.io/features/authorization"
|
||||
blank
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Pane>
|
||||
<Pane
|
||||
:size="COLUMN_LAYOUT ? 65 : 50"
|
||||
class="hide-scrollbar !overflow-auto flex flex-col"
|
||||
>
|
||||
<RealtimeLog :title="$t('socketio.log')" :log="log" />
|
||||
</Pane>
|
||||
</Splitpanes>
|
||||
</Pane>
|
||||
<Pane
|
||||
v-if="SIDEBAR"
|
||||
size="25"
|
||||
min-size="20"
|
||||
class="hide-scrollbar !overflow-auto flex flex-col"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #secondary>
|
||||
<RealtimeLog :title="$t('socketio.log')" :log="log" />
|
||||
</template>
|
||||
<template #sidebar>
|
||||
<div class="flex items-center justify-between p-4">
|
||||
<label for="events" class="font-semibold text-secondaryLight">
|
||||
{{ $t("socketio.events") }}
|
||||
@@ -297,24 +269,19 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Pane>
|
||||
</Splitpanes>
|
||||
</template>
|
||||
</AppPaneLayout>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent, ref } from "@nuxtjs/composition-api"
|
||||
import { Splitpanes, Pane } from "splitpanes"
|
||||
import "splitpanes/dist/splitpanes.css"
|
||||
// All Socket.IO client version imports
|
||||
import ClientV2 from "socket.io-client-v2"
|
||||
import { io as ClientV3 } from "socket.io-client-v3"
|
||||
import { io as ClientV4 } from "socket.io-client-v4"
|
||||
|
||||
import wildcard from "socketio-wildcard"
|
||||
import debounce from "lodash/debounce"
|
||||
import { breakpointsTailwind, useBreakpoints } from "@vueuse/core"
|
||||
import { logHoppRequestRunToAnalytics } from "~/helpers/fb/analytics"
|
||||
import { useSetting } from "~/newstore/settings"
|
||||
import {
|
||||
SIOEndpoint$,
|
||||
setSIOEndpoint,
|
||||
@@ -341,16 +308,8 @@ const socketIoClients = {
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
components: { Splitpanes, Pane },
|
||||
setup() {
|
||||
const breakpoints = useBreakpoints(breakpointsTailwind)
|
||||
const mdAndLarger = breakpoints.greater("md")
|
||||
|
||||
return {
|
||||
mdAndLarger,
|
||||
SIDEBAR: useSetting("SIDEBAR"),
|
||||
COLUMN_LAYOUT: useSetting("COLUMN_LAYOUT"),
|
||||
SIDEBAR_ON_LEFT: useSetting("SIDEBAR_ON_LEFT"),
|
||||
socketIoClients,
|
||||
url: useStream(SIOEndpoint$, "", setSIOEndpoint),
|
||||
clientVersion: useStream(SIOVersion$, "", setSIOVersion),
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
<template>
|
||||
<Splitpanes class="smart-splitter" :horizontal="COLUMN_LAYOUT">
|
||||
<Pane
|
||||
:size="COLUMN_LAYOUT ? 45 : 50"
|
||||
class="hide-scrollbar !overflow-auto flex flex-col"
|
||||
>
|
||||
<AppPaneLayout>
|
||||
<template #primary>
|
||||
<div
|
||||
class="sticky top-0 z-10 flex flex-shrink-0 p-4 overflow-x-auto space-x-2 bg-primary hide-scrollbar"
|
||||
>
|
||||
@@ -48,23 +45,18 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Pane>
|
||||
<Pane
|
||||
:size="COLUMN_LAYOUT ? 65 : 50"
|
||||
class="hide-scrollbar !overflow-auto flex flex-col"
|
||||
>
|
||||
</template>
|
||||
<template #secondary>
|
||||
<RealtimeLog :title="$t('sse.log')" :log="log" />
|
||||
</Pane>
|
||||
</Splitpanes>
|
||||
</template>
|
||||
</AppPaneLayout>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from "@nuxtjs/composition-api"
|
||||
import { Splitpanes, Pane } from "splitpanes"
|
||||
import "splitpanes/dist/splitpanes.css"
|
||||
import debounce from "lodash/debounce"
|
||||
import { logHoppRequestRunToAnalytics } from "~/helpers/fb/analytics"
|
||||
import { useSetting } from "~/newstore/settings"
|
||||
import {
|
||||
SSEEndpoint$,
|
||||
setSSEEndpoint,
|
||||
@@ -83,10 +75,8 @@ import {
|
||||
import { useStream } from "~/helpers/utils/composables"
|
||||
|
||||
export default defineComponent({
|
||||
components: { Splitpanes, Pane },
|
||||
setup() {
|
||||
return {
|
||||
COLUMN_LAYOUT: useSetting("COLUMN_LAYOUT"),
|
||||
connectionSSEState: useStream(
|
||||
SSEConnectionState$,
|
||||
false,
|
||||
|
||||
@@ -1,158 +1,130 @@
|
||||
<template>
|
||||
<Splitpanes
|
||||
class="smart-splitter"
|
||||
:rtl="SIDEBAR_ON_LEFT && mdAndLarger"
|
||||
:class="{
|
||||
'!flex-row-reverse': SIDEBAR_ON_LEFT && mdAndLarger,
|
||||
}"
|
||||
:horizontal="!mdAndLarger"
|
||||
>
|
||||
<Pane
|
||||
size="75"
|
||||
min-size="65"
|
||||
class="hide-scrollbar !overflow-auto flex flex-col"
|
||||
>
|
||||
<Splitpanes class="smart-splitter" :horizontal="COLUMN_LAYOUT">
|
||||
<Pane
|
||||
:size="COLUMN_LAYOUT ? 45 : 50"
|
||||
class="hide-scrollbar !overflow-auto flex flex-col"
|
||||
>
|
||||
<div
|
||||
class="sticky top-0 z-10 flex flex-shrink-0 p-4 overflow-x-auto space-x-2 bg-primary hide-scrollbar"
|
||||
>
|
||||
<div class="inline-flex flex-1 space-x-2">
|
||||
<input
|
||||
id="websocket-url"
|
||||
v-model="url"
|
||||
class="w-full px-4 py-2 border rounded bg-primaryLight border-divider text-secondaryDark"
|
||||
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="sticky z-10 flex items-center justify-between pl-4 border-b bg-primary border-dividerLight top-upperPrimaryStickyFold"
|
||||
>
|
||||
<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="flex border-b divide-x divide-dividerLight border-dividerLight"
|
||||
>
|
||||
<input
|
||||
v-model="protocol.value"
|
||||
class="flex flex-1 px-4 py-2 bg-transparent"
|
||||
: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: 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 items-center justify-center p-4 text-secondaryLight"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/add_category.svg`"
|
||||
loading="lazy"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
||||
:alt="$t('empty.protocols')"
|
||||
/>
|
||||
<span class="mb-4 text-center">
|
||||
{{ $t("empty.protocols") }}
|
||||
</span>
|
||||
</div>
|
||||
</Pane>
|
||||
<Pane
|
||||
:size="COLUMN_LAYOUT ? 65 : 50"
|
||||
class="hide-scrollbar !overflow-auto flex flex-col"
|
||||
>
|
||||
<RealtimeLog :title="$t('websocket.log')" :log="log" />
|
||||
</Pane>
|
||||
</Splitpanes>
|
||||
</Pane>
|
||||
<Pane
|
||||
v-if="SIDEBAR"
|
||||
size="25"
|
||||
min-size="20"
|
||||
class="hide-scrollbar !overflow-auto flex flex-col"
|
||||
>
|
||||
<AppPaneLayout>
|
||||
<template #primary>
|
||||
<div
|
||||
class="sticky top-0 z-10 flex flex-shrink-0 p-4 overflow-x-auto space-x-2 bg-primary hide-scrollbar"
|
||||
>
|
||||
<div class="inline-flex flex-1 space-x-2">
|
||||
<input
|
||||
id="websocket-url"
|
||||
v-model="url"
|
||||
class="w-full px-4 py-2 border rounded bg-primaryLight border-divider text-secondaryDark"
|
||||
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="sticky z-10 flex items-center justify-between pl-4 border-b bg-primary border-dividerLight top-upperPrimaryStickyFold"
|
||||
>
|
||||
<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="flex border-b divide-x divide-dividerLight border-dividerLight"
|
||||
>
|
||||
<input
|
||||
v-model="protocol.value"
|
||||
class="flex flex-1 px-4 py-2 bg-transparent"
|
||||
: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: 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 items-center justify-center p-4 text-secondaryLight"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/add_category.svg`"
|
||||
loading="lazy"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
||||
:alt="$t('empty.protocols')"
|
||||
/>
|
||||
<span class="mb-4 text-center">
|
||||
{{ $t("empty.protocols") }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #secondary>
|
||||
<RealtimeLog :title="$t('websocket.log')" :log="log" />
|
||||
</template>
|
||||
<template #sidebar>
|
||||
<div class="flex items-center justify-between p-4">
|
||||
<label
|
||||
for="websocket-message"
|
||||
@@ -183,18 +155,14 @@
|
||||
@click.native="sendMessage"
|
||||
/>
|
||||
</div>
|
||||
</Pane>
|
||||
</Splitpanes>
|
||||
</template>
|
||||
</AppPaneLayout>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from "@nuxtjs/composition-api"
|
||||
import { Splitpanes, Pane } from "splitpanes"
|
||||
import "splitpanes/dist/splitpanes.css"
|
||||
import debounce from "lodash/debounce"
|
||||
import { breakpointsTailwind, useBreakpoints } from "@vueuse/core"
|
||||
import { logHoppRequestRunToAnalytics } from "~/helpers/fb/analytics"
|
||||
import { useSetting } from "~/newstore/settings"
|
||||
import {
|
||||
setWSEndpoint,
|
||||
WSEndpoint$,
|
||||
@@ -217,16 +185,8 @@ import {
|
||||
import { useStream } from "~/helpers/utils/composables"
|
||||
|
||||
export default defineComponent({
|
||||
components: { Splitpanes, Pane },
|
||||
setup() {
|
||||
const breakpoints = useBreakpoints(breakpointsTailwind)
|
||||
const mdAndLarger = breakpoints.greater("md")
|
||||
|
||||
return {
|
||||
mdAndLarger,
|
||||
SIDEBAR: useSetting("SIDEBAR"),
|
||||
COLUMN_LAYOUT: useSetting("COLUMN_LAYOUT"),
|
||||
SIDEBAR_ON_LEFT: useSetting("SIDEBAR_ON_LEFT"),
|
||||
url: useStream(WSEndpoint$, "", setWSEndpoint),
|
||||
protocols: useStream(WSProtocols$, [], setWSProtocols),
|
||||
connectionState: useStream(
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
horizontal
|
||||
>
|
||||
<Pane class="flex flex-1 hide-scrollbar !overflow-auto">
|
||||
<main class="flex flex-1 w-full">
|
||||
<main class="flex flex-1 w-full" role="main">
|
||||
<nuxt class="flex flex-1" />
|
||||
</main>
|
||||
</Pane>
|
||||
|
||||
@@ -1,132 +1,103 @@
|
||||
<template>
|
||||
<Splitpanes
|
||||
class="smart-splitter"
|
||||
:rtl="SIDEBAR_ON_LEFT && mdAndLarger"
|
||||
:class="{
|
||||
'!flex-row-reverse': SIDEBAR_ON_LEFT && mdAndLarger,
|
||||
}"
|
||||
:horizontal="!mdAndLarger"
|
||||
>
|
||||
<Pane
|
||||
size="75"
|
||||
min-size="65"
|
||||
class="hide-scrollbar !overflow-auto flex flex-col"
|
||||
>
|
||||
<Splitpanes class="smart-splitter" :horizontal="COLUMN_LAYOUT">
|
||||
<Pane
|
||||
:size="COLUMN_LAYOUT ? 45 : 50"
|
||||
class="hide-scrollbar !overflow-auto flex flex-col"
|
||||
<AppPaneLayout>
|
||||
<template #primary>
|
||||
<div class="flex items-start justify-between p-4">
|
||||
<label>
|
||||
{{ $t("documentation.generate_message") }}
|
||||
</label>
|
||||
<span
|
||||
class="inline-flex px-2 py-1 rounded bg-accentDark text-accentContrast"
|
||||
>
|
||||
<div class="flex items-start justify-between p-4">
|
||||
<label>
|
||||
{{ $t("documentation.generate_message") }}
|
||||
</label>
|
||||
<span
|
||||
class="inline-flex px-2 py-1 rounded bg-accentDark text-accentContrast"
|
||||
>
|
||||
BETA
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="sticky top-0 z-10 flex items-start justify-between border-b bg-primary border-dividerLight"
|
||||
>
|
||||
<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"
|
||||
/>
|
||||
<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="w-full p-4 font-mono bg-primary"
|
||||
autofocus
|
||||
rows="8"
|
||||
BETA
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="sticky top-0 z-10 flex items-start justify-between border-b bg-primary border-dividerLight"
|
||||
>
|
||||
<label for="collectionUpload">
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
title="JSON"
|
||||
svg="folder"
|
||||
class="!rounded-none"
|
||||
:label="$t('import.collections')"
|
||||
@click.native="$refs.collectionUpload.click()"
|
||||
/>
|
||||
<div
|
||||
class="sticky bottom-0 z-10 flex items-start justify-between p-4 border-t border-b bg-primary border-dividerLight"
|
||||
</label>
|
||||
<input
|
||||
ref="collectionUpload"
|
||||
class="input"
|
||||
name="collectionUpload"
|
||||
type="file"
|
||||
@change="uploadCollection"
|
||||
/>
|
||||
<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="w-full p-4 font-mono bg-primary"
|
||||
autofocus
|
||||
rows="8"
|
||||
/>
|
||||
<div
|
||||
class="sticky bottom-0 z-10 flex items-start justify-between p-4 border-t border-b bg-primary border-dividerLight"
|
||||
>
|
||||
<ButtonPrimary
|
||||
:label="$t('documentation.generate')"
|
||||
@click.native="getDoc"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #secondary>
|
||||
<div class="flex flex-col">
|
||||
<div
|
||||
v-if="items.length === 0"
|
||||
class="flex flex-col items-center justify-center p-4 text-secondaryLight"
|
||||
>
|
||||
<i class="pb-2 opacity-75 material-icons">topic</i>
|
||||
<span class="text-center">
|
||||
{{ $t("helpers.generate_documentation_first") }}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="sticky top-0 z-10 flex flex-1 p-4 border-b bg-primary border-dividerLight"
|
||||
>
|
||||
<span
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="
|
||||
!currentUser
|
||||
? $t('export.require_github')
|
||||
: currentUser.provider !== 'github.com'
|
||||
? $t('export.require_github')
|
||||
: 'Beta'
|
||||
"
|
||||
>
|
||||
<ButtonPrimary
|
||||
:label="$t('documentation.generate')"
|
||||
@click.native="getDoc"
|
||||
:disabled="
|
||||
!currentUser
|
||||
? true
|
||||
: currentUser.provider !== 'github.com'
|
||||
? true
|
||||
: false
|
||||
"
|
||||
:label="$t('export.create_secret_gist')"
|
||||
@click.native="createDocsGist"
|
||||
/>
|
||||
</div>
|
||||
</Pane>
|
||||
<Pane
|
||||
:size="COLUMN_LAYOUT ? 65 : 50"
|
||||
class="hide-scrollbar !overflow-auto flex flex-col"
|
||||
>
|
||||
<div class="flex flex-col">
|
||||
<div
|
||||
v-if="items.length === 0"
|
||||
class="flex flex-col items-center justify-center p-4 text-secondaryLight"
|
||||
>
|
||||
<i class="pb-2 opacity-75 material-icons">topic</i>
|
||||
<span class="text-center">
|
||||
{{ $t("helpers.generate_documentation_first") }}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="sticky top-0 z-10 flex flex-1 p-4 border-b bg-primary border-dividerLight"
|
||||
>
|
||||
<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>
|
||||
<Pane
|
||||
v-if="SIDEBAR"
|
||||
size="25"
|
||||
min-size="20"
|
||||
class="hide-scrollbar !overflow-auto flex flex-col"
|
||||
>
|
||||
</span>
|
||||
</div>
|
||||
<div v-for="(collection, index) in items" :key="`collection-${index}`">
|
||||
<DocsCollection :collection="collection" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #sidebar>
|
||||
<aside>
|
||||
<Collections
|
||||
:selected="selected"
|
||||
@@ -135,35 +106,23 @@
|
||||
@remove-collection="removeSelectedCollection($event)"
|
||||
/>
|
||||
</aside>
|
||||
</Pane>
|
||||
</Splitpanes>
|
||||
</template>
|
||||
</AppPaneLayout>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from "@nuxtjs/composition-api"
|
||||
import { Splitpanes, Pane } from "splitpanes"
|
||||
import "splitpanes/dist/splitpanes.css"
|
||||
import Mustache from "mustache"
|
||||
import { breakpointsTailwind, useBreakpoints } from "@vueuse/core"
|
||||
import { currentUser$ } from "~/helpers/fb/auth"
|
||||
import DocsTemplate from "~/assets/md/docs.md"
|
||||
import folderContents from "~/assets/md/folderContents.md"
|
||||
import folderBody from "~/assets/md/folderBody.md"
|
||||
import { useSetting } from "~/newstore/settings"
|
||||
import { useReadonlyStream } from "~/helpers/utils/composables"
|
||||
|
||||
export default defineComponent({
|
||||
components: { Splitpanes, Pane },
|
||||
setup() {
|
||||
const breakpoints = useBreakpoints(breakpointsTailwind)
|
||||
const mdAndLarger = breakpoints.greater("md")
|
||||
|
||||
return {
|
||||
mdAndLarger,
|
||||
SIDEBAR: useSetting("SIDEBAR"),
|
||||
COLUMN_LAYOUT: useSetting("COLUMN_LAYOUT"),
|
||||
currentUser: useReadonlyStream(currentUser$, null),
|
||||
SIDEBAR_ON_LEFT: useSetting("SIDEBAR_ON_LEFT"),
|
||||
}
|
||||
},
|
||||
data() {
|
||||
|
||||
@@ -1,55 +1,24 @@
|
||||
<template>
|
||||
<Splitpanes
|
||||
class="smart-splitter"
|
||||
:rtl="SIDEBAR_ON_LEFT && mdAndLarger"
|
||||
:class="{
|
||||
'!flex-row-reverse': SIDEBAR_ON_LEFT && mdAndLarger,
|
||||
}"
|
||||
:horizontal="!mdAndLarger"
|
||||
>
|
||||
<Pane
|
||||
size="75"
|
||||
min-size="65"
|
||||
class="hide-scrollbar !overflow-auto flex flex-col"
|
||||
>
|
||||
<Splitpanes class="smart-splitter" :horizontal="COLUMN_LAYOUT">
|
||||
<Pane
|
||||
:size="COLUMN_LAYOUT ? 45 : 50"
|
||||
class="hide-scrollbar !overflow-auto flex flex-col"
|
||||
>
|
||||
<GraphqlRequest :conn="gqlConn" />
|
||||
<GraphqlRequestOptions :conn="gqlConn" />
|
||||
</Pane>
|
||||
<Pane
|
||||
:size="COLUMN_LAYOUT ? 65 : 50"
|
||||
class="hide-scrollbar !overflow-auto flex flex-col"
|
||||
>
|
||||
<GraphqlResponse :conn="gqlConn" />
|
||||
</Pane>
|
||||
</Splitpanes>
|
||||
</Pane>
|
||||
<Pane
|
||||
v-if="SIDEBAR"
|
||||
size="25"
|
||||
min-size="20"
|
||||
class="hide-scrollbar !overflow-auto flex flex-col"
|
||||
>
|
||||
<AppPaneLayout>
|
||||
<template #primary>
|
||||
<GraphqlRequest :conn="gqlConn" />
|
||||
<GraphqlRequestOptions :conn="gqlConn" />
|
||||
</template>
|
||||
<template #secondary>
|
||||
<GraphqlResponse :conn="gqlConn" />
|
||||
</template>
|
||||
<template #sidebar>
|
||||
<GraphqlSidebar :conn="gqlConn" />
|
||||
</Pane>
|
||||
</Splitpanes>
|
||||
</template>
|
||||
</AppPaneLayout>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, watch } from "@nuxtjs/composition-api"
|
||||
import { Splitpanes, Pane } from "splitpanes"
|
||||
import "splitpanes/dist/splitpanes.css"
|
||||
import { breakpointsTailwind, useBreakpoints } from "@vueuse/core"
|
||||
import { useSetting } from "~/newstore/settings"
|
||||
import { GQLConnection } from "~/helpers/GQLConnection"
|
||||
import { useNuxt, useReadonlyStream } from "~/helpers/utils/composables"
|
||||
|
||||
export default defineComponent({
|
||||
components: { Splitpanes, Pane },
|
||||
beforeRouteLeave(_to, _from, next) {
|
||||
if (this.gqlConn.connected$.value) {
|
||||
this.gqlConn.disconnect()
|
||||
@@ -68,14 +37,7 @@ export default defineComponent({
|
||||
else nuxt.value.$loading.finish()
|
||||
})
|
||||
|
||||
const breakpoints = useBreakpoints(breakpointsTailwind)
|
||||
const mdAndLarger = breakpoints.greater("md")
|
||||
|
||||
return {
|
||||
mdAndLarger,
|
||||
SIDEBAR: useSetting("SIDEBAR"),
|
||||
COLUMN_LAYOUT: useSetting("COLUMN_LAYOUT"),
|
||||
SIDEBAR_ON_LEFT: useSetting("SIDEBAR_ON_LEFT"),
|
||||
gqlConn,
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,85 +1,56 @@
|
||||
<template>
|
||||
<Splitpanes
|
||||
class="smart-splitter"
|
||||
:rtl="SIDEBAR_ON_LEFT && mdAndLarger"
|
||||
:class="{
|
||||
'!flex-row-reverse': SIDEBAR_ON_LEFT && mdAndLarger,
|
||||
}"
|
||||
:horizontal="!mdAndLarger"
|
||||
>
|
||||
<Pane
|
||||
size="75"
|
||||
min-size="65"
|
||||
class="hide-scrollbar !overflow-auto flex flex-col"
|
||||
>
|
||||
<Splitpanes class="smart-splitter" :horizontal="COLUMN_LAYOUT">
|
||||
<Pane
|
||||
:size="COLUMN_LAYOUT ? 45 : 50"
|
||||
class="hide-scrollbar !overflow-auto flex flex-col"
|
||||
<AppPaneLayout>
|
||||
<template #primary>
|
||||
<HttpRequest />
|
||||
<SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10">
|
||||
<SmartTab
|
||||
:id="'params'"
|
||||
:label="`${$t('tab.parameters')}`"
|
||||
:selected="true"
|
||||
:info="`${newActiveParamsCount$}`"
|
||||
>
|
||||
<HttpRequest />
|
||||
<SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10">
|
||||
<SmartTab
|
||||
:id="'params'"
|
||||
:label="`${$t('tab.parameters')}`"
|
||||
:selected="true"
|
||||
:info="`${newActiveParamsCount$}`"
|
||||
>
|
||||
<HttpParameters />
|
||||
</SmartTab>
|
||||
<HttpParameters />
|
||||
</SmartTab>
|
||||
|
||||
<SmartTab :id="'bodyParams'" :label="`${$t('tab.body')}`">
|
||||
<HttpBody />
|
||||
</SmartTab>
|
||||
<SmartTab :id="'bodyParams'" :label="`${$t('tab.body')}`">
|
||||
<HttpBody />
|
||||
</SmartTab>
|
||||
|
||||
<SmartTab
|
||||
:id="'headers'"
|
||||
:label="`${$t('tab.headers')}`"
|
||||
:info="`${newActiveHeadersCount$}`"
|
||||
>
|
||||
<HttpHeaders />
|
||||
</SmartTab>
|
||||
|
||||
<SmartTab
|
||||
:id="'authorization'"
|
||||
:label="`${$t('tab.authorization')}`"
|
||||
>
|
||||
<HttpAuthorization />
|
||||
</SmartTab>
|
||||
|
||||
<SmartTab
|
||||
:id="'preRequestScript'"
|
||||
:label="`${$t('tab.pre_request_script')}`"
|
||||
:indicator="
|
||||
preRequestScript && preRequestScript.length > 0 ? true : false
|
||||
"
|
||||
>
|
||||
<HttpPreRequestScript />
|
||||
</SmartTab>
|
||||
|
||||
<SmartTab
|
||||
:id="'tests'"
|
||||
:label="`${$t('tab.tests')}`"
|
||||
:indicator="testScript && testScript.length > 0 ? true : false"
|
||||
>
|
||||
<HttpTests />
|
||||
</SmartTab>
|
||||
</SmartTabs>
|
||||
</Pane>
|
||||
<Pane
|
||||
:size="COLUMN_LAYOUT ? 65 : 50"
|
||||
class="flex flex-col hide-scrollbar !overflow-auto flex flex-col"
|
||||
<SmartTab
|
||||
:id="'headers'"
|
||||
:label="`${$t('tab.headers')}`"
|
||||
:info="`${newActiveHeadersCount$}`"
|
||||
>
|
||||
<HttpResponse ref="response" />
|
||||
</Pane>
|
||||
</Splitpanes>
|
||||
</Pane>
|
||||
<Pane
|
||||
v-if="SIDEBAR"
|
||||
size="25"
|
||||
min-size="20"
|
||||
class="hide-scrollbar !overflow-auto flex flex-col"
|
||||
>
|
||||
<HttpHeaders />
|
||||
</SmartTab>
|
||||
|
||||
<SmartTab :id="'authorization'" :label="`${$t('tab.authorization')}`">
|
||||
<HttpAuthorization />
|
||||
</SmartTab>
|
||||
|
||||
<SmartTab
|
||||
:id="'preRequestScript'"
|
||||
:label="`${$t('tab.pre_request_script')}`"
|
||||
:indicator="
|
||||
preRequestScript && preRequestScript.length > 0 ? true : false
|
||||
"
|
||||
>
|
||||
<HttpPreRequestScript />
|
||||
</SmartTab>
|
||||
|
||||
<SmartTab
|
||||
:id="'tests'"
|
||||
:label="`${$t('tab.tests')}`"
|
||||
:indicator="testScript && testScript.length > 0 ? true : false"
|
||||
>
|
||||
<HttpTests />
|
||||
</SmartTab>
|
||||
</SmartTabs>
|
||||
</template>
|
||||
<template #secondary>
|
||||
<HttpResponse ref="response" />
|
||||
</template>
|
||||
<template #sidebar>
|
||||
<SmartTabs styles="sticky bg-primary z-10 top-0" vertical>
|
||||
<SmartTab
|
||||
:id="'history'"
|
||||
@@ -106,8 +77,8 @@
|
||||
<Environments />
|
||||
</SmartTab>
|
||||
</SmartTabs>
|
||||
</Pane>
|
||||
</Splitpanes>
|
||||
</template>
|
||||
</AppPaneLayout>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@@ -121,8 +92,6 @@ import {
|
||||
useContext,
|
||||
watch,
|
||||
} from "@nuxtjs/composition-api"
|
||||
import { Splitpanes, Pane } from "splitpanes"
|
||||
import "splitpanes/dist/splitpanes.css"
|
||||
import { map } from "rxjs/operators"
|
||||
import { Subscription } from "rxjs"
|
||||
import isEqual from "lodash/isEqual"
|
||||
@@ -131,8 +100,6 @@ import {
|
||||
HoppRESTAuthOAuth2,
|
||||
safelyExtractRESTRequest,
|
||||
} from "@hoppscotch/data"
|
||||
import { breakpointsTailwind, useBreakpoints } from "@vueuse/core"
|
||||
import { useSetting } from "~/newstore/settings"
|
||||
import {
|
||||
restActiveParamsCount$,
|
||||
restActiveHeadersCount$,
|
||||
@@ -227,7 +194,6 @@ function setupRequestSync(
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
components: { Splitpanes, Pane },
|
||||
setup() {
|
||||
const requestForSync = ref<HoppRESTRequest | null>(null)
|
||||
|
||||
@@ -271,11 +237,7 @@ export default defineComponent({
|
||||
setupRequestSync(confirmSync, requestForSync)
|
||||
bindRequestToURLParams()
|
||||
|
||||
const breakpoints = useBreakpoints(breakpointsTailwind)
|
||||
const mdAndLarger = breakpoints.greater("md")
|
||||
|
||||
return {
|
||||
mdAndLarger,
|
||||
newActiveParamsCount$: useReadonlyStream(
|
||||
restActiveParamsCount$.pipe(
|
||||
map((e) => {
|
||||
@@ -294,9 +256,6 @@ export default defineComponent({
|
||||
),
|
||||
null
|
||||
),
|
||||
SIDEBAR: useSetting("SIDEBAR"),
|
||||
COLUMN_LAYOUT: useSetting("COLUMN_LAYOUT"),
|
||||
SIDEBAR_ON_LEFT: useSetting("SIDEBAR_ON_LEFT"),
|
||||
confirmSync,
|
||||
syncRequest,
|
||||
oAuthURL,
|
||||
|
||||
Reference in New Issue
Block a user