Compare commits

...

23 Commits

Author SHA1 Message Date
Andrew Bastin
0ffc9e3a4d refactor: network strategy rewrite 2021-12-12 16:43:07 +05:30
liyasthomas
75e34feabf feat: context menu for secondary actions in collection, environment and team components - #2005 2021-12-11 08:03:39 +05:30
liyasthomas
fe13de2ea0 feat: show existing name while renaming collections/folders/requests - resolved #2006 2021-12-10 10:55:49 +05:30
liyasthomas
dec26ce2aa feat: update and verify email address 2021-12-08 20:50:59 +05:30
liyasthomas
b0f02fee57 feat: change and verify user's email address 2021-12-07 06:52:43 +05:30
Andrew Bastin
02be413eff fix: fail state requests with response data can run tests fixes #1996 2021-12-06 20:06:19 +05:30
liyasthomas
42849e6853 chore(deps): bump 2021-12-05 21:18:55 +05:30
liyasthomas
e7535d505e fix: catch an edge case while saving request 2021-12-05 18:21:41 +05:30
liyasthomas
fb6015ce26 refactor: improve ui consistency 2021-12-05 10:04:01 +05:30
liyasthomas
f3a38bab3c chore(deps): bump 2021-12-05 06:15:21 +05:30
liyasthomas
1a1f45401c fix: package import location 2021-12-04 20:57:10 +05:30
Andrew Bastin
4a43807f34 fix: formdata inconsistencies 2021-12-04 19:50:04 +05:30
liyasthomas
88cc21e3d4 chore(deps): bump 2021-12-04 19:08:12 +05:30
liyasthomas
ecce830787 Merge remote-tracking branch 'origin/i18n' 2021-12-04 19:03:09 +05:30
liyasthomas
084039f59f refactor: minor ui improvements 2021-12-04 18:59:26 +05:30
liyasthomas
0de9f3d8c3 fix: broken function import 2021-12-03 20:34:20 +05:30
Andrew Bastin
4d6d30c92b fix: shared references on saveRequest causing overwrite fixes #1992 2021-12-03 16:27:18 +05:30
Andrew Bastin
38755bf3e3 refactor: separate out data structures into hoppscotch-data 2021-12-03 16:10:56 +05:30
Lokesh Sanapalli
2884854aab fix: docker node-gyp python not found (#1987)
Co-authored-by: Liyas Thomas <liyascthomas@gmail.com>
2021-12-03 13:14:34 +05:30
Andrius Petrauskis
d24d07e420 fix: show an error when pre-request script fails (#1991)
* fix: show an error when pre-request script fails

* refactor: minor ui improvements

Co-authored-by: Liyas Thomas <liyascthomas@gmail.com>
2021-12-02 23:14:26 +05:30
0xc0Der
cc81242294 realtime persistence. (#1952)
* feat: websocket persistence

* feat: socketio persistence

* feat: sse persistence

* feat: mqtt persistence

* fix: added types

* fix: typescript issues

Co-authored-by: Andrew Bastin <andrewbastin.k@gmail.com>
2021-12-02 20:20:24 +05:30
liyasthomas
a508909471 refactor: sort windi class names 2021-12-01 22:59:01 +05:30
SiderealArt
475a28b159 chore(i18n): update tw translations (#1986) 2021-11-30 10:50:57 +05:30
186 changed files with 4807 additions and 2028 deletions

View File

@@ -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

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View 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

View 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

View File

@@ -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);

View File

@@ -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>

View File

@@ -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,
}"

View File

@@ -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>

View File

@@ -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>

View File

@@ -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')"

View File

@@ -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

View File

@@ -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) }}

View File

@@ -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>

View File

@@ -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>

View File

@@ -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

View File

@@ -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}`"

View File

@@ -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>

View File

@@ -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>

View File

@@ -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,

View File

@@ -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

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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>

View File

@@ -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) {

View File

@@ -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({

View File

@@ -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"
},
},

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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"
},
},

View File

@@ -12,7 +12,6 @@
<ButtonSecondary
v-tippy="{ theme: 'tooltip' }"
:title="$t('action.more')"
class="rounded"
svg="more-vertical"
/>
</template>

View File

@@ -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"

View File

@@ -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

View File

@@ -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)"
/>

View File

@@ -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"
},
},

View File

@@ -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"
},
},

View File

@@ -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$,

View File

@@ -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"
},
},

View File

@@ -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"
},
},

View File

@@ -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$,

View File

@@ -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

View File

@@ -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

View File

@@ -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">

View File

@@ -12,7 +12,6 @@
<ButtonSecondary
v-tippy="{ theme: 'tooltip' }"
:title="$t('action.more')"
class="rounded"
svg="more-vertical"
/>
</template>

View File

@@ -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

View File

@@ -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"

View File

@@ -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 {

View File

@@ -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"

View File

@@ -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"

View File

@@ -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>

View File

@@ -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,

View File

@@ -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>

View File

@@ -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"

View File

@@ -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>

View File

@@ -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')"
/>

View File

@@ -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"

View File

@@ -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

View File

@@ -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,

View File

@@ -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>

View File

@@ -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()

View File

@@ -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"

View File

@@ -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,
}
},
}

View File

@@ -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,

View File

@@ -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">

View File

@@ -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

View File

@@ -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()

View File

@@ -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)

View File

@@ -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

View File

@@ -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"

View File

@@ -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"

View File

@@ -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">

View File

@@ -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"

View File

@@ -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

View File

@@ -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"

View File

@@ -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>

View File

@@ -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

View File

@@ -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

View File

@@ -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"

View File

@@ -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>

View File

@@ -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") +

View File

@@ -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(),

View File

@@ -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",

View File

@@ -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>

View File

@@ -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;

View File

@@ -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>

View File

@@ -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"

View File

@@ -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)

View File

@@ -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 }}

View File

@@ -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>

View File

@@ -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"
>&#8203;</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()) {

View File

@@ -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;

View File

@@ -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;

View File

@@ -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`

View File

@@ -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

View File

@@ -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>

View File

@@ -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"

View File

@@ -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