feat: environment quick peek (#3119)
This commit is contained in:
@@ -204,13 +204,18 @@
|
|||||||
"deleted": "Environment deletion",
|
"deleted": "Environment deletion",
|
||||||
"edit": "Edit Environment",
|
"edit": "Edit Environment",
|
||||||
"global": "Global",
|
"global": "Global",
|
||||||
|
"empty_variables": "No variables",
|
||||||
|
"global_variables": "Global variables",
|
||||||
"invalid_name": "Please provide a name for the environment",
|
"invalid_name": "Please provide a name for the environment",
|
||||||
|
"list": "Environment variables",
|
||||||
"my_environments": "My Environments",
|
"my_environments": "My Environments",
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
"nested_overflow": "nested environment variables are limited to 10 levels",
|
"nested_overflow": "nested environment variables are limited to 10 levels",
|
||||||
"new": "New Environment",
|
"new": "New Environment",
|
||||||
|
"no_active_environment": "No active environment",
|
||||||
"no_environment": "No environment",
|
"no_environment": "No environment",
|
||||||
"no_environment_description": "No environments were selected. Choose what to do with the following variables.",
|
"no_environment_description": "No environments were selected. Choose what to do with the following variables.",
|
||||||
|
"quick_peek": "Environment Quick Peek",
|
||||||
"replace_with_variable": "Replace with variable",
|
"replace_with_variable": "Replace with variable",
|
||||||
"scope": "Scope",
|
"scope": "Scope",
|
||||||
"select": "Select environment",
|
"select": "Select environment",
|
||||||
|
|||||||
37
packages/hoppscotch-common/src/components.d.ts
vendored
37
packages/hoppscotch-common/src/components.d.ts
vendored
@@ -77,29 +77,6 @@ declare module '@vue/runtime-core' {
|
|||||||
History: typeof import('./components/history/index.vue')['default']
|
History: typeof import('./components/history/index.vue')['default']
|
||||||
HistoryGraphqlCard: typeof import('./components/history/graphql/Card.vue')['default']
|
HistoryGraphqlCard: typeof import('./components/history/graphql/Card.vue')['default']
|
||||||
HistoryRestCard: typeof import('./components/history/rest/Card.vue')['default']
|
HistoryRestCard: typeof import('./components/history/rest/Card.vue')['default']
|
||||||
HoppButtonPrimary: typeof import('@hoppscotch/ui')['HoppButtonPrimary']
|
|
||||||
HoppButtonSecondary: typeof import('@hoppscotch/ui')['HoppButtonSecondary']
|
|
||||||
HoppSmartAnchor: typeof import('@hoppscotch/ui')['HoppSmartAnchor']
|
|
||||||
HoppSmartAutoComplete: typeof import('@hoppscotch/ui')['HoppSmartAutoComplete']
|
|
||||||
HoppSmartCheckbox: typeof import('@hoppscotch/ui')['HoppSmartCheckbox']
|
|
||||||
HoppSmartConfirmModal: typeof import('@hoppscotch/ui')['HoppSmartConfirmModal']
|
|
||||||
HoppSmartExpand: typeof import('@hoppscotch/ui')['HoppSmartExpand']
|
|
||||||
HoppSmartFileChip: typeof import('@hoppscotch/ui')['HoppSmartFileChip']
|
|
||||||
HoppSmartInput: typeof import('@hoppscotch/ui')['HoppSmartInput']
|
|
||||||
HoppSmartItem: typeof import('@hoppscotch/ui')['HoppSmartItem']
|
|
||||||
HoppSmartLink: typeof import('@hoppscotch/ui')['HoppSmartLink']
|
|
||||||
HoppSmartModal: typeof import('@hoppscotch/ui')['HoppSmartModal']
|
|
||||||
HoppSmartPicture: typeof import('@hoppscotch/ui')['HoppSmartPicture']
|
|
||||||
HoppSmartPlaceholder: typeof import('@hoppscotch/ui')['HoppSmartPlaceholder']
|
|
||||||
HoppSmartProgressRing: typeof import('@hoppscotch/ui')['HoppSmartProgressRing']
|
|
||||||
HoppSmartRadioGroup: typeof import('@hoppscotch/ui')['HoppSmartRadioGroup']
|
|
||||||
HoppSmartSlideOver: typeof import('@hoppscotch/ui')['HoppSmartSlideOver']
|
|
||||||
HoppSmartSpinner: typeof import('@hoppscotch/ui')['HoppSmartSpinner']
|
|
||||||
HoppSmartTab: typeof import('@hoppscotch/ui')['HoppSmartTab']
|
|
||||||
HoppSmartTabs: typeof import('@hoppscotch/ui')['HoppSmartTabs']
|
|
||||||
HoppSmartToggle: typeof import('@hoppscotch/ui')['HoppSmartToggle']
|
|
||||||
HoppSmartWindow: typeof import('@hoppscotch/ui')['HoppSmartWindow']
|
|
||||||
HoppSmartWindows: typeof import('@hoppscotch/ui')['HoppSmartWindows']
|
|
||||||
HttpAuthorization: typeof import('./components/http/Authorization.vue')['default']
|
HttpAuthorization: typeof import('./components/http/Authorization.vue')['default']
|
||||||
HttpAuthorizationApiKey: typeof import('./components/http/authorization/ApiKey.vue')['default']
|
HttpAuthorizationApiKey: typeof import('./components/http/authorization/ApiKey.vue')['default']
|
||||||
HttpAuthorizationBasic: typeof import('./components/http/authorization/Basic.vue')['default']
|
HttpAuthorizationBasic: typeof import('./components/http/authorization/Basic.vue')['default']
|
||||||
@@ -119,25 +96,13 @@ declare module '@vue/runtime-core' {
|
|||||||
HttpResponse: typeof import('./components/http/Response.vue')['default']
|
HttpResponse: typeof import('./components/http/Response.vue')['default']
|
||||||
HttpResponseMeta: typeof import('./components/http/ResponseMeta.vue')['default']
|
HttpResponseMeta: typeof import('./components/http/ResponseMeta.vue')['default']
|
||||||
HttpSidebar: typeof import('./components/http/Sidebar.vue')['default']
|
HttpSidebar: typeof import('./components/http/Sidebar.vue')['default']
|
||||||
|
HttpTabHead: typeof import('./components/http/TabHead.vue')['default']
|
||||||
HttpTestResult: typeof import('./components/http/TestResult.vue')['default']
|
HttpTestResult: typeof import('./components/http/TestResult.vue')['default']
|
||||||
HttpTestResultEntry: typeof import('./components/http/TestResultEntry.vue')['default']
|
HttpTestResultEntry: typeof import('./components/http/TestResultEntry.vue')['default']
|
||||||
HttpTestResultEnv: typeof import('./components/http/TestResultEnv.vue')['default']
|
HttpTestResultEnv: typeof import('./components/http/TestResultEnv.vue')['default']
|
||||||
HttpTestResultReport: typeof import('./components/http/TestResultReport.vue')['default']
|
HttpTestResultReport: typeof import('./components/http/TestResultReport.vue')['default']
|
||||||
HttpTests: typeof import('./components/http/Tests.vue')['default']
|
HttpTests: typeof import('./components/http/Tests.vue')['default']
|
||||||
HttpURLEncodedParams: typeof import('./components/http/URLEncodedParams.vue')['default']
|
HttpURLEncodedParams: typeof import('./components/http/URLEncodedParams.vue')['default']
|
||||||
IconLucideAlertTriangle: typeof import('~icons/lucide/alert-triangle')['default']
|
|
||||||
IconLucideArrowLeft: typeof import('~icons/lucide/arrow-left')['default']
|
|
||||||
IconLucideCheckCircle: typeof import('~icons/lucide/check-circle')['default']
|
|
||||||
IconLucideChevronRight: typeof import('~icons/lucide/chevron-right')['default']
|
|
||||||
IconLucideGlobe: typeof import('~icons/lucide/globe')['default']
|
|
||||||
IconLucideHelpCircle: typeof import('~icons/lucide/help-circle')['default']
|
|
||||||
IconLucideInbox: typeof import('~icons/lucide/inbox')['default']
|
|
||||||
IconLucideInfo: typeof import('~icons/lucide/info')['default']
|
|
||||||
IconLucideLayers: typeof import('~icons/lucide/layers')['default']
|
|
||||||
IconLucideListEnd: typeof import('~icons/lucide/list-end')['default']
|
|
||||||
IconLucideMinus: typeof import('~icons/lucide/minus')['default']
|
|
||||||
IconLucideSearch: typeof import('~icons/lucide/search')['default']
|
|
||||||
IconLucideUsers: typeof import('~icons/lucide/users')['default']
|
|
||||||
LensesHeadersRenderer: typeof import('./components/lenses/HeadersRenderer.vue')['default']
|
LensesHeadersRenderer: typeof import('./components/lenses/HeadersRenderer.vue')['default']
|
||||||
LensesHeadersRendererEntry: typeof import('./components/lenses/HeadersRendererEntry.vue')['default']
|
LensesHeadersRendererEntry: typeof import('./components/lenses/HeadersRendererEntry.vue')['default']
|
||||||
LensesRenderersAudioLensRenderer: typeof import('./components/lenses/renderers/AudioLensRenderer.vue')['default']
|
LensesRenderersAudioLensRenderer: typeof import('./components/lenses/renderers/AudioLensRenderer.vue')['default']
|
||||||
|
|||||||
@@ -18,14 +18,14 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="inline-flex items-center justify-center flex-1 space-x-2">
|
<div class="inline-flex items-center justify-center flex-1 space-x-2">
|
||||||
<button
|
<button
|
||||||
class="flex flex-1 items-center justify-between px-2 py-1 bg-primaryDark transition text-secondaryLight cursor-text rounded border border-dividerDark max-w-xs hover:border-dividerDark hover:bg-primaryLight hover:text-secondary focus-visible:border-dividerDark focus-visible:bg-primaryLight focus-visible:text-secondary"
|
class="flex flex-1 items-center justify-between px-2 py-1 self-stretch bg-primaryDark transition text-secondaryLight cursor-text rounded border border-dividerDark max-w-60 hover:border-dividerDark hover:bg-primaryLight hover:text-secondary focus-visible:border-dividerDark focus-visible:bg-primaryLight focus-visible:text-secondary"
|
||||||
@click="invokeAction('modals.search.toggle')"
|
@click="invokeAction('modals.search.toggle')"
|
||||||
>
|
>
|
||||||
<span class="inline-flex flex-1 items-center">
|
<span class="inline-flex flex-1 items-center">
|
||||||
<icon-lucide-search class="mr-2 svg-icons" />
|
<icon-lucide-search class="mr-2 svg-icons" />
|
||||||
{{ t("app.search") }}
|
{{ t("app.search") }}
|
||||||
</span>
|
</span>
|
||||||
<span class="flex">
|
<span class="flex space-x-1">
|
||||||
<kbd class="shortcut-key">{{ getPlatformSpecialKey() }}</kbd>
|
<kbd class="shortcut-key">{{ getPlatformSpecialKey() }}</kbd>
|
||||||
<kbd class="shortcut-key">K</kbd>
|
<kbd class="shortcut-key">K</kbd>
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -1,203 +1,301 @@
|
|||||||
<template>
|
<template>
|
||||||
<tippy
|
<div class="flex divide-x divide-dividerLight">
|
||||||
interactive
|
<tippy
|
||||||
trigger="click"
|
interactive
|
||||||
theme="popover"
|
trigger="click"
|
||||||
:on-shown="() => tippyActions!.focus()"
|
theme="popover"
|
||||||
>
|
:on-shown="() => envSelectorActions!.focus()"
|
||||||
<span
|
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
|
||||||
:title="`${t('environment.select')}`"
|
|
||||||
class="bg-transparent select-wrapper"
|
|
||||||
>
|
>
|
||||||
<HoppButtonSecondary
|
<span
|
||||||
:icon="IconLayers"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:label="
|
:title="`${t('environment.select')}`"
|
||||||
mdAndLarger
|
class="bg-transparent border-b border-dividerLight select-wrapper"
|
||||||
? selectedEnv.type !== 'NO_ENV_SELECTED'
|
|
||||||
? selectedEnv.name
|
|
||||||
: `${t('environment.select')}`
|
|
||||||
: ''
|
|
||||||
"
|
|
||||||
class="flex-1 !justify-start pr-8 rounded-none"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<template #content="{ hide }">
|
|
||||||
<div
|
|
||||||
ref="tippyActions"
|
|
||||||
role="menu"
|
|
||||||
class="flex flex-col focus:outline-none"
|
|
||||||
tabindex="0"
|
|
||||||
@keyup.escape="hide()"
|
|
||||||
>
|
>
|
||||||
<HoppSmartItem
|
<HoppButtonSecondary
|
||||||
v-if="!isScopeSelector"
|
:icon="IconLayers"
|
||||||
:label="`${t('environment.no_environment')}`"
|
:label="
|
||||||
:info-icon="
|
mdAndLarger
|
||||||
selectedEnvironmentIndex.type === 'NO_ENV_SELECTED'
|
? selectedEnv.type !== 'NO_ENV_SELECTED'
|
||||||
? IconCheck
|
? selectedEnv.name
|
||||||
: undefined
|
: `${t('environment.select')}`
|
||||||
"
|
: ''
|
||||||
:active-info-icon="
|
|
||||||
selectedEnvironmentIndex.type === 'NO_ENV_SELECTED'
|
|
||||||
"
|
|
||||||
@click="
|
|
||||||
() => {
|
|
||||||
selectedEnvironmentIndex = { type: 'NO_ENV_SELECTED' }
|
|
||||||
hide()
|
|
||||||
}
|
|
||||||
"
|
"
|
||||||
|
class="flex-1 !justify-start pr-8 rounded-none"
|
||||||
/>
|
/>
|
||||||
<HoppSmartItem
|
</span>
|
||||||
v-else-if="isScopeSelector && modelValue"
|
<template #content="{ hide }">
|
||||||
:label="t('environment.global')"
|
<div
|
||||||
:icon="IconGlobe"
|
ref="envSelectorActions"
|
||||||
:info-icon="modelValue.type === 'global' ? IconCheck : undefined"
|
role="menu"
|
||||||
:active-info-icon="modelValue.type === 'global'"
|
class="flex flex-col focus:outline-none"
|
||||||
@click="
|
tabindex="0"
|
||||||
() => {
|
@keyup.escape="hide()"
|
||||||
$emit('update:modelValue', {
|
|
||||||
type: 'global',
|
|
||||||
})
|
|
||||||
hide()
|
|
||||||
}
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
<HoppSmartTabs
|
|
||||||
v-model="selectedEnvTab"
|
|
||||||
styles="sticky overflow-x-auto my-2 border border-divider rounded flex-shrink-0 z-10 top-0 bg-primary"
|
|
||||||
render-inactive-tabs
|
|
||||||
>
|
>
|
||||||
<HoppSmartTab
|
<HoppSmartItem
|
||||||
:id="'my-environments'"
|
:label="`${t('environment.no_environment')}`"
|
||||||
:label="`${t('environment.my_environments')}`"
|
:info-icon="
|
||||||
|
selectedEnvironmentIndex.type === 'NO_ENV_SELECTED'
|
||||||
|
? IconCheck
|
||||||
|
: undefined
|
||||||
|
"
|
||||||
|
:active-info-icon="
|
||||||
|
selectedEnvironmentIndex.type === 'NO_ENV_SELECTED'
|
||||||
|
"
|
||||||
|
@click="
|
||||||
|
() => {
|
||||||
|
selectedEnvironmentIndex = { type: 'NO_ENV_SELECTED' }
|
||||||
|
hide()
|
||||||
|
}
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
<HoppSmartTabs
|
||||||
|
v-model="selectedEnvTab"
|
||||||
|
styles="sticky overflow-x-auto my-2 border border-divider rounded flex-shrink-0 z-0 top-0 bg-primary"
|
||||||
|
render-inactive-tabs
|
||||||
>
|
>
|
||||||
<HoppSmartItem
|
<HoppSmartTab
|
||||||
v-for="(gen, index) in myEnvironments"
|
:id="'my-environments'"
|
||||||
:key="`gen-${index}`"
|
:label="`${t('environment.my_environments')}`"
|
||||||
:icon="IconLayers"
|
|
||||||
:label="gen.name"
|
|
||||||
:info-icon="isEnvActive(index) ? IconCheck : undefined"
|
|
||||||
:active-info-icon="isEnvActive(index)"
|
|
||||||
@click="
|
|
||||||
() => {
|
|
||||||
handleEnvironmentChange(index, {
|
|
||||||
type: 'my-environment',
|
|
||||||
environment: gen,
|
|
||||||
})
|
|
||||||
hide()
|
|
||||||
}
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
<HoppSmartPlaceholder
|
|
||||||
v-if="myEnvironments.length === 0"
|
|
||||||
:src="`/images/states/${colorMode.value}/blockchain.svg`"
|
|
||||||
:alt="`${t('empty.environments')}`"
|
|
||||||
:text="t('empty.environments')"
|
|
||||||
>
|
>
|
||||||
</HoppSmartPlaceholder>
|
|
||||||
</HoppSmartTab>
|
|
||||||
<HoppSmartTab
|
|
||||||
:id="'team-environments'"
|
|
||||||
:label="`${t('environment.team_environments')}`"
|
|
||||||
:disabled="!isTeamSelected || workspace.type === 'personal'"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
v-if="teamListLoading"
|
|
||||||
class="flex flex-col items-center justify-center p-4"
|
|
||||||
>
|
|
||||||
<HoppSmartSpinner class="my-4" />
|
|
||||||
<span class="text-secondaryLight">{{ t("state.loading") }}</span>
|
|
||||||
</div>
|
|
||||||
<div v-else-if="isTeamSelected" class="flex flex-col">
|
|
||||||
<HoppSmartItem
|
<HoppSmartItem
|
||||||
v-for="(gen, index) in teamEnvironmentList"
|
v-for="(gen, index) in myEnvironments"
|
||||||
:key="`gen-team-${index}`"
|
:key="`gen-${index}`"
|
||||||
:icon="IconLayers"
|
:icon="IconLayers"
|
||||||
:label="gen.environment.name"
|
:label="gen.name"
|
||||||
:info-icon="isEnvActive(gen.id) ? IconCheck : undefined"
|
:info-icon="index === selectedEnv.index ? IconCheck : undefined"
|
||||||
:active-info-icon="isEnvActive(gen.id)"
|
:active-info-icon="index === selectedEnv.index"
|
||||||
@click="
|
@click="
|
||||||
() => {
|
() => {
|
||||||
handleEnvironmentChange(index, {
|
selectedEnvironmentIndex = {
|
||||||
type: 'team-environment',
|
type: 'MY_ENV',
|
||||||
environment: gen,
|
index: index,
|
||||||
})
|
}
|
||||||
hide()
|
hide()
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
|
<div
|
||||||
<HoppSmartPlaceholder
|
v-if="myEnvironments.length === 0"
|
||||||
v-if="teamEnvironmentList.length === 0"
|
class="flex flex-col items-center justify-center text-secondaryLight"
|
||||||
:src="`/images/states/${colorMode.value}/blockchain.svg`"
|
|
||||||
:alt="`${t('empty.environments')}`"
|
|
||||||
:text="t('empty.environments')"
|
|
||||||
>
|
>
|
||||||
</HoppSmartPlaceholder>
|
<img
|
||||||
|
:src="`/images/states/${colorMode.value}/blockchain.svg`"
|
||||||
|
loading="lazy"
|
||||||
|
class="inline-flex flex-col object-contain object-center w-16 h-16 mb-2"
|
||||||
|
:alt="`${t('empty.environments')}`"
|
||||||
|
/>
|
||||||
|
<span class="pb-2 text-center">
|
||||||
|
{{ t("empty.environments") }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</HoppSmartTab>
|
||||||
|
<HoppSmartTab
|
||||||
|
:id="'team-environments'"
|
||||||
|
:label="`${t('environment.team_environments')}`"
|
||||||
|
:disabled="!isTeamSelected || workspace.type === 'personal'"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-if="teamListLoading"
|
||||||
|
class="flex flex-col items-center justify-center p-4"
|
||||||
|
>
|
||||||
|
<HoppSmartSpinner class="my-4" />
|
||||||
|
<span class="text-secondaryLight">
|
||||||
|
{{ t("state.loading") }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div v-if="isTeamSelected" class="flex flex-col">
|
||||||
|
<HoppSmartItem
|
||||||
|
v-for="(gen, index) in teamEnvironmentList"
|
||||||
|
:key="`gen-team-${index}`"
|
||||||
|
:icon="IconLayers"
|
||||||
|
:label="gen.environment.name"
|
||||||
|
:info-icon="
|
||||||
|
gen.id === selectedEnv.teamEnvID ? IconCheck : undefined
|
||||||
|
"
|
||||||
|
:active-info-icon="gen.id === selectedEnv.teamEnvID"
|
||||||
|
@click="
|
||||||
|
() => {
|
||||||
|
selectedEnvironmentIndex = {
|
||||||
|
type: 'TEAM_ENV',
|
||||||
|
teamEnvID: gen.id,
|
||||||
|
teamID: gen.teamID,
|
||||||
|
environment: gen.environment,
|
||||||
|
}
|
||||||
|
hide()
|
||||||
|
}
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
v-if="teamEnvironmentList.length === 0"
|
||||||
|
class="flex flex-col items-center justify-center text-secondaryLight"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
:src="`/images/states/${colorMode.value}/blockchain.svg`"
|
||||||
|
loading="lazy"
|
||||||
|
class="inline-flex flex-col object-contain object-center w-16 h-16 mb-2"
|
||||||
|
:alt="`${t('empty.environments')}`"
|
||||||
|
/>
|
||||||
|
<span class="pb-2 text-center">
|
||||||
|
{{ t("empty.environments") }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="!teamListLoading && teamAdapterError"
|
||||||
|
class="flex flex-col items-center py-4"
|
||||||
|
>
|
||||||
|
<icon-lucide-help-circle class="mb-4 svg-icons" />
|
||||||
|
{{ getErrorMessage(teamAdapterError) }}
|
||||||
|
</div>
|
||||||
|
</HoppSmartTab>
|
||||||
|
</HoppSmartTabs>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</tippy>
|
||||||
|
<span class="flex">
|
||||||
|
<tippy
|
||||||
|
interactive
|
||||||
|
trigger="click"
|
||||||
|
theme="popover"
|
||||||
|
:on-shown="() => envQuickPeekActions!.focus()"
|
||||||
|
>
|
||||||
|
<HoppButtonSecondary
|
||||||
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
|
:title="`${t('environment.quick_peek')}`"
|
||||||
|
:icon="IconEye"
|
||||||
|
class="!px-4"
|
||||||
|
/>
|
||||||
|
<template #content="{ hide }">
|
||||||
|
<div
|
||||||
|
ref="envQuickPeekActions"
|
||||||
|
role="menu"
|
||||||
|
class="flex flex-col focus:outline-none"
|
||||||
|
tabindex="0"
|
||||||
|
@keyup.escape="hide()"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="sticky top-0 font-semibold truncate flex items-center justify-between text-secondaryDark bg-primary border border-divider rounded pl-4"
|
||||||
|
>
|
||||||
|
{{ t("environment.global_variables") }}
|
||||||
|
<HoppButtonSecondary
|
||||||
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
|
:title="t('action.edit')"
|
||||||
|
:icon="IconEdit"
|
||||||
|
@click="
|
||||||
|
() => {
|
||||||
|
editGlobalEnv()
|
||||||
|
hide()
|
||||||
|
}
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="my-2 flex flex-col flex-1 space-y-2 pl-4">
|
||||||
|
<div class="flex flex-1 space-x-4">
|
||||||
|
<span class="w-20 truncate text-tiny font-semibold">
|
||||||
|
{{ t("environment.name") }}
|
||||||
|
</span>
|
||||||
|
<span class="w-36 truncate text-tiny font-semibold">
|
||||||
|
{{ t("environment.value") }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-for="(variable, index) in globalEnvs"
|
||||||
|
:key="index"
|
||||||
|
class="flex flex-1 space-x-4"
|
||||||
|
>
|
||||||
|
<span class="text-secondaryLight w-20 truncate">
|
||||||
|
{{ variable.key }}
|
||||||
|
</span>
|
||||||
|
<span class="text-secondaryLight w-36 truncate">
|
||||||
|
{{ variable.value }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div v-if="globalEnvs.length === 0" class="text-secondaryLight">
|
||||||
|
{{ t("environment.empty_variables") }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="!teamListLoading && teamAdapterError"
|
class="sticky top-0 font-semibold truncate flex items-center justify-between text-secondaryDark bg-primary border border-divider rounded pl-4"
|
||||||
class="flex flex-col items-center py-4"
|
:class="{
|
||||||
|
'py-2 pr-4': !selectedEnv.variables,
|
||||||
|
}"
|
||||||
>
|
>
|
||||||
<icon-lucide-help-circle class="mb-4 svg-icons" />
|
{{ t("environment.list") }}
|
||||||
{{ getErrorMessage(teamAdapterError) }}
|
<HoppButtonSecondary
|
||||||
|
v-if="selectedEnv.variables"
|
||||||
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
|
:title="t('action.edit')"
|
||||||
|
:icon="IconEdit"
|
||||||
|
@click="
|
||||||
|
() => {
|
||||||
|
editEnv()
|
||||||
|
hide()
|
||||||
|
}
|
||||||
|
"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</HoppSmartTab>
|
<div
|
||||||
</HoppSmartTabs>
|
v-if="selectedEnv.type === 'NO_ENV_SELECTED'"
|
||||||
</div>
|
class="text-secondaryLight my-2 flex flex-col flex-1 pl-4"
|
||||||
</template>
|
>
|
||||||
</tippy>
|
{{ t("environment.no_active_environment") }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="my-2 flex flex-col flex-1 space-y-2 pl-4">
|
||||||
|
<div class="flex flex-1 space-x-4">
|
||||||
|
<span class="w-20 truncate text-tiny font-semibold">
|
||||||
|
{{ t("environment.name") }}
|
||||||
|
</span>
|
||||||
|
<span class="w-36 truncate text-tiny font-semibold">
|
||||||
|
{{ t("environment.value") }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-for="(variable, index) in environmentVariables"
|
||||||
|
:key="index"
|
||||||
|
class="flex flex-1 space-x-4"
|
||||||
|
>
|
||||||
|
<span class="text-secondaryLight w-20 truncate">
|
||||||
|
{{ variable.key }}
|
||||||
|
</span>
|
||||||
|
<span class="text-secondaryLight w-36 truncate">
|
||||||
|
{{ variable.value }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="environmentVariables.length === 0"
|
||||||
|
class="text-secondaryLight"
|
||||||
|
>
|
||||||
|
{{ t("environment.empty_variables") }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</tippy>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, onMounted, ref, watch } from "vue"
|
import { computed, ref, watch } from "vue"
|
||||||
import IconCheck from "~icons/lucide/check"
|
import IconCheck from "~icons/lucide/check"
|
||||||
import IconLayers from "~icons/lucide/layers"
|
import IconLayers from "~icons/lucide/layers"
|
||||||
import IconGlobe from "~icons/lucide/globe"
|
import IconEye from "~icons/lucide/eye"
|
||||||
|
import IconEdit from "~icons/lucide/edit"
|
||||||
import { TippyComponent } from "vue-tippy"
|
import { TippyComponent } from "vue-tippy"
|
||||||
import { useI18n } from "~/composables/i18n"
|
import { useI18n } from "~/composables/i18n"
|
||||||
import { GQLError } from "~/helpers/backend/GQLClient"
|
import { GQLError } from "~/helpers/backend/GQLClient"
|
||||||
import { useReadonlyStream, useStream } from "~/composables/stream"
|
import { useReadonlyStream, useStream } from "~/composables/stream"
|
||||||
import {
|
import {
|
||||||
environments$,
|
environments$,
|
||||||
|
globalEnv$,
|
||||||
selectedEnvironmentIndex$,
|
selectedEnvironmentIndex$,
|
||||||
setSelectedEnvironmentIndex,
|
setSelectedEnvironmentIndex,
|
||||||
} from "~/newstore/environments"
|
} from "~/newstore/environments"
|
||||||
import { changeWorkspace, workspaceStatus$ } from "~/newstore/workspace"
|
import { workspaceStatus$ } from "~/newstore/workspace"
|
||||||
import TeamEnvironmentAdapter from "~/helpers/teams/TeamEnvironmentAdapter"
|
import TeamEnvironmentAdapter from "~/helpers/teams/TeamEnvironmentAdapter"
|
||||||
import { useColorMode } from "@composables/theming"
|
import { useColorMode } from "@composables/theming"
|
||||||
import { breakpointsTailwind, useBreakpoints } from "@vueuse/core"
|
import { breakpointsTailwind, useBreakpoints } from "@vueuse/core"
|
||||||
import TeamListAdapter from "~/helpers/teams/TeamListAdapter"
|
import { invokeAction } from "~/helpers/actions"
|
||||||
import { useLocalState } from "~/newstore/localstate"
|
|
||||||
import { onLoggedIn } from "~/composables/auth"
|
|
||||||
import { GetMyTeamsQuery } from "~/helpers/backend/graphql"
|
|
||||||
import { TeamEnvironment } from "~/helpers/teams/TeamEnvironment"
|
|
||||||
import { Environment } from "@hoppscotch/data"
|
|
||||||
|
|
||||||
type Scope =
|
|
||||||
| {
|
|
||||||
type: "global"
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
type: "my-environment"
|
|
||||||
environment: Environment
|
|
||||||
index: number
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
type: "team-environment"
|
|
||||||
environment: TeamEnvironment
|
|
||||||
}
|
|
||||||
|
|
||||||
const props = defineProps<{
|
|
||||||
isScopeSelector?: boolean
|
|
||||||
modelValue?: Scope
|
|
||||||
}>()
|
|
||||||
|
|
||||||
const emit = defineEmits<{
|
|
||||||
(e: "update:modelValue", data: Scope): void
|
|
||||||
}>()
|
|
||||||
|
|
||||||
const breakpoints = useBreakpoints(breakpointsTailwind)
|
const breakpoints = useBreakpoints(breakpointsTailwind)
|
||||||
const mdAndLarger = breakpoints.greater("md")
|
const mdAndLarger = breakpoints.greater("md")
|
||||||
@@ -212,39 +310,6 @@ const myEnvironments = useReadonlyStream(environments$, [])
|
|||||||
|
|
||||||
const workspace = useReadonlyStream(workspaceStatus$, { type: "personal" })
|
const workspace = useReadonlyStream(workspaceStatus$, { type: "personal" })
|
||||||
|
|
||||||
// TeamList-Adapter
|
|
||||||
const teamListAdapter = new TeamListAdapter(true)
|
|
||||||
const myTeams = useReadonlyStream(teamListAdapter.teamList$, null)
|
|
||||||
const teamListFetched = ref(false)
|
|
||||||
const REMEMBERED_TEAM_ID = useLocalState("REMEMBERED_TEAM_ID")
|
|
||||||
|
|
||||||
onLoggedIn(() => {
|
|
||||||
!teamListAdapter.isInitialized && teamListAdapter.initialize()
|
|
||||||
})
|
|
||||||
|
|
||||||
const switchToTeamWorkspace = (team: GetMyTeamsQuery["myTeams"][number]) => {
|
|
||||||
REMEMBERED_TEAM_ID.value = team.id
|
|
||||||
changeWorkspace({
|
|
||||||
teamID: team.id,
|
|
||||||
teamName: team.name,
|
|
||||||
type: "team",
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => myTeams.value,
|
|
||||||
(newTeams) => {
|
|
||||||
if (newTeams && !teamListFetched.value) {
|
|
||||||
teamListFetched.value = true
|
|
||||||
if (REMEMBERED_TEAM_ID.value) {
|
|
||||||
const team = newTeams.find((t) => t.id === REMEMBERED_TEAM_ID.value)
|
|
||||||
if (team) switchToTeamWorkspace(team)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// TeamEnv List Adapter
|
|
||||||
const teamEnvListAdapter = new TeamEnvironmentAdapter(undefined)
|
const teamEnvListAdapter = new TeamEnvironmentAdapter(undefined)
|
||||||
const teamListLoading = useReadonlyStream(teamEnvListAdapter.loading$, false)
|
const teamListLoading = useReadonlyStream(teamEnvListAdapter.loading$, false)
|
||||||
const teamAdapterError = useReadonlyStream(teamEnvListAdapter.error$, null)
|
const teamAdapterError = useReadonlyStream(teamEnvListAdapter.error$, null)
|
||||||
@@ -279,157 +344,41 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
const handleEnvironmentChange = (
|
|
||||||
index: number,
|
|
||||||
env?:
|
|
||||||
| {
|
|
||||||
type: "my-environment"
|
|
||||||
environment: Environment
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
type: "team-environment"
|
|
||||||
environment: TeamEnvironment
|
|
||||||
}
|
|
||||||
) => {
|
|
||||||
if (props.isScopeSelector && env) {
|
|
||||||
if (env.type === "my-environment") {
|
|
||||||
emit("update:modelValue", {
|
|
||||||
type: "my-environment",
|
|
||||||
environment: env.environment,
|
|
||||||
index,
|
|
||||||
})
|
|
||||||
} else if (env.type === "team-environment") {
|
|
||||||
emit("update:modelValue", {
|
|
||||||
type: "team-environment",
|
|
||||||
environment: env.environment,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (env && env.type === "my-environment") {
|
|
||||||
selectedEnvironmentIndex.value = {
|
|
||||||
type: "MY_ENV",
|
|
||||||
index,
|
|
||||||
}
|
|
||||||
} else if (env && env.type === "team-environment") {
|
|
||||||
selectedEnvironmentIndex.value = {
|
|
||||||
type: "TEAM_ENV",
|
|
||||||
teamEnvID: env.environment.id,
|
|
||||||
teamID: env.environment.teamID,
|
|
||||||
environment: env.environment.environment,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const isEnvActive = (id: string | number) => {
|
|
||||||
if (props.isScopeSelector) {
|
|
||||||
if (props.modelValue?.type === "my-environment") {
|
|
||||||
return props.modelValue.index === id
|
|
||||||
} else if (props.modelValue?.type === "team-environment") {
|
|
||||||
return (
|
|
||||||
props.modelValue?.type === "team-environment" &&
|
|
||||||
props.modelValue.environment &&
|
|
||||||
props.modelValue.environment.id === id
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (selectedEnvironmentIndex.value.type === "MY_ENV") {
|
|
||||||
return selectedEnv.value.index === id
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
selectedEnvironmentIndex.value.type === "TEAM_ENV" &&
|
|
||||||
selectedEnv.value.teamEnvID === id
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const selectedEnv = computed(() => {
|
const selectedEnv = computed(() => {
|
||||||
if (props.isScopeSelector) {
|
if (selectedEnvironmentIndex.value.type === "MY_ENV") {
|
||||||
if (props.modelValue?.type === "my-environment") {
|
const environment =
|
||||||
return {
|
myEnvironments.value[selectedEnvironmentIndex.value.index]
|
||||||
type: "MY_ENV",
|
return {
|
||||||
index: props.modelValue.index,
|
type: "MY_ENV",
|
||||||
name: props.modelValue.environment?.name,
|
index: selectedEnvironmentIndex.value.index,
|
||||||
}
|
name: environment.name,
|
||||||
} else if (props.modelValue?.type === "team-environment") {
|
variables: environment.variables,
|
||||||
|
}
|
||||||
|
} else if (selectedEnvironmentIndex.value.type === "TEAM_ENV") {
|
||||||
|
const teamEnv = teamEnvironmentList.value.find(
|
||||||
|
(env) =>
|
||||||
|
env.id ===
|
||||||
|
(selectedEnvironmentIndex.value.type === "TEAM_ENV" &&
|
||||||
|
selectedEnvironmentIndex.value.teamEnvID)
|
||||||
|
)
|
||||||
|
if (teamEnv) {
|
||||||
return {
|
return {
|
||||||
type: "TEAM_ENV",
|
type: "TEAM_ENV",
|
||||||
name: props.modelValue.environment.environment.name,
|
name: teamEnv.environment.name,
|
||||||
teamEnvID: props.modelValue.environment.id,
|
teamEnvID: selectedEnvironmentIndex.value.teamEnvID,
|
||||||
}
|
variables: teamEnv.environment.variables,
|
||||||
} else {
|
|
||||||
return { type: "global", name: "Global" }
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (selectedEnvironmentIndex.value.type === "MY_ENV") {
|
|
||||||
return {
|
|
||||||
type: "MY_ENV",
|
|
||||||
index: selectedEnvironmentIndex.value.index,
|
|
||||||
name: myEnvironments.value[selectedEnvironmentIndex.value.index].name,
|
|
||||||
}
|
|
||||||
} else if (selectedEnvironmentIndex.value.type === "TEAM_ENV") {
|
|
||||||
const teamEnv = teamEnvironmentList.value.find(
|
|
||||||
(env) =>
|
|
||||||
env.id ===
|
|
||||||
(selectedEnvironmentIndex.value.type === "TEAM_ENV" &&
|
|
||||||
selectedEnvironmentIndex.value.teamEnvID)
|
|
||||||
)
|
|
||||||
if (teamEnv) {
|
|
||||||
return {
|
|
||||||
type: "TEAM_ENV",
|
|
||||||
name: teamEnv.environment.name,
|
|
||||||
teamEnvID: selectedEnvironmentIndex.value.teamEnvID,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return { type: "NO_ENV_SELECTED" }
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return { type: "NO_ENV_SELECTED" }
|
return { type: "NO_ENV_SELECTED" }
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
})
|
return { type: "NO_ENV_SELECTED" }
|
||||||
|
|
||||||
// Set the selected environment as initial scope value
|
|
||||||
onMounted(() => {
|
|
||||||
if (props.isScopeSelector) {
|
|
||||||
if (
|
|
||||||
selectedEnvironmentIndex.value.type === "MY_ENV" &&
|
|
||||||
selectedEnvironmentIndex.value.index !== undefined
|
|
||||||
) {
|
|
||||||
emit("update:modelValue", {
|
|
||||||
type: "my-environment",
|
|
||||||
environment: myEnvironments.value[selectedEnvironmentIndex.value.index],
|
|
||||||
index: selectedEnvironmentIndex.value.index,
|
|
||||||
})
|
|
||||||
} else if (
|
|
||||||
selectedEnvironmentIndex.value.type === "TEAM_ENV" &&
|
|
||||||
selectedEnvironmentIndex.value.teamEnvID &&
|
|
||||||
teamEnvironmentList.value &&
|
|
||||||
teamEnvironmentList.value.length > 0
|
|
||||||
) {
|
|
||||||
const teamEnv = teamEnvironmentList.value.find(
|
|
||||||
(env) =>
|
|
||||||
env.id ===
|
|
||||||
(selectedEnvironmentIndex.value.type === "TEAM_ENV" &&
|
|
||||||
selectedEnvironmentIndex.value.teamEnvID)
|
|
||||||
)
|
|
||||||
if (teamEnv) {
|
|
||||||
emit("update:modelValue", {
|
|
||||||
type: "team-environment",
|
|
||||||
environment: teamEnv,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
emit("update:modelValue", {
|
|
||||||
type: "global",
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// Template refs
|
// Template refs
|
||||||
const tippyActions = ref<TippyComponent | null>(null)
|
const envSelectorActions = ref<TippyComponent | null>(null)
|
||||||
|
const envQuickPeekActions = ref<TippyComponent | null>(null)
|
||||||
|
|
||||||
const getErrorMessage = (err: GQLError<string>) => {
|
const getErrorMessage = (err: GQLError<string>) => {
|
||||||
if (err.type === "network_error") {
|
if (err.type === "network_error") {
|
||||||
@@ -443,4 +392,32 @@ const getErrorMessage = (err: GQLError<string>) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const globalEnvs = useReadonlyStream(globalEnv$, [])
|
||||||
|
|
||||||
|
const environmentVariables = computed(() => {
|
||||||
|
if (selectedEnv.value.variables) {
|
||||||
|
return selectedEnv.value.variables
|
||||||
|
} else {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const editGlobalEnv = () => {
|
||||||
|
invokeAction("modals.my.environment.edit", {
|
||||||
|
envName: "Global",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const editEnv = () => {
|
||||||
|
if (selectedEnv.value.type === "MY_ENV" && selectedEnv.value.name) {
|
||||||
|
invokeAction("modals.my.environment.edit", {
|
||||||
|
envName: selectedEnv.value.name,
|
||||||
|
})
|
||||||
|
} else if (selectedEnv.value.type === "TEAM_ENV" && selectedEnv.value.name) {
|
||||||
|
invokeAction("modals.team.environment.edit", {
|
||||||
|
envName: selectedEnv.value.name,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -11,9 +11,9 @@
|
|||||||
@edit-environment="editEnvironment('Global')"
|
@edit-environment="editEnvironment('Global')"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<EnvironmentsMy v-if="environmentType.type === 'my-environments'" />
|
<EnvironmentsMy v-show="environmentType.type === 'my-environments'" />
|
||||||
<EnvironmentsTeams
|
<EnvironmentsTeams
|
||||||
v-if="environmentType.type === 'team-environments'"
|
v-show="environmentType.type === 'team-environments'"
|
||||||
:team="environmentType.selectedTeam"
|
:team="environmentType.selectedTeam"
|
||||||
:team-environments="teamEnvironmentList"
|
:team-environments="teamEnvironmentList"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
@@ -201,7 +201,7 @@ const resetSelectedData = () => {
|
|||||||
defineActionHandler(
|
defineActionHandler(
|
||||||
"modals.my.environment.edit",
|
"modals.my.environment.edit",
|
||||||
({ envName, variableName }) => {
|
({ envName, variableName }) => {
|
||||||
editingVariableName.value = variableName
|
if (variableName) editingVariableName.value = variableName
|
||||||
envName === "Global" && editEnvironment("Global")
|
envName === "Global" && editEnvironment("Global")
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ const resetSelectedData = () => {
|
|||||||
defineActionHandler(
|
defineActionHandler(
|
||||||
"modals.my.environment.edit",
|
"modals.my.environment.edit",
|
||||||
({ envName, variableName }) => {
|
({ envName, variableName }) => {
|
||||||
editingVariableName.value = variableName
|
if (variableName) editingVariableName.value = variableName
|
||||||
const envIndex: number = environments.value.findIndex(
|
const envIndex: number = environments.value.findIndex(
|
||||||
(environment: Environment) => {
|
(environment: Environment) => {
|
||||||
return environment.name === envName
|
return environment.name === envName
|
||||||
|
|||||||
@@ -178,7 +178,7 @@ const getErrorMessage = (err: GQLError<string>) => {
|
|||||||
defineActionHandler(
|
defineActionHandler(
|
||||||
"modals.team.environment.edit",
|
"modals.team.environment.edit",
|
||||||
({ envName, variableName }) => {
|
({ envName, variableName }) => {
|
||||||
editingVariableName.value = variableName
|
if (variableName) editingVariableName.value = variableName
|
||||||
const teamEnvToEdit = props.teamEnvironments.find(
|
const teamEnvToEdit = props.teamEnvironments.find(
|
||||||
(environment) => environment.environment.name === envName
|
(environment) => environment.environment.name === envName
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -67,11 +67,11 @@ type HoppActionArgsMap = {
|
|||||||
}
|
}
|
||||||
"modals.my.environment.edit": {
|
"modals.my.environment.edit": {
|
||||||
envName: string
|
envName: string
|
||||||
variableName: string
|
variableName?: string
|
||||||
}
|
}
|
||||||
"modals.team.environment.edit": {
|
"modals.team.environment.edit": {
|
||||||
envName: string
|
envName: string
|
||||||
variableName: string
|
variableName?: string
|
||||||
}
|
}
|
||||||
"rest.request.open": {
|
"rest.request.open": {
|
||||||
doc: HoppRESTDocument
|
doc: HoppRESTDocument
|
||||||
|
|||||||
@@ -100,7 +100,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="hasActions" :class="mdAndLarger ? 'w-64' : 'w-16'">
|
<div v-if="hasActions" :class="mdAndLarger ? 'w-64' : 'w-28'">
|
||||||
<slot name="actions" />
|
<slot name="actions" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -116,7 +116,7 @@
|
|||||||
:style="[
|
:style="[
|
||||||
`--thumb-width: ${scrollThumb.width}px`,
|
`--thumb-width: ${scrollThumb.width}px`,
|
||||||
`width: calc(100% - ${
|
`width: calc(100% - ${
|
||||||
hasActions ? (mdAndLarger ? '19rem' : '7rem') : '3rem'
|
hasActions ? (mdAndLarger ? '19rem' : '10rem') : '3rem'
|
||||||
})`,
|
})`,
|
||||||
]"
|
]"
|
||||||
id="myRange"
|
id="myRange"
|
||||||
|
|||||||
Reference in New Issue
Block a user