fix(common): improve responsive layout and overflow in realtime pages (#5843)
Co-authored-by: nivedin <nivedinp@gmail.com> Co-authored-by: James George <25279263+jamesgeorge007@users.noreply.github.com>
This commit is contained in:
parent
28a6569f42
commit
680439a1b0
4 changed files with 182 additions and 171 deletions
|
|
@ -17,114 +17,117 @@
|
|||
/>
|
||||
</div>
|
||||
<div
|
||||
class="sticky z-10 flex flex-shrink-0 items-center justify-between overflow-x-auto border-b border-dividerLight bg-primary pl-4"
|
||||
class="sticky z-10 w-0 min-w-full flex-shrink-0 overflow-x-auto border-b border-dividerLight bg-primary"
|
||||
:class="stickyHeaderStyles"
|
||||
>
|
||||
<span class="flex items-center">
|
||||
<label class="truncate font-semibold text-secondaryLight">
|
||||
{{ t("websocket.message") }}
|
||||
</label>
|
||||
<tippy
|
||||
interactive
|
||||
trigger="click"
|
||||
theme="popover"
|
||||
:on-shown="() => tippyActions.focus()"
|
||||
>
|
||||
<HoppSmartSelectWrapper>
|
||||
<HoppButtonSecondary
|
||||
:label="contentType || t('state.none').toLowerCase()"
|
||||
class="ml-2 rounded-none pr-8"
|
||||
/>
|
||||
</HoppSmartSelectWrapper>
|
||||
<template #content="{ hide }">
|
||||
<div
|
||||
ref="tippyActions"
|
||||
class="flex flex-col focus:outline-none"
|
||||
tabindex="0"
|
||||
@keyup.escape="hide()"
|
||||
>
|
||||
<HoppSmartItem
|
||||
v-for="(contentTypeItem, index) in validContentTypes"
|
||||
:key="`contentTypeItem-${index}`"
|
||||
:label="contentTypeItem"
|
||||
:info-icon="
|
||||
contentTypeItem === contentType ? IconDone : undefined
|
||||
"
|
||||
:active-info-icon="contentTypeItem === contentType"
|
||||
@click="
|
||||
() => {
|
||||
contentType = contentTypeItem
|
||||
hide()
|
||||
}
|
||||
"
|
||||
<div class="flex items-center justify-between pl-4">
|
||||
<span class="flex items-center">
|
||||
<label class="truncate font-semibold text-secondaryLight">
|
||||
{{ t("websocket.message") }}
|
||||
</label>
|
||||
<tippy
|
||||
interactive
|
||||
trigger="click"
|
||||
theme="popover"
|
||||
:on-shown="() => tippyActions.focus()"
|
||||
>
|
||||
<HoppSmartSelectWrapper>
|
||||
<HoppButtonSecondary
|
||||
:label="contentType || t('state.none').toLowerCase()"
|
||||
class="ml-2 rounded-none pr-8"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</tippy>
|
||||
</span>
|
||||
<div class="flex">
|
||||
<HoppButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip', delay: [500, 20], allowHTML: true }"
|
||||
:title="`${t(
|
||||
'request.run'
|
||||
)} <kbd>${getSpecialKey()}</kbd><kbd>↩</kbd>`"
|
||||
:label="`${t('action.send')}`"
|
||||
:disabled="!communicationBody || !isConnected"
|
||||
:icon="IconSend"
|
||||
class="!hover:text-accentDark rounded-none !text-accent"
|
||||
@click="sendMessage()"
|
||||
/>
|
||||
<HoppSmartCheckbox
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:on="clearInputOnSend"
|
||||
class="px-2"
|
||||
:title="`${t('mqtt.clear_input_on_send')}`"
|
||||
@change="clearInputOnSend = !clearInputOnSend"
|
||||
>
|
||||
{{ t("mqtt.clear_input") }}
|
||||
</HoppSmartCheckbox>
|
||||
<HoppButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
to="https://docs.hoppscotch.io/documentation/features/realtime-api-testing"
|
||||
blank
|
||||
:title="t('app.wiki')"
|
||||
:icon="IconHelpCircle"
|
||||
/>
|
||||
<HoppButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('action.clear')"
|
||||
:icon="IconTrash2"
|
||||
@click="clearContent"
|
||||
/>
|
||||
<HoppButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('state.linewrap')"
|
||||
:class="{ '!text-accent': linewrapEnabled }"
|
||||
:icon="IconWrapText"
|
||||
@click.prevent="linewrapEnabled = !linewrapEnabled"
|
||||
/>
|
||||
<HoppButtonSecondary
|
||||
v-if="contentType && contentType == 'JSON'"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('action.prettify')"
|
||||
:icon="prettifyIcon"
|
||||
@click="prettifyRequestBody"
|
||||
/>
|
||||
<label for="payload">
|
||||
</HoppSmartSelectWrapper>
|
||||
<template #content="{ hide }">
|
||||
<div
|
||||
ref="tippyActions"
|
||||
class="flex flex-col focus:outline-none"
|
||||
tabindex="0"
|
||||
@keyup.escape="hide()"
|
||||
>
|
||||
<HoppSmartItem
|
||||
v-for="(contentTypeItem, index) in validContentTypes"
|
||||
:key="`contentTypeItem-${index}`"
|
||||
:label="contentTypeItem"
|
||||
:info-icon="
|
||||
contentTypeItem === contentType ? IconDone : undefined
|
||||
"
|
||||
:active-info-icon="contentTypeItem === contentType"
|
||||
@click="
|
||||
() => {
|
||||
contentType = contentTypeItem
|
||||
hide()
|
||||
}
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</tippy>
|
||||
</span>
|
||||
<div class="flex">
|
||||
<HoppButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip', delay: [500, 20], allowHTML: true }"
|
||||
:title="`${t(
|
||||
'request.run'
|
||||
)} <kbd>${getSpecialKey()}</kbd><kbd>↩</kbd>`"
|
||||
:label="`${t('action.send')}`"
|
||||
:disabled="!communicationBody || !isConnected"
|
||||
:icon="IconSend"
|
||||
class="!hover:text-accentDark rounded-none !text-accent"
|
||||
@click="sendMessage()"
|
||||
/>
|
||||
<HoppSmartCheckbox
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:on="clearInputOnSend"
|
||||
class="px-2"
|
||||
:title="`${t('mqtt.clear_input_on_send')}`"
|
||||
@change="clearInputOnSend = !clearInputOnSend"
|
||||
>
|
||||
{{ t("mqtt.clear_input") }}
|
||||
</HoppSmartCheckbox>
|
||||
<HoppButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('import.title')"
|
||||
:icon="IconFilePlus"
|
||||
@click="payload!.click()"
|
||||
to="https://docs.hoppscotch.io/documentation/features/realtime-api-testing"
|
||||
blank
|
||||
:title="t('app.wiki')"
|
||||
:icon="IconHelpCircle"
|
||||
/>
|
||||
</label>
|
||||
<input
|
||||
ref="payload"
|
||||
class="input"
|
||||
name="payload"
|
||||
type="file"
|
||||
@change="uploadPayload"
|
||||
/>
|
||||
<HoppButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('action.clear')"
|
||||
:icon="IconTrash2"
|
||||
@click="clearContent"
|
||||
/>
|
||||
<HoppButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('state.linewrap')"
|
||||
:class="{ '!text-accent': linewrapEnabled }"
|
||||
:icon="IconWrapText"
|
||||
@click.prevent="linewrapEnabled = !linewrapEnabled"
|
||||
/>
|
||||
<HoppButtonSecondary
|
||||
v-if="contentType && contentType == 'JSON'"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('action.prettify')"
|
||||
:icon="prettifyIcon"
|
||||
@click="prettifyRequestBody"
|
||||
/>
|
||||
<label for="payload">
|
||||
<HoppButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('import.title')"
|
||||
:icon="IconFilePlus"
|
||||
@click="payload!.click()"
|
||||
/>
|
||||
</label>
|
||||
<input
|
||||
id="payload"
|
||||
ref="payload"
|
||||
class="input"
|
||||
name="payload"
|
||||
type="file"
|
||||
@change="uploadPayload"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="h-full relative overflow-auto flex flex-col flex-1">
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
<div
|
||||
class="sticky top-0 z-10 flex flex-shrink-0 space-x-2 overflow-x-auto bg-primary p-4"
|
||||
>
|
||||
<div class="inline-flex flex-1 space-x-2">
|
||||
<div class="flex flex-1">
|
||||
<div class="sm:inline-flex flex-1 sm:space-x-2 sm:space-y-0 space-y-2">
|
||||
<div class="flex flex-1 sm:flex-row flex-col sm:space-y-0 space-y-2">
|
||||
<input
|
||||
id="mqtt-url"
|
||||
v-model="url"
|
||||
|
|
@ -20,28 +20,30 @@
|
|||
"
|
||||
@keyup.enter="isUrlValid ? toggleConnection() : null"
|
||||
/>
|
||||
<label
|
||||
for="client-id"
|
||||
class="truncate border-b border-t border-divider bg-primaryLight px-4 py-2 font-semibold text-secondaryLight"
|
||||
>
|
||||
{{ t("mqtt.client_id") }}
|
||||
</label>
|
||||
<input
|
||||
id="client-id"
|
||||
v-model="clientID"
|
||||
class="flex w-full flex-1 rounded-r border border-divider bg-primaryLight px-4 py-2 text-secondaryDark"
|
||||
spellcheck="false"
|
||||
:disabled="
|
||||
connectionState === 'CONNECTED' ||
|
||||
connectionState === 'CONNECTING'
|
||||
"
|
||||
@keyup.enter="isUrlValid ? toggleConnection() : null"
|
||||
/>
|
||||
<div class="flex">
|
||||
<label
|
||||
for="client-id"
|
||||
class="truncate border-b border-t border-divider bg-primaryLight px-4 py-2 font-semibold text-secondaryLight"
|
||||
>
|
||||
{{ t("mqtt.client_id") }}
|
||||
</label>
|
||||
<input
|
||||
id="client-id"
|
||||
v-model="clientID"
|
||||
class="flex w-full flex-1 rounded-r border border-divider bg-primaryLight px-4 py-2 text-secondaryDark"
|
||||
spellcheck="false"
|
||||
:disabled="
|
||||
connectionState === 'CONNECTED' ||
|
||||
connectionState === 'CONNECTING'
|
||||
"
|
||||
@keyup.enter="isUrlValid ? toggleConnection() : null"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<HoppButtonPrimary
|
||||
id="connect"
|
||||
:disabled="!isUrlValid"
|
||||
class="w-32"
|
||||
class="sm:w-32 w-full"
|
||||
:label="
|
||||
connectionState === 'CONNECTING'
|
||||
? t('action.connecting')
|
||||
|
|
|
|||
|
|
@ -4,21 +4,22 @@
|
|||
<div
|
||||
class="sticky top-0 z-10 flex flex-shrink-0 space-x-2 overflow-x-auto bg-primary p-4"
|
||||
>
|
||||
<div class="inline-flex flex-1 space-x-2">
|
||||
<div class="flex flex-1">
|
||||
<div class="sm:inline-flex flex-1 sm:space-x-2 sm:space-y-0 space-y-2">
|
||||
<div class="flex flex-1 sm:flex-row flex-col sm:space-y-0 space-y-2">
|
||||
<label for="client-version">
|
||||
<tippy
|
||||
interactive
|
||||
trigger="click"
|
||||
theme="popover"
|
||||
:on-shown="() => tippyActions.focus()"
|
||||
class="sm:bg-primaryLight"
|
||||
>
|
||||
<HoppSmartSelectWrapper>
|
||||
<input
|
||||
id="client-version"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
title="socket.io-client version"
|
||||
class="flex w-26 cursor-pointer rounded-l border border-divider bg-primaryLight px-4 py-2 font-semibold text-secondaryDark"
|
||||
class="flex sm:w-26 flex-1 cursor-pointer rounded-l border border-divider bg-primaryLight px-4 py-2 font-semibold text-secondaryDark"
|
||||
:value="`Client ${clientVersion}`"
|
||||
readonly
|
||||
:disabled="
|
||||
|
|
@ -49,38 +50,40 @@
|
|||
</template>
|
||||
</tippy>
|
||||
</label>
|
||||
<input
|
||||
id="socketio-url"
|
||||
v-model="url"
|
||||
type="url"
|
||||
autocomplete="off"
|
||||
spellcheck="false"
|
||||
:class="{ error: !isUrlValid }"
|
||||
class="flex w-full flex-1 border border-divider bg-primaryLight px-4 py-2 text-secondaryDark"
|
||||
:placeholder="`${t('socketio.url')}`"
|
||||
:disabled="
|
||||
connectionState === 'CONNECTED' ||
|
||||
connectionState === 'CONNECTING'
|
||||
"
|
||||
@keyup.enter="isUrlValid ? toggleConnection() : null"
|
||||
/>
|
||||
<input
|
||||
id="socketio-path"
|
||||
v-model="path"
|
||||
class="flex w-full flex-1 rounded-r border border-divider bg-primaryLight px-4 py-2 text-secondaryDark"
|
||||
spellcheck="false"
|
||||
:disabled="
|
||||
connectionState === 'CONNECTED' ||
|
||||
connectionState === 'CONNECTING'
|
||||
"
|
||||
@keyup.enter="isUrlValid ? toggleConnection() : null"
|
||||
/>
|
||||
<div class="flex flex-1">
|
||||
<input
|
||||
id="socketio-url"
|
||||
v-model="url"
|
||||
type="url"
|
||||
autocomplete="off"
|
||||
spellcheck="false"
|
||||
:class="{ error: !isUrlValid }"
|
||||
class="flex w-full flex-1 border border-divider bg-primaryLight px-4 py-2 text-secondaryDark"
|
||||
:placeholder="`${t('socketio.url')}`"
|
||||
:disabled="
|
||||
connectionState === 'CONNECTED' ||
|
||||
connectionState === 'CONNECTING'
|
||||
"
|
||||
@keyup.enter="isUrlValid ? toggleConnection() : null"
|
||||
/>
|
||||
<input
|
||||
id="socketio-path"
|
||||
v-model="path"
|
||||
class="flex w-full flex-1 rounded-r border border-divider bg-primaryLight px-4 py-2 text-secondaryDark"
|
||||
spellcheck="false"
|
||||
:disabled="
|
||||
connectionState === 'CONNECTED' ||
|
||||
connectionState === 'CONNECTING'
|
||||
"
|
||||
@keyup.enter="isUrlValid ? toggleConnection() : null"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<HoppButtonPrimary
|
||||
id="connect"
|
||||
:disabled="!isUrlValid"
|
||||
name="connect"
|
||||
class="w-32"
|
||||
class="sm:w-32 w-full"
|
||||
:label="
|
||||
connectionState === 'CONNECTING'
|
||||
? t('action.connecting')
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
<div
|
||||
class="sticky top-0 z-10 flex flex-shrink-0 space-x-2 overflow-x-auto bg-primary p-4"
|
||||
>
|
||||
<div class="inline-flex flex-1 space-x-2">
|
||||
<div class="flex flex-1">
|
||||
<div class="sm:inline-flex flex-1 sm:space-x-2 sm:space-y-0 space-y-2">
|
||||
<div class="flex flex-1 flex-col space-y-1 sm:space-y-0 sm:flex-row">
|
||||
<input
|
||||
id="server"
|
||||
v-model="server"
|
||||
|
|
@ -19,28 +19,31 @@
|
|||
"
|
||||
@keyup.enter="isUrlValid ? toggleSSEConnection() : null"
|
||||
/>
|
||||
<label
|
||||
for="event-type"
|
||||
class="truncate border-b border-t border-divider bg-primaryLight px-4 py-2 font-semibold text-secondaryLight"
|
||||
>
|
||||
{{ t("sse.event_type") }}
|
||||
</label>
|
||||
<input
|
||||
id="event-type"
|
||||
v-model="eventType"
|
||||
class="flex w-full flex-1 rounded-r border border-divider bg-primaryLight px-4 py-2 text-secondaryDark"
|
||||
spellcheck="false"
|
||||
:disabled="
|
||||
connectionState === 'STARTED' || connectionState === 'STARTING'
|
||||
"
|
||||
@keyup.enter="isUrlValid ? toggleSSEConnection() : null"
|
||||
/>
|
||||
<div class="flex flex-1">
|
||||
<label
|
||||
for="event-type"
|
||||
class="truncate border-b border-t border-divider bg-primaryLight px-4 py-2 font-semibold text-secondaryLight"
|
||||
>
|
||||
{{ t("sse.event_type") }}
|
||||
</label>
|
||||
<input
|
||||
id="event-type"
|
||||
v-model="eventType"
|
||||
class="flex w-full flex-1 rounded-r border border-divider bg-primaryLight px-4 py-2 text-secondaryDark"
|
||||
spellcheck="false"
|
||||
:disabled="
|
||||
connectionState === 'STARTED' ||
|
||||
connectionState === 'STARTING'
|
||||
"
|
||||
@keyup.enter="isUrlValid ? toggleSSEConnection() : null"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<HoppButtonPrimary
|
||||
id="start"
|
||||
:disabled="!isUrlValid"
|
||||
name="start"
|
||||
class="w-32"
|
||||
class="sm:w-32 w-full"
|
||||
:label="
|
||||
connectionState === 'STARTING'
|
||||
? t('action.starting')
|
||||
|
|
|
|||
Loading…
Reference in a new issue