feat: vertical tabs for right sidebars

This commit is contained in:
liyasthomas
2021-09-18 23:50:42 +05:30
parent e1e763575d
commit b0a6692179
12 changed files with 217 additions and 166 deletions

View File

@@ -0,0 +1 @@
<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="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"></path><polyline points="3.27 6.96 12 12.01 20.73 6.96"></polyline><line x1="12" y1="22.08" x2="12" y2="12"></line></svg>

After

Width:  |  Height:  |  Size: 435 B

View File

@@ -0,0 +1 @@
<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"><circle cx="12" cy="12" r="10"></circle><polyline points="12 6 12 12 16 14"></polyline></svg>

After

Width:  |  Height:  |  Size: 275 B

View File

@@ -8,7 +8,7 @@
divide-y divide-dividerLight divide-y divide-dividerLight
border-b border-dividerLight border-b border-dividerLight
flex flex-col flex flex-col
top-sidebarPrimaryStickyFold top-0
z-10 z-10
sticky sticky
" "

View File

@@ -14,7 +14,6 @@
z-10 z-10
sticky sticky
" "
:class="{ '!top-sidebarPrimaryStickyFold': !saveRequest && !doc }"
> >
<div v-if="!saveRequest" class="search-wrappe"> <div v-if="!saveRequest" class="search-wrappe">
<input <input

View File

@@ -1,15 +1,6 @@
<template> <template>
<AppSection :label="`${$t('environment.title')}`"> <AppSection :label="`${$t('environment.title')}`">
<div <div class="bg-primary rounded-t flex flex-col top-0 z-10 sticky">
class="
bg-primary
rounded-t
flex flex-col
top-sidebarPrimaryStickyFold
z-10
sticky
"
>
<tippy ref="options" interactive trigger="click" theme="popover" arrow> <tippy ref="options" interactive trigger="click" theme="popover" arrow>
<template #trigger> <template #trigger>
<span <span

View File

@@ -1,9 +1,54 @@
<template> <template>
<aside> <SmartTabs styles="sticky bg-primary z-10 top-0" vertical>
<SmartTabs styles="sticky bg-primary z-10 top-0"> <SmartTab
<SmartTab :id="'docs'" :label="`Docs`" :selected="true"> :id="'history'"
<AppSection label="docs"> icon="clock"
<div class="bg-primary flex top-sidebarPrimaryStickyFold z-10 sticky"> :label="`${$t('tab.history')}`"
:selected="true"
>
<History
ref="graphqlHistoryComponent"
:page="'graphql'"
@useHistory="handleUseHistory"
/>
</SmartTab>
<SmartTab
:id="'collections'"
icon="folder"
:label="`${$t('tab.collections')}`"
>
<CollectionsGraphql />
</SmartTab>
<SmartTab
:id="'docs'"
icon="book-open"
:label="`${$t('tab.documentation')}`"
>
<AppSection label="docs">
<div
v-if="
queryFields.length === 0 &&
mutationFields.length === 0 &&
subscriptionFields.length === 0 &&
graphqlTypes.length === 0
"
class="
flex flex-col
text-secondaryLight
p-4
items-center
justify-center
"
>
<i class="opacity-75 pb-2 material-icons">link</i>
<span class="text-center">
{{ $t("empty.schema") }}
</span>
</div>
<div v-else>
<div class="bg-primary flex top-0 z-10 sticky">
<input <input
v-model="graphqlFieldsFilterText" v-model="graphqlFieldsFilterText"
type="search" type="search"
@@ -23,7 +68,7 @@
</div> </div>
<SmartTabs <SmartTabs
ref="gqlTabs" ref="gqlTabs"
styles="border-t border-dividerLight bg-primary sticky z-10 top-sidebarSecondaryStickyFold" styles="border-t border-b border-dividerLight bg-primary sticky z-10 top-sidebarPrimaryStickyFold"
> >
<div class="gqlTabs"> <div class="gqlTabs">
<SmartTab <SmartTab
@@ -88,110 +133,79 @@
</SmartTab> </SmartTab>
</div> </div>
</SmartTabs> </SmartTabs>
<div </div>
v-if=" </AppSection>
queryFields.length === 0 && </SmartTab>
mutationFields.length === 0 &&
subscriptionFields.length === 0 &&
graphqlTypes.length === 0
"
class="
flex flex-col
text-secondaryLight
p-4
items-center
justify-center
"
>
<i class="opacity-75 pb-2 material-icons">link</i>
<span class="text-center">
{{ $t("empty.schema") }}
</span>
</div>
</AppSection>
</SmartTab>
<SmartTab :id="'history'" :label="`${$t('tab.history')}`"> <SmartTab :id="'schema'" icon="box" :label="`${$t('tab.schema')}`">
<History <AppSection ref="schema" label="schema">
ref="graphqlHistoryComponent" <div
:page="'graphql'" v-if="schemaString"
@useHistory="handleUseHistory" class="
/> bg-primary
</SmartTab> flex flex-1
top-0
<SmartTab :id="'collections'" :label="`${$t('tab.collections')}`"> pl-4
<CollectionsGraphql /> z-10
</SmartTab> sticky
items-center
<SmartTab :id="'schema'" :label="`Schema`"> justify-between
<AppSection ref="schema" label="schema"> border-b border-dividerLight
<div "
v-if="schemaString" >
class=" <label class="font-semibold text-secondaryLight">
bg-primary {{ $t("graphql.schema") }}
flex flex-1 </label>
top-sidebarPrimaryStickyFold <div class="flex">
pl-4 <ButtonSecondary
z-10 v-tippy="{ theme: 'tooltip' }"
sticky to="https://docs.hoppscotch.io/quickstart/graphql"
items-center blank
justify-between :title="$t('app.wiki')"
" svg="help-circle"
> />
<label class="font-semibold text-secondaryLight"> <ButtonSecondary
{{ $t("graphql.schema") }} v-tippy="{ theme: 'tooltip' }"
</label> :title="$t('state.linewrap')"
<div class="flex"> :class="{ '!text-accent': linewrapEnabled }"
<ButtonSecondary svg="corner-down-left"
v-tippy="{ theme: 'tooltip' }" @click.native.prevent="linewrapEnabled = !linewrapEnabled"
to="https://docs.hoppscotch.io/quickstart/graphql" />
blank <ButtonSecondary
:title="$t('app.wiki')" ref="downloadSchema"
svg="help-circle" v-tippy="{ theme: 'tooltip' }"
/> :title="$t('action.download_file')"
<ButtonSecondary :svg="downloadSchemaIcon"
v-tippy="{ theme: 'tooltip' }" @click.native="downloadSchema"
:title="$t('state.linewrap')" />
:class="{ '!text-accent': linewrapEnabled }" <ButtonSecondary
svg="corner-down-left" ref="copySchemaCode"
@click.native.prevent="linewrapEnabled = !linewrapEnabled" v-tippy="{ theme: 'tooltip' }"
/> :title="$t('action.copy')"
<ButtonSecondary :svg="copySchemaIcon"
ref="downloadSchema" @click.native="copySchema"
v-tippy="{ theme: 'tooltip' }" />
:title="$t('action.download_file')"
:svg="downloadSchemaIcon"
@click.native="downloadSchema"
/>
<ButtonSecondary
ref="copySchemaCode"
v-tippy="{ theme: 'tooltip' }"
:title="$t('action.copy')"
:svg="copySchemaIcon"
@click.native="copySchema"
/>
</div>
</div> </div>
<div v-if="schemaString" ref="schemaEditor"></div> </div>
<div <div v-if="schemaString" ref="schemaEditor"></div>
v-else <div
class=" v-else
flex flex-col class="
text-secondaryLight flex flex-col
p-4 text-secondaryLight
items-center p-4
justify-center items-center
" justify-center
> "
<i class="opacity-75 pb-2 material-icons">link</i> >
<span class="text-center"> <i class="opacity-75 pb-2 material-icons">link</i>
{{ $t("empty.schema") }} <span class="text-center">
</span> {{ $t("empty.schema") }}
</div> </span>
</AppSection> </div>
</SmartTab> </AppSection>
</SmartTabs> </SmartTab>
</aside> </SmartTabs>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">

View File

@@ -1,15 +1,6 @@
<template> <template>
<AppSection label="history"> <AppSection label="history">
<div <div class="bg-primary border-b border-dividerLight flex top-0 z-10 sticky">
class="
bg-primary
border-b border-dividerLight
flex
top-sidebarPrimaryStickyFold
z-10
sticky
"
>
<input <input
v-model="filterText" v-model="filterText"
type="search" type="search"

View File

@@ -1,34 +1,53 @@
<template> <template>
<div class="flex flex-col flex-nowrap flex-1"> <div
<div class="tabs hide-scrollbar relative" :class="styles"> class="flex flex-nowrap flex-1 h-full"
:class="{ 'flex-col': !vertical }"
>
<div
class="tabs hide-scrollbar relative"
:class="[{ 'border-r border-dividerLight': vertical }, styles]"
>
<div class="flex flex-1"> <div class="flex flex-1">
<div class="flex flex-1 justify-between"> <div
<div class="flex"> class="flex flex-1 justify-between"
:class="{ 'flex-col': vertical }"
>
<div class="flex" :class="{ 'flex-col space-y-2 p-2': vertical }">
<button <button
v-for="(tab, index) in tabs" v-for="(tab, index) in tabs"
:key="`tab-${index}`" :key="`tab-${index}`"
class="tab" class="tab"
:class="{ active: tab.active }" :class="[{ active: tab.active }, { vertical: vertical }]"
tabindex="0" tabindex="0"
@keyup.enter="selectTab(tab)" @keyup.enter="selectTab(tab)"
@click="selectTab(tab)" @click="selectTab(tab)"
> >
<i v-if="tab.icon" class="material-icons"> <SmartIcon v-if="tab.icon" class="svg-icons" :name="tab.icon" />
{{ tab.icon }} <tippy
</i> v-if="vertical && tab.label"
<span v-if="tab.label">{{ tab.label }}</span> placement="left"
theme="tooltip"
:content="tab.label"
/>
<span v-else-if="tab.label">{{ tab.label }}</span>
<span v-if="tab.info && tab.info !== 'null'" class="tab-info"> <span v-if="tab.info && tab.info !== 'null'" class="tab-info">
{{ tab.info }} {{ tab.info }}
</span> </span>
</button> </button>
</div> </div>
<div class="flex"> <div class="flex justify-center items-center">
<slot name="actions"></slot> <slot name="actions"></slot>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<slot></slot> <div
:class="{
'flex flex-col flex-1 overflow-y-auto hide-scrollbar': vertical,
}"
>
<slot></slot>
</div>
</div> </div>
</template> </template>
@@ -41,6 +60,10 @@ export default defineComponent({
type: String, type: String,
default: "", default: "",
}, },
vertical: {
type: Boolean,
default: false,
},
}, },
data() { data() {
@@ -49,8 +72,10 @@ export default defineComponent({
} }
}, },
created() { mounted() {
this.tabs = this.$children this.tabs = this.$children.filter(
(child) => child.$options.name === "SmartTab"
)
}, },
methods: { methods: {
@@ -69,6 +94,7 @@ export default defineComponent({
@apply flex; @apply flex;
@apply whitespace-nowrap; @apply whitespace-nowrap;
@apply overflow-auto; @apply overflow-auto;
@apply flex-shrink-0;
// &::after { // &::after {
// @apply absolute; // @apply absolute;
@@ -84,6 +110,7 @@ export default defineComponent({
.tab { .tab {
@apply relative; @apply relative;
@apply flex; @apply flex;
@apply flex-shrink-0;
@apply items-center; @apply items-center;
@apply justify-center; @apply justify-center;
@apply px-4 py-2; @apply px-4 py-2;
@@ -120,10 +147,6 @@ export default defineComponent({
content: ""; content: "";
} }
.material-icons {
@apply mr-4;
}
&:focus::after { &:focus::after {
@apply bg-divider; @apply bg-divider;
} }
@@ -140,6 +163,28 @@ export default defineComponent({
@apply bg-accent; @apply bg-accent;
} }
} }
&.vertical {
@apply p-2;
@apply rounded;
&:focus::after {
@apply hidden;
}
&.active {
@apply text-accent;
.tab-info {
@apply text-secondary;
@apply border-dividerDark;
}
&::after {
@apply hidden;
}
}
}
} }
} }
</style> </style>

View File

@@ -442,6 +442,7 @@
"authorization": "Authorization", "authorization": "Authorization",
"body": "Body", "body": "Body",
"collections": "Collections", "collections": "Collections",
"documentation": "Documentation",
"headers": "Headers", "headers": "Headers",
"history": "History", "history": "History",
"mqtt": "MQTT", "mqtt": "MQTT",
@@ -449,6 +450,7 @@
"pre_request_script": "Pre-request Script", "pre_request_script": "Pre-request Script",
"queries": "Queries", "queries": "Queries",
"query": "Query", "query": "Query",
"schema": "Schema",
"socketio": "Socket.IO", "socketio": "Socket.IO",
"sse": "SSE", "sse": "SSE",
"tests": "Tests", "tests": "Tests",

View File

@@ -71,7 +71,7 @@ export const defaultSettings: SettingsType = {
bearerToken: true, bearerToken: true,
oauth2Token: true, oauth2Token: true,
}, },
THEME_COLOR: "blue", THEME_COLOR: "indigo",
BG_COLOR: "system", BG_COLOR: "system",
TELEMETRY_ENABLED: true, TELEMETRY_ENABLED: true,
LEFT_SIDEBAR: true, LEFT_SIDEBAR: true,

View File

@@ -61,25 +61,32 @@
min-size="20" min-size="20"
class="hide-scrollbar !overflow-auto" class="hide-scrollbar !overflow-auto"
> >
<aside> <SmartTabs styles="sticky bg-primary z-10 top-0" vertical>
<SmartTabs styles="sticky bg-primary z-10 top-0"> <SmartTab
<SmartTab :id="'history'"
:id="'history'" icon="clock"
:label="`${$t('tab.history')}`" :label="`${$t('tab.history')}`"
:selected="true" :selected="true"
> >
<History ref="historyComponent" :page="'rest'" /> <History ref="historyComponent" :page="'rest'" />
</SmartTab> </SmartTab>
<SmartTab :id="'collections'" :label="`${$t('tab.collections')}`"> <SmartTab
<Collections /> :id="'collections'"
</SmartTab> icon="folder"
:label="`${$t('tab.collections')}`"
>
<Collections />
</SmartTab>
<SmartTab :id="'env'" :label="`${$t('environment.title')}`"> <SmartTab
<Environments /> :id="'env'"
</SmartTab> icon="layers"
</SmartTabs> :label="`${$t('environment.title')}`"
</aside> >
<Environments />
</SmartTab>
</SmartTabs>
</Pane> </Pane>
<SmartConfirmModal <SmartConfirmModal
:show="confirmSync" :show="confirmSync"

View File

@@ -397,7 +397,7 @@ export default defineComponent({
showLogin: false, showLogin: false,
active: getLocalConfig("THEME_COLOR") || "blue", active: getLocalConfig("THEME_COLOR") || "indigo",
confirmRemove: false, confirmRemove: false,
} }
}, },