Compare commits
23 Commits
feat/embed
...
refactor/s
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0ffc9e3a4d | ||
|
|
75e34feabf | ||
|
|
fe13de2ea0 | ||
|
|
dec26ce2aa | ||
|
|
b0f02fee57 | ||
|
|
02be413eff | ||
|
|
42849e6853 | ||
|
|
e7535d505e | ||
|
|
fb6015ce26 | ||
|
|
f3a38bab3c | ||
|
|
1a1f45401c | ||
|
|
4a43807f34 | ||
|
|
88cc21e3d4 | ||
|
|
ecce830787 | ||
|
|
084039f59f | ||
|
|
0de9f3d8c3 | ||
|
|
4d6d30c92b | ||
|
|
38755bf3e3 | ||
|
|
2884854aab | ||
|
|
d24d07e420 | ||
|
|
cc81242294 | ||
|
|
a508909471 | ||
|
|
475a28b159 |
@@ -3,8 +3,10 @@ FROM node:lts-alpine
|
||||
LABEL maintainer="Hoppscotch (support@hoppscotch.io)"
|
||||
|
||||
# Add git as the prebuild target requires it to parse version information
|
||||
RUN apk add --update --no-cache \
|
||||
git
|
||||
RUN apk add --no-cache --virtual .gyp \
|
||||
python3 \
|
||||
make \
|
||||
g++
|
||||
|
||||
# Create app directory
|
||||
WORKDIR /app
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
"sideEffects": false,
|
||||
"dependencies": {
|
||||
"@codemirror/highlight": "^0.19.6",
|
||||
"@codemirror/language": "^0.19.6",
|
||||
"@lezer/lr": "^0.15.0"
|
||||
"@codemirror/language": "^0.19.7",
|
||||
"@lezer/lr": "^0.15.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@lezer/generator": "^0.15.0",
|
||||
"mocha": "^9.0.1",
|
||||
"rollup": "^2.60.1",
|
||||
"rollup": "^2.60.2",
|
||||
"rollup-plugin-dts": "^4.0.1",
|
||||
"rollup-plugin-ts": "^2.0.4",
|
||||
"typescript": "^4.5.2"
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M22 19a2 2 0 01-2 2H4a2 2 0 01-2-2V5a2 2 0 012-2h5l2 3h9a2 2 0 012 2z"></path>
|
||||
<line x1="9" y1="14" x2="15" y2="14"></line>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 325 B |
@@ -1,4 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<polyline points="9 10 4 15 9 20"></polyline>
|
||||
<path d="M20 4v7a4 4 0 01-4 4H4"></path>
|
||||
</svg>
|
||||
<path d="M6 17l2-5h14l-3 8a2 2 0 01-2 1H4a2 2 0 01-2-2V5a2 2 0 012-2h5l2 3h7a2 2 0 012 2v4"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 279 B After Width: | Height: | Size: 291 B |
25
packages/hoppscotch-app/assets/icons/logo.svg
Normal file
25
packages/hoppscotch-app/assets/icons/logo.svg
Normal file
@@ -0,0 +1,25 @@
|
||||
<svg width="128" height="128" viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0 16C0 7.16344 7.16344 0 16 0H112C120.837 0 128 7.16344 128 16V112C128 120.837 120.837 128 112 128H16C7.16344 128 0 120.837 0 112V16Z" fill="#10B981"/>
|
||||
<ellipse cx="49.94" cy="39.46" rx="2.5" ry="2.5" fill="white" fill-opacity="0.75"/>
|
||||
<ellipse cx="65.44" cy="40.46" rx="3" ry="3" fill="white" fill-opacity="0.75"/>
|
||||
<ellipse cx="80.44" cy="44.46" rx="2.50001" ry="2.5" fill="white" fill-opacity="0.75"/>
|
||||
<path d="M86.7407 58.919C87.2596 55.7445 77.0229 51.468 63.9989 49.3955C50.9765 47.3216 39.8979 48.2292 39.379 51.4037C39.3147 51.6624 39.379 51.8568 39.4448 52.1169C39.1203 51.9868 20.2663 104.92 20.2663 104.92H91.5347C91.5347 104.92 87.1295 59.5665 86.482 59.5665C86.6107 59.3735 86.7407 59.1792 86.7407 58.919Z" fill="url(#paint0_linear_202_73)"/>
|
||||
<path d="M79.2254 56.8465C78.9009 58.8547 71.5157 59.3078 62.6397 57.9471C53.828 56.5221 46.8943 53.7363 47.2188 51.7925C47.3489 51.145 48.1907 50.6261 49.5514 50.3675C45.0162 50.5618 42.0361 51.4037 41.7774 52.8287C41.3887 55.4858 50.4591 59.1134 62.1208 60.993C73.7826 62.8711 83.5662 62.1593 84.0193 59.5679C84.2795 58.0114 81.6867 56.3277 77.4116 54.7083C78.6422 55.4201 79.2897 56.1976 79.2254 56.8465Z" fill="#A7F3D0" fill-opacity="0.5"/>
|
||||
<path d="M83.8892 39.3532C83.1131 31.319 76.9571 24.5155 68.6642 23.2205C60.3713 21.9241 52.5315 26.4593 49.227 33.7803C54.5397 34.1047 60.2412 34.6879 66.2029 35.6598C72.5519 36.6318 78.5122 37.9282 83.8892 39.3532Z" fill="url(#paint1_radial_202_73)"/>
|
||||
<path d="M19.0356 39.5005C18.3882 43.4526 26.6153 48.3123 39.5091 52.2643C39.4448 52.0042 39.4448 51.8098 39.4448 51.5511C39.9622 48.3766 50.9765 47.469 64.0647 49.5429C77.1515 51.6154 87.3239 55.8919 86.805 59.0664C86.7407 59.3266 86.6764 59.5209 86.5463 59.7139C99.9576 59.9083 109.288 57.8358 109.936 53.8837C110.842 47.8577 91.2759 39.7592 66.203 35.8072C41.0642 31.8552 19.9418 33.4746 19.0356 39.5005ZM47.9321 39.1761C48.1264 38.1398 49.0984 37.3623 50.1346 37.5567C51.1709 37.7511 51.9484 38.723 51.754 39.7592C51.6239 40.7955 50.5877 41.5087 49.5515 41.3786C48.5152 41.1843 47.7377 40.2123 47.9321 39.1761ZM62.8984 40.2123C63.0928 38.7873 64.4535 37.8154 65.8785 38.0755C67.3035 38.2699 68.2754 39.6292 68.0168 41.0556C67.7566 42.4164 66.3973 43.3883 65.0366 43.1939C63.6102 42.9995 62.6382 41.6388 62.8984 40.2123ZM78.6423 44.0358C78.8366 42.9995 79.8086 42.222 80.8448 42.4164C81.8811 42.6107 82.6586 43.5827 82.4642 44.6189C82.3356 45.6552 81.2979 46.4327 80.2617 46.2383C79.2254 46.0439 78.4479 45.072 78.6423 44.0358Z" fill="url(#paint2_radial_202_73)"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_202_73" x1="56.7496" y1="39.4014" x2="56.7496" y2="100.924" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#86EFAC" stop-opacity="0.75"/>
|
||||
<stop offset="0.635417" stop-color="white" stop-opacity="0.2"/>
|
||||
<stop offset="1" stop-color="white" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="paint1_radial_202_73" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(66.5581 31.1766) rotate(90) scale(8.17659 17.3311)">
|
||||
<stop stop-color="#047857"/>
|
||||
<stop offset="1" stop-color="#064E3B"/>
|
||||
</radialGradient>
|
||||
<radialGradient id="paint2_radial_202_73" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(64.4593 46.6885) scale(347.403)">
|
||||
<stop stop-color="#047857"/>
|
||||
<stop offset="0.114583" stop-color="#064E3B"/>
|
||||
</radialGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.4 KiB |
6
packages/hoppscotch-app/assets/icons/wrap-text.svg
Normal file
6
packages/hoppscotch-app/assets/icons/wrap-text.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<line x1="3" y1="6" x2="21" y2="6"></line>
|
||||
<path d="M3 12h15a3 3 0 110 6h-4"></path>
|
||||
<polyline points="16 16 14 18 16 20"></polyline>
|
||||
<line x1="3" y1="18" x2="10" y2="18"></line>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 375 B |
@@ -19,7 +19,8 @@
|
||||
@apply bg-divider bg-clip-content;
|
||||
@apply rounded-full;
|
||||
@apply border-solid border-transparent border-4;
|
||||
@apply hover:(bg-dividerDark bg-clip-content);
|
||||
@apply hover:bg-dividerDark;
|
||||
@apply hover:bg-clip-content;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
@@ -130,7 +131,8 @@ a {
|
||||
@apply text-accent;
|
||||
@apply rounded;
|
||||
@apply hover:text-accentDark;
|
||||
@apply focus-visible:(ring ring-accent);
|
||||
@apply focus-visible:ring;
|
||||
@apply focus-visible:ring-accent;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -336,7 +338,8 @@ pre.ace_editor {
|
||||
@apply rounded;
|
||||
@apply text-current;
|
||||
@apply normal-case;
|
||||
@apply hover:(bg-opacity-20 no-underline);
|
||||
@apply hover:bg-opacity-20;
|
||||
@apply hover:no-underline;
|
||||
@apply font-medium;
|
||||
|
||||
font-size: var(--body-font-size);
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<template>
|
||||
<div class="bg-error flex justify-between">
|
||||
<span
|
||||
class="group relative flex items-center justify-center px-4 py-2 transition"
|
||||
class="flex py-2 px-4 transition justify-center group relative items-center"
|
||||
>
|
||||
<i class="material-icons mr-2">info_outline</i>
|
||||
<i class="mr-2 material-icons">info_outline</i>
|
||||
<span class="text-secondaryDark">
|
||||
<span class="md:hidden">
|
||||
{{ t("helpers.offline_short") }}
|
||||
</span>
|
||||
<span class="md:inline hidden">
|
||||
<span class="hidden md:inline">
|
||||
{{ t("helpers.offline") }}
|
||||
</span>
|
||||
</span>
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
@click.native="$refs.options.tippy().hide()"
|
||||
/>
|
||||
<!-- <SmartItem :label="t('app.status')" /> -->
|
||||
<div class="flex px-4 py-2 opacity-50">
|
||||
<div class="flex opacity-50 py-2 px-4">
|
||||
{{ `${t("app.name")} ${t("app.version")}` }}
|
||||
</div>
|
||||
</div>
|
||||
@@ -135,7 +135,7 @@
|
||||
@click.native="COLUMN_LAYOUT = !COLUMN_LAYOUT"
|
||||
/>
|
||||
<span
|
||||
class="transition transform"
|
||||
class="transform transition"
|
||||
:class="{
|
||||
'rotate-180': SIDEBAR_ON_LEFT,
|
||||
}"
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
/>
|
||||
<div
|
||||
v-if="searchResults.length === 0"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<i class="material-icons pb-2 opacity-75">manage_search</i>
|
||||
<i class="opacity-75 pb-2 material-icons">manage_search</i>
|
||||
<span class="text-center">
|
||||
{{ t("state.nothing_found") }} "{{ search }}"
|
||||
</span>
|
||||
|
||||
@@ -1,37 +1,37 @@
|
||||
<template>
|
||||
<div>
|
||||
<header
|
||||
class="flex items-center justify-between flex-1 px-2 py-2 space-x-2"
|
||||
class="flex space-x-2 flex-1 py-2 px-2 items-center justify-between"
|
||||
>
|
||||
<div class="inline-flex items-center space-x-2">
|
||||
<div class="space-x-2 inline-flex items-center">
|
||||
<ButtonSecondary
|
||||
class="tracking-wide !font-bold !text-secondaryDark"
|
||||
class="tracking-wide !font-bold !text-secondaryDark hover:bg-primaryDark focus-visible:bg-primaryDark"
|
||||
label="HOPPSCOTCH"
|
||||
to="/"
|
||||
/>
|
||||
<AppGitHubStarButton class="mt-1.5 transition hidden sm:flex" />
|
||||
</div>
|
||||
<div class="inline-flex items-center space-x-2">
|
||||
<div class="space-x-2 inline-flex items-center">
|
||||
<ButtonSecondary
|
||||
id="installPWA"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('header.install_pwa')"
|
||||
svg="download"
|
||||
class="rounded"
|
||||
class="rounded hover:bg-primaryDark focus-visible:bg-primaryDark"
|
||||
@click.native="showInstallPrompt()"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="`${t('app.search')} <kbd>/</kbd>`"
|
||||
svg="search"
|
||||
class="rounded"
|
||||
class="rounded hover:bg-primaryDark focus-visible:bg-primaryDark"
|
||||
@click.native="showSearch = true"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="`${t('support.title')} <kbd>?</kbd>`"
|
||||
svg="life-buoy"
|
||||
class="rounded"
|
||||
class="rounded hover:bg-primaryDark focus-visible:bg-primaryDark"
|
||||
@click.native="showSupport = true"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
@@ -39,7 +39,7 @@
|
||||
svg="upload-cloud"
|
||||
:label="t('header.save_workspace')"
|
||||
filled
|
||||
class="md:flex hidden"
|
||||
class="hidden md:flex"
|
||||
@click.native="showLogin = true"
|
||||
/>
|
||||
<ButtonPrimary
|
||||
@@ -47,13 +47,13 @@
|
||||
:label="t('header.login')"
|
||||
@click.native="showLogin = true"
|
||||
/>
|
||||
<div v-else class="inline-flex items-center space-x-2">
|
||||
<div v-else class="space-x-2 inline-flex items-center">
|
||||
<ButtonPrimary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('team.invite_tooltip')"
|
||||
:label="t('team.invite')"
|
||||
svg="user-plus"
|
||||
class="!bg-green-500 !text-green-500 !bg-opacity-15 !hover:bg-opacity-10 !hover:text-green-600 !hover:bg-green-400"
|
||||
class="!bg-green-500 !bg-opacity-15 !text-green-500 !hover:bg-opacity-10 !hover:bg-green-400 !hover:text-green-600"
|
||||
@click.native="showTeamsModal = true"
|
||||
/>
|
||||
<span class="px-2">
|
||||
@@ -74,7 +74,7 @@
|
||||
v-else
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('header.account')"
|
||||
class="rounded"
|
||||
class="rounded hover:bg-primaryDark focus-visible:bg-primaryDark"
|
||||
svg="user"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="flex flex-col items-start p-4 space-y-4">
|
||||
<div class="flex flex-col space-y-4 p-4 items-start">
|
||||
<SmartToggle
|
||||
:on="PROXY_ENABLED"
|
||||
@change="toggleSettingKey('PROXY_ENABLED')"
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
autocomplete="off"
|
||||
name="command"
|
||||
:placeholder="`${t('app.type_a_command_search')}`"
|
||||
class="border-dividerLight text-secondaryDark flex flex-shrink-0 p-6 text-base bg-transparent border-b"
|
||||
class="bg-transparent border-b border-dividerLight flex flex-shrink-0 text-base text-secondaryDark p-6"
|
||||
/>
|
||||
<AppFuse
|
||||
v-if="search && show"
|
||||
@@ -24,14 +24,14 @@
|
||||
/>
|
||||
<div
|
||||
v-else
|
||||
class="divide-dividerLight hide-scrollbar flex flex-col flex-1 space-y-4 overflow-auto divide-y"
|
||||
class="divide-dividerLight divide-y flex flex-col space-y-4 flex-1 overflow-auto hide-scrollbar"
|
||||
>
|
||||
<div
|
||||
v-for="(map, mapIndex) in mappings"
|
||||
:key="`map-${mapIndex}`"
|
||||
class="flex flex-col"
|
||||
>
|
||||
<h5 class="text-secondaryLight px-6 py-2 my-2">
|
||||
<h5 class="my-2 text-secondaryLight py-2 px-6">
|
||||
{{ t(map.section) }}
|
||||
</h5>
|
||||
<AppPowerSearchEntry
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
<template>
|
||||
<button
|
||||
class="search-entry focus:outline-none flex items-center flex-1 px-6 py-2 transition cursor-pointer"
|
||||
class="cursor-pointer flex flex-1 py-2 px-6 transition items-center search-entry focus:outline-none"
|
||||
:class="{ active: active }"
|
||||
tabindex="-1"
|
||||
@click="$emit('action', shortcut.action)"
|
||||
@keydown.enter="$emit('action', shortcut.action)"
|
||||
>
|
||||
<SmartIcon
|
||||
class="svg-icons mr-4 transition opacity-50"
|
||||
class="mr-4 opacity-50 transition svg-icons"
|
||||
:class="{ 'opacity-100 text-secondaryDark': active }"
|
||||
:name="shortcut.icon"
|
||||
/>
|
||||
<span
|
||||
class="flex flex-1 mr-4 font-medium transition"
|
||||
class="flex font-medium flex-1 mr-4 transition"
|
||||
:class="{ 'text-secondaryDark': active }"
|
||||
>
|
||||
{{ t(shortcut.label) }}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<section :id="label.toLowerCase()" class="relative flex flex-col flex-1">
|
||||
<section :id="label.toLowerCase()" class="flex flex-col flex-1 relative">
|
||||
<slot></slot>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
@close="hideModal"
|
||||
>
|
||||
<template #body>
|
||||
<p class="text-secondaryLight px-2 mb-8">
|
||||
<p class="text-secondaryLight mb-8 px-2">
|
||||
{{ t("app.invite_description") }}
|
||||
</p>
|
||||
<div class="flex flex-col px-2 space-y-2">
|
||||
<div class="grid grid-cols-3 gap-4">
|
||||
<div class="flex flex-col space-y-2 px-2">
|
||||
<div class="grid gap-4 grid-cols-3">
|
||||
<a
|
||||
v-for="(platform, index) in platforms"
|
||||
:key="`platform-${index}`"
|
||||
@@ -17,13 +17,13 @@
|
||||
target="_blank"
|
||||
class="share-link"
|
||||
>
|
||||
<SmartIcon :name="platform.icon" class="w-6 h-6" />
|
||||
<SmartIcon :name="platform.icon" class="h-6 w-6" />
|
||||
<span class="mt-3">
|
||||
{{ platform.name }}
|
||||
</span>
|
||||
</a>
|
||||
<button class="share-link" @click="copyAppLink">
|
||||
<SmartIcon class="w-6 h-6 text-xl" :name="copyIcon" />
|
||||
<SmartIcon class="h-6 text-xl w-6" :name="copyIcon" />
|
||||
<span class="mt-3">
|
||||
{{ t("app.copy") }}
|
||||
</span>
|
||||
|
||||
@@ -2,34 +2,34 @@
|
||||
<AppSlideOver :show="show" @close="close()">
|
||||
<template #content>
|
||||
<div
|
||||
class="bg-primary border-dividerLight sticky top-0 z-10 flex items-center justify-between p-2 border-b"
|
||||
class="bg-primary border-b border-dividerLight flex p-2 top-0 z-10 sticky items-center justify-between"
|
||||
>
|
||||
<h3 class="heading ml-4">{{ t("app.shortcuts") }}</h3>
|
||||
<h3 class="ml-4 heading">{{ t("app.shortcuts") }}</h3>
|
||||
<div class="flex">
|
||||
<ButtonSecondary svg="x" class="rounded" @click.native="close()" />
|
||||
<ButtonSecondary svg="x" @click.native="close()" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-primary border-dividerLight border-b">
|
||||
<div class="flex flex-col mx-6 my-4">
|
||||
<div class="bg-primary border-b border-dividerLight">
|
||||
<div class="flex flex-col my-4 mx-6">
|
||||
<input
|
||||
v-model="filterText"
|
||||
type="search"
|
||||
autocomplete="off"
|
||||
class="bg-primaryLight border-dividerLight focus-visible:border-divider flex w-full px-4 py-2 border rounded"
|
||||
class="bg-primaryLight border border-dividerLight rounded flex w-full py-2 px-4 focus-visible:border-divider"
|
||||
:placeholder="`${t('action.search')}`"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="filterText"
|
||||
class="divide-dividerLight hide-scrollbar flex flex-col flex-1 overflow-auto divide-y"
|
||||
class="divide-dividerLight divide-y flex flex-col flex-1 overflow-auto hide-scrollbar"
|
||||
>
|
||||
<div
|
||||
v-for="(map, mapIndex) in searchResults"
|
||||
:key="`map-${mapIndex}`"
|
||||
class="px-6 py-4 space-y-4"
|
||||
class="space-y-4 py-4 px-6"
|
||||
>
|
||||
<h1 class="text-secondaryDark font-semibold">
|
||||
<h1 class="font-semibold text-secondaryDark">
|
||||
{{ t(map.item.section) }}
|
||||
</h1>
|
||||
<AppShortcutsEntry
|
||||
@@ -40,9 +40,9 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="searchResults.length === 0"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<i class="material-icons pb-2 opacity-75">manage_search</i>
|
||||
<i class="opacity-75 pb-2 material-icons">manage_search</i>
|
||||
<span class="text-center">
|
||||
{{ t("state.nothing_found") }} "{{ filterText }}"
|
||||
</span>
|
||||
@@ -50,14 +50,14 @@
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="divide-dividerLight hide-scrollbar flex flex-col flex-1 overflow-auto divide-y"
|
||||
class="divide-dividerLight divide-y flex flex-col flex-1 overflow-auto hide-scrollbar"
|
||||
>
|
||||
<div
|
||||
v-for="(map, mapIndex) in mappings"
|
||||
:key="`map-${mapIndex}`"
|
||||
class="px-6 py-4 space-y-4"
|
||||
class="space-y-4 py-4 px-6"
|
||||
>
|
||||
<h1 class="text-secondaryDark font-semibold">
|
||||
<h1 class="font-semibold text-secondaryDark">
|
||||
{{ t(map.section) }}
|
||||
</h1>
|
||||
<AppShortcutsEntry
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<aside class="md:flex-col flex justify-between h-full">
|
||||
<nav class="flex-nowrap md:flex-col md:flex-none flex flex-1">
|
||||
<aside class="flex h-full justify-between md:flex-col">
|
||||
<nav class="flex flex-nowrap flex-1 md:flex-col md:flex-none">
|
||||
<NuxtLink
|
||||
v-for="(navigation, index) in primaryNavigation"
|
||||
:key="`navigation-${index}`"
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
<template>
|
||||
<div>
|
||||
<transition v-if="show" name="fade" appear>
|
||||
<div class="fixed inset-0 z-20 transition-opacity" @keydown.esc="close()">
|
||||
<div class="inset-0 transition-opacity z-20 fixed" @keydown.esc="close()">
|
||||
<div
|
||||
class="bg-primaryLight opacity-90 absolute inset-0"
|
||||
class="bg-primaryLight opacity-90 inset-0 absolute"
|
||||
tabindex="0"
|
||||
@click="close()"
|
||||
></div>
|
||||
</div>
|
||||
</transition>
|
||||
<aside
|
||||
class="bg-primary w-96 fixed top-0 right-0 z-30 flex flex-col h-full max-w-full overflow-auto transition duration-300 ease-in-out transform"
|
||||
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="show ? 'shadow-xl translate-x-0' : 'translate-x-full'"
|
||||
>
|
||||
<slot name="content"></slot>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
:to="`${/^\/(?!\/).*$/.test(to) ? localePath(to) : to}`"
|
||||
:exact="exact"
|
||||
:blank="blank"
|
||||
class="focus:outline-none focus-visible:bg-accentDark inline-flex items-center justify-center py-2 font-bold transition"
|
||||
class="font-bold py-2 transition inline-flex items-center justify-center focus:outline-none focus-visible:bg-accentDark"
|
||||
:class="[
|
||||
color
|
||||
? `text-${color}-800 bg-${color}-200 hover:(text-${color}-900 bg-${color}-300) focus-visible:(text-${color}-900 bg-${color}-300)`
|
||||
@@ -29,7 +29,7 @@
|
||||
>
|
||||
<span
|
||||
v-if="!loading"
|
||||
class="whitespace-nowrap inline-flex items-center justify-center"
|
||||
class="inline-flex items-center justify-center whitespace-nowrap"
|
||||
:class="{ 'flex-row-reverse': reverse }"
|
||||
>
|
||||
<i
|
||||
@@ -56,7 +56,7 @@
|
||||
<kbd
|
||||
v-for="(key, index) in shortcut"
|
||||
:key="`key-${index}`"
|
||||
class="bg-accentLight inline-flex px-1 ml-1 rounded"
|
||||
class="bg-accentLight rounded ml-1 px-1 inline-flex"
|
||||
>
|
||||
{{ key }}
|
||||
</kbd>
|
||||
|
||||
@@ -3,11 +3,12 @@
|
||||
:to="`${/^\/(?!\/).*$/.test(to) ? localePath(to) : to}`"
|
||||
:exact="exact"
|
||||
:blank="blank"
|
||||
class="whitespace-nowrap hover:bg-primaryDark focus:outline-none focus-visible:bg-primaryDark inline-flex items-center justify-center py-2 font-semibold transition"
|
||||
class="font-semibold py-2 transition inline-flex items-center justify-center whitespace-nowrap focus:outline-none"
|
||||
:class="[
|
||||
color
|
||||
? `text-${color}-500 hover:(text-${color}-600 text-${color}-600)`
|
||||
? `text-${color}-500 hover:text-${color}-600 focus-visible:text-${color}-600`
|
||||
: 'text-secondary hover:text-secondaryDark focus-visible:text-secondaryDark',
|
||||
{ 'pointer-events-none': loading },
|
||||
label ? 'rounded px-4' : 'px-2',
|
||||
{ 'rounded-full': rounded },
|
||||
{ 'opacity-75 cursor-not-allowed': disabled },
|
||||
@@ -17,39 +18,50 @@
|
||||
'border border-divider hover:border-dividerDark focus-visible:border-dividerDark':
|
||||
outline,
|
||||
},
|
||||
{ '!bg-primaryLight !hover:bg-primaryDark': filled },
|
||||
{
|
||||
'bg-primaryLight hover:bg-primaryDark focus-visible:bg-primaryDark':
|
||||
filled,
|
||||
},
|
||||
]"
|
||||
:disabled="disabled"
|
||||
:tabindex="loading ? '-1' : '0'"
|
||||
>
|
||||
<i
|
||||
v-if="icon"
|
||||
class="material-icons"
|
||||
:class="[
|
||||
{ '!text-2xl': large },
|
||||
label ? (reverse ? 'ml-2' : 'mr-2') : '',
|
||||
]"
|
||||
<span
|
||||
v-if="!loading"
|
||||
class="inline-flex items-center justify-center whitespace-nowrap"
|
||||
:class="{ 'flex-row-reverse': reverse }"
|
||||
>
|
||||
{{ icon }}
|
||||
</i>
|
||||
<SmartIcon
|
||||
v-if="svg"
|
||||
:name="svg"
|
||||
class="svg-icons"
|
||||
:class="[
|
||||
{ '!h-6 !w-6': large },
|
||||
label ? (reverse ? 'ml-2' : 'mr-2') : '',
|
||||
]"
|
||||
/>
|
||||
{{ label }}
|
||||
<div v-if="shortcut.length" class="ml-2">
|
||||
<kbd
|
||||
v-for="(key, index) in shortcut"
|
||||
:key="`key-${index}`"
|
||||
class="bg-dividerLight text-secondaryLight inline-flex px-1 ml-1 rounded"
|
||||
<i
|
||||
v-if="icon"
|
||||
class="material-icons"
|
||||
:class="[
|
||||
{ '!text-2xl': large },
|
||||
label ? (reverse ? 'ml-2' : 'mr-2') : '',
|
||||
]"
|
||||
>
|
||||
{{ key }}
|
||||
</kbd>
|
||||
</div>
|
||||
{{ icon }}
|
||||
</i>
|
||||
<SmartIcon
|
||||
v-if="svg"
|
||||
:name="svg"
|
||||
class="svg-icons"
|
||||
:class="[
|
||||
{ '!h-6 !w-6': large },
|
||||
label ? (reverse ? 'ml-2' : 'mr-2') : '',
|
||||
]"
|
||||
/>
|
||||
{{ label }}
|
||||
<div v-if="shortcut.length" class="ml-2">
|
||||
<kbd
|
||||
v-for="(key, index) in shortcut"
|
||||
:key="`key-${index}`"
|
||||
class="bg-dividerLight rounded text-secondaryLight ml-1 px-1 inline-flex"
|
||||
>
|
||||
{{ key }}
|
||||
</kbd>
|
||||
</div>
|
||||
</span>
|
||||
<SmartSpinner v-else />
|
||||
</SmartLink>
|
||||
</template>
|
||||
|
||||
@@ -90,6 +102,10 @@ export default defineComponent({
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
reverse: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
type="text"
|
||||
autocomplete="off"
|
||||
autofocus
|
||||
class="border-dividerLight hover:bg-primaryDark flex w-full px-4 py-2 font-semibold bg-transparent border-t appearance-none cursor-pointer"
|
||||
class="bg-transparent border-t border-dividerLight cursor-pointer flex font-semibold w-full py-2 px-4 appearance-none hover:bg-primaryDark"
|
||||
@change="updateSelectedTeam(myTeams[$event.target.value])"
|
||||
>
|
||||
<option
|
||||
|
||||
@@ -38,13 +38,18 @@ import { defineComponent } from "@nuxtjs/composition-api"
|
||||
export default defineComponent({
|
||||
props: {
|
||||
show: Boolean,
|
||||
placeholderCollName: { type: String, default: null },
|
||||
editingCollectionName: { type: String, default: null },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
name: null,
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
editingCollectionName(val) {
|
||||
this.name = val
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
saveCollection() {
|
||||
if (!this.name) {
|
||||
|
||||
@@ -39,12 +39,18 @@ import { defineComponent } from "@nuxtjs/composition-api"
|
||||
export default defineComponent({
|
||||
props: {
|
||||
show: Boolean,
|
||||
editingFolderName: { type: String, default: null },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
name: null,
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
editingFolderName(val) {
|
||||
this.name = val
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
editFolder() {
|
||||
if (!this.name) {
|
||||
|
||||
@@ -35,7 +35,7 @@ import { defineComponent } from "@nuxtjs/composition-api"
|
||||
export default defineComponent({
|
||||
props: {
|
||||
show: Boolean,
|
||||
placeholderReqName: { type: String, default: null },
|
||||
editingRequestName: { type: String, default: null },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -44,6 +44,11 @@ export default defineComponent({
|
||||
},
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
editingRequestName(val) {
|
||||
this.requestUpdateData.name = val
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
saveRequest() {
|
||||
if (!this.requestUpdateData.name) {
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
v-if="mode == 'import_from_my_collections'"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.go_back')"
|
||||
class="rounded"
|
||||
svg="arrow-left"
|
||||
@click.native="
|
||||
() => {
|
||||
@@ -34,7 +33,6 @@
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.more')"
|
||||
class="rounded"
|
||||
svg="more-vertical"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
>
|
||||
<template #body>
|
||||
<div class="flex flex-col px-2">
|
||||
<div class="relative flex">
|
||||
<div class="flex relative">
|
||||
<input
|
||||
id="selectLabelSaveReq"
|
||||
v-model="requestName"
|
||||
@@ -59,7 +59,8 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref, watch } from "@nuxtjs/composition-api"
|
||||
import { isHoppRESTRequest } from "~/helpers/types/HoppRESTRequest"
|
||||
import { HoppGQLRequest, isHoppRESTRequest } from "@hoppscotch/data"
|
||||
import cloneDeep from "lodash/cloneDeep"
|
||||
import {
|
||||
editGraphqlRequest,
|
||||
editRESTRequest,
|
||||
@@ -74,7 +75,6 @@ import {
|
||||
} from "~/newstore/RESTSession"
|
||||
import * as teamUtils from "~/helpers/teams/utils"
|
||||
import { apolloClient } from "~/helpers/apollo"
|
||||
import { HoppGQLRequest } from "~/helpers/types/HoppGQLRequest"
|
||||
import { useI18n, useToast } from "~/helpers/utils/composables"
|
||||
|
||||
const t = useI18n()
|
||||
@@ -200,8 +200,12 @@ const saveRequestAs = async () => {
|
||||
return
|
||||
}
|
||||
|
||||
// Clone Deep because objects are shared by reference so updating
|
||||
// just one bit will update other referenced shared instances
|
||||
const requestUpdated =
|
||||
props.mode === "rest" ? getRESTRequest() : getGQLSession().request
|
||||
props.mode === "rest"
|
||||
? cloneDeep(getRESTRequest())
|
||||
: cloneDeep(getGQLSession().request)
|
||||
|
||||
// // Filter out all REST file inputs
|
||||
// if (this.mode === "rest" && requestUpdated.bodyParams) {
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from "@nuxtjs/composition-api"
|
||||
import { HoppGQLRequest } from "~/helpers/types/HoppGQLRequest"
|
||||
import { HoppGQLRequest } from "@hoppscotch/data"
|
||||
import { addGraphqlCollection, makeCollection } from "~/newstore/collections"
|
||||
|
||||
export default defineComponent({
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
<template>
|
||||
<div class="flex flex-col" :class="[{ 'bg-primaryLight': dragging }]">
|
||||
<div
|
||||
class="group flex items-center"
|
||||
class="flex items-stretch group"
|
||||
@dragover.prevent
|
||||
@drop.prevent="dropEvent"
|
||||
@dragover="dragging = true"
|
||||
@drop="dragging = false"
|
||||
@dragleave="dragging = false"
|
||||
@dragend="dragging = false"
|
||||
@contextmenu.prevent="$refs.options.tippy().show()"
|
||||
>
|
||||
<span
|
||||
class="flex items-center justify-center px-4 cursor-pointer"
|
||||
class="cursor-pointer flex px-4 items-center justify-center"
|
||||
@click="toggleShowChildren()"
|
||||
>
|
||||
<SmartIcon
|
||||
@@ -20,7 +21,7 @@
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="group-hover:text-secondaryDark flex flex-1 min-w-0 py-2 pr-2 transition cursor-pointer"
|
||||
class="cursor-pointer flex flex-1 min-w-0 py-2 pr-2 transition group-hover:text-secondaryDark"
|
||||
@click="toggleShowChildren()"
|
||||
>
|
||||
<span class="truncate"> {{ collection.name }} </span>
|
||||
@@ -30,7 +31,7 @@
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
svg="folder-plus"
|
||||
:title="$t('folder.new')"
|
||||
class="group-hover:inline-flex hidden"
|
||||
class="hidden group-hover:inline-flex"
|
||||
@click.native="
|
||||
$emit('add-folder', {
|
||||
path: `${collectionIndex}`,
|
||||
@@ -91,7 +92,7 @@
|
||||
</div>
|
||||
<div v-if="showChildren || isFiltered" class="flex">
|
||||
<div
|
||||
class="flex w-1 transform transition cursor-nsResize ml-5.5 bg-dividerLight hover:scale-x-125 hover:bg-dividerDark"
|
||||
class="bg-dividerLight cursor-nsResize flex ml-5.5 transform transition w-1 hover:bg-dividerDark hover:scale-x-125"
|
||||
@click="toggleShowChildren()"
|
||||
></div>
|
||||
<div class="flex flex-col flex-1 truncate">
|
||||
@@ -132,12 +133,12 @@
|
||||
v-if="
|
||||
collection.folders.length === 0 && collection.requests.length === 0
|
||||
"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/pack.svg`"
|
||||
loading="lazy"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 mb-4"
|
||||
class="flex-col object-contain object-center h-16 mb-4 w-16 inline-flex"
|
||||
:alt="$t('empty.collection')"
|
||||
/>
|
||||
<span class="text-center">
|
||||
@@ -191,7 +192,7 @@ export default defineComponent({
|
||||
getCollectionIcon() {
|
||||
if (this.isSelected) return "check-circle"
|
||||
else if (!this.showChildren && !this.isFiltered) return "folder"
|
||||
else if (this.showChildren || this.isFiltered) return "folder-minus"
|
||||
else if (this.showChildren || this.isFiltered) return "folder-open"
|
||||
else return "folder"
|
||||
},
|
||||
},
|
||||
|
||||
@@ -45,12 +45,18 @@ export default defineComponent({
|
||||
show: Boolean,
|
||||
editingCollection: { type: Object, default: () => {} },
|
||||
editingCollectionIndex: { type: Number, default: null },
|
||||
editingCollectionName: { type: String, default: null },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
name: null as string | null,
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
editingCollectionName(val) {
|
||||
this.name = val
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
saveCollection() {
|
||||
if (!this.name) {
|
||||
|
||||
@@ -45,12 +45,18 @@ export default defineComponent({
|
||||
show: Boolean,
|
||||
folder: { type: Object, default: () => {} },
|
||||
folderPath: { type: String, default: null },
|
||||
editingFolderName: { type: String, default: null },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
name: "",
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
editingFolderName(val) {
|
||||
this.name = val
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
editFolder() {
|
||||
if (!this.name) {
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, PropType } from "@nuxtjs/composition-api"
|
||||
import { HoppGQLRequest } from "~/helpers/types/HoppGQLRequest"
|
||||
import { HoppGQLRequest } from "@hoppscotch/data"
|
||||
import { editGraphqlRequest } from "~/newstore/collections"
|
||||
|
||||
export default defineComponent({
|
||||
@@ -47,6 +47,7 @@ export default defineComponent({
|
||||
folderPath: { type: String, default: null },
|
||||
request: { type: Object as PropType<HoppGQLRequest>, default: () => {} },
|
||||
requestIndex: { type: Number, default: null },
|
||||
editingRequestName: { type: String, default: null },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -55,6 +56,11 @@ export default defineComponent({
|
||||
},
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
editingRequestName(val) {
|
||||
this.requestUpdateData.name = val
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
saveRequest() {
|
||||
if (!this.requestUpdateData.name) {
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
<template>
|
||||
<div class="flex flex-col" :class="[{ 'bg-primaryLight': dragging }]">
|
||||
<div
|
||||
class="group flex items-center"
|
||||
class="flex items-stretch group"
|
||||
@dragover.prevent
|
||||
@drop.prevent="dropEvent"
|
||||
@dragover="dragging = true"
|
||||
@drop="dragging = false"
|
||||
@dragleave="dragging = false"
|
||||
@dragend="dragging = false"
|
||||
@contextmenu.prevent="$refs.options.tippy().show()"
|
||||
>
|
||||
<span
|
||||
class="flex items-center justify-center px-4 cursor-pointer"
|
||||
class="cursor-pointer flex px-4 items-center justify-center"
|
||||
@click="toggleShowChildren()"
|
||||
>
|
||||
<SmartIcon
|
||||
@@ -20,7 +21,7 @@
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="group-hover:text-secondaryDark flex flex-1 min-w-0 py-2 pr-2 transition cursor-pointer"
|
||||
class="cursor-pointer flex flex-1 min-w-0 py-2 pr-2 transition group-hover:text-secondaryDark"
|
||||
@click="toggleShowChildren()"
|
||||
>
|
||||
<span class="truncate">
|
||||
@@ -32,7 +33,7 @@
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
svg="folder-plus"
|
||||
:title="$t('folder.new')"
|
||||
class="group-hover:inline-flex hidden"
|
||||
class="hidden group-hover:inline-flex"
|
||||
@click.native="$emit('add-folder', { folder, path: folderPath })"
|
||||
/>
|
||||
<span>
|
||||
@@ -87,7 +88,7 @@
|
||||
</div>
|
||||
<div v-if="showChildren || isFiltered" class="flex">
|
||||
<div
|
||||
class="flex w-1 transform transition cursor-nsResize ml-5.5 bg-dividerLight hover:scale-x-125 hover:bg-dividerDark"
|
||||
class="bg-dividerLight cursor-nsResize flex ml-5.5 transform transition w-1 hover:bg-dividerDark hover:scale-x-125"
|
||||
@click="toggleShowChildren()"
|
||||
></div>
|
||||
<div class="flex flex-col flex-1 truncate">
|
||||
@@ -131,12 +132,12 @@
|
||||
folder.requests &&
|
||||
folder.requests.length === 0
|
||||
"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/pack.svg`"
|
||||
loading="lazy"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 mb-4"
|
||||
class="flex-col object-contain object-center h-16 mb-4 w-16 inline-flex"
|
||||
:alt="$t('empty.folder')"
|
||||
/>
|
||||
<span class="text-center">
|
||||
@@ -189,7 +190,7 @@ export default defineComponent({
|
||||
getCollectionIcon() {
|
||||
if (this.isSelected) return "check-circle"
|
||||
else if (!this.showChildren && !this.isFiltered) return "folder"
|
||||
else if (this.showChildren || this.isFiltered) return "folder-minus"
|
||||
else if (this.showChildren || this.isFiltered) return "folder-open"
|
||||
else return "folder"
|
||||
},
|
||||
},
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.more')"
|
||||
class="rounded"
|
||||
svg="more-vertical"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
<template>
|
||||
<div class="flex flex-col" :class="[{ 'bg-primaryLight': dragging }]">
|
||||
<div
|
||||
class="group flex items-center"
|
||||
class="flex items-stretch group"
|
||||
draggable="true"
|
||||
@dragstart="dragStart"
|
||||
@dragover.stop
|
||||
@dragleave="dragging = false"
|
||||
@dragend="dragging = false"
|
||||
@contextmenu.prevent="$refs.options.tippy().show()"
|
||||
>
|
||||
<span
|
||||
class="flex items-center justify-center w-16 px-2 truncate cursor-pointer"
|
||||
class="cursor-pointer flex px-2 w-16 items-center justify-center truncate"
|
||||
@click="!doc ? selectRequest() : {}"
|
||||
>
|
||||
<SmartIcon
|
||||
@@ -19,7 +20,7 @@
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="group-hover:text-secondaryDark flex flex-1 min-w-0 py-2 pr-2 transition cursor-pointer"
|
||||
class="cursor-pointer flex flex-1 min-w-0 py-2 pr-2 transition group-hover:text-secondaryDark"
|
||||
@click="!doc ? selectRequest() : {}"
|
||||
>
|
||||
<span class="truncate"> {{ request.name }} </span>
|
||||
@@ -30,7 +31,7 @@
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
svg="rotate-ccw"
|
||||
:title="$t('action.restore')"
|
||||
class="group-hover:inline-flex hidden"
|
||||
class="hidden group-hover:inline-flex"
|
||||
@click.native="!doc ? selectRequest() : {}"
|
||||
/>
|
||||
<span>
|
||||
@@ -102,7 +103,7 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, PropType } from "@nuxtjs/composition-api"
|
||||
import { HoppGQLRequest, makeGQLRequest } from "~/helpers/types/HoppGQLRequest"
|
||||
import { HoppGQLRequest, makeGQLRequest } from "@hoppscotch/data"
|
||||
import { removeGraphqlRequest } from "~/newstore/collections"
|
||||
import { setGQLSession } from "~/newstore/GQLSession"
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
:class="{ 'rounded border border-divider': savingMode }"
|
||||
>
|
||||
<div
|
||||
class="divide-dividerLight border-dividerLight sticky top-0 z-10 flex flex-col border-b divide-y"
|
||||
class="divide-dividerLight divide-y border-b border-dividerLight flex flex-col top-0 z-10 sticky"
|
||||
:class="{ 'bg-primary': !savingMode }"
|
||||
>
|
||||
<input
|
||||
@@ -13,9 +13,9 @@
|
||||
type="search"
|
||||
autocomplete="off"
|
||||
:placeholder="$t('action.search')"
|
||||
class="flex w-full px-4 py-2 bg-transparent"
|
||||
class="bg-transparent flex w-full py-2 px-4"
|
||||
/>
|
||||
<div class="flex justify-between flex-1">
|
||||
<div class="flex flex-1 justify-between">
|
||||
<ButtonSecondary
|
||||
svg="plus"
|
||||
:label="$t('action.new')"
|
||||
@@ -62,15 +62,15 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="collections.length === 0"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/pack.svg`"
|
||||
loading="lazy"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
||||
class="flex-col object-contain object-center h-16 my-4 w-16 inline-flex"
|
||||
:alt="$t('empty.collections')"
|
||||
/>
|
||||
<span class="pb-4 text-center">
|
||||
<span class="text-center pb-4">
|
||||
{{ $t("empty.collections") }}
|
||||
</span>
|
||||
<ButtonSecondary
|
||||
@@ -81,9 +81,9 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="!(filteredCollections.length !== 0 || collections.length === 0)"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<i class="material-icons pb-2 opacity-75">manage_search</i>
|
||||
<i class="opacity-75 pb-2 material-icons">manage_search</i>
|
||||
<span class="text-center">
|
||||
{{ $t("state.nothing_found") }} "{{ filterText }}"
|
||||
</span>
|
||||
@@ -96,6 +96,7 @@
|
||||
:show="showModalEdit"
|
||||
:editing-collection="editingCollection"
|
||||
:editing-collection-index="editingCollectionIndex"
|
||||
:editing-collection-name="editingCollection ? editingCollection.name : ''"
|
||||
@hide-modal="displayModalEdit(false)"
|
||||
/>
|
||||
<CollectionsGraphqlAddFolder
|
||||
@@ -110,6 +111,7 @@
|
||||
:folder="editingFolder"
|
||||
:folder-index="editingFolderIndex"
|
||||
:folder-path="editingFolderPath"
|
||||
:editing-folder-name="editingFolder ? editingFolder.name : ''"
|
||||
@hide-modal="displayModalEditFolder(false)"
|
||||
/>
|
||||
<CollectionsGraphqlEditRequest
|
||||
@@ -117,6 +119,7 @@
|
||||
:folder-path="editingFolderPath"
|
||||
:request="editingRequest"
|
||||
:request-index="editingRequestIndex"
|
||||
:editing-request-name="editingRequest ? editingRequest.name : ''"
|
||||
@hide-modal="displayModalEditRequest(false)"
|
||||
/>
|
||||
<CollectionsGraphqlImportExport
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
:class="{ 'rounded border border-divider': saveRequest }"
|
||||
>
|
||||
<div
|
||||
class="divide-dividerLight bg-primary border-dividerLight sticky top-0 z-10 flex flex-col border-b divide-y rounded-t"
|
||||
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(--body-font-size))' : 'top: 0'"
|
||||
>
|
||||
<div v-if="!saveRequest" class="search-wrappe">
|
||||
<input
|
||||
@@ -12,7 +13,7 @@
|
||||
type="search"
|
||||
autocomplete="off"
|
||||
:placeholder="$t('action.search')"
|
||||
class="flex w-full py-2 pl-4 pr-2 bg-transparent"
|
||||
class="bg-transparent flex w-full py-2 pr-2 pl-4"
|
||||
/>
|
||||
</div>
|
||||
<CollectionsChooseType
|
||||
@@ -22,7 +23,7 @@
|
||||
@update-collection-type="updateCollectionType"
|
||||
@update-selected-team="updateSelectedTeam"
|
||||
/>
|
||||
<div class="flex justify-between flex-1">
|
||||
<div class="flex flex-1 justify-between">
|
||||
<ButtonSecondary
|
||||
v-if="
|
||||
collectionsType.type == 'team-collections' &&
|
||||
@@ -98,15 +99,15 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="filteredCollections.length === 0 && filterText.length === 0"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/pack.svg`"
|
||||
loading="lazy"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
||||
class="flex-col object-contain object-center h-16 my-4 w-16 inline-flex"
|
||||
:alt="$t('empty.collections')"
|
||||
/>
|
||||
<span class="pb-4 text-center">
|
||||
<span class="text-center pb-4">
|
||||
{{ $t("empty.collections") }}
|
||||
</span>
|
||||
<ButtonSecondary
|
||||
@@ -131,9 +132,9 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="filterText.length !== 0 && filteredCollections.length === 0"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<i class="material-icons pb-2 opacity-75">manage_search</i>
|
||||
<i class="opacity-75 pb-2 material-icons">manage_search</i>
|
||||
<span class="text-center">
|
||||
{{ $t("state.nothing_found") }} "{{ filterText }}"
|
||||
</span>
|
||||
@@ -145,8 +146,11 @@
|
||||
/>
|
||||
<CollectionsEdit
|
||||
:show="showModalEdit"
|
||||
:editing-coll-name="editingCollection ? editingCollection.name : ''"
|
||||
:placeholder-coll-name="editingCollection ? editingCollection.name : ''"
|
||||
:editing-collection-name="
|
||||
editingCollection
|
||||
? editingCollection.name || editingCollection.title
|
||||
: ''
|
||||
"
|
||||
@hide-modal="displayModalEdit(false)"
|
||||
@submit="updateEditingCollection"
|
||||
/>
|
||||
@@ -159,12 +163,15 @@
|
||||
/>
|
||||
<CollectionsEditFolder
|
||||
:show="showModalEditFolder"
|
||||
:editing-folder-name="
|
||||
editingFolder ? editingFolder.name || editingFolder.title : ''
|
||||
"
|
||||
@submit="updateEditingFolder"
|
||||
@hide-modal="displayModalEditFolder(false)"
|
||||
/>
|
||||
<CollectionsEditRequest
|
||||
:show="showModalEditRequest"
|
||||
:placeholder-req-name="editingRequest ? editingRequest.name : ''"
|
||||
:editing-request-name="editingRequest ? editingRequest.name : ''"
|
||||
@submit="updateEditingRequest"
|
||||
@hide-modal="displayModalEditRequest(false)"
|
||||
/>
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
<template>
|
||||
<div class="flex flex-col" :class="[{ 'bg-primaryLight': dragging }]">
|
||||
<div
|
||||
class="group flex items-center"
|
||||
class="flex items-stretch group"
|
||||
@dragover.prevent
|
||||
@drop.prevent="dropEvent"
|
||||
@dragover="dragging = true"
|
||||
@drop="dragging = false"
|
||||
@dragleave="dragging = false"
|
||||
@dragend="dragging = false"
|
||||
@contextmenu.prevent="$refs.options.tippy().show()"
|
||||
>
|
||||
<span
|
||||
class="flex items-center justify-center px-4 cursor-pointer"
|
||||
class="cursor-pointer flex px-4 items-center justify-center"
|
||||
@click="toggleShowChildren()"
|
||||
>
|
||||
<SmartIcon
|
||||
@@ -20,7 +21,7 @@
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="group-hover:text-secondaryDark flex flex-1 min-w-0 py-2 pr-2 transition cursor-pointer"
|
||||
class="cursor-pointer flex flex-1 min-w-0 py-2 pr-2 transition group-hover:text-secondaryDark"
|
||||
@click="toggleShowChildren()"
|
||||
>
|
||||
<span class="truncate"> {{ collection.name }} </span>
|
||||
@@ -47,7 +48,7 @@
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
svg="folder-plus"
|
||||
:title="$t('folder.new')"
|
||||
class="group-hover:inline-flex hidden"
|
||||
class="hidden group-hover:inline-flex"
|
||||
@click.native="
|
||||
$emit('add-folder', {
|
||||
folder: collection,
|
||||
@@ -110,7 +111,7 @@
|
||||
</div>
|
||||
<div v-if="showChildren || isFiltered" class="flex">
|
||||
<div
|
||||
class="flex w-1 transform transition cursor-nsResize ml-5.5 bg-dividerLight hover:scale-x-125 hover:bg-dividerDark"
|
||||
class="bg-dividerLight cursor-nsResize flex ml-5.5 transform transition w-1 hover:bg-dividerDark hover:scale-x-125"
|
||||
@click="toggleShowChildren()"
|
||||
></div>
|
||||
<div class="flex flex-col flex-1 truncate">
|
||||
@@ -158,12 +159,12 @@
|
||||
(collection.requests == undefined ||
|
||||
collection.requests.length === 0)
|
||||
"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/pack.svg`"
|
||||
loading="lazy"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 mb-4"
|
||||
class="flex-col object-contain object-center h-16 mb-4 w-16 inline-flex"
|
||||
:alt="$t('empty.collection')"
|
||||
/>
|
||||
<span class="text-center">
|
||||
@@ -218,7 +219,7 @@ export default defineComponent({
|
||||
getCollectionIcon() {
|
||||
if (this.isSelected) return "check-circle"
|
||||
else if (!this.showChildren && !this.isFiltered) return "folder"
|
||||
else if (this.showChildren || this.isFiltered) return "folder-minus"
|
||||
else if (this.showChildren || this.isFiltered) return "folder-open"
|
||||
else return "folder"
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
<template>
|
||||
<div class="flex flex-col" :class="[{ 'bg-primaryLight': dragging }]">
|
||||
<div
|
||||
class="group flex items-center"
|
||||
class="flex items-stretch group"
|
||||
@dragover.prevent
|
||||
@drop.prevent="dropEvent"
|
||||
@dragover="dragging = true"
|
||||
@drop="dragging = false"
|
||||
@dragleave="dragging = false"
|
||||
@dragend="dragging = false"
|
||||
@contextmenu.prevent="$refs.options.tippy().show()"
|
||||
>
|
||||
<span
|
||||
class="flex items-center justify-center px-4 cursor-pointer"
|
||||
class="cursor-pointer flex px-4 items-center justify-center"
|
||||
@click="toggleShowChildren()"
|
||||
>
|
||||
<SmartIcon
|
||||
@@ -20,7 +21,7 @@
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="group-hover:text-secondaryDark flex flex-1 min-w-0 py-2 pr-2 transition cursor-pointer"
|
||||
class="cursor-pointer flex flex-1 min-w-0 py-2 pr-2 transition group-hover:text-secondaryDark"
|
||||
@click="toggleShowChildren()"
|
||||
>
|
||||
<span class="truncate">
|
||||
@@ -32,7 +33,7 @@
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
svg="folder-plus"
|
||||
:title="$t('folder.new')"
|
||||
class="group-hover:inline-flex hidden"
|
||||
class="hidden group-hover:inline-flex"
|
||||
@click.native="$emit('add-folder', { folder, path: folderPath })"
|
||||
/>
|
||||
<span>
|
||||
@@ -92,7 +93,7 @@
|
||||
</div>
|
||||
<div v-if="showChildren || isFiltered" class="flex">
|
||||
<div
|
||||
class="flex w-1 transform transition cursor-nsResize ml-5.5 bg-dividerLight hover:scale-x-125 hover:bg-dividerDark"
|
||||
class="bg-dividerLight cursor-nsResize flex ml-5.5 transform transition w-1 hover:bg-dividerDark hover:scale-x-125"
|
||||
@click="toggleShowChildren()"
|
||||
></div>
|
||||
<div class="flex flex-col flex-1 truncate">
|
||||
@@ -140,12 +141,12 @@
|
||||
folder.requests &&
|
||||
folder.requests.length === 0
|
||||
"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/pack.svg`"
|
||||
loading="lazy"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 mb-4"
|
||||
class="flex-col object-contain object-center h-16 mb-4 w-16 inline-flex"
|
||||
:alt="$t('empty.folder')"
|
||||
/>
|
||||
<span class="text-center">
|
||||
@@ -204,7 +205,7 @@ export default defineComponent({
|
||||
getCollectionIcon() {
|
||||
if (this.isSelected) return "check-circle"
|
||||
else if (!this.showChildren && !this.isFiltered) return "folder"
|
||||
else if (this.showChildren || this.isFiltered) return "folder-minus"
|
||||
else if (this.showChildren || this.isFiltered) return "folder-open"
|
||||
else return "folder"
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
<template>
|
||||
<div class="flex flex-col" :class="[{ 'bg-primaryLight': dragging }]">
|
||||
<div
|
||||
class="group flex items-center"
|
||||
class="flex items-stretch group"
|
||||
draggable="true"
|
||||
@dragstart="dragStart"
|
||||
@dragover.stop
|
||||
@dragleave="dragging = false"
|
||||
@dragend="dragging = false"
|
||||
@contextmenu.prevent="$refs.options.tippy().show()"
|
||||
>
|
||||
<span
|
||||
class="flex items-center justify-center w-16 px-2 truncate cursor-pointer"
|
||||
class="cursor-pointer flex px-2 w-16 items-center justify-center truncate"
|
||||
:class="getRequestLabelColor(request.method)"
|
||||
@click="!doc ? selectRequest() : {}"
|
||||
>
|
||||
@@ -24,7 +25,7 @@
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
class="group-hover:text-secondaryDark flex items-center flex-1 min-w-0 py-2 pr-2 transition cursor-pointer"
|
||||
class="cursor-pointer flex flex-1 min-w-0 py-2 pr-2 transition items-center group-hover:text-secondaryDark"
|
||||
@click="!doc ? selectRequest() : {}"
|
||||
>
|
||||
<span class="truncate"> {{ request.name }} </span>
|
||||
@@ -44,7 +45,7 @@
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
svg="rotate-ccw"
|
||||
:title="$t('action.restore')"
|
||||
class="group-hover:inline-flex hidden"
|
||||
class="hidden group-hover:inline-flex"
|
||||
@click.native="!doc ? selectRequest() : {}"
|
||||
/>
|
||||
<span>
|
||||
@@ -116,7 +117,7 @@
|
||||
|
||||
<script>
|
||||
import { defineComponent } from "@nuxtjs/composition-api"
|
||||
import { translateToNewRequest } from "~/helpers/types/HoppRESTRequest"
|
||||
import { translateToNewRequest } from "@hoppscotch/data"
|
||||
import { useReadonlyStream } from "~/helpers/utils/composables"
|
||||
import {
|
||||
restSaveContext$,
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
<template>
|
||||
<div class="flex flex-col">
|
||||
<div class="group flex items-center">
|
||||
<div
|
||||
class="flex items-stretch group"
|
||||
@contextmenu.prevent="$refs.options.tippy().show()"
|
||||
>
|
||||
<span
|
||||
class="flex items-center justify-center px-4 cursor-pointer"
|
||||
class="cursor-pointer flex px-4 items-center justify-center"
|
||||
@click="toggleShowChildren()"
|
||||
>
|
||||
<SmartIcon
|
||||
@@ -12,7 +15,7 @@
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="group-hover:text-secondaryDark flex flex-1 min-w-0 py-2 pr-2 transition cursor-pointer"
|
||||
class="cursor-pointer flex flex-1 min-w-0 py-2 pr-2 transition group-hover:text-secondaryDark"
|
||||
@click="toggleShowChildren()"
|
||||
>
|
||||
<span class="truncate"> {{ collection.title }} </span>
|
||||
@@ -39,7 +42,7 @@
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
svg="folder-plus"
|
||||
:title="$t('folder.new')"
|
||||
class="group-hover:inline-flex hidden"
|
||||
class="hidden group-hover:inline-flex"
|
||||
@click.native="
|
||||
$emit('add-folder', {
|
||||
folder: collection,
|
||||
@@ -106,7 +109,7 @@
|
||||
</div>
|
||||
<div v-if="showChildren || isFiltered" class="flex">
|
||||
<div
|
||||
class="flex w-1 transform transition cursor-nsResize ml-5.5 bg-dividerLight hover:scale-x-125 hover:bg-dividerDark"
|
||||
class="bg-dividerLight cursor-nsResize flex ml-5.5 transform transition w-1 hover:bg-dividerDark hover:scale-x-125"
|
||||
@click="toggleShowChildren()"
|
||||
></div>
|
||||
<div class="flex flex-col flex-1 truncate">
|
||||
@@ -152,12 +155,12 @@
|
||||
(collection.requests == undefined ||
|
||||
collection.requests.length === 0)
|
||||
"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/pack.svg`"
|
||||
loading="lazy"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 mb-4"
|
||||
class="flex-col object-contain object-center h-16 mb-4 w-16 inline-flex"
|
||||
:alt="$t('empty.collection')"
|
||||
/>
|
||||
<span class="text-center">
|
||||
@@ -210,7 +213,7 @@ export default defineComponent({
|
||||
getCollectionIcon() {
|
||||
if (this.isSelected) return "check-circle"
|
||||
else if (!this.showChildren && !this.isFiltered) return "folder"
|
||||
else if (this.showChildren || this.isFiltered) return "folder-minus"
|
||||
else if (this.showChildren || this.isFiltered) return "folder-open"
|
||||
else return "folder"
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
<template>
|
||||
<div class="flex flex-col">
|
||||
<div class="group flex items-center">
|
||||
<div
|
||||
class="flex items-stretch group"
|
||||
@contextmenu.prevent="$refs.options.tippy().show()"
|
||||
>
|
||||
<span
|
||||
class="flex items-center justify-center px-4 cursor-pointer"
|
||||
class="cursor-pointer flex px-4 items-center justify-center"
|
||||
@click="toggleShowChildren()"
|
||||
>
|
||||
<SmartIcon
|
||||
@@ -12,7 +15,7 @@
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="group-hover:text-secondaryDark flex flex-1 min-w-0 py-2 pr-2 transition cursor-pointer"
|
||||
class="cursor-pointer flex flex-1 min-w-0 py-2 pr-2 transition group-hover:text-secondaryDark"
|
||||
@click="toggleShowChildren()"
|
||||
>
|
||||
<span class="truncate">
|
||||
@@ -25,7 +28,7 @@
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
svg="folder-plus"
|
||||
:title="$t('folder.new')"
|
||||
class="group-hover:inline-flex hidden"
|
||||
class="hidden group-hover:inline-flex"
|
||||
@click.native="$emit('add-folder', { folder, path: folderPath })"
|
||||
/>
|
||||
<span>
|
||||
@@ -89,7 +92,7 @@
|
||||
</div>
|
||||
<div v-if="showChildren || isFiltered" class="flex">
|
||||
<div
|
||||
class="flex w-1 transform transition cursor-nsResize ml-5.5 bg-dividerLight hover:scale-x-125 hover:bg-dividerDark"
|
||||
class="bg-dividerLight cursor-nsResize flex ml-5.5 transform transition w-1 hover:bg-dividerDark hover:scale-x-125"
|
||||
@click="toggleShowChildren()"
|
||||
></div>
|
||||
<div class="flex flex-col flex-1 truncate">
|
||||
@@ -133,12 +136,12 @@
|
||||
(folder.children == undefined || folder.children.length === 0) &&
|
||||
(folder.requests == undefined || folder.requests.length === 0)
|
||||
"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/pack.svg`"
|
||||
loading="lazy"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 mb-4"
|
||||
class="flex-col object-contain object-center h-16 mb-4 w-16 inline-flex"
|
||||
:alt="$t('empty.folder')"
|
||||
/>
|
||||
<span class="text-center">
|
||||
@@ -192,7 +195,7 @@ export default defineComponent({
|
||||
getCollectionIcon() {
|
||||
if (this.isSelected) return "check-circle"
|
||||
else if (!this.showChildren && !this.isFiltered) return "folder"
|
||||
else if (this.showChildren || this.isFiltered) return "folder-minus"
|
||||
else if (this.showChildren || this.isFiltered) return "folder-open"
|
||||
else return "folder"
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
<template>
|
||||
<div class="flex flex-col">
|
||||
<div class="group flex items-center">
|
||||
<div
|
||||
class="flex items-stretch group"
|
||||
@contextmenu.prevent="$refs.options.tippy().show()"
|
||||
>
|
||||
<span
|
||||
class="flex items-center justify-center w-16 px-2 truncate cursor-pointer"
|
||||
class="cursor-pointer flex px-2 w-16 items-center justify-center truncate"
|
||||
:class="getRequestLabelColor(request.method)"
|
||||
@click="!doc ? selectRequest() : {}"
|
||||
>
|
||||
@@ -17,7 +20,7 @@
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
class="group-hover:text-secondaryDark flex items-center flex-1 min-w-0 py-2 pr-2 transition cursor-pointer"
|
||||
class="cursor-pointer flex flex-1 min-w-0 py-2 pr-2 transition items-center group-hover:text-secondaryDark"
|
||||
@click="!doc ? selectRequest() : {}"
|
||||
>
|
||||
<span class="truncate"> {{ request.name }} </span>
|
||||
@@ -36,7 +39,7 @@
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
svg="rotate-ccw"
|
||||
:title="$t('action.restore')"
|
||||
class="group-hover:inline-flex hidden"
|
||||
class="hidden group-hover:inline-flex"
|
||||
@click.native="!doc ? selectRequest() : {}"
|
||||
/>
|
||||
<span>
|
||||
@@ -93,7 +96,7 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from "@nuxtjs/composition-api"
|
||||
import { translateToNewRequest } from "~/helpers/types/HoppRESTRequest"
|
||||
import { translateToNewRequest } from "@hoppscotch/data"
|
||||
import { useReadonlyStream } from "~/helpers/utils/composables"
|
||||
import {
|
||||
restSaveContext$,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="folder">
|
||||
<h3 class="heading">
|
||||
<SmartIcon name="folder-minus" class="svg-icons" />
|
||||
<SmartIcon name="folder-open" class="svg-icons" />
|
||||
{{ folder.name || $t("state.none") }}
|
||||
</h3>
|
||||
<div
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
>
|
||||
<template #body>
|
||||
<div class="flex flex-col px-2">
|
||||
<div class="relative flex">
|
||||
<div class="flex relative">
|
||||
<input
|
||||
id="selectLabelEnvEdit"
|
||||
v-model="name"
|
||||
@@ -22,7 +22,7 @@
|
||||
{{ $t("action.label") }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="flex items-center justify-between flex-1">
|
||||
<div class="flex flex-1 items-center justify-between">
|
||||
<label for="variableList" class="p-4">
|
||||
{{ $t("environment.variable_list") }}
|
||||
</label>
|
||||
@@ -31,33 +31,31 @@
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.clear_all')"
|
||||
:svg="clearIcon"
|
||||
class="rounded"
|
||||
@click.native="clearContent()"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
svg="plus"
|
||||
:title="$t('add.new')"
|
||||
class="rounded"
|
||||
@click.native="addEnvironmentVariable"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="divide-dividerLight border-divider border divide-y rounded">
|
||||
<div class="divide-dividerLight divide-y border border-divider rounded">
|
||||
<div
|
||||
v-for="(variable, index) in vars"
|
||||
:key="`variable-${index}`"
|
||||
class="divide-dividerLight flex divide-x"
|
||||
class="divide-dividerLight divide-x flex"
|
||||
>
|
||||
<input
|
||||
v-model="variable.key"
|
||||
class="flex flex-1 px-4 py-2 bg-transparent"
|
||||
class="bg-transparent flex flex-1 py-2 px-4"
|
||||
:placeholder="`${$t('count.variable', { count: index + 1 })}`"
|
||||
:name="'param' + index"
|
||||
/>
|
||||
<input
|
||||
v-model="variable.value"
|
||||
class="flex flex-1 px-4 py-2 bg-transparent"
|
||||
class="bg-transparent flex flex-1 py-2 px-4"
|
||||
:placeholder="`${$t('count.value', { count: index + 1 })}`"
|
||||
:name="'value' + index"
|
||||
/>
|
||||
@@ -74,15 +72,15 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="vars.length === 0"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/blockchain.svg`"
|
||||
loading="lazy"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
||||
class="flex-col object-contain object-center h-16 my-4 w-16 inline-flex"
|
||||
:alt="$t('empty.environments')"
|
||||
/>
|
||||
<span class="pb-4 text-center">
|
||||
<span class="text-center pb-4">
|
||||
{{ $t("empty.environments") }}
|
||||
</span>
|
||||
<ButtonSecondary
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
<template>
|
||||
<div class="group flex items-center">
|
||||
<div
|
||||
class="flex items-stretch group"
|
||||
@contextmenu.prevent="$refs.options.tippy().show()"
|
||||
>
|
||||
<span
|
||||
class="flex items-center justify-center px-4 cursor-pointer"
|
||||
class="cursor-pointer flex px-4 items-center justify-center"
|
||||
@click="$emit('edit-environment')"
|
||||
>
|
||||
<SmartIcon class="svg-icons" name="layers" />
|
||||
</span>
|
||||
<span
|
||||
class="group-hover:text-secondaryDark flex flex-1 min-w-0 py-2 pr-2 transition cursor-pointer"
|
||||
class="cursor-pointer flex flex-1 min-w-0 py-2 pr-2 transition group-hover:text-secondaryDark"
|
||||
@click="$emit('edit-environment')"
|
||||
>
|
||||
<span class="truncate">
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.more')"
|
||||
class="rounded"
|
||||
svg="more-vertical"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
<template>
|
||||
<AppSection :label="`${$t('environment.title')}`">
|
||||
<div class="bg-primary sticky top-0 z-10 flex flex-col rounded-t">
|
||||
<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>
|
||||
<span
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="`${$t('environment.select')}`"
|
||||
class="border-dividerLight select-wrapper flex-1 bg-transparent border-b"
|
||||
class="bg-transparent border-b border-dividerLight flex-1 select-wrapper"
|
||||
>
|
||||
<ButtonSecondary
|
||||
v-if="selectedEnvironmentIndex !== -1"
|
||||
:label="environments[selectedEnvironmentIndex].name"
|
||||
class="flex-1 pr-8 rounded-none"
|
||||
class="rounded-none flex-1 pr-8"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-else
|
||||
:label="`${$t('environment.no_environment')}`"
|
||||
class="flex-1 pr-8 rounded-none"
|
||||
class="rounded-none flex-1 pr-8"
|
||||
/>
|
||||
</span>
|
||||
</template>
|
||||
@@ -45,7 +45,7 @@
|
||||
"
|
||||
/>
|
||||
</tippy>
|
||||
<div class="border-dividerLight flex justify-between flex-1 border-b">
|
||||
<div class="border-b border-dividerLight flex flex-1 justify-between">
|
||||
<ButtonSecondary
|
||||
svg="plus"
|
||||
:label="`${$t('action.new')}`"
|
||||
@@ -86,7 +86,7 @@
|
||||
<EnvironmentsEnvironment
|
||||
environment-index="Global"
|
||||
:environment="globalEnvironment"
|
||||
class="border-dividerLight border-b border-dashed"
|
||||
class="border-b border-dashed border-dividerLight"
|
||||
@edit-environment="editEnvironment('Global')"
|
||||
/>
|
||||
<EnvironmentsEnvironment
|
||||
@@ -99,15 +99,15 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="environments.length === 0"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/blockchain.svg`"
|
||||
loading="lazy"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
||||
class="flex-col object-contain object-center h-16 my-4 w-16 inline-flex"
|
||||
:alt="$t('empty.environments')"
|
||||
/>
|
||||
<span class="pb-4 text-center">
|
||||
<span class="text-center pb-4">
|
||||
{{ $t("empty.environments") }}
|
||||
</span>
|
||||
<ButtonSecondary
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
@close="hideModal"
|
||||
>
|
||||
<template #body>
|
||||
<div v-if="mode === 'sign-in'" class="flex flex-col px-2 space-y-2">
|
||||
<div v-if="mode === 'sign-in'" class="flex flex-col space-y-2 px-2">
|
||||
<SmartItem
|
||||
:loading="signingInWithGitHub"
|
||||
svg="auth/github"
|
||||
@@ -56,8 +56,8 @@
|
||||
/>
|
||||
</form>
|
||||
<div v-if="mode === 'email-sent'" class="flex flex-col px-4">
|
||||
<div class="flex flex-col items-center justify-center max-w-md">
|
||||
<SmartIcon class="text-accent w-6 h-6" name="inbox" />
|
||||
<div class="flex flex-col max-w-md items-center justify-center">
|
||||
<SmartIcon class="h-6 text-accent w-6" name="inbox" />
|
||||
<h3 class="my-2 text-lg text-center">
|
||||
{{ $t("auth.we_sent_magic_link") }}
|
||||
</h3>
|
||||
@@ -95,7 +95,7 @@
|
||||
</p>
|
||||
<p
|
||||
v-if="mode === 'email-sent'"
|
||||
class="text-secondaryLight flex justify-between flex-1"
|
||||
class="flex flex-1 text-secondaryLight justify-between"
|
||||
>
|
||||
<SmartAnchor
|
||||
class="link"
|
||||
|
||||
@@ -21,19 +21,19 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="gqlField.description"
|
||||
class="text-secondaryLight field-desc py-2"
|
||||
class="text-secondaryLight py-2 field-desc"
|
||||
>
|
||||
{{ gqlField.description }}
|
||||
</div>
|
||||
<div
|
||||
v-if="gqlField.isDeprecated"
|
||||
class="field-deprecated inline-block px-2 py-1 my-1 text-black bg-yellow-200 rounded"
|
||||
class="rounded bg-yellow-200 my-1 text-black py-1 px-2 inline-block field-deprecated"
|
||||
>
|
||||
{{ $t("state.deprecated") }}
|
||||
</div>
|
||||
<div v-if="fieldArgs.length > 0">
|
||||
<h5 class="my-2">Arguments:</h5>
|
||||
<div class="border-divider pl-4 border-l-2">
|
||||
<div class="border-divider border-l-2 pl-4">
|
||||
<div v-for="(field, index) in fieldArgs" :key="`field-${index}`">
|
||||
<span>
|
||||
{{ field.name }}:
|
||||
@@ -44,7 +44,7 @@
|
||||
</span>
|
||||
<div
|
||||
v-if="field.description"
|
||||
class="text-secondaryLight field-desc py-2"
|
||||
class="text-secondaryLight py-2 field-desc"
|
||||
>
|
||||
{{ field.description }}
|
||||
</div>
|
||||
@@ -77,7 +77,7 @@ export default defineComponent({
|
||||
|
||||
<style scoped lang="scss">
|
||||
.field-highlighted {
|
||||
@apply border-b-2 border-accent;
|
||||
@apply border-accent border-b-2;
|
||||
}
|
||||
|
||||
.field-title {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<template>
|
||||
<div class="bg-primary sticky top-0 z-10 flex p-4">
|
||||
<div class="inline-flex flex-1 space-x-2">
|
||||
<div class="bg-primary flex p-4 top-0 z-10 sticky">
|
||||
<div class="space-x-2 flex-1 inline-flex">
|
||||
<input
|
||||
id="url"
|
||||
v-model="url"
|
||||
type="url"
|
||||
autocomplete="off"
|
||||
spellcheck="false"
|
||||
class="bg-primaryLight border-divider text-secondaryDark hover:border-dividerDark focus-visible:bg-transparent focus-visible:border-dividerDark w-full px-4 py-2 border rounded"
|
||||
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('request.url')}`"
|
||||
:disabled="connected"
|
||||
@keyup.enter="onConnectClick"
|
||||
|
||||
@@ -1,33 +1,31 @@
|
||||
<template>
|
||||
<div>
|
||||
<SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10">
|
||||
<template #actions>
|
||||
<ButtonSecondary
|
||||
:label="`${t('request.run')}`"
|
||||
svg="play"
|
||||
class="rounded-none !text-accent"
|
||||
@click.native="runQuery()"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
ref="saveRequest"
|
||||
:label="`${t('request.save')}`"
|
||||
class="rounded-none"
|
||||
@click.native="saveRequest"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<SmartTab :id="'query'" :label="`${t('tab.query')}`" :selected="true">
|
||||
<AppSection label="query">
|
||||
<div
|
||||
class="bg-primary border-dividerLight top-upperSecondaryStickyFold gqlRunQuery sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 top-upperSecondaryStickyFold pl-4 z-10 sticky items-center justify-between gqlRunQuery"
|
||||
>
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
<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/#queries"
|
||||
to="https://docs.hoppscotch.io/graphql"
|
||||
blank
|
||||
:title="t('app.wiki')"
|
||||
svg="help-circle"
|
||||
@@ -53,15 +51,15 @@
|
||||
<SmartTab :id="'variables'" :label="`${t('tab.variables')}`">
|
||||
<AppSection label="variables">
|
||||
<div
|
||||
class="bg-primary border-dividerLight top-upperSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 top-upperSecondaryStickyFold pl-4 z-10 sticky items-center justify-between"
|
||||
>
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ t("request.variables") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
to="https://docs.hoppscotch.io/graphql/#queries"
|
||||
to="https://docs.hoppscotch.io/graphql"
|
||||
blank
|
||||
:title="t('app.wiki')"
|
||||
svg="help-circle"
|
||||
@@ -81,15 +79,15 @@
|
||||
<SmartTab :id="'headers'" :label="`${t('tab.headers')}`">
|
||||
<AppSection label="headers">
|
||||
<div
|
||||
class="bg-primary border-dividerLight top-upperSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 top-upperSecondaryStickyFold pl-4 z-10 sticky items-center justify-between"
|
||||
>
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ t("tab.headers") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
to="https://docs.hoppscotch.io/graphql/#headers"
|
||||
to="https://docs.hoppscotch.io/graphql"
|
||||
blank
|
||||
:title="t('app.wiki')"
|
||||
svg="help-circle"
|
||||
@@ -121,7 +119,7 @@
|
||||
<div
|
||||
v-for="(header, index) in headers"
|
||||
:key="`header-${String(index)}`"
|
||||
class="divide-dividerLight border-dividerLight flex border-b divide-x"
|
||||
class="divide-dividerLight divide-x border-b border-dividerLight flex"
|
||||
>
|
||||
<SmartAutoComplete
|
||||
:placeholder="`${t('count.header', { count: index + 1 })}`"
|
||||
@@ -137,7 +135,7 @@
|
||||
px-4
|
||||
truncate
|
||||
"
|
||||
class="!flex flex-1"
|
||||
class="flex-1 !flex"
|
||||
@input="
|
||||
updateRequestHeader(index, {
|
||||
key: $event,
|
||||
@@ -147,7 +145,7 @@
|
||||
"
|
||||
/>
|
||||
<input
|
||||
class="flex flex-1 px-4 py-2 bg-transparent"
|
||||
class="bg-transparent flex flex-1 py-2 px-4"
|
||||
:placeholder="`${t('count.value', { count: index + 1 })}`"
|
||||
:name="`value ${String(index)}`"
|
||||
:value="header.value"
|
||||
@@ -199,15 +197,15 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="headers.length === 0"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<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"
|
||||
class="flex-col object-contain object-center h-16 my-4 w-16 inline-flex"
|
||||
:alt="`${t('empty.headers')}`"
|
||||
/>
|
||||
<span class="pb-4 text-center">
|
||||
<span class="text-center pb-4">
|
||||
{{ t("empty.headers") }}
|
||||
</span>
|
||||
<ButtonSecondary
|
||||
@@ -235,6 +233,7 @@
|
||||
import { onMounted, ref, watch } from "@nuxtjs/composition-api"
|
||||
import clone from "lodash/clone"
|
||||
import * as gql from "graphql"
|
||||
import { GQLHeader, makeGQLRequest } from "@hoppscotch/data"
|
||||
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
||||
import {
|
||||
useNuxt,
|
||||
@@ -262,7 +261,6 @@ import { GQLConnection } from "~/helpers/GQLConnection"
|
||||
import { makeGQLHistoryEntry, addGraphqlHistoryEntry } from "~/newstore/history"
|
||||
import { logHoppRequestRunToAnalytics } from "~/helpers/fb/analytics"
|
||||
import { getCurrentStrategyID } from "~/helpers/network"
|
||||
import { GQLHeader, makeGQLRequest } from "~/helpers/types/HoppGQLRequest"
|
||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||
import jsonLinter from "~/helpers/editor/linting/json"
|
||||
import { createGQLQueryLinter } from "~/helpers/editor/linting/gqlQuery"
|
||||
|
||||
@@ -2,16 +2,16 @@
|
||||
<AppSection ref="response" label="response">
|
||||
<div
|
||||
v-if="responseString === 'loading'"
|
||||
class="flex flex-col items-center justify-center p-4"
|
||||
class="flex flex-col p-4 items-center justify-center"
|
||||
>
|
||||
<SmartSpinner class="my-4" />
|
||||
<span class="text-secondaryLight">{{ t("state.loading") }}</span>
|
||||
</div>
|
||||
<div v-else-if="responseString">
|
||||
<div
|
||||
class="bg-primary border-dividerLight sticky top-0 z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 pl-4 top-0 z-10 sticky items-center justify-between"
|
||||
>
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ t("response.title") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
@@ -19,7 +19,7 @@
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('state.linewrap')"
|
||||
:class="{ '!text-accent': linewrapEnabled }"
|
||||
svg="corner-down-left"
|
||||
svg="wrap-text"
|
||||
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
@@ -42,14 +42,14 @@
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="text-secondaryLight flex flex-col items-center justify-center flex-1 p-4"
|
||||
class="flex flex-col flex-1 text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<div class="flex pb-4 my-4 space-x-2">
|
||||
<div class="flex flex-col items-end space-y-4 text-right">
|
||||
<span class="flex items-center flex-1">
|
||||
<div class="flex space-x-2 my-4 pb-4">
|
||||
<div class="flex flex-col space-y-4 text-right items-end">
|
||||
<span class="flex flex-1 items-center">
|
||||
{{ t("shortcut.general.command_menu") }}
|
||||
</span>
|
||||
<span class="flex items-center flex-1">
|
||||
<span class="flex flex-1 items-center">
|
||||
{{ t("shortcut.general.help_menu") }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -34,26 +34,26 @@
|
||||
subscriptionFields.length === 0 &&
|
||||
graphqlTypes.length === 0
|
||||
"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/add_comment.svg`"
|
||||
loading="lazy"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
||||
class="flex-col object-contain object-center h-16 my-4 w-16 inline-flex"
|
||||
:alt="`${t('empty.documentation')}`"
|
||||
/>
|
||||
<span class="mb-4 text-center">
|
||||
<span class="text-center mb-4">
|
||||
{{ t("empty.documentation") }}
|
||||
</span>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="bg-primary sticky top-0 z-10 flex">
|
||||
<div class="bg-primary flex top-0 z-10 sticky">
|
||||
<input
|
||||
v-model="graphqlFieldsFilterText"
|
||||
type="search"
|
||||
autocomplete="off"
|
||||
:placeholder="`${t('action.search')}`"
|
||||
class="flex w-full p-4 py-2 bg-transparent"
|
||||
class="bg-transparent flex w-full p-4 py-2"
|
||||
/>
|
||||
<div class="flex">
|
||||
<ButtonSecondary
|
||||
@@ -140,9 +140,9 @@
|
||||
<AppSection ref="schema" label="schema">
|
||||
<div
|
||||
v-if="schemaString"
|
||||
class="bg-primary border-dividerLight sticky top-0 z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 pl-4 top-0 z-10 sticky items-center justify-between"
|
||||
>
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ t("graphql.schema") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
@@ -157,7 +157,7 @@
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('state.linewrap')"
|
||||
:class="{ '!text-accent': linewrapEnabled }"
|
||||
svg="corner-down-left"
|
||||
svg="wrap-text"
|
||||
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
@@ -179,15 +179,15 @@
|
||||
<div v-if="schemaString" ref="schemaEditor"></div>
|
||||
<div
|
||||
v-else
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/blockchain.svg`"
|
||||
loading="lazy"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
||||
class="flex-col object-contain object-center h-16 my-4 w-16 inline-flex"
|
||||
:alt="`${t('empty.schema')}`"
|
||||
/>
|
||||
<span class="mb-4 text-center">
|
||||
<span class="text-center mb-4">
|
||||
{{ t("empty.schema") }}
|
||||
</span>
|
||||
</div>
|
||||
@@ -200,9 +200,9 @@
|
||||
import { computed, nextTick, reactive, ref } from "@nuxtjs/composition-api"
|
||||
import { GraphQLField, GraphQLType } from "graphql"
|
||||
import { map } from "rxjs/operators"
|
||||
import { GQLHeader } from "@hoppscotch/data"
|
||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||
import { GQLConnection } from "~/helpers/GQLConnection"
|
||||
import { GQLHeader } from "~/helpers/types/HoppGQLRequest"
|
||||
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
||||
import {
|
||||
useReadonlyStream,
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<span v-else-if="isEnum" class="text-accent">enum </span>
|
||||
{{ gqlType.name }}
|
||||
</div>
|
||||
<div v-if="gqlType.description" class="py-2 text-secondaryLight type-desc">
|
||||
<div v-if="gqlType.description" class="text-secondaryLight py-2 type-desc">
|
||||
{{ gqlType.description }}
|
||||
</div>
|
||||
<div v-if="interfaces.length > 0">
|
||||
@@ -18,7 +18,7 @@
|
||||
<GraphqlTypeLink
|
||||
:gql-type="gqlInterface"
|
||||
:jump-type-callback="jumpTypeCallback"
|
||||
class="pl-4 border-l-2 border-divider"
|
||||
class="border-divider border-l-2 pl-4"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -29,7 +29,7 @@
|
||||
:key="`child-${index}`"
|
||||
:gql-type="child"
|
||||
:jump-type-callback="jumpTypeCallback"
|
||||
class="pl-4 border-l-2 border-divider"
|
||||
class="border-divider border-l-2 pl-4"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="gqlType.getFields">
|
||||
@@ -37,7 +37,7 @@
|
||||
<GraphqlField
|
||||
v-for="(field, index) in gqlType.getFields()"
|
||||
:key="`field-${index}`"
|
||||
class="pl-4 border-l-2 border-divider"
|
||||
class="border-divider border-l-2 pl-4"
|
||||
:gql-field="field"
|
||||
:is-highlighted="isFieldHighlighted({ field })"
|
||||
:jump-type-callback="jumpTypeCallback"
|
||||
@@ -48,7 +48,7 @@
|
||||
<div
|
||||
v-for="(value, index) in gqlType.getValues()"
|
||||
:key="`value-${index}`"
|
||||
class="pl-4 border-l-2 border-divider"
|
||||
class="border-divider border-l-2 pl-4"
|
||||
v-text="value.name"
|
||||
></div>
|
||||
</div>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div class="group flex flex-col">
|
||||
<div class="flex flex-col group">
|
||||
<div class="flex items-center">
|
||||
<span
|
||||
class="group-hover:text-secondaryDark flex flex-1 min-w-0 py-2 pl-4 pr-2 transition cursor-pointer"
|
||||
class="cursor-pointer flex flex-1 min-w-0 py-2 pr-2 pl-4 transition group-hover:text-secondaryDark"
|
||||
data-testid="restore_history_entry"
|
||||
@click="useEntry"
|
||||
>
|
||||
@@ -15,7 +15,7 @@
|
||||
svg="trash"
|
||||
color="red"
|
||||
:title="$t('action.remove')"
|
||||
class="group-hover:inline-flex hidden"
|
||||
class="hidden group-hover:inline-flex"
|
||||
data-testid="delete_history_entry"
|
||||
@click.native="$emit('delete-entry')"
|
||||
/>
|
||||
@@ -23,7 +23,7 @@
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="expand ? $t('hide.more') : $t('show.more')"
|
||||
:svg="expand ? 'minimize-2' : 'maximize-2'"
|
||||
class="group-hover:inline-flex hidden"
|
||||
class="hidden group-hover:inline-flex"
|
||||
@click.native="expand = !expand"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
@@ -40,7 +40,7 @@
|
||||
<span
|
||||
v-for="(line, index) in query"
|
||||
:key="`line-${index}`"
|
||||
class="text-secondaryLight px-4 truncate whitespace-pre cursor-pointer"
|
||||
class="cursor-pointer font-mono text-secondaryLight px-4 truncate whitespace-pre"
|
||||
data-testid="restore_history_entry"
|
||||
@click="useEntry"
|
||||
>{{ line }}</span
|
||||
@@ -56,7 +56,7 @@ import {
|
||||
PropType,
|
||||
ref,
|
||||
} from "@nuxtjs/composition-api"
|
||||
import { makeGQLRequest } from "~/helpers/types/HoppGQLRequest"
|
||||
import { makeGQLRequest } from "@hoppscotch/data"
|
||||
import { setGQLSession } from "~/newstore/GQLSession"
|
||||
import { GQLHistoryEntry } from "~/newstore/history"
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<template>
|
||||
<AppSection label="history">
|
||||
<div class="sticky top-0 z-10 flex border-b bg-primary border-dividerLight">
|
||||
<div class="bg-primary border-b border-dividerLight flex top-0 z-10 sticky">
|
||||
<input
|
||||
v-model="filterText"
|
||||
type="search"
|
||||
autocomplete="off"
|
||||
class="flex w-full p-4 py-2 bg-transparent"
|
||||
class="bg-transparent flex w-full p-4 py-2"
|
||||
:placeholder="`${$t('action.search')}`"
|
||||
/>
|
||||
<div class="flex">
|
||||
@@ -49,24 +49,24 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="!(filteredHistory.length !== 0 || history.length === 0)"
|
||||
class="flex flex-col items-center justify-center p-4 text-secondaryLight"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<i class="pb-2 opacity-75 material-icons">manage_search</i>
|
||||
<i class="opacity-75 pb-2 material-icons">manage_search</i>
|
||||
<span class="text-center">
|
||||
{{ $t("state.nothing_found") }} "{{ filterText }}"
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="history.length === 0"
|
||||
class="flex flex-col items-center justify-center p-4 text-secondaryLight"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/history.svg`"
|
||||
loading="lazy"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
||||
class="flex-col object-contain object-center h-16 my-4 w-16 inline-flex"
|
||||
:alt="$t('empty.history')"
|
||||
/>
|
||||
<span class="mb-4 text-center">
|
||||
<span class="text-center mb-4">
|
||||
{{ $t("empty.history") }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="group flex items-center">
|
||||
<div class="flex items-stretch group">
|
||||
<span
|
||||
class="flex items-center justify-center w-16 px-2 truncate cursor-pointer"
|
||||
class="cursor-pointer flex px-2 w-16 items-center justify-center truncate"
|
||||
:class="entryStatus.className"
|
||||
data-testid="restore_history_entry"
|
||||
:title="`${duration}`"
|
||||
@@ -10,7 +10,7 @@
|
||||
{{ entry.request.method }}
|
||||
</span>
|
||||
<span
|
||||
class="group-hover:text-secondaryDark flex flex-1 min-w-0 py-2 pr-2 transition cursor-pointer"
|
||||
class="cursor-pointer flex flex-1 min-w-0 py-2 pr-2 transition group-hover:text-secondaryDark"
|
||||
data-testid="restore_history_entry"
|
||||
:title="`${duration}`"
|
||||
@click="$emit('use-entry')"
|
||||
@@ -24,7 +24,7 @@
|
||||
svg="trash"
|
||||
color="red"
|
||||
:title="$t('action.remove')"
|
||||
class="group-hover:inline-flex hidden"
|
||||
class="hidden group-hover:inline-flex"
|
||||
data-testid="delete_history_entry"
|
||||
@click.native="$emit('delete-entry')"
|
||||
/>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
class="bg-primary border-dividerLight top-upperSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 top-upperSecondaryStickyFold pl-4 z-10 sticky items-center justify-between"
|
||||
>
|
||||
<span class="flex items-center">
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ $t("authorization.type") }}
|
||||
</label>
|
||||
<tippy
|
||||
@@ -17,13 +17,18 @@
|
||||
<template #trigger>
|
||||
<span class="select-wrapper">
|
||||
<ButtonSecondary
|
||||
class="pr-8 ml-2 rounded-none"
|
||||
class="rounded-none ml-2 pr-8"
|
||||
:label="authName"
|
||||
/>
|
||||
</span>
|
||||
</template>
|
||||
<SmartItem
|
||||
label="None"
|
||||
:icon="
|
||||
authName === 'None'
|
||||
? 'radio_button_checked'
|
||||
: 'radio_button_unchecked'
|
||||
"
|
||||
@click.native="
|
||||
authType = 'none'
|
||||
$refs.authTypeOptions.tippy().hide()
|
||||
@@ -31,6 +36,11 @@
|
||||
/>
|
||||
<SmartItem
|
||||
label="Basic Auth"
|
||||
:icon="
|
||||
authName === 'Basic Auth'
|
||||
? 'radio_button_checked'
|
||||
: 'radio_button_unchecked'
|
||||
"
|
||||
@click.native="
|
||||
authType = 'basic'
|
||||
$refs.authTypeOptions.tippy().hide()
|
||||
@@ -38,6 +48,11 @@
|
||||
/>
|
||||
<SmartItem
|
||||
label="Bearer Token"
|
||||
:icon="
|
||||
authName === 'Bearer'
|
||||
? 'radio_button_checked'
|
||||
: 'radio_button_unchecked'
|
||||
"
|
||||
@click.native="
|
||||
authType = 'bearer'
|
||||
$refs.authTypeOptions.tippy().hide()
|
||||
@@ -45,6 +60,11 @@
|
||||
/>
|
||||
<SmartItem
|
||||
label="OAuth 2.0"
|
||||
:icon="
|
||||
authName === 'OAuth 2.0'
|
||||
? 'radio_button_checked'
|
||||
: 'radio_button_unchecked'
|
||||
"
|
||||
@click.native="
|
||||
authType = 'oauth-2'
|
||||
$refs.authTypeOptions.tippy().hide()
|
||||
@@ -83,15 +103,15 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="authType === 'none'"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<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"
|
||||
class="flex-col object-contain object-center h-16 my-4 w-16 inline-flex"
|
||||
:alt="$t('empty.authorization')"
|
||||
/>
|
||||
<span class="pb-4 text-center">
|
||||
<span class="text-center pb-4">
|
||||
{{ $t("empty.authorization") }}
|
||||
</span>
|
||||
<ButtonSecondary
|
||||
@@ -104,16 +124,16 @@
|
||||
class="mb-4"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="authType === 'basic'" class="border-dividerLight flex border-b">
|
||||
<div class="border-dividerLight w-2/3 border-r">
|
||||
<div class="border-dividerLight flex border-b">
|
||||
<div v-if="authType === 'basic'" class="border-b border-dividerLight flex">
|
||||
<div class="border-r border-dividerLight w-2/3">
|
||||
<div class="border-b border-dividerLight flex">
|
||||
<SmartEnvInput
|
||||
v-model="basicUsername"
|
||||
:placeholder="$t('authorization.username')"
|
||||
styles="bg-transparent flex flex-1 py-1 px-4"
|
||||
/>
|
||||
</div>
|
||||
<div class="border-dividerLight flex border-b">
|
||||
<div class="border-b border-dividerLight flex">
|
||||
<SmartEnvInput
|
||||
v-model="basicPassword"
|
||||
:placeholder="$t('authorization.password')"
|
||||
@@ -122,7 +142,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="bg-primary top-upperTertiaryStickyFold min-w-46 max-w-1/3 z-9 sticky h-full p-4 overflow-auto"
|
||||
class="bg-primary h-full top-upperTertiaryStickyFold min-w-46 max-w-1/3 p-4 z-9 sticky overflow-auto"
|
||||
>
|
||||
<div class="p-2">
|
||||
<div class="text-secondaryLight pb-2">
|
||||
@@ -137,9 +157,9 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="authType === 'bearer'" class="border-dividerLight flex border-b">
|
||||
<div class="border-dividerLight w-2/3 border-r">
|
||||
<div class="border-dividerLight flex border-b">
|
||||
<div v-if="authType === 'bearer'" class="border-b border-dividerLight flex">
|
||||
<div class="border-r border-dividerLight w-2/3">
|
||||
<div class="border-b border-dividerLight flex">
|
||||
<SmartEnvInput
|
||||
v-model="bearerToken"
|
||||
placeholder="Token"
|
||||
@@ -148,7 +168,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="bg-primary top-upperTertiaryStickyFold min-w-46 max-w-1/3 z-9 sticky h-full p-4 overflow-auto"
|
||||
class="bg-primary h-full top-upperTertiaryStickyFold min-w-46 max-w-1/3 p-4 z-9 sticky overflow-auto"
|
||||
>
|
||||
<div class="p-2">
|
||||
<div class="text-secondaryLight pb-2">
|
||||
@@ -165,10 +185,10 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="authType === 'oauth-2'"
|
||||
class="border-dividerLight flex border-b"
|
||||
class="border-b border-dividerLight flex"
|
||||
>
|
||||
<div class="border-dividerLight w-2/3 border-r">
|
||||
<div class="border-dividerLight flex border-b">
|
||||
<div class="border-r border-dividerLight w-2/3">
|
||||
<div class="border-b border-dividerLight flex">
|
||||
<SmartEnvInput
|
||||
v-model="oauth2Token"
|
||||
placeholder="Token"
|
||||
@@ -178,7 +198,7 @@
|
||||
<HttpOAuth2Authorization />
|
||||
</div>
|
||||
<div
|
||||
class="bg-primary top-upperTertiaryStickyFold min-w-46 max-w-1/3 z-9 sticky h-full p-4 overflow-auto"
|
||||
class="bg-primary h-full top-upperTertiaryStickyFold min-w-46 max-w-1/3 p-4 z-9 sticky overflow-auto"
|
||||
>
|
||||
<div class="p-2">
|
||||
<div class="text-secondaryLight pb-2">
|
||||
@@ -202,7 +222,7 @@ import {
|
||||
HoppRESTAuthBasic,
|
||||
HoppRESTAuthBearer,
|
||||
HoppRESTAuthOAuth2,
|
||||
} from "~/helpers/types/HoppRESTAuth"
|
||||
} from "@hoppscotch/data"
|
||||
import { pluckRef, useStream } from "~/helpers/utils/composables"
|
||||
import { restAuth$, setRESTAuth } from "~/newstore/RESTSession"
|
||||
import { useSetting } from "~/newstore/settings"
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
class="bg-primary border-dividerLight top-upperSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 top-upperSecondaryStickyFold pl-4 z-10 sticky items-center justify-between"
|
||||
>
|
||||
<span class="flex items-center">
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ $t("request.content_type") }}
|
||||
</label>
|
||||
<tippy
|
||||
@@ -18,7 +18,7 @@
|
||||
<span class="select-wrapper">
|
||||
<ButtonSecondary
|
||||
:label="contentType || $t('state.none').toLowerCase()"
|
||||
class="pr-8 ml-2 rounded-none"
|
||||
class="rounded-none ml-2 pr-8"
|
||||
/>
|
||||
</span>
|
||||
</template>
|
||||
@@ -53,15 +53,15 @@
|
||||
<HttpRawBody v-else-if="contentType !== null" :content-type="contentType" />
|
||||
<div
|
||||
v-if="contentType == null"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/upload_single_file.svg`"
|
||||
loading="lazy"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
||||
class="flex-col object-contain object-center h-16 my-4 w-16 inline-flex"
|
||||
:alt="$t('empty.body')"
|
||||
/>
|
||||
<span class="pb-4 text-center">
|
||||
<span class="text-center pb-4">
|
||||
{{ $t("empty.body") }}
|
||||
</span>
|
||||
<ButtonSecondary
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<AppSection label="bodyParameters">
|
||||
<div
|
||||
class="bg-primary border-dividerLight top-upperTertiaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 top-upperTertiaryStickyFold pl-4 z-10 sticky items-center justify-between"
|
||||
>
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ $t("request.body") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
@@ -31,7 +31,7 @@
|
||||
<div
|
||||
v-for="(param, index) in bodyParams"
|
||||
:key="`param-${index}`"
|
||||
class="divide-dividerLight border-dividerLight flex border-b divide-x"
|
||||
class="divide-dividerLight divide-x border-b border-dividerLight flex"
|
||||
>
|
||||
<SmartEnvInput
|
||||
v-model="param.key"
|
||||
@@ -53,7 +53,7 @@
|
||||
"
|
||||
/>
|
||||
<div v-if="param.isFile" class="file-chips-container hide-scrollbar">
|
||||
<div class="file-chips-wrapper space-x-2">
|
||||
<div class="space-x-2 file-chips-wrapper">
|
||||
<SmartDeletableChip
|
||||
v-for="(file, fileIndex) in param.value"
|
||||
:key="`param-${index}-file-${fileIndex}`"
|
||||
@@ -141,15 +141,15 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="bodyParams.length === 0"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/upload_single_file.svg`"
|
||||
loading="lazy"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
||||
class="flex-col object-contain object-center h-16 my-4 w-16 inline-flex"
|
||||
:alt="$t('empty.body')"
|
||||
/>
|
||||
<span class="pb-4 text-center">
|
||||
<span class="text-center pb-4">
|
||||
{{ $t("empty.body") }}
|
||||
</span>
|
||||
<ButtonSecondary
|
||||
@@ -165,7 +165,7 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, onMounted, Ref, watch } from "@nuxtjs/composition-api"
|
||||
import { FormDataKeyValue } from "~/helpers/types/HoppRESTRequest"
|
||||
import { FormDataKeyValue } from "@hoppscotch/data"
|
||||
import { pluckRef } from "~/helpers/utils/composables"
|
||||
import {
|
||||
addFormDataEntry,
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
"
|
||||
/>
|
||||
</tippy>
|
||||
<div class="flex justify-between flex-1">
|
||||
<div class="flex flex-1 justify-between">
|
||||
<label for="generatedCode" class="p-4">
|
||||
{{ t("request.generated_code") }}
|
||||
</label>
|
||||
@@ -41,7 +41,7 @@
|
||||
<div
|
||||
v-if="codegenType"
|
||||
ref="generatedCode"
|
||||
class="border rounded border-dividerLight"
|
||||
class="border border-dividerLight rounded"
|
||||
></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<AppSection label="headers">
|
||||
<div
|
||||
class="bg-primary border-dividerLight top-upperSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 top-upperSecondaryStickyFold pl-4 z-10 sticky items-center justify-between"
|
||||
>
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ t("request.header_list") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
@@ -41,7 +41,7 @@
|
||||
<div
|
||||
v-for="(header, index) in headers$"
|
||||
:key="`header-${index}`"
|
||||
class="divide-dividerLight border-dividerLight flex border-b divide-x"
|
||||
class="divide-dividerLight divide-x border-b border-dividerLight flex"
|
||||
>
|
||||
<SmartAutoComplete
|
||||
:placeholder="`${t('count.header', { count: index + 1 })}`"
|
||||
@@ -57,7 +57,7 @@
|
||||
px-4
|
||||
truncate
|
||||
"
|
||||
class="!flex flex-1"
|
||||
class="flex-1 !flex"
|
||||
@input="
|
||||
updateHeader(index, {
|
||||
key: $event,
|
||||
@@ -125,15 +125,15 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="headers$.length === 0"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<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"
|
||||
class="flex-col object-contain object-center h-16 my-4 w-16 inline-flex"
|
||||
:alt="`${t('empty.headers')}`"
|
||||
/>
|
||||
<span class="pb-4 text-center">
|
||||
<span class="text-center pb-4">
|
||||
{{ t("empty.headers") }}
|
||||
</span>
|
||||
<ButtonSecondary
|
||||
@@ -150,6 +150,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onBeforeUpdate, ref, watch } from "@nuxtjs/composition-api"
|
||||
import { HoppRESTHeader } from "@hoppscotch/data"
|
||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||
import {
|
||||
addRESTHeader,
|
||||
@@ -165,7 +166,6 @@ import {
|
||||
useI18n,
|
||||
useToast,
|
||||
} from "~/helpers/utils/composables"
|
||||
import { HoppRESTHeader } from "~/helpers/types/HoppRESTRequest"
|
||||
|
||||
const t = useI18n()
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<SmartModal v-if="show" :title="`${t('import.curl')}`" @close="hideModal">
|
||||
<template #body>
|
||||
<div class="flex flex-col px-2">
|
||||
<div ref="curlEditor" class="border rounded border-dividerLight"></div>
|
||||
<div ref="curlEditor" class="border border-dividerLight rounded"></div>
|
||||
</div>
|
||||
</template>
|
||||
<template #footer>
|
||||
@@ -22,13 +22,13 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from "@nuxtjs/composition-api"
|
||||
import parseCurlCommand from "~/helpers/curlparser"
|
||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||
import {
|
||||
HoppRESTHeader,
|
||||
HoppRESTParam,
|
||||
makeRESTRequest,
|
||||
} from "~/helpers/types/HoppRESTRequest"
|
||||
} from "@hoppscotch/data"
|
||||
import parseCurlCommand from "~/helpers/curlparser"
|
||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||
import { setRESTRequest } from "~/newstore/RESTSession"
|
||||
import { useI18n, useToast } from "~/helpers/utils/composables"
|
||||
|
||||
|
||||
@@ -1,46 +1,46 @@
|
||||
<template>
|
||||
<div class="flex flex-col">
|
||||
<div class="flex border-b border-dividerLight">
|
||||
<div class="border-b border-dividerLight flex">
|
||||
<input
|
||||
id="oidcDiscoveryURL"
|
||||
v-model="oidcDiscoveryURL"
|
||||
class="flex flex-1 px-4 py-2 bg-transparent"
|
||||
class="bg-transparent flex flex-1 py-2 px-4"
|
||||
placeholder="OpenID Connect Discovery URL"
|
||||
name="oidcDiscoveryURL"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex border-b border-dividerLight">
|
||||
<div class="border-b border-dividerLight flex">
|
||||
<input
|
||||
id="authURL"
|
||||
v-model="authURL"
|
||||
class="flex flex-1 px-4 py-2 bg-transparent"
|
||||
class="bg-transparent flex flex-1 py-2 px-4"
|
||||
placeholder="Authentication URL"
|
||||
name="authURL"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex border-b border-dividerLight">
|
||||
<div class="border-b border-dividerLight flex">
|
||||
<input
|
||||
id="accessTokenURL"
|
||||
v-model="accessTokenURL"
|
||||
class="flex flex-1 px-4 py-2 bg-transparent"
|
||||
class="bg-transparent flex flex-1 py-2 px-4"
|
||||
placeholder="Access Token URL"
|
||||
name="accessTokenURL"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex border-b border-dividerLight">
|
||||
<div class="border-b border-dividerLight flex">
|
||||
<input
|
||||
id="clientID"
|
||||
v-model="clientID"
|
||||
class="flex flex-1 px-4 py-2 bg-transparent"
|
||||
class="bg-transparent flex flex-1 py-2 px-4"
|
||||
placeholder="Client ID"
|
||||
name="clientID"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex border-b border-dividerLight">
|
||||
<div class="border-b border-dividerLight flex">
|
||||
<input
|
||||
id="scope"
|
||||
v-model="scope"
|
||||
class="flex flex-1 px-4 py-2 bg-transparent"
|
||||
class="bg-transparent flex flex-1 py-2 px-4"
|
||||
placeholder="Scope"
|
||||
name="scope"
|
||||
/>
|
||||
@@ -57,13 +57,13 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { Ref } from "@nuxtjs/composition-api"
|
||||
import { HoppRESTAuthOAuth2 } from "@hoppscotch/data"
|
||||
import {
|
||||
pluckRef,
|
||||
useI18n,
|
||||
useStream,
|
||||
useToast,
|
||||
} from "~/helpers/utils/composables"
|
||||
import { HoppRESTAuthOAuth2 } from "~/helpers/types/HoppRESTAuth"
|
||||
import { restAuth$, setRESTAuth } from "~/newstore/RESTSession"
|
||||
import { tokenRequest } from "~/helpers/oauth"
|
||||
|
||||
@@ -124,6 +124,7 @@ export default {
|
||||
clientID,
|
||||
scope,
|
||||
handleAccessTokenRequest,
|
||||
t,
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<AppSection label="parameters">
|
||||
<div
|
||||
class="bg-primary border-dividerLight top-upperSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 top-upperSecondaryStickyFold pl-4 z-10 sticky items-center justify-between"
|
||||
>
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ t("request.parameter_list") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
@@ -41,7 +41,7 @@
|
||||
<div
|
||||
v-for="(param, index) in params$"
|
||||
:key="`param-${index}`"
|
||||
class="divide-dividerLight border-dividerLight flex border-b divide-x"
|
||||
class="divide-dividerLight divide-x border-b border-dividerLight flex"
|
||||
>
|
||||
<SmartEnvInput
|
||||
v-model="param.key"
|
||||
@@ -118,15 +118,15 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="params$.length === 0"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/add_files.svg`"
|
||||
loading="lazy"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
||||
class="flex-col object-contain object-center h-16 my-4 w-16 inline-flex"
|
||||
:alt="`${t('empty.parameters')}`"
|
||||
/>
|
||||
<span class="pb-4 text-center">
|
||||
<span class="text-center pb-4">
|
||||
{{ t("empty.parameters") }}
|
||||
</span>
|
||||
<ButtonSecondary
|
||||
@@ -143,8 +143,8 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch, onBeforeUpdate } from "@nuxtjs/composition-api"
|
||||
import { HoppRESTParam } from "@hoppscotch/data"
|
||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||
import { HoppRESTParam } from "~/helpers/types/HoppRESTRequest"
|
||||
import {
|
||||
useReadonlyStream,
|
||||
useI18n,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<AppSection id="script" :label="`${t('preRequest.script')}`">
|
||||
<div
|
||||
class="bg-primary border-dividerLight top-upperSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 top-upperSecondaryStickyFold pl-4 z-10 sticky items-center justify-between"
|
||||
>
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ t("preRequest.javascript_code") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
@@ -18,7 +18,7 @@
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('state.linewrap')"
|
||||
:class="{ '!text-accent': linewrapEnabled }"
|
||||
svg="corner-down-left"
|
||||
svg="wrap-text"
|
||||
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
@@ -29,12 +29,12 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border-dividerLight flex border-b">
|
||||
<div class="border-dividerLight w-2/3 border-r">
|
||||
<div class="border-b border-dividerLight flex">
|
||||
<div class="border-r border-dividerLight w-2/3">
|
||||
<div ref="preRrequestEditor"></div>
|
||||
</div>
|
||||
<div
|
||||
class="bg-primary top-upperTertiaryStickyFold min-w-46 max-w-1/3 z-9 sticky h-full p-4 overflow-auto"
|
||||
class="bg-primary h-full top-upperTertiaryStickyFold min-w-46 max-w-1/3 p-4 z-9 sticky overflow-auto"
|
||||
>
|
||||
<div class="text-secondaryLight pb-2">
|
||||
{{ t("helpers.pre_request_script") }}
|
||||
@@ -44,7 +44,7 @@
|
||||
to="https://docs.hoppscotch.io/features/pre-request-script"
|
||||
blank
|
||||
/>
|
||||
<h4 class="text-secondaryLight pt-6 font-bold">
|
||||
<h4 class="font-bold text-secondaryLight pt-6">
|
||||
{{ t("preRequest.snippets") }}
|
||||
</h4>
|
||||
<div class="flex flex-col pt-4">
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
class="bg-primary border-dividerLight top-upperTertiaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 top-upperTertiaryStickyFold pl-4 z-10 sticky items-center justify-between"
|
||||
>
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ t("request.raw_body") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
@@ -18,7 +18,7 @@
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('state.linewrap')"
|
||||
:class="{ '!text-accent': linewrapEnabled }"
|
||||
svg="corner-down-left"
|
||||
svg="wrap-text"
|
||||
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<div
|
||||
class="bg-primary hide-scrollbar sticky top-0 z-10 flex p-4 space-x-2 overflow-x-auto"
|
||||
class="bg-primary flex space-x-2 p-4 top-0 z-10 sticky overflow-x-auto hide-scrollbar"
|
||||
>
|
||||
<div class="flex flex-1">
|
||||
<div class="relative flex">
|
||||
<div class="flex relative">
|
||||
<label for="method">
|
||||
<tippy
|
||||
ref="methodOptions"
|
||||
@@ -16,7 +16,7 @@
|
||||
<span class="select-wrapper">
|
||||
<input
|
||||
id="method"
|
||||
class="bg-primaryLight border-divider text-secondaryDark w-26 hover:border-dividerDark focus-visible:bg-transparent focus-visible:border-dividerDark flex px-4 py-2 font-semibold border rounded-l cursor-pointer"
|
||||
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="newMethod"
|
||||
:readonly="!isCustomMethod"
|
||||
:placeholder="`${t('request.method')}`"
|
||||
@@ -58,7 +58,7 @@
|
||||
<div class="flex">
|
||||
<ButtonPrimary
|
||||
id="send"
|
||||
class="min-w-20 flex-1 rounded-r-none"
|
||||
class="rounded-r-none flex-1 min-w-20"
|
||||
:label="`${!loading ? t('action.send') : t('action.cancel')}`"
|
||||
@click.native="!loading ? newSendRequest() : cancelRequest()"
|
||||
/>
|
||||
@@ -107,7 +107,7 @@
|
||||
</tippy>
|
||||
</span>
|
||||
<ButtonSecondary
|
||||
class="ml-2 rounded rounded-r-none"
|
||||
class="rounded rounded-r-none ml-2"
|
||||
:label="
|
||||
windowInnerWidth.x.value >= 768 && COLUMN_LAYOUT
|
||||
? `${t('request.save')}`
|
||||
@@ -139,7 +139,7 @@
|
||||
name="request-name"
|
||||
type="text"
|
||||
autocomplete="off"
|
||||
class="input mb-2"
|
||||
class="mb-2 input"
|
||||
@keyup.enter="saveOptions.tippy().hide()"
|
||||
/>
|
||||
<SmartItem
|
||||
@@ -185,7 +185,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, watch } from "@nuxtjs/composition-api"
|
||||
import { isRight } from "fp-ts/lib/Either"
|
||||
import { isLeft, isRight } from "fp-ts/lib/Either"
|
||||
import * as E from "fp-ts/Either"
|
||||
import {
|
||||
updateRESTResponse,
|
||||
@@ -198,6 +198,7 @@ import {
|
||||
getRESTSaveContext,
|
||||
getRESTRequest,
|
||||
restRequest$,
|
||||
setRESTSaveContext,
|
||||
} from "~/newstore/RESTSession"
|
||||
import { editRESTRequest } from "~/newstore/collections"
|
||||
import { runRESTRequest$ } from "~/helpers/RequestRunner"
|
||||
@@ -273,7 +274,6 @@ const newSendRequest = async () => {
|
||||
// Double calling is because the function returns a TaskEither than should be executed
|
||||
const streamResult = await runRESTRequest$()()
|
||||
|
||||
// TODO: What if stream fetching failed (script execution errors ?) (isLeft)
|
||||
if (isRight(streamResult)) {
|
||||
subscribeToStream(
|
||||
streamResult.right,
|
||||
@@ -291,6 +291,19 @@ const newSendRequest = async () => {
|
||||
loading.value = false
|
||||
}
|
||||
)
|
||||
} else if (isLeft(streamResult)) {
|
||||
loading.value = false
|
||||
toast.error(`${t("error.script_fail")}`)
|
||||
let error: Error
|
||||
if (typeof streamResult.left === "string") {
|
||||
error = { name: "RequestFailure", message: streamResult.left }
|
||||
} else {
|
||||
error = streamResult.left
|
||||
}
|
||||
updateRESTResponse({
|
||||
type: "script_fail",
|
||||
error,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -406,8 +419,17 @@ const saveRequest = () => {
|
||||
}
|
||||
|
||||
if (saveCtx.originLocation === "user-collection") {
|
||||
editRESTRequest(saveCtx.folderPath, saveCtx.requestIndex, getRESTRequest())
|
||||
toast.success(`${t("request.saved")}`)
|
||||
try {
|
||||
editRESTRequest(
|
||||
saveCtx.folderPath,
|
||||
saveCtx.requestIndex,
|
||||
getRESTRequest()
|
||||
)
|
||||
toast.success(`${t("request.saved")}`)
|
||||
} catch (e) {
|
||||
setRESTSaveContext(null)
|
||||
saveRequest()
|
||||
}
|
||||
} else if (saveCtx.originLocation === "team-collection") {
|
||||
const req = getRESTRequest()
|
||||
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
<template>
|
||||
<div
|
||||
class="bg-primary hide-scrollbar whitespace-nowrap sticky top-0 z-10 flex items-center p-4 overflow-auto"
|
||||
class="bg-primary flex p-4 top-0 z-10 sticky items-center overflow-auto hide-scrollbar whitespace-nowrap"
|
||||
>
|
||||
<div
|
||||
v-if="response == null"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center flex-1"
|
||||
class="flex flex-col flex-1 text-secondaryLight items-center justify-center"
|
||||
>
|
||||
<div class="flex pb-4 my-4 space-x-2">
|
||||
<div class="flex flex-col items-end space-y-4 text-right">
|
||||
<span class="flex items-center flex-1">
|
||||
<div class="flex space-x-2 my-4 pb-4">
|
||||
<div class="flex flex-col space-y-4 text-right items-end">
|
||||
<span class="flex flex-1 items-center">
|
||||
{{ t("shortcut.request.send_request") }}
|
||||
</span>
|
||||
<span class="flex items-center flex-1">
|
||||
<span class="flex flex-1 items-center">
|
||||
{{ t("shortcut.general.show_all") }}
|
||||
</span>
|
||||
<span class="flex items-center flex-1">
|
||||
<span class="flex flex-1 items-center">
|
||||
{{ t("shortcut.general.command_menu") }}
|
||||
</span>
|
||||
<span class="flex items-center flex-1">
|
||||
<span class="flex flex-1 items-center">
|
||||
{{ t("shortcut.general.help_menu") }}
|
||||
</span>
|
||||
</div>
|
||||
@@ -57,26 +57,53 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="response.type === 'network_fail'"
|
||||
class="flex flex-col items-center justify-center flex-1 p-4"
|
||||
class="flex flex-col flex-1 p-4 items-center justify-center"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/youre_lost.svg`"
|
||||
loading="lazy"
|
||||
class="inline-flex flex-col object-contain object-center w-32 h-32 my-4"
|
||||
class="flex-col object-contain object-center h-32 my-4 w-32 inline-flex"
|
||||
:alt="`${t('error.network_fail')}`"
|
||||
/>
|
||||
<span class="mb-2 font-semibold text-center">
|
||||
<span class="font-semibold text-center mb-2">
|
||||
{{ t("error.network_fail") }}
|
||||
</span>
|
||||
<span class="text-secondaryLight max-w-sm mb-4 text-center">
|
||||
<span
|
||||
class="max-w-sm text-secondaryLight text-center mb-4 whitespace-normal"
|
||||
>
|
||||
{{ t("helpers.network_fail") }}
|
||||
</span>
|
||||
<AppInterceptor />
|
||||
</div>
|
||||
<div
|
||||
v-if="response.type === 'script_fail'"
|
||||
class="flex flex-col flex-1 p-4 items-center justify-center"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/youre_lost.svg`"
|
||||
loading="lazy"
|
||||
class="flex-col object-contain object-center h-32 my-4 w-32 inline-flex"
|
||||
:alt="`${t('error.script_fail')}`"
|
||||
/>
|
||||
<span class="font-semibold text-center mb-2">
|
||||
{{ t("error.script_fail") }}
|
||||
</span>
|
||||
<span
|
||||
class="max-w-sm text-secondaryLight text-center mb-4 whitespace-normal"
|
||||
>
|
||||
{{ t("helpers.script_fail") }}
|
||||
</span>
|
||||
<div
|
||||
class="bg-primaryLight rounded font-mono w-full py-2 px-4 text-red-400 overflow-auto whitespace-normal"
|
||||
>
|
||||
{{ response.error.name }}: {{ response.error.message }}<br />
|
||||
{{ response.error.stack }}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="response.type === 'success' || 'fail'"
|
||||
:class="statusCategory.className"
|
||||
class="space-x-4 font-semibold"
|
||||
class="font-semibold space-x-4"
|
||||
>
|
||||
<span v-if="response.statusCode">
|
||||
<span class="text-secondary"> {{ t("response.status") }}: </span>
|
||||
@@ -111,7 +138,8 @@ const props = defineProps<{
|
||||
const statusCategory = computed(() => {
|
||||
if (
|
||||
props.response.type === "loading" ||
|
||||
props.response.type === "network_fail"
|
||||
props.response.type === "network_fail" ||
|
||||
props.response.type === "script_fail"
|
||||
)
|
||||
return ""
|
||||
return findStatusGroup(props.response.statusCode)
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
"
|
||||
>
|
||||
<div
|
||||
class="bg-primary border-dividerLight top-lowerSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 top-lowerSecondaryStickyFold pl-4 z-10 sticky items-center justify-between"
|
||||
>
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ t("test.report") }}
|
||||
</label>
|
||||
<ButtonSecondary
|
||||
@@ -19,7 +19,7 @@
|
||||
@click.native="clearContent()"
|
||||
/>
|
||||
</div>
|
||||
<div class="divide-dividerLight border-dividerLight border-b divide-y-4">
|
||||
<div class="divide-dividerLight border-b border-dividerLight divide-y-4">
|
||||
<div v-if="testResults.tests" class="divide-dividerLight divide-y-4">
|
||||
<HttpTestResultEntry
|
||||
v-for="(result, index) in testResults.tests"
|
||||
@@ -38,10 +38,10 @@
|
||||
<div
|
||||
v-for="(result, index) in testResults.expectResults"
|
||||
:key="`result-${index}`"
|
||||
class="flex items-center px-4 py-2"
|
||||
class="flex py-2 px-4 items-center"
|
||||
>
|
||||
<i
|
||||
class="material-icons mr-4"
|
||||
class="mr-4 material-icons"
|
||||
:class="
|
||||
result.status === 'pass' ? 'text-green-500' : 'text-red-500'
|
||||
"
|
||||
@@ -64,18 +64,18 @@
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/validation.svg`"
|
||||
loading="lazy"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
||||
class="flex-col object-contain object-center h-16 my-4 w-16 inline-flex"
|
||||
:alt="`${t('empty.tests')}`"
|
||||
/>
|
||||
<span class="pb-2 text-center">
|
||||
<span class="text-center pb-2">
|
||||
{{ t("empty.tests") }}
|
||||
</span>
|
||||
<span class="pb-4 text-center">
|
||||
<span class="text-center pb-4">
|
||||
{{ t("helpers.tests") }}
|
||||
</span>
|
||||
<ButtonSecondary
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div>
|
||||
<span
|
||||
v-if="testResults.description"
|
||||
class="flex items-center px-4 py-2 font-bold text-secondaryDark"
|
||||
class="flex font-bold text-secondaryDark py-2 px-4 items-center"
|
||||
>
|
||||
{{ testResults.description }}
|
||||
</span>
|
||||
@@ -14,7 +14,7 @@
|
||||
<div
|
||||
v-for="(result, index) in testResults.expectResults"
|
||||
:key="`result-${index}`"
|
||||
class="flex items-center px-4 py-2"
|
||||
class="flex py-2 px-4 items-center"
|
||||
>
|
||||
<i
|
||||
class="mr-4 material-icons"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="flex items-center p-2">
|
||||
<div class="flex p-2 items-center">
|
||||
<SmartProgressRing
|
||||
class="text-red-500"
|
||||
:radius="16"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<AppSection id="script" :label="`${t('test.script')}`">
|
||||
<div
|
||||
class="bg-primary border-dividerLight top-upperSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 top-upperSecondaryStickyFold pl-4 z-10 sticky items-center justify-between"
|
||||
>
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ t("test.javascript_code") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
@@ -18,7 +18,7 @@
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('state.linewrap')"
|
||||
:class="{ '!text-accent': linewrapEnabled }"
|
||||
svg="corner-down-left"
|
||||
svg="wrap-text"
|
||||
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
@@ -29,12 +29,12 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border-dividerLight flex border-b">
|
||||
<div class="border-dividerLight w-2/3 border-r">
|
||||
<div class="border-b border-dividerLight flex">
|
||||
<div class="border-r border-dividerLight w-2/3">
|
||||
<div ref="testScriptEditor"></div>
|
||||
</div>
|
||||
<div
|
||||
class="bg-primary top-upperTertiaryStickyFold min-w-46 max-w-1/3 z-9 sticky h-full p-4 overflow-auto"
|
||||
class="bg-primary h-full top-upperTertiaryStickyFold min-w-46 max-w-1/3 p-4 z-9 sticky overflow-auto"
|
||||
>
|
||||
<div class="text-secondaryLight pb-2">
|
||||
{{ t("helpers.post_request_tests") }}
|
||||
@@ -44,7 +44,7 @@
|
||||
to="https://docs.hoppscotch.io/features/tests"
|
||||
blank
|
||||
/>
|
||||
<h4 class="text-secondaryLight pt-6 font-bold">
|
||||
<h4 class="font-bold text-secondaryLight pt-6">
|
||||
{{ t("test.snippets") }}
|
||||
</h4>
|
||||
<div class="flex flex-col pt-4">
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
class="bg-primary border-dividerLight top-lowerSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 top-lowerSecondaryStickyFold pl-4 z-10 sticky items-center justify-between"
|
||||
>
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ t("request.header_list") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
@@ -20,19 +20,19 @@
|
||||
<div
|
||||
v-for="(header, index) in headers"
|
||||
:key="`header-${index}`"
|
||||
class="divide-dividerLight border-dividerLight group flex border-b divide-x"
|
||||
class="divide-dividerLight divide-x border-b border-dividerLight flex group"
|
||||
>
|
||||
<span
|
||||
class="group-hover:text-secondaryDark flex flex-1 min-w-0 px-4 py-2 transition"
|
||||
class="flex flex-1 min-w-0 py-2 px-4 transition group-hover:text-secondaryDark"
|
||||
>
|
||||
<span class="truncate rounded-sm select-all">
|
||||
<span class="rounded-sm truncate select-all">
|
||||
{{ header.key }}
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
class="group-hover:text-secondaryDark flex flex-1 min-w-0 px-4 py-2 transition"
|
||||
class="flex flex-1 min-w-0 py-2 px-4 transition group-hover:text-secondaryDark"
|
||||
>
|
||||
<span class="truncate rounded-sm select-all">
|
||||
<span class="rounded-sm truncate select-all">
|
||||
{{ header.value }}
|
||||
</span>
|
||||
</span>
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from "@nuxtjs/composition-api"
|
||||
import { HoppRESTHeader } from "~/helpers/types/HoppRESTRequest"
|
||||
import { HoppRESTHeader } from "@hoppscotch/data"
|
||||
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
||||
import { useI18n, useToast } from "~/helpers/utils/composables"
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<div class="flex flex-col flex-1">
|
||||
<div
|
||||
class="bg-primary border-dividerLight top-lowerSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 top-lowerSecondaryStickyFold pl-4 z-10 sticky items-center justify-between"
|
||||
>
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ t("response.body") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
@@ -12,7 +12,7 @@
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('state.linewrap')"
|
||||
:class="{ '!text-accent': linewrapEnabled }"
|
||||
svg="corner-down-left"
|
||||
svg="wrap-text"
|
||||
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
class="bg-primary border-dividerLight top-lowerSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 top-lowerSecondaryStickyFold pl-4 z-10 sticky items-center justify-between"
|
||||
>
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ $t("response.body") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
@@ -18,7 +18,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<img
|
||||
class="border-dividerLight flex flex-1 max-w-full border-b"
|
||||
class="border-b border-dividerLight flex max-w-full flex-1"
|
||||
:src="imageSource"
|
||||
loading="lazy"
|
||||
:alt="imageSource"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
class="bg-primary border-dividerLight top-lowerSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 top-lowerSecondaryStickyFold pl-4 z-10 sticky items-center justify-between"
|
||||
>
|
||||
<label class="text-secondaryLight font-semibold">{{
|
||||
<label class="font-semibold text-secondaryLight">{{
|
||||
t("response.body")
|
||||
}}</label>
|
||||
<div class="flex">
|
||||
@@ -12,7 +12,7 @@
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('state.linewrap')"
|
||||
:class="{ '!text-accent': linewrapEnabled }"
|
||||
svg="corner-down-left"
|
||||
svg="wrap-text"
|
||||
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
@@ -36,7 +36,7 @@
|
||||
<div ref="jsonResponse"></div>
|
||||
<div
|
||||
v-if="outlinePath"
|
||||
class="bg-primaryLight border-dividerLight flex-nowrap hide-scrollbar sticky bottom-0 z-10 flex flex-1 px-2 overflow-auto border-t"
|
||||
class="bg-primaryLight border-t border-dividerLight flex flex-nowrap flex-1 px-2 bottom-0 z-10 sticky overflow-auto hide-scrollbar"
|
||||
>
|
||||
<div
|
||||
v-for="(item, index) in outlinePath"
|
||||
@@ -115,7 +115,7 @@
|
||||
</tippy>
|
||||
<i
|
||||
v-if="index + 1 !== outlinePath.length"
|
||||
class="text-secondaryLight material-icons opacity-50"
|
||||
class="text-secondaryLight opacity-50 material-icons"
|
||||
>chevron_right</i
|
||||
>
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
class="bg-primary border-dividerLight top-lowerSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 top-lowerSecondaryStickyFold pl-4 z-10 sticky items-center justify-between"
|
||||
>
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ t("response.body") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
@@ -12,7 +12,7 @@
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('state.linewrap')"
|
||||
:class="{ '!text-accent': linewrapEnabled }"
|
||||
svg="corner-down-left"
|
||||
svg="wrap-text"
|
||||
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
class="bg-primary border-dividerLight top-lowerSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 top-lowerSecondaryStickyFold pl-4 z-10 sticky items-center justify-between"
|
||||
>
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ t("response.body") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
@@ -12,7 +12,7 @@
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('state.linewrap')"
|
||||
:class="{ '!text-accent': linewrapEnabled }"
|
||||
svg="corner-down-left"
|
||||
svg="wrap-text"
|
||||
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<div class="relative flex items-center justify-center w-5 h-5 cursor-pointer">
|
||||
<div class="cursor-pointer flex h-5 w-5 relative items-center justify-center">
|
||||
<img
|
||||
class="bg-primaryDark absolute object-cover object-center w-5 h-5 transition rounded-full"
|
||||
class="bg-primaryDark rounded-full object-cover object-center h-5 transition w-5 absolute"
|
||||
:src="url"
|
||||
:alt="alt"
|
||||
loading="lazy"
|
||||
/>
|
||||
<div class="absolute inset-0 rounded-full shadow-inner"></div>
|
||||
<div class="rounded-full shadow-inner inset-0 absolute"></div>
|
||||
<span
|
||||
v-if="indicator"
|
||||
class="border-primary rounded-full border-2 h-2.5 -top-0.5 -right-0.5 w-2.5 absolute"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<div class="flex flex-col">
|
||||
<div
|
||||
class="bg-primary border-dividerLight sticky top-0 z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 pl-4 top-0 z-10 sticky items-center justify-between"
|
||||
>
|
||||
<label for="log" class="text-secondaryLight py-2 font-semibold">
|
||||
<label for="log" class="font-semibold text-secondaryLight py-2">
|
||||
{{ title }}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@@ -15,16 +15,16 @@
|
||||
>
|
||||
<AppSection label="request">
|
||||
<div
|
||||
class="bg-primary sticky top-0 z-10 flex flex-col p-4 space-y-4"
|
||||
class="bg-primary flex flex-col space-y-4 p-4 top-0 z-10 sticky"
|
||||
>
|
||||
<div class="inline-flex flex-1 space-x-2">
|
||||
<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-divider text-secondaryDark hover:border-dividerDark focus-visible:bg-transparent focus-visible:border-dividerDark w-full px-4 py-2 border rounded"
|
||||
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"
|
||||
@@ -80,8 +80,8 @@
|
||||
class="hide-scrollbar !overflow-auto"
|
||||
>
|
||||
<AppSection label="messages">
|
||||
<div class="flex inline-flex flex-col flex-1 p-4">
|
||||
<label for="pub_topic" class="text-secondaryLight font-semibold">
|
||||
<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>
|
||||
@@ -96,12 +96,12 @@
|
||||
spellcheck="false"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex items-center justify-between flex-1 p-4">
|
||||
<label for="mqtt-message" class="text-secondaryLight font-semibold">
|
||||
<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 px-4 space-x-2">
|
||||
<div class="flex space-x-2 px-4">
|
||||
<input
|
||||
id="mqtt-message"
|
||||
v-model="msg"
|
||||
@@ -120,13 +120,13 @@
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="border-dividerLight flex inline-flex flex-col flex-1 p-4 mt-4 border-t"
|
||||
class="border-t border-dividerLight flex flex-col flex-1 mt-4 p-4 inline-flex"
|
||||
>
|
||||
<label for="sub_topic" class="text-secondaryLight font-semibold">
|
||||
<label for="sub_topic" class="font-semibold text-secondaryLight">
|
||||
{{ $t("mqtt.topic") }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="flex px-4 space-x-2">
|
||||
<div class="flex space-x-2 px-4">
|
||||
<input
|
||||
id="sub_topic"
|
||||
v-model="sub_topic"
|
||||
@@ -161,6 +161,22 @@ import debounce from "lodash/debounce"
|
||||
import { logHoppRequestRunToAnalytics } from "~/helpers/fb/analytics"
|
||||
import { useSetting } from "~/newstore/settings"
|
||||
import useWindowSize from "~/helpers/utils/useWindowSize"
|
||||
import {
|
||||
MQTTEndpoint$,
|
||||
setMQTTEndpoint,
|
||||
MQTTConnectingState$,
|
||||
MQTTConnectionState$,
|
||||
setMQTTConnectingState,
|
||||
setMQTTConnectionState,
|
||||
MQTTSubscriptionState$,
|
||||
setMQTTSubscriptionState,
|
||||
MQTTSocket$,
|
||||
setMQTTSocket,
|
||||
MQTTLog$,
|
||||
setMQTTLog,
|
||||
addMQTTLogLine,
|
||||
} from "~/newstore/MQTTSession"
|
||||
import { useStream } from "~/helpers/utils/composables"
|
||||
|
||||
export default defineComponent({
|
||||
components: { Splitpanes, Pane },
|
||||
@@ -170,21 +186,33 @@ export default defineComponent({
|
||||
SIDEBAR: useSetting("SIDEBAR"),
|
||||
COLUMN_LAYOUT: useSetting("COLUMN_LAYOUT"),
|
||||
SIDEBAR_ON_LEFT: useSetting("SIDEBAR_ON_LEFT"),
|
||||
url: useStream(MQTTEndpoint$, "", setMQTTEndpoint),
|
||||
connectionState: useStream(
|
||||
MQTTConnectionState$,
|
||||
false,
|
||||
setMQTTConnectionState
|
||||
),
|
||||
connectingState: useStream(
|
||||
MQTTConnectingState$,
|
||||
false,
|
||||
setMQTTConnectingState
|
||||
),
|
||||
subscriptionState: useStream(
|
||||
MQTTSubscriptionState$,
|
||||
false,
|
||||
setMQTTSubscriptionState
|
||||
),
|
||||
log: useStream(MQTTLog$, null, setMQTTLog),
|
||||
client: useStream(MQTTSocket$, null, setMQTTSocket),
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
url: "wss://test.mosquitto.org:8081",
|
||||
isUrlValid: true,
|
||||
client: null,
|
||||
pub_topic: "",
|
||||
sub_topic: "",
|
||||
msg: "",
|
||||
connectionState: false,
|
||||
connectingState: false,
|
||||
log: null,
|
||||
manualDisconnect: false,
|
||||
subscriptionState: false,
|
||||
username: "",
|
||||
password: "",
|
||||
}
|
||||
@@ -261,7 +289,7 @@ export default defineComponent({
|
||||
onConnectionFailure() {
|
||||
this.connectingState = false
|
||||
this.connectionState = false
|
||||
this.log.push({
|
||||
addMQTTLogLine({
|
||||
payload: this.$t("error.something_went_wrong"),
|
||||
source: "info",
|
||||
color: "#ff5555",
|
||||
@@ -271,7 +299,7 @@ export default defineComponent({
|
||||
onConnectionSuccess() {
|
||||
this.connectingState = false
|
||||
this.connectionState = true
|
||||
this.log.push({
|
||||
addMQTTLogLine({
|
||||
payload: this.$t("state.connected_to", { name: this.url }),
|
||||
source: "info",
|
||||
color: "var(--accent-color)",
|
||||
@@ -280,7 +308,7 @@ export default defineComponent({
|
||||
this.$toast.success(this.$t("state.connected"))
|
||||
},
|
||||
onMessageArrived({ payloadString, destinationName }) {
|
||||
this.log.push({
|
||||
addMQTTLogLine({
|
||||
payload: `Message: ${payloadString} arrived on topic: ${destinationName}`,
|
||||
source: "info",
|
||||
color: "var(--accent-color)",
|
||||
@@ -297,7 +325,7 @@ export default defineComponent({
|
||||
disconnect() {
|
||||
this.manualDisconnect = true
|
||||
this.client.disconnect()
|
||||
this.log.push({
|
||||
addMQTTLogLine({
|
||||
payload: this.$t("state.disconnected_from", { name: this.url }),
|
||||
source: "info",
|
||||
color: "#ff5555",
|
||||
@@ -318,14 +346,14 @@ export default defineComponent({
|
||||
publish() {
|
||||
try {
|
||||
this.client.publish(this.pub_topic, this.msg, 0, false)
|
||||
this.log.push({
|
||||
addMQTTLogLine({
|
||||
payload: `Published message: ${this.msg} to topic: ${this.pub_topic}`,
|
||||
ts: new Date().toLocaleTimeString(),
|
||||
source: "info",
|
||||
color: "var(--accent-color)",
|
||||
})
|
||||
} catch (e) {
|
||||
this.log.push({
|
||||
addMQTTLogLine({
|
||||
payload:
|
||||
this.$t("error.something_went_wrong") +
|
||||
`while publishing msg: ${this.msg} to topic: ${this.pub_topic}`,
|
||||
@@ -349,7 +377,7 @@ export default defineComponent({
|
||||
onFailure: this.usubFailure,
|
||||
})
|
||||
} catch (e) {
|
||||
this.log.push({
|
||||
addMQTTLogLine({
|
||||
payload:
|
||||
this.$t("error.something_went_wrong") +
|
||||
`while subscribing to topic: ${this.sub_topic}`,
|
||||
@@ -361,7 +389,7 @@ export default defineComponent({
|
||||
},
|
||||
usubSuccess() {
|
||||
this.subscriptionState = !this.subscriptionState
|
||||
this.log.push({
|
||||
addMQTTLogLine({
|
||||
payload:
|
||||
`Successfully ` +
|
||||
(this.subscriptionState ? "subscribed" : "unsubscribed") +
|
||||
@@ -372,7 +400,7 @@ export default defineComponent({
|
||||
})
|
||||
},
|
||||
usubFailure() {
|
||||
this.log.push({
|
||||
addMQTTLogLine({
|
||||
payload:
|
||||
`Failed to ` +
|
||||
(this.subscriptionState ? "unsubscribe" : "subscribe") +
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
class="hide-scrollbar !overflow-auto"
|
||||
>
|
||||
<AppSection label="request">
|
||||
<div class="bg-primary sticky top-0 z-10 flex p-4">
|
||||
<div class="inline-flex flex-1 space-x-2">
|
||||
<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
|
||||
@@ -31,7 +31,7 @@
|
||||
id="client-version"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
title="socket.io-client version"
|
||||
class="bg-primaryLight border-divider text-secondaryDark w-26 hover:border-dividerDark focus-visible:bg-transparent focus-visible:border-dividerDark flex px-4 py-2 font-semibold border rounded-l cursor-pointer"
|
||||
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"
|
||||
@@ -53,7 +53,7 @@
|
||||
autocomplete="off"
|
||||
spellcheck="false"
|
||||
:class="{ error: !urlValid }"
|
||||
class="bg-primaryLight border-divider text-secondaryDark hover:border-dividerDark focus-visible:bg-transparent focus-visible:border-dividerDark flex flex-1 w-full px-4 py-2 border"
|
||||
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"
|
||||
@@ -61,7 +61,7 @@
|
||||
<input
|
||||
id="socketio-path"
|
||||
v-model="path"
|
||||
class="bg-primaryLight border-divider text-secondaryDark hover:border-dividerDark focus-visible:bg-transparent focus-visible:border-dividerDark flex flex-1 w-full px-4 py-2 border rounded-r"
|
||||
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"
|
||||
@@ -89,7 +89,7 @@
|
||||
class="hide-scrollbar !overflow-auto"
|
||||
>
|
||||
<AppSection label="response">
|
||||
<RealtimeLog :title="$t('socketio.log')" :log="communication.log" />
|
||||
<RealtimeLog :title="$t('socketio.log')" :log="log" />
|
||||
</AppSection>
|
||||
</Pane>
|
||||
</Splitpanes>
|
||||
@@ -101,8 +101,8 @@
|
||||
class="hide-scrollbar !overflow-auto"
|
||||
>
|
||||
<AppSection label="messages">
|
||||
<div class="flex inline-flex flex-col flex-1 p-4">
|
||||
<label for="events" class="text-secondaryLight font-semibold">
|
||||
<div class="flex flex-col flex-1 p-4 inline-flex">
|
||||
<label for="events" class="font-semibold text-secondaryLight">
|
||||
{{ $t("socketio.events") }}
|
||||
</label>
|
||||
</div>
|
||||
@@ -118,8 +118,8 @@
|
||||
:disabled="!connectionState"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex items-center justify-between flex-1 p-4">
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
<div class="flex flex-1 p-4 items-center justify-between">
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ $t("socketio.communication") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
@@ -127,12 +127,11 @@
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('add.new')"
|
||||
svg="plus"
|
||||
class="rounded"
|
||||
@click.native="addCommunicationInput"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col px-4 pb-4 space-y-2">
|
||||
<div class="flex flex-col space-y-2 px-4 pb-4">
|
||||
<div
|
||||
v-for="(input, index) of communication.inputs"
|
||||
:key="`input-${index}`"
|
||||
@@ -153,7 +152,6 @@
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.remove')"
|
||||
svg="trash"
|
||||
class="rounded"
|
||||
color="red"
|
||||
outline
|
||||
@click.native="removeCommunicationInput({ index })"
|
||||
@@ -188,6 +186,24 @@ import debounce from "lodash/debounce"
|
||||
import { logHoppRequestRunToAnalytics } from "~/helpers/fb/analytics"
|
||||
import { useSetting } from "~/newstore/settings"
|
||||
import useWindowSize from "~/helpers/utils/useWindowSize"
|
||||
import {
|
||||
SIOEndpoint$,
|
||||
setSIOEndpoint,
|
||||
SIOVersion$,
|
||||
setSIOVersion,
|
||||
SIOPath$,
|
||||
setSIOPath,
|
||||
SIOConnectionState$,
|
||||
SIOConnectingState$,
|
||||
setSIOConnectionState,
|
||||
setSIOConnectingState,
|
||||
SIOSocket$,
|
||||
setSIOSocket,
|
||||
SIOLog$,
|
||||
setSIOLog,
|
||||
addSIOLogLine,
|
||||
} from "~/newstore/SocketIOSession"
|
||||
import { useStream } from "~/helpers/utils/composables"
|
||||
|
||||
const socketIoClients = {
|
||||
v4: ClientV4,
|
||||
@@ -204,20 +220,27 @@ export default defineComponent({
|
||||
COLUMN_LAYOUT: useSetting("COLUMN_LAYOUT"),
|
||||
SIDEBAR_ON_LEFT: useSetting("SIDEBAR_ON_LEFT"),
|
||||
socketIoClients,
|
||||
url: useStream(SIOEndpoint$, "", setSIOEndpoint),
|
||||
clientVersion: useStream(SIOVersion$, "", setSIOVersion),
|
||||
path: useStream(SIOPath$, "", setSIOPath),
|
||||
connectingState: useStream(
|
||||
SIOConnectingState$,
|
||||
false,
|
||||
setSIOConnectingState
|
||||
),
|
||||
connectionState: useStream(
|
||||
SIOConnectionState$,
|
||||
false,
|
||||
setSIOConnectionState
|
||||
),
|
||||
io: useStream(SIOSocket$, null, setSIOSocket),
|
||||
log: useStream(SIOLog$, [], setSIOLog),
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// default version is set to v4
|
||||
clientVersion: "v4",
|
||||
url: "wss://hoppscotch-socketio.herokuapp.com",
|
||||
path: "/socket.io",
|
||||
isUrlValid: true,
|
||||
connectingState: false,
|
||||
connectionState: false,
|
||||
io: null,
|
||||
communication: {
|
||||
log: null,
|
||||
eventName: "",
|
||||
inputs: [""],
|
||||
},
|
||||
@@ -267,7 +290,7 @@ export default defineComponent({
|
||||
},
|
||||
connect() {
|
||||
this.connectingState = true
|
||||
this.communication.log = [
|
||||
this.log = [
|
||||
{
|
||||
payload: this.$t("state.connecting_to", { name: this.url }),
|
||||
source: "info",
|
||||
@@ -286,7 +309,7 @@ export default defineComponent({
|
||||
this.io.on("connect", () => {
|
||||
this.connectingState = false
|
||||
this.connectionState = true
|
||||
this.communication.log = [
|
||||
this.log = [
|
||||
{
|
||||
payload: this.$t("state.connected_to", { name: this.url }),
|
||||
source: "info",
|
||||
@@ -298,7 +321,7 @@ export default defineComponent({
|
||||
})
|
||||
this.io.on("*", ({ data }) => {
|
||||
const [eventName, message] = data
|
||||
this.communication.log.push({
|
||||
addSIOLogLine({
|
||||
payload: `[${eventName}] ${message ? JSON.stringify(message) : ""}`,
|
||||
source: "server",
|
||||
ts: new Date().toLocaleTimeString(),
|
||||
@@ -316,7 +339,7 @@ export default defineComponent({
|
||||
this.io.on("disconnect", () => {
|
||||
this.connectingState = false
|
||||
this.connectionState = false
|
||||
this.communication.log.push({
|
||||
addSIOLogLine({
|
||||
payload: this.$t("state.disconnected_from", { name: this.url }),
|
||||
source: "info",
|
||||
color: "#ff5555",
|
||||
@@ -340,14 +363,14 @@ export default defineComponent({
|
||||
this.disconnect()
|
||||
this.connectingState = false
|
||||
this.connectionState = false
|
||||
this.communication.log.push({
|
||||
addSIOLogLine({
|
||||
payload: this.$t("error.something_went_wrong"),
|
||||
source: "info",
|
||||
color: "#ff5555",
|
||||
ts: new Date().toLocaleTimeString(),
|
||||
})
|
||||
if (error !== null)
|
||||
this.communication.log.push({
|
||||
addSIOLogLine({
|
||||
payload: error,
|
||||
source: "info",
|
||||
color: "#ff5555",
|
||||
@@ -369,14 +392,14 @@ export default defineComponent({
|
||||
if (this.io) {
|
||||
this.io.emit(eventName, ...messages, (data) => {
|
||||
// receive response from server
|
||||
this.communication.log.push({
|
||||
addSIOLogLine({
|
||||
payload: `[${eventName}] ${JSON.stringify(data)}`,
|
||||
source: "server",
|
||||
ts: new Date().toLocaleTimeString(),
|
||||
})
|
||||
})
|
||||
|
||||
this.communication.log.push({
|
||||
addSIOLogLine({
|
||||
payload: `[${eventName}] ${JSON.stringify(messages)}`,
|
||||
source: "client",
|
||||
ts: new Date().toLocaleTimeString(),
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<Splitpanes class="smart-splitter" :horizontal="COLUMN_LAYOUT">
|
||||
<Pane :size="COLUMN_LAYOUT ? 45 : 50" class="hide-scrollbar !overflow-auto">
|
||||
<div class="bg-primary sticky top-0 z-10 flex p-4">
|
||||
<div class="inline-flex flex-1 space-x-2">
|
||||
<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">
|
||||
<input
|
||||
id="server"
|
||||
@@ -10,21 +10,21 @@
|
||||
type="url"
|
||||
autocomplete="off"
|
||||
:class="{ error: !serverValid }"
|
||||
class="bg-primaryLight border-divider text-secondaryDark hover:border-dividerDark focus-visible:bg-transparent focus-visible:border-dividerDark flex flex-1 w-full px-4 py-2 border rounded-l"
|
||||
class="bg-primaryLight border border-divider rounded-l flex flex-1 text-secondaryDark w-full py-2 px-4 hover:border-dividerDark focus-visible:bg-transparent focus-visible:border-dividerDark"
|
||||
:placeholder="$t('sse.url')"
|
||||
:disabled="connectionSSEState"
|
||||
@keyup.enter="serverValid ? toggleSSEConnection() : null"
|
||||
/>
|
||||
<label
|
||||
for="event-type"
|
||||
class="bg-primaryLight border-divider text-secondaryLight px-4 py-2 font-semibold truncate border-t border-b"
|
||||
class="bg-primaryLight border-t border-b border-divider font-semibold text-secondaryLight py-2 px-4 truncate"
|
||||
>
|
||||
{{ $t("sse.event_type") }}
|
||||
</label>
|
||||
<input
|
||||
id="event-type"
|
||||
v-model="eventType"
|
||||
class="bg-primaryLight border-divider text-secondaryDark hover:border-dividerDark focus-visible:bg-transparent focus-visible:border-dividerDark flex flex-1 w-full px-4 py-2 border rounded-r"
|
||||
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="connectionSSEState"
|
||||
@keyup.enter="serverValid ? toggleSSEConnection() : null"
|
||||
@@ -48,7 +48,7 @@
|
||||
<AppSection label="response">
|
||||
<ul>
|
||||
<li>
|
||||
<RealtimeLog :title="$t('sse.log')" :log="events.log" />
|
||||
<RealtimeLog :title="$t('sse.log')" :log="log" />
|
||||
<div id="result"></div>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -64,26 +64,47 @@ import "splitpanes/dist/splitpanes.css"
|
||||
import debounce from "lodash/debounce"
|
||||
import { logHoppRequestRunToAnalytics } from "~/helpers/fb/analytics"
|
||||
import { useSetting } from "~/newstore/settings"
|
||||
import {
|
||||
SSEEndpoint$,
|
||||
setSSEEndpoint,
|
||||
SSEEventType$,
|
||||
setSSEEventType,
|
||||
SSESocket$,
|
||||
setSSESocket,
|
||||
SSEConnectingState$,
|
||||
SSEConnectionState$,
|
||||
setSSEConnectionState,
|
||||
setSSEConnectingState,
|
||||
SSELog$,
|
||||
setSSELog,
|
||||
addSSELogLine,
|
||||
} from "~/newstore/SSESession"
|
||||
import { useStream } from "~/helpers/utils/composables"
|
||||
|
||||
export default defineComponent({
|
||||
components: { Splitpanes, Pane },
|
||||
setup() {
|
||||
return {
|
||||
COLUMN_LAYOUT: useSetting("COLUMN_LAYOUT"),
|
||||
connectionSSEState: useStream(
|
||||
SSEConnectionState$,
|
||||
false,
|
||||
setSSEConnectionState
|
||||
),
|
||||
connectingState: useStream(
|
||||
SSEConnectingState$,
|
||||
false,
|
||||
setSSEConnectingState
|
||||
),
|
||||
server: useStream(SSEEndpoint$, "", setSSEEndpoint),
|
||||
eventType: useStream(SSEEventType$, "", setSSEEventType),
|
||||
sse: useStream(SSESocket$, null, setSSESocket),
|
||||
log: useStream(SSELog$, [], setSSELog),
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
connectionSSEState: false,
|
||||
connectingState: false,
|
||||
server: "https://express-eventsource.herokuapp.com/events",
|
||||
isUrlValid: true,
|
||||
sse: null,
|
||||
events: {
|
||||
log: null,
|
||||
input: "",
|
||||
},
|
||||
eventType: "data",
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -120,7 +141,7 @@ export default defineComponent({
|
||||
},
|
||||
start() {
|
||||
this.connectingState = true
|
||||
this.events.log = [
|
||||
this.log = [
|
||||
{
|
||||
payload: this.$t("state.connecting_to", { name: this.server }),
|
||||
source: "info",
|
||||
@@ -133,7 +154,7 @@ export default defineComponent({
|
||||
this.sse.onopen = () => {
|
||||
this.connectingState = false
|
||||
this.connectionSSEState = true
|
||||
this.events.log = [
|
||||
this.log = [
|
||||
{
|
||||
payload: this.$t("state.connected_to", { name: this.server }),
|
||||
source: "info",
|
||||
@@ -148,7 +169,7 @@ export default defineComponent({
|
||||
}
|
||||
this.sse.onclose = () => {
|
||||
this.connectionSSEState = false
|
||||
this.events.log.push({
|
||||
addSSELogLine({
|
||||
payload: this.$t("state.disconnected_from", {
|
||||
name: this.server,
|
||||
}),
|
||||
@@ -159,7 +180,7 @@ export default defineComponent({
|
||||
this.$toast.error(this.$t("state.disconnected"))
|
||||
}
|
||||
this.sse.addEventListener(this.eventType, ({ data }) => {
|
||||
this.events.log.push({
|
||||
addSSELogLine({
|
||||
payload: data,
|
||||
source: "server",
|
||||
ts: new Date().toLocaleTimeString(),
|
||||
@@ -170,7 +191,7 @@ export default defineComponent({
|
||||
this.$toast.error(this.$t("error.something_went_wrong"))
|
||||
}
|
||||
} else {
|
||||
this.events.log = [
|
||||
this.log = [
|
||||
{
|
||||
payload: this.$t("error.browser_support_sse"),
|
||||
source: "info",
|
||||
@@ -187,14 +208,14 @@ export default defineComponent({
|
||||
handleSSEError(error) {
|
||||
this.stop()
|
||||
this.connectionSSEState = false
|
||||
this.events.log.push({
|
||||
addSSELogLine({
|
||||
payload: this.$t("error.something_went_wrong"),
|
||||
source: "info",
|
||||
color: "#ff5555",
|
||||
ts: new Date().toLocaleTimeString(),
|
||||
})
|
||||
if (error !== null)
|
||||
this.events.log.push({
|
||||
addSSELogLine({
|
||||
payload: error,
|
||||
source: "info",
|
||||
color: "#ff5555",
|
||||
|
||||
@@ -14,12 +14,12 @@
|
||||
class="hide-scrollbar !overflow-auto"
|
||||
>
|
||||
<AppSection label="request">
|
||||
<div class="bg-primary sticky top-0 z-10 flex p-4">
|
||||
<div class="inline-flex flex-1 space-x-2">
|
||||
<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-divider text-secondaryDark hover:border-dividerDark focus-visible:bg-transparent focus-visible:border-dividerDark w-full px-4 py-2 border rounded"
|
||||
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"
|
||||
@@ -44,9 +44,9 @@
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="bg-primary border-dividerLight top-upperPrimaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
class="bg-primary border-b border-dividerLight flex flex-1 top-upperPrimaryStickyFold pl-4 z-10 sticky items-center justify-between"
|
||||
>
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ $t("websocket.protocols") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
@@ -67,15 +67,21 @@
|
||||
<div
|
||||
v-for="(protocol, index) of protocols"
|
||||
:key="`protocol-${index}`"
|
||||
class="divide-dividerLight border-dividerLight flex border-b divide-x"
|
||||
class="divide-dividerLight divide-x border-b border-dividerLight flex"
|
||||
>
|
||||
<input
|
||||
v-model="protocol.value"
|
||||
class="flex flex-1 px-4 py-2 bg-transparent"
|
||||
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
|
||||
@@ -96,9 +102,10 @@
|
||||
"
|
||||
color="green"
|
||||
@click.native="
|
||||
protocol.active = protocol.hasOwnProperty('active')
|
||||
? !protocol.active
|
||||
: false
|
||||
updateProtocol(index, {
|
||||
value: protocol.value,
|
||||
active: !protocol.active,
|
||||
})
|
||||
"
|
||||
/>
|
||||
</span>
|
||||
@@ -114,15 +121,15 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="protocols.length === 0"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<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"
|
||||
class="flex-col object-contain object-center h-16 my-4 w-16 inline-flex"
|
||||
:alt="$t('empty.protocols')"
|
||||
/>
|
||||
<span class="mb-4 text-center">
|
||||
<span class="text-center mb-4">
|
||||
{{ $t("empty.protocols") }}
|
||||
</span>
|
||||
</div>
|
||||
@@ -133,10 +140,7 @@
|
||||
class="hide-scrollbar !overflow-auto"
|
||||
>
|
||||
<AppSection label="response">
|
||||
<RealtimeLog
|
||||
:title="$t('websocket.log')"
|
||||
:log="communication.log"
|
||||
/>
|
||||
<RealtimeLog :title="$t('websocket.log')" :log="log" />
|
||||
</AppSection>
|
||||
</Pane>
|
||||
</Splitpanes>
|
||||
@@ -148,15 +152,15 @@
|
||||
class="hide-scrollbar !overflow-auto"
|
||||
>
|
||||
<AppSection label="messages">
|
||||
<div class="flex inline-flex flex-col flex-1 p-4">
|
||||
<div class="flex flex-col flex-1 p-4 inline-flex">
|
||||
<label
|
||||
for="websocket-message"
|
||||
class="text-secondaryLight font-semibold"
|
||||
class="font-semibold text-secondaryLight"
|
||||
>
|
||||
{{ $t("websocket.communication") }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="flex px-4 space-x-2">
|
||||
<div class="flex space-x-2 px-4">
|
||||
<input
|
||||
id="websocket-message"
|
||||
v-model="communication.input"
|
||||
@@ -191,6 +195,26 @@ import debounce from "lodash/debounce"
|
||||
import { logHoppRequestRunToAnalytics } from "~/helpers/fb/analytics"
|
||||
import useWindowSize from "~/helpers/utils/useWindowSize"
|
||||
import { useSetting } from "~/newstore/settings"
|
||||
import {
|
||||
setWSEndpoint,
|
||||
WSEndpoint$,
|
||||
WSProtocols$,
|
||||
setWSProtocols,
|
||||
addWSProtocol,
|
||||
deleteWSProtocol,
|
||||
updateWSProtocol,
|
||||
deleteAllWSProtocols,
|
||||
WSSocket$,
|
||||
setWSSocket,
|
||||
setWSConnectionState,
|
||||
setWSConnectingState,
|
||||
WSConnectionState$,
|
||||
WSConnectingState$,
|
||||
addWSLogLine,
|
||||
WSLog$,
|
||||
setWSLog,
|
||||
} from "~/newstore/WebSocketSession"
|
||||
import { useStream } from "~/helpers/utils/composables"
|
||||
|
||||
export default defineComponent({
|
||||
components: { Splitpanes, Pane },
|
||||
@@ -200,21 +224,29 @@ export default defineComponent({
|
||||
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(
|
||||
WSConnectionState$,
|
||||
false,
|
||||
setWSConnectionState
|
||||
),
|
||||
connectingState: useStream(
|
||||
WSConnectingState$,
|
||||
false,
|
||||
setWSConnectingState
|
||||
),
|
||||
socket: useStream(WSSocket$, null, setWSSocket),
|
||||
log: useStream(WSLog$, [], setWSLog),
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
connectionState: false,
|
||||
connectingState: false,
|
||||
url: "wss://hoppscotch-websocket.herokuapp.com",
|
||||
isUrlValid: true,
|
||||
socket: null,
|
||||
communication: {
|
||||
log: null,
|
||||
input: "",
|
||||
},
|
||||
currentIndex: -1, // index of the message log array to put in input box
|
||||
protocols: [],
|
||||
activeProtocols: [],
|
||||
}
|
||||
},
|
||||
@@ -251,7 +283,7 @@ export default defineComponent({
|
||||
},
|
||||
methods: {
|
||||
clearContent() {
|
||||
this.protocols = []
|
||||
deleteAllWSProtocols()
|
||||
},
|
||||
debouncer: debounce(function () {
|
||||
this.worker.postMessage({ type: "ws", url: this.url })
|
||||
@@ -266,7 +298,7 @@ export default defineComponent({
|
||||
else return this.disconnect()
|
||||
},
|
||||
connect() {
|
||||
this.communication.log = [
|
||||
this.log = [
|
||||
{
|
||||
payload: this.$t("state.connecting_to", { name: this.url }),
|
||||
source: "info",
|
||||
@@ -279,7 +311,7 @@ export default defineComponent({
|
||||
this.socket.onopen = () => {
|
||||
this.connectingState = false
|
||||
this.connectionState = true
|
||||
this.communication.log = [
|
||||
this.log = [
|
||||
{
|
||||
payload: this.$t("state.connected_to", { name: this.url }),
|
||||
source: "info",
|
||||
@@ -294,7 +326,7 @@ export default defineComponent({
|
||||
}
|
||||
this.socket.onclose = () => {
|
||||
this.connectionState = false
|
||||
this.communication.log.push({
|
||||
addWSLogLine({
|
||||
payload: this.$t("state.disconnected_from", { name: this.url }),
|
||||
source: "info",
|
||||
color: "#ff5555",
|
||||
@@ -303,7 +335,7 @@ export default defineComponent({
|
||||
this.$toast.error(this.$t("state.disconnected"))
|
||||
}
|
||||
this.socket.onmessage = ({ data }) => {
|
||||
this.communication.log.push({
|
||||
addWSLogLine({
|
||||
payload: data,
|
||||
source: "server",
|
||||
ts: new Date().toLocaleTimeString(),
|
||||
@@ -328,14 +360,14 @@ export default defineComponent({
|
||||
handleError(error) {
|
||||
this.disconnect()
|
||||
this.connectionState = false
|
||||
this.communication.log.push({
|
||||
addWSLogLine({
|
||||
payload: this.$t("error.something_went_wrong"),
|
||||
source: "info",
|
||||
color: "#ff5555",
|
||||
ts: new Date().toLocaleTimeString(),
|
||||
})
|
||||
if (error !== null)
|
||||
this.communication.log.push({
|
||||
addWSLogLine({
|
||||
payload: error,
|
||||
source: "info",
|
||||
color: "#ff5555",
|
||||
@@ -345,7 +377,7 @@ export default defineComponent({
|
||||
sendMessage() {
|
||||
const message = this.communication.input
|
||||
this.socket.send(message)
|
||||
this.communication.log.push({
|
||||
addWSLogLine({
|
||||
payload: message,
|
||||
source: "client",
|
||||
ts: new Date().toLocaleTimeString(),
|
||||
@@ -353,7 +385,7 @@ export default defineComponent({
|
||||
this.communication.input = ""
|
||||
},
|
||||
walkHistory(direction) {
|
||||
const clientMessages = this.communication.log.filter(
|
||||
const clientMessages = this.log.filter(
|
||||
({ source }) => source === "client"
|
||||
)
|
||||
const length = clientMessages.length
|
||||
@@ -389,11 +421,11 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
addProtocol() {
|
||||
this.protocols.push({ value: "", active: true })
|
||||
addWSProtocol({ value: "", active: true })
|
||||
},
|
||||
deleteProtocol({ index }) {
|
||||
const oldProtocols = this.protocols.slice()
|
||||
this.$delete(this.protocols, index)
|
||||
deleteWSProtocol(index)
|
||||
this.$toast.success(this.$t("state.deleted"), {
|
||||
action: {
|
||||
text: this.$t("action.undo"),
|
||||
@@ -405,6 +437,9 @@ export default defineComponent({
|
||||
},
|
||||
})
|
||||
},
|
||||
updateProtocol(index, updated) {
|
||||
updateWSProtocol(index, updated)
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
/>
|
||||
<ul
|
||||
v-if="suggestions.length > 0 && suggestionsVisible"
|
||||
class="suggestions"
|
||||
class="suggestions hide-scrollbar"
|
||||
:style="{ transform: `translate(${suggestionsOffsetLeft}px, 0)` }"
|
||||
>
|
||||
<li
|
||||
@@ -101,8 +101,8 @@ export default defineComponent({
|
||||
)
|
||||
// Cut off the part that's already been typed.
|
||||
.map((entry) => entry.substring(this.selectionStart))
|
||||
// We only want the top 6 suggestions.
|
||||
.slice(0, 6)
|
||||
// We only want the top 10 suggestions.
|
||||
.slice(0, 10)
|
||||
)
|
||||
},
|
||||
},
|
||||
@@ -215,6 +215,8 @@ export default defineComponent({
|
||||
@apply left-0;
|
||||
@apply z-50;
|
||||
@apply shadow-lg;
|
||||
@apply max-h-46;
|
||||
@apply overflow-y-auto;
|
||||
|
||||
top: calc(100% - 4px);
|
||||
border-radius: 0 0 8px 8px;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div
|
||||
class="flex-nowrap group hover:text-secondaryDark inline-flex items-center justify-center transition cursor-pointer"
|
||||
class="cursor-pointer flex-nowrap transition inline-flex items-center justify-center group hover:text-secondaryDark"
|
||||
@click="$emit('change')"
|
||||
>
|
||||
<input
|
||||
@@ -12,7 +12,7 @@
|
||||
/>
|
||||
<label
|
||||
for="checkbox"
|
||||
class="pl-0 font-semibold align-middle cursor-pointer"
|
||||
class="cursor-pointer font-semibold pl-0 align-middle"
|
||||
>
|
||||
<slot></slot>
|
||||
</label>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<span class="chip">
|
||||
<i class="opacity-75 material-icons">attachment</i>
|
||||
<span class="px-2 truncate max-w-64"><slot></slot></span>
|
||||
<span class="max-w-64 px-2 truncate"><slot></slot></span>
|
||||
<ButtonSecondary
|
||||
class="rounded close-button"
|
||||
svg="x"
|
||||
|
||||
@@ -19,8 +19,9 @@
|
||||
v-for="(size, index) in fontSizes"
|
||||
:key="`size-${index}`"
|
||||
:label="`${getFontSizeName(size)}`"
|
||||
:info-icon="size === active ? 'done' : ''"
|
||||
:active-info-icon="size === active"
|
||||
:icon="
|
||||
size === active ? 'radio_button_checked' : 'radio_button_unchecked'
|
||||
"
|
||||
@click.native="
|
||||
() => {
|
||||
setActiveFont(size)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
:to="`${/^\/(?!\/).*$/.test(to) ? localePath(to) : to}`"
|
||||
:exact="exact"
|
||||
:blank="blank"
|
||||
class="hover:bg-primaryDark hover:text-secondaryDark focus:outline-none focus-visible:bg-primaryDark focus-visible:text-secondaryDark inline-flex items-center flex-shrink-0 px-4 py-2 transition rounded"
|
||||
class="rounded flex-shrink-0 py-2 px-4 transition inline-flex items-center hover:bg-primaryDark hover:text-secondaryDark focus:outline-none focus-visible:bg-primaryDark focus-visible:text-secondaryDark"
|
||||
:class="[
|
||||
{ 'opacity-75 cursor-not-allowed': disabled },
|
||||
{ 'pointer-events-none': loading },
|
||||
@@ -42,9 +42,9 @@
|
||||
class="svg-icons"
|
||||
/>
|
||||
</span>
|
||||
<SmartSpinner v-else class="text-secondaryDark mr-4" />
|
||||
<SmartSpinner v-else class="mr-4 text-secondaryDark" />
|
||||
<div
|
||||
class="inline-flex items-start flex-1 truncate"
|
||||
class="flex-1 inline-flex items-start truncate"
|
||||
:class="{ 'flex-col': description }"
|
||||
>
|
||||
<div class="font-semibold truncate">
|
||||
@@ -52,14 +52,14 @@
|
||||
</div>
|
||||
<p
|
||||
v-if="description"
|
||||
class="text-secondaryLight my-2 font-medium text-left"
|
||||
class="font-medium my-2 text-left text-secondaryLight"
|
||||
>
|
||||
{{ description }}
|
||||
</p>
|
||||
</div>
|
||||
<i
|
||||
v-if="infoIcon"
|
||||
class="material-icons items-center self-center ml-6"
|
||||
class="ml-6 items-center self-center material-icons"
|
||||
:class="{ 'text-accent': activeInfoIcon }"
|
||||
>
|
||||
{{ infoIcon }}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="text-sm text-secondaryLight animate-pulse">
|
||||
<AppLogo class="w-8 h-8" />
|
||||
<AppLogo class="h-8 w-8" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
<transition name="fade" appear @leave="onTransitionLeaveStart">
|
||||
<div
|
||||
ref="modal"
|
||||
class="hide-scrollbar fixed inset-0 z-10 z-50 overflow-y-auto transition"
|
||||
class="inset-0 transition z-10 z-50 fixed overflow-y-auto hide-scrollbar"
|
||||
>
|
||||
<div
|
||||
class="sm:block flex items-end justify-center min-h-screen text-center"
|
||||
class="flex min-h-screen text-center items-end justify-center sm:block"
|
||||
>
|
||||
<transition name="fade" appear>
|
||||
<div
|
||||
class="bg-primaryLight opacity-90 fixed inset-0 transition"
|
||||
class="bg-primaryLight opacity-90 inset-0 transition fixed"
|
||||
@touchstart="!dialog ? close() : null"
|
||||
@touchend="!dialog ? close() : null"
|
||||
@mouseup="!dialog ? close() : null"
|
||||
@@ -18,7 +18,7 @@
|
||||
</transition>
|
||||
<span
|
||||
v-if="placement === 'center'"
|
||||
class="sm:h-screen sm:inline-block sm:align-middle hidden"
|
||||
class="hidden sm:h-screen sm:inline-block sm:align-middle"
|
||||
aria-hidden="true"
|
||||
>​</span
|
||||
>
|
||||
@@ -32,7 +32,7 @@
|
||||
leave-to-class="scale-95 translate-y-4"
|
||||
>
|
||||
<div
|
||||
class="bg-primary sm:align-middle sm:rounded-xl inline-block w-full overflow-hidden text-left align-bottom transition-all transform shadow-lg"
|
||||
class="bg-primary shadow-lg text-left w-full transform transition-all inline-block overflow-hidden align-bottom sm:rounded-xl sm:align-middle"
|
||||
:class="[
|
||||
{ 'mt-24 md:mb-8': placement === 'top' },
|
||||
{ 'p-4': !fullWidth },
|
||||
@@ -41,28 +41,27 @@
|
||||
>
|
||||
<div
|
||||
v-if="title"
|
||||
class="flex items-center justify-between pl-2 mb-4"
|
||||
class="flex mb-4 pl-2 items-center justify-between"
|
||||
>
|
||||
<h3 class="heading">{{ title }}</h3>
|
||||
<span class="flex">
|
||||
<slot name="actions"></slot>
|
||||
<ButtonSecondary
|
||||
v-if="dimissible"
|
||||
class="rounded"
|
||||
svg="x"
|
||||
@click.native="close"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="max-h-md hide-scrollbar flex flex-col overflow-y-auto"
|
||||
class="flex flex-col max-h-md overflow-y-auto hide-scrollbar"
|
||||
:class="{ 'py-2': !fullWidth }"
|
||||
>
|
||||
<slot name="body"></slot>
|
||||
</div>
|
||||
<div
|
||||
v-if="hasFooterSlot"
|
||||
class="flex items-center justify-between flex-1 p-2 mt-4"
|
||||
class="flex flex-1 mt-4 p-2 items-center justify-between"
|
||||
>
|
||||
<slot name="footer"></slot>
|
||||
</div>
|
||||
@@ -74,7 +73,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from "@nuxtjs/composition-api"
|
||||
import { defineComponent, onBeforeUnmount } from "@nuxtjs/composition-api"
|
||||
import { useKeybindingDisabler } from "~/helpers/keybindings"
|
||||
|
||||
const PORTAL_DOM_ID = "hoppscotch-modal-portal"
|
||||
@@ -119,9 +118,12 @@ export default defineComponent({
|
||||
setup() {
|
||||
const { disableKeybindings, enableKeybindings } = useKeybindingDisabler()
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
enableKeybindings()
|
||||
})
|
||||
|
||||
return {
|
||||
disableKeybindings,
|
||||
enableKeybindings,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@@ -155,7 +157,6 @@ export default defineComponent({
|
||||
methods: {
|
||||
close() {
|
||||
this.$emit("close")
|
||||
this.enableKeybindings()
|
||||
},
|
||||
onKeyDown(e: KeyboardEvent) {
|
||||
if (e.key === "Escape" && this.stackId === stack.peek()) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div
|
||||
class="flex flex-1 h-full flex-nowrap"
|
||||
class="flex flex-nowrap h-full flex-1"
|
||||
:class="{ 'flex-col h-auto': !vertical }"
|
||||
>
|
||||
<div
|
||||
@@ -9,7 +9,7 @@
|
||||
>
|
||||
<div class="flex flex-1">
|
||||
<div
|
||||
class="flex justify-between flex-1"
|
||||
class="flex flex-1 justify-between"
|
||||
:class="{ 'flex-col': vertical }"
|
||||
>
|
||||
<div class="flex" :class="{ 'flex-col space-y-2 p-2': vertical }">
|
||||
@@ -35,7 +35,7 @@
|
||||
</span>
|
||||
<span
|
||||
v-if="tab.indicator"
|
||||
class="w-1 h-1 ml-2 rounded-full bg-accentLight"
|
||||
class="bg-accentLight rounded-full h-1 ml-2 w-1"
|
||||
></span>
|
||||
</button>
|
||||
</div>
|
||||
@@ -46,7 +46,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="w-full h-full contents"
|
||||
class="h-full w-full contents"
|
||||
:class="{
|
||||
'!flex flex-col flex-1 overflow-y-auto hide-scrollbar': vertical,
|
||||
}"
|
||||
@@ -128,7 +128,7 @@ export default defineComponent({
|
||||
@apply flex-shrink-0;
|
||||
@apply items-center;
|
||||
@apply justify-center;
|
||||
@apply px-4 py-2;
|
||||
@apply py-2 px-4;
|
||||
@apply text-secondary;
|
||||
@apply font-semibold;
|
||||
@apply cursor-pointer;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<div
|
||||
class="inline-flex items-center justify-center cursor-pointer flex-nowrap"
|
||||
class="cursor-pointer flex-nowrap transition inline-flex items-center justify-center group hover:text-secondaryDark"
|
||||
@click="$emit('change')"
|
||||
>
|
||||
<label ref="toggle" class="toggle" :class="{ on: on }">
|
||||
<span class="handle"></span>
|
||||
</label>
|
||||
<label class="pl-0 font-semibold align-middle cursor-pointer">
|
||||
<label class="cursor-pointer font-semibold pl-0 align-middle">
|
||||
<slot></slot>
|
||||
</label>
|
||||
</div>
|
||||
@@ -28,7 +28,7 @@ export default defineComponent({
|
||||
<style scoped lang="scss">
|
||||
$useBorder: true;
|
||||
$borderColor: var(--divider-color);
|
||||
$activeColor: var(--divider-color);
|
||||
$activeColor: var(--divider-dark-color);
|
||||
$inactiveColor: var(--divider-color);
|
||||
$inactiveHandleColor: var(--secondary-light-color);
|
||||
$activeHandleColor: var(--accent-color);
|
||||
@@ -49,6 +49,8 @@ $transition: all 0.2s ease-in-out;
|
||||
@apply mr-4;
|
||||
@apply cursor-pointer;
|
||||
@apply flex-shrink-0;
|
||||
@apply group-hover:border-accentDark;
|
||||
@apply transition;
|
||||
|
||||
width: $width;
|
||||
height: $height;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
:to="`${/^\/(?!\/).*$/.test(to) ? localePath(to) : to}`"
|
||||
:exact="exact"
|
||||
:blank="blank"
|
||||
class="focus:outline-none inline-flex items-center px-4 py-2 truncate transition rounded"
|
||||
class="rounded py-2 px-4 transition inline-flex items-center truncate focus:outline-none"
|
||||
:class="[
|
||||
color
|
||||
? `text-${color}-500 hover:text-${color}-600 focus-visible:text-${color}-600`
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
:to="`${/^\/(?!\/).*$/.test(to) ? localePath(to) : to}`"
|
||||
:exact="exact"
|
||||
:blank="blank"
|
||||
class="hover:translate-x-2 focus:outline-none focus-visible:translate-x-2 inline-flex items-center flex-1 py-2 font-semibold truncate transition transform"
|
||||
class="font-semibold flex-1 py-2 transform transition inline-flex items-center truncate hover:translate-x-2 focus:outline-none focus-visible:translate-x-2"
|
||||
:class="[
|
||||
label ? 'px-3' : 'px-2',
|
||||
active
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<SmartModal v-if="show" :title="t('team.edit')" @close="hideModal">
|
||||
<template #body>
|
||||
<div class="flex flex-col px-2">
|
||||
<div class="relative flex">
|
||||
<div class="flex relative">
|
||||
<input
|
||||
id="selectLabelTeamEdit"
|
||||
v-model="name"
|
||||
@@ -17,7 +17,7 @@
|
||||
{{ t("action.label") }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="flex items-center justify-between flex-1 pt-4">
|
||||
<div class="flex flex-1 pt-4 items-center justify-between">
|
||||
<label for="memberList" class="p-4">
|
||||
{{ t("team.members") }}
|
||||
</label>
|
||||
@@ -47,19 +47,19 @@
|
||||
E.isRight(teamDetails.data) &&
|
||||
teamDetails.data.right.team.teamMembers
|
||||
"
|
||||
class="divide-dividerLight border-divider border divide-y rounded"
|
||||
class="divide-dividerLight divide-y border border-divider rounded"
|
||||
>
|
||||
<div
|
||||
v-if="teamDetails.data.right.team.teamMembers === 0"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/add_group.svg`"
|
||||
loading="lazy"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
||||
class="flex-col object-contain object-center h-16 my-4 w-16 inline-flex"
|
||||
:alt="`${t('empty.members')}`"
|
||||
/>
|
||||
<span class="pb-4 text-center">
|
||||
<span class="text-center pb-4">
|
||||
{{ t("empty.members") }}
|
||||
</span>
|
||||
<ButtonSecondary
|
||||
@@ -76,10 +76,10 @@
|
||||
<div
|
||||
v-for="(member, index) in membersList"
|
||||
:key="`member-${index}`"
|
||||
class="divide-dividerLight flex divide-x"
|
||||
class="divide-dividerLight divide-x flex"
|
||||
>
|
||||
<input
|
||||
class="flex flex-1 px-4 py-2 bg-transparent"
|
||||
class="bg-transparent flex flex-1 py-2 px-4"
|
||||
:placeholder="`${t('team.email')}`"
|
||||
:name="'param' + index"
|
||||
:value="member.email"
|
||||
@@ -96,20 +96,21 @@
|
||||
<template #trigger>
|
||||
<span class="select-wrapper">
|
||||
<input
|
||||
class="flex flex-1 px-4 py-2 bg-transparent cursor-pointer"
|
||||
class="bg-transparent cursor-pointer flex flex-1 py-2 px-4"
|
||||
:placeholder="`${t('team.permissions')}`"
|
||||
:name="'value' + index"
|
||||
:value="
|
||||
typeof member.role === 'string'
|
||||
? member.role
|
||||
: JSON.stringify(member.role)
|
||||
"
|
||||
:value="member.role"
|
||||
readonly
|
||||
/>
|
||||
</span>
|
||||
</template>
|
||||
<SmartItem
|
||||
label="OWNER"
|
||||
:icon="
|
||||
member.role === 'OWNER'
|
||||
? 'radio_button_checked'
|
||||
: 'radio_button_unchecked'
|
||||
"
|
||||
@click.native="
|
||||
() => {
|
||||
updateMemberRole(member.userID, 'OWNER')
|
||||
@@ -119,6 +120,11 @@
|
||||
/>
|
||||
<SmartItem
|
||||
label="EDITOR"
|
||||
:icon="
|
||||
member.role === 'EDITOR'
|
||||
? 'radio_button_checked'
|
||||
: 'radio_button_unchecked'
|
||||
"
|
||||
@click.native="
|
||||
() => {
|
||||
updateMemberRole(member.userID, 'EDITOR')
|
||||
@@ -128,6 +134,11 @@
|
||||
/>
|
||||
<SmartItem
|
||||
label="VIEWER"
|
||||
:icon="
|
||||
member.role === 'VIEWER'
|
||||
? 'radio_button_checked'
|
||||
: 'radio_button_unchecked'
|
||||
"
|
||||
@click.native="
|
||||
() => {
|
||||
updateMemberRole(member.userID, 'VIEWER')
|
||||
@@ -154,7 +165,7 @@
|
||||
v-if="!teamDetails.loading && E.isLeft(teamDetails.data)"
|
||||
class="flex flex-col items-center"
|
||||
>
|
||||
<i class="material-icons mb-4">help_outline</i>
|
||||
<i class="mb-4 material-icons">help_outline</i>
|
||||
{{ t("error.something_went_wrong") }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
<SmartModal v-if="show" :title="t('team.invite')" @close="hideModal">
|
||||
<template #body>
|
||||
<div v-if="sendInvitesResult.length" class="flex flex-col px-4">
|
||||
<div class="flex flex-col items-center justify-center max-w-md">
|
||||
<SmartIcon class="text-accent w-6 h-6" name="users" />
|
||||
<div class="flex flex-col max-w-md items-center justify-center">
|
||||
<SmartIcon class="h-6 text-accent w-6" name="users" />
|
||||
<h3 class="my-2 text-lg text-center">
|
||||
{{ t("team.we_sent_invite_link") }}
|
||||
</h3>
|
||||
@@ -12,7 +12,7 @@
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="border-dividerLight flex flex-col p-4 mt-8 space-y-6 border rounded"
|
||||
class="border border-dividerLight rounded flex flex-col space-y-6 mt-8 p-4"
|
||||
>
|
||||
<div
|
||||
v-for="(invitee, index) in sendInvitesResult"
|
||||
@@ -20,7 +20,7 @@
|
||||
>
|
||||
<p class="flex items-center">
|
||||
<i
|
||||
class="material-icons mr-4"
|
||||
class="mr-4 material-icons"
|
||||
:class="
|
||||
invitee.status === 'error' ? 'text-red-500' : 'text-green-500'
|
||||
"
|
||||
@@ -41,20 +41,20 @@
|
||||
</div>
|
||||
<div
|
||||
v-else-if="sendingInvites"
|
||||
class="flex items-center justify-center p-4"
|
||||
class="flex p-4 items-center justify-center"
|
||||
>
|
||||
<SmartSpinner />
|
||||
</div>
|
||||
<div v-else class="flex flex-col px-2">
|
||||
<div class="flex items-center justify-between flex-1">
|
||||
<div class="flex flex-1 items-center justify-between">
|
||||
<label for="memberList" class="px-4 pb-4">
|
||||
{{ t("team.pending_invites") }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="divide-dividerLight border-divider border divide-y rounded">
|
||||
<div class="divide-dividerLight divide-y border border-divider rounded">
|
||||
<div
|
||||
v-if="pendingInvites.loading"
|
||||
class="flex items-center justify-center p-4"
|
||||
class="flex p-4 items-center justify-center"
|
||||
>
|
||||
<SmartSpinner />
|
||||
</div>
|
||||
@@ -66,25 +66,21 @@
|
||||
v-for="(invitee, index) in pendingInvites.data.right.team
|
||||
.teamInvitations"
|
||||
:key="`invitee-${index}`"
|
||||
class="divide-dividerLight flex divide-x"
|
||||
class="divide-dividerLight divide-x flex"
|
||||
>
|
||||
<input
|
||||
v-if="invitee"
|
||||
class="text-secondaryLight flex flex-1 px-4 py-2 bg-transparent"
|
||||
class="bg-transparent flex flex-1 text-secondaryLight py-2 px-4"
|
||||
:placeholder="`${t('team.email')}`"
|
||||
:name="'param' + index"
|
||||
:value="invitee.inviteeEmail"
|
||||
readonly
|
||||
/>
|
||||
<input
|
||||
class="text-secondaryLight flex flex-1 px-4 py-2 bg-transparent"
|
||||
class="bg-transparent flex flex-1 text-secondaryLight py-2 px-4"
|
||||
:placeholder="`${t('team.permissions')}`"
|
||||
:name="'value' + index"
|
||||
:value="
|
||||
typeof invitee.inviteeRole === 'string'
|
||||
? invitee.inviteeRole
|
||||
: JSON.stringify(invitee.inviteeRole)
|
||||
"
|
||||
:value="invitee.inviteeRole"
|
||||
readonly
|
||||
/>
|
||||
<div class="flex">
|
||||
@@ -103,7 +99,7 @@
|
||||
E.isRight(pendingInvites.data) &&
|
||||
pendingInvites.data.right.team.teamInvitations.length === 0
|
||||
"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<span class="text-center">
|
||||
{{ t("empty.pending_invites") }}
|
||||
@@ -111,14 +107,14 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="!pendingInvites.loading && E.isLeft(pendingInvites.data)"
|
||||
class="flex flex-col items-center p-4"
|
||||
class="flex flex-col p-4 items-center"
|
||||
>
|
||||
<i class="material-icons mb-4">help_outline</i>
|
||||
<i class="mb-4 material-icons">help_outline</i>
|
||||
{{ t("error.something_went_wrong") }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-between flex-1 pt-4">
|
||||
<div class="flex flex-1 pt-4 items-center justify-between">
|
||||
<label for="memberList" class="p-4">
|
||||
{{ t("team.invite_tooltip") }}
|
||||
</label>
|
||||
@@ -131,15 +127,15 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="divide-dividerLight border-divider border divide-y rounded">
|
||||
<div class="divide-dividerLight divide-y border border-divider rounded">
|
||||
<div
|
||||
v-for="(invitee, index) in newInvites"
|
||||
:key="`new-invitee-${index}`"
|
||||
class="divide-dividerLight flex divide-x"
|
||||
class="divide-dividerLight divide-x flex"
|
||||
>
|
||||
<input
|
||||
v-model="invitee.key"
|
||||
class="flex flex-1 px-4 py-2 bg-transparent"
|
||||
class="bg-transparent flex flex-1 py-2 px-4"
|
||||
:placeholder="`${t('team.email')}`"
|
||||
:name="'invitee' + index"
|
||||
autofocus
|
||||
@@ -155,20 +151,21 @@
|
||||
<template #trigger>
|
||||
<span class="select-wrapper">
|
||||
<input
|
||||
class="flex flex-1 px-4 py-2 bg-transparent cursor-pointer"
|
||||
class="bg-transparent cursor-pointer flex flex-1 py-2 px-4"
|
||||
:placeholder="`${t('team.permissions')}`"
|
||||
:name="'value' + index"
|
||||
:value="
|
||||
typeof invitee.value === 'string'
|
||||
? invitee.value
|
||||
: JSON.stringify(invitee.value)
|
||||
"
|
||||
:value="invitee.value"
|
||||
readonly
|
||||
/>
|
||||
</span>
|
||||
</template>
|
||||
<SmartItem
|
||||
label="OWNER"
|
||||
:icon="
|
||||
invitee.value === 'OWNER'
|
||||
? 'radio_button_checked'
|
||||
: 'radio_button_unchecked'
|
||||
"
|
||||
@click.native="
|
||||
() => {
|
||||
updateNewInviteeRole(index, 'OWNER')
|
||||
@@ -178,6 +175,11 @@
|
||||
/>
|
||||
<SmartItem
|
||||
label="EDITOR"
|
||||
:icon="
|
||||
invitee.value === 'EDITOR'
|
||||
? 'radio_button_checked'
|
||||
: 'radio_button_unchecked'
|
||||
"
|
||||
@click.native="
|
||||
() => {
|
||||
updateNewInviteeRole(index, 'EDITOR')
|
||||
@@ -187,6 +189,11 @@
|
||||
/>
|
||||
<SmartItem
|
||||
label="VIEWER"
|
||||
:icon="
|
||||
invitee.value === 'VIEWER'
|
||||
? 'radio_button_checked'
|
||||
: 'radio_button_unchecked'
|
||||
"
|
||||
@click.native="
|
||||
() => {
|
||||
updateNewInviteeRole(index, 'VIEWER')
|
||||
@@ -209,15 +216,15 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="newInvites.length === 0"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/add_group.svg`"
|
||||
loading="lazy"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 mb-4"
|
||||
class="flex-col object-contain object-center h-16 mb-4 w-16 inline-flex"
|
||||
:alt="`${t('empty.invites')}`"
|
||||
/>
|
||||
<span class="pb-4 text-center">
|
||||
<span class="text-center pb-4">
|
||||
{{ t("empty.invites") }}
|
||||
</span>
|
||||
<ButtonSecondary
|
||||
@@ -229,12 +236,12 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="newInvites.length"
|
||||
class="border-dividerLight flex flex-col items-start px-4 py-4 mt-4 border rounded"
|
||||
class="border border-dividerLight rounded flex flex-col mt-4 py-4 px-4 items-start"
|
||||
>
|
||||
<span
|
||||
class="bg-primaryDark border-divider flex items-center justify-center px-2 py-1 mb-4 font-semibold border rounded-full"
|
||||
class="bg-primaryDark border border-divider rounded-full flex font-semibold mb-4 py-1 px-2 items-center justify-center"
|
||||
>
|
||||
<i class="text-secondaryLight material-icons mr-2">help_outline</i>
|
||||
<i class="mr-2 text-secondaryLight material-icons">help_outline</i>
|
||||
{{ t("profile.roles") }}
|
||||
</span>
|
||||
<p>
|
||||
@@ -242,10 +249,10 @@
|
||||
{{ t("profile.roles_description") }}
|
||||
</span>
|
||||
</p>
|
||||
<ul class="mt-4 space-y-4">
|
||||
<ul class="space-y-4 mt-4">
|
||||
<li class="flex">
|
||||
<span
|
||||
class="text-secondaryDark max-w-16 w-1/4 font-semibold uppercase truncate"
|
||||
class="font-semibold text-secondaryDark max-w-16 w-1/4 uppercase truncate"
|
||||
>
|
||||
{{ t("profile.owner") }}
|
||||
</span>
|
||||
@@ -255,7 +262,7 @@
|
||||
</li>
|
||||
<li class="flex">
|
||||
<span
|
||||
class="text-secondaryDark max-w-16 w-1/4 font-semibold uppercase truncate"
|
||||
class="font-semibold text-secondaryDark max-w-16 w-1/4 uppercase truncate"
|
||||
>
|
||||
{{ t("profile.editor") }}
|
||||
</span>
|
||||
@@ -265,7 +272,7 @@
|
||||
</li>
|
||||
<li class="flex">
|
||||
<span
|
||||
class="text-secondaryDark max-w-16 w-1/4 font-semibold uppercase truncate"
|
||||
class="font-semibold text-secondaryDark max-w-16 w-1/4 uppercase truncate"
|
||||
>
|
||||
{{ t("profile.viewer") }}
|
||||
</span>
|
||||
@@ -280,7 +287,7 @@
|
||||
<template #footer>
|
||||
<p
|
||||
v-if="sendInvitesResult.length"
|
||||
class="text-secondaryLight flex justify-between flex-1"
|
||||
class="flex flex-1 text-secondaryLight justify-between"
|
||||
>
|
||||
<SmartAnchor
|
||||
class="link"
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
<template>
|
||||
<div class="flex flex-col flex-1 border rounded border-divider">
|
||||
<div
|
||||
class="border border-divider rounded flex flex-col flex-1"
|
||||
@contextmenu.prevent="!compact ? $refs.options.tippy().show() : null"
|
||||
>
|
||||
<div
|
||||
class="flex items-start flex-1"
|
||||
class="flex flex-1 items-start"
|
||||
:class="
|
||||
compact
|
||||
? team.myRole === 'OWNER'
|
||||
@@ -24,7 +27,7 @@
|
||||
>
|
||||
{{ team.name || t("state.nothing_found") }}
|
||||
</label>
|
||||
<div class="flex mt-2 overflow-hidden -space-x-1">
|
||||
<div class="flex -space-x-1 mt-2 overflow-hidden">
|
||||
<img
|
||||
v-for="(member, index) in team.teamMembers"
|
||||
:key="`member-${index}`"
|
||||
@@ -32,13 +35,13 @@
|
||||
:title="member.user.displayName"
|
||||
:src="member.user.photoURL || undefined"
|
||||
:alt="member.user.displayName"
|
||||
class="inline-block w-5 h-5 rounded-full ring-primary ring-2"
|
||||
class="rounded-full h-5 ring-primary ring-2 w-5 inline-block"
|
||||
loading="lazy"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!compact" class="flex items-end justify-between flex-shrink-0">
|
||||
<div v-if="!compact" class="flex flex-shrink-0 items-end justify-between">
|
||||
<span>
|
||||
<ButtonSecondary
|
||||
v-if="team.myRole === 'OWNER'"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user