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
border-b border-dividerLight
flex flex-col
top-sidebarPrimaryStickyFold
top-0
z-10
sticky
"

View File

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

View File

@@ -1,15 +1,6 @@
<template>
<AppSection :label="`${$t('environment.title')}`">
<div
class="
bg-primary
rounded-t
flex flex-col
top-sidebarPrimaryStickyFold
z-10
sticky
"
>
<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

View File

@@ -1,9 +1,54 @@
<template>
<aside>
<SmartTabs styles="sticky bg-primary z-10 top-0">
<SmartTab :id="'docs'" :label="`Docs`" :selected="true">
<AppSection label="docs">
<div class="bg-primary flex top-sidebarPrimaryStickyFold z-10 sticky">
<SmartTabs styles="sticky bg-primary z-10 top-0" vertical>
<SmartTab
:id="'history'"
icon="clock"
: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
v-model="graphqlFieldsFilterText"
type="search"
@@ -23,7 +68,7 @@
</div>
<SmartTabs
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">
<SmartTab
@@ -88,110 +133,79 @@
</SmartTab>
</div>
</SmartTabs>
<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>
</AppSection>
</SmartTab>
</div>
</AppSection>
</SmartTab>
<SmartTab :id="'history'" :label="`${$t('tab.history')}`">
<History
ref="graphqlHistoryComponent"
:page="'graphql'"
@useHistory="handleUseHistory"
/>
</SmartTab>
<SmartTab :id="'collections'" :label="`${$t('tab.collections')}`">
<CollectionsGraphql />
</SmartTab>
<SmartTab :id="'schema'" :label="`Schema`">
<AppSection ref="schema" label="schema">
<div
v-if="schemaString"
class="
bg-primary
flex flex-1
top-sidebarPrimaryStickyFold
pl-4
z-10
sticky
items-center
justify-between
"
>
<label class="font-semibold text-secondaryLight">
{{ $t("graphql.schema") }}
</label>
<div class="flex">
<ButtonSecondary
v-tippy="{ theme: 'tooltip' }"
to="https://docs.hoppscotch.io/quickstart/graphql"
blank
:title="$t('app.wiki')"
svg="help-circle"
/>
<ButtonSecondary
v-tippy="{ theme: 'tooltip' }"
:title="$t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }"
svg="corner-down-left"
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
/>
<ButtonSecondary
ref="downloadSchema"
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>
<SmartTab :id="'schema'" icon="box" :label="`${$t('tab.schema')}`">
<AppSection ref="schema" label="schema">
<div
v-if="schemaString"
class="
bg-primary
flex flex-1
top-0
pl-4
z-10
sticky
items-center
justify-between
border-b border-dividerLight
"
>
<label class="font-semibold text-secondaryLight">
{{ $t("graphql.schema") }}
</label>
<div class="flex">
<ButtonSecondary
v-tippy="{ theme: 'tooltip' }"
to="https://docs.hoppscotch.io/quickstart/graphql"
blank
:title="$t('app.wiki')"
svg="help-circle"
/>
<ButtonSecondary
v-tippy="{ theme: 'tooltip' }"
:title="$t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }"
svg="corner-down-left"
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
/>
<ButtonSecondary
ref="downloadSchema"
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 v-if="schemaString" ref="schemaEditor"></div>
<div
v-else
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>
</SmartTabs>
</aside>
</div>
<div v-if="schemaString" ref="schemaEditor"></div>
<div
v-else
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>
</SmartTabs>
</template>
<script setup lang="ts">

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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