chore: merge hoppscotch/staging into self-hosted/main
This commit is contained in:
@@ -131,6 +131,7 @@
|
|||||||
@click="emit('export-json-collection')"
|
@click="emit('export-json-collection')"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
|
v-if="platform.platformFeatureFlags.exportAsGIST"
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="
|
:title="
|
||||||
!currentUser
|
!currentUser
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ export type PlatformDef = {
|
|||||||
history: HistoryPlatformDef
|
history: HistoryPlatformDef
|
||||||
tabState: TabStatePlatformDef
|
tabState: TabStatePlatformDef
|
||||||
}
|
}
|
||||||
|
platformFeatureFlags: {
|
||||||
|
exportAsGIST: boolean
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export let platform: PlatformDef
|
export let platform: PlatformDef
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col flex-1 h-auto overflow-y-hidden flex-nowrap">
|
<div class="flex flex-col flex-1 h-auto overflow-y-hidden flex-nowrap">
|
||||||
<div
|
<div
|
||||||
class="relative sticky top-0 z-10 flex-shrink-0 overflow-x-auto tabs bg-primaryLight"
|
class="relative sticky top-0 z-10 flex-shrink-0 overflow-x-auto tabs bg-primaryLight group-tabs"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="flex flex-1 flex-shrink-0 w-0 overflow-x-auto"
|
class="flex flex-1 flex-shrink-0 w-0 overflow-x-auto"
|
||||||
@@ -95,6 +95,22 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<input
|
||||||
|
type="range"
|
||||||
|
min="1"
|
||||||
|
:max="MAX_SCROLL_VALUE"
|
||||||
|
v-model="thumbPosition"
|
||||||
|
class="slider absolute bottom-0 hidden left-0"
|
||||||
|
:class="{
|
||||||
|
'!block': scrollThumb.show,
|
||||||
|
}"
|
||||||
|
:style="{
|
||||||
|
'--thumb-width': scrollThumb.width + 'px',
|
||||||
|
}"
|
||||||
|
style="width: calc(100% - 3rem)"
|
||||||
|
id="myRange"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-full h-full contents">
|
<div class="w-full h-full contents">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
@@ -110,7 +126,8 @@ import { pipe } from "fp-ts/function"
|
|||||||
import { not } from "fp-ts/Predicate"
|
import { not } from "fp-ts/Predicate"
|
||||||
import * as A from "fp-ts/Array"
|
import * as A from "fp-ts/Array"
|
||||||
import * as O from "fp-ts/Option"
|
import * as O from "fp-ts/Option"
|
||||||
import { ref, ComputedRef, computed, provide, inject } from "vue"
|
import { ref, ComputedRef, computed, provide, inject, watch } from "vue"
|
||||||
|
import { useElementSize } from "@vueuse/core"
|
||||||
import type { Slot } from "vue"
|
import type { Slot } from "vue"
|
||||||
import draggable from "vuedraggable-es"
|
import draggable from "vuedraggable-es"
|
||||||
import { HoppUIPluginOptions, HOPP_UI_OPTIONS } from "./../../index"
|
import { HoppUIPluginOptions, HOPP_UI_OPTIONS } from "./../../index"
|
||||||
@@ -135,32 +152,24 @@ export type TabProvider = {
|
|||||||
|
|
||||||
const { t } = inject<HoppUIPluginOptions>(HOPP_UI_OPTIONS) ?? {}
|
const { t } = inject<HoppUIPluginOptions>(HOPP_UI_OPTIONS) ?? {}
|
||||||
|
|
||||||
const props = defineProps({
|
const props = withDefaults(
|
||||||
styles: {
|
defineProps<{
|
||||||
type: String,
|
styles: string
|
||||||
default: "",
|
modelValue: string
|
||||||
},
|
renderInactiveTabs: boolean
|
||||||
modelValue: {
|
canAddNewTab: boolean
|
||||||
type: String,
|
newText: string | null
|
||||||
required: true,
|
closeText: string | null
|
||||||
},
|
}>(),
|
||||||
renderInactiveTabs: {
|
{
|
||||||
type: Boolean,
|
styles: "",
|
||||||
default: false,
|
renderInactiveTabs: false,
|
||||||
},
|
canAddNewTab: true,
|
||||||
canAddNewTab: {
|
newText: null,
|
||||||
type: Boolean,
|
closeText: null,
|
||||||
default: true,
|
}
|
||||||
},
|
)
|
||||||
newText: {
|
|
||||||
type: String,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
closeText: {
|
|
||||||
type: String,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: "update:modelValue", newTabID: string): void
|
(e: "update:modelValue", newTabID: string): void
|
||||||
(e: "sort", body: { oldIndex: number; newIndex: number }): void
|
(e: "sort", body: { oldIndex: number; newIndex: number }): void
|
||||||
@@ -241,12 +250,46 @@ const addTab = () => {
|
|||||||
emit("addTab")
|
emit("addTab")
|
||||||
}
|
}
|
||||||
|
|
||||||
const scrollContainer = ref<HTMLElement | null>(null)
|
/**
|
||||||
|
* Scroll related properties
|
||||||
|
*/
|
||||||
|
|
||||||
|
const MAX_SCROLL_VALUE = 500
|
||||||
|
const scrollContainer = ref<HTMLElement>()
|
||||||
|
const { width: scrollContainerWidth } = useElementSize(scrollContainer)
|
||||||
|
const thumbPosition = ref(0)
|
||||||
|
|
||||||
|
const scrollThumb = computed(() => {
|
||||||
|
const clientWidth = scrollContainerWidth.value ?? 0
|
||||||
|
const scrollWidth = tabEntries.value.length * 184
|
||||||
|
|
||||||
|
return {
|
||||||
|
width: (clientWidth / scrollWidth) * clientWidth || 300,
|
||||||
|
show: clientWidth ? scrollWidth > clientWidth : false,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Scroll with mouse wheel
|
||||||
|
*/
|
||||||
const scroll = (e: WheelEvent) => {
|
const scroll = (e: WheelEvent) => {
|
||||||
scrollContainer.value!.scrollLeft += e.deltaY
|
scrollContainer.value!.scrollLeft += e.deltaY
|
||||||
scrollContainer.value!.scrollLeft += e.deltaX
|
scrollContainer.value!.scrollLeft += e.deltaX
|
||||||
|
|
||||||
|
const { scrollWidth, clientWidth, scrollLeft } = scrollContainer.value!
|
||||||
|
const maxScroll = scrollWidth - clientWidth
|
||||||
|
thumbPosition.value = (scrollLeft / maxScroll) * MAX_SCROLL_VALUE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Scroll with scrollbar/slider
|
||||||
|
* when scroll thumb is dragged or clicked on the scrollbar
|
||||||
|
*/
|
||||||
|
watch(thumbPosition, (newVal) => {
|
||||||
|
const { scrollWidth, clientWidth } = scrollContainer.value!
|
||||||
|
const maxScroll = scrollWidth - clientWidth
|
||||||
|
scrollContainer.value!.scrollLeft = maxScroll * (newVal / MAX_SCROLL_VALUE)
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@@ -302,4 +345,38 @@ const scroll = (e: WheelEvent) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$slider-height: 4px;
|
||||||
|
.slider {
|
||||||
|
--thumb-width: 300px;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
width: 100%;
|
||||||
|
height: $slider-height;
|
||||||
|
background: transparent;
|
||||||
|
outline: none;
|
||||||
|
opacity: 0;
|
||||||
|
-webkit-transition: 0.2s;
|
||||||
|
transition: opacity 0.2s;
|
||||||
|
|
||||||
|
&::-webkit-slider-thumb {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
appearance: none;
|
||||||
|
min-width: 300px;
|
||||||
|
width: var(--thumb-width);
|
||||||
|
height: $slider-height;
|
||||||
|
background: gray;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
&::-moz-range-thumb {
|
||||||
|
min-width: 300px;
|
||||||
|
width: var(--thumb-width);
|
||||||
|
height: $slider-height;
|
||||||
|
background: gray;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.group-tabs:hover .slider {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -20,4 +20,7 @@ createHoppApp("#app", {
|
|||||||
history: historyDef,
|
history: historyDef,
|
||||||
tabState: tabStateDef,
|
tabState: tabStateDef,
|
||||||
},
|
},
|
||||||
|
platformFeatureFlags: {
|
||||||
|
exportAsGIST: true,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user