Compare commits
11 Commits
HPS-OSS-1
...
feat/env-s
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
37153b6401 | ||
|
|
f3f9891017 | ||
|
|
8450fb6596 | ||
|
|
41fa3b5a8c | ||
|
|
522de45a62 | ||
|
|
4acc4b2dda | ||
|
|
c1f4855daf | ||
|
|
3506e96cfd | ||
|
|
b42a94ed77 | ||
|
|
80da790a3c | ||
|
|
d6c706d0f9 |
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "hoppscotch-backend",
|
||||
"version": "2023.4.0",
|
||||
"version": "2023.4.1",
|
||||
"description": "",
|
||||
"author": "",
|
||||
"private": true,
|
||||
|
||||
@@ -459,6 +459,14 @@ pre.ace_editor {
|
||||
@apply bg-dividerLight;
|
||||
}
|
||||
|
||||
.splitpanes--horizontal .splitpanes__pane {
|
||||
@apply transition-none;
|
||||
}
|
||||
|
||||
.splitpanes--vertical .splitpanes__pane {
|
||||
@apply transition-none;
|
||||
}
|
||||
|
||||
.cm-focused {
|
||||
@apply select-auto;
|
||||
@apply outline-none #{!important};
|
||||
|
||||
@@ -269,7 +269,6 @@
|
||||
--lower-secondary-sticky-fold: 5.063rem;
|
||||
--lower-tertiary-sticky-fold: 7.125rem;
|
||||
--sidebar-primary-sticky-fold: 2rem;
|
||||
--request-body-sticky-fold: 10rem;
|
||||
}
|
||||
|
||||
@mixin font-medium {
|
||||
@@ -286,7 +285,6 @@
|
||||
--lower-secondary-sticky-fold: 5.563rem;
|
||||
--lower-tertiary-sticky-fold: 7.875rem;
|
||||
--sidebar-primary-sticky-fold: 2.25rem;
|
||||
--request-body-sticky-fold: 11rem;
|
||||
}
|
||||
|
||||
@mixin font-large {
|
||||
@@ -303,7 +301,6 @@
|
||||
--lower-secondary-sticky-fold: 6.063rem;
|
||||
--lower-tertiary-sticky-fold: 8.625rem;
|
||||
--sidebar-primary-sticky-fold: 2.5rem;
|
||||
--request-body-sticky-fold: 12rem;
|
||||
}
|
||||
|
||||
:root[data-font-size="small"] {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@hoppscotch/common",
|
||||
"private": true,
|
||||
"version": "2023.4.0",
|
||||
"version": "2023.4.1",
|
||||
"scripts": {
|
||||
"dev": "pnpm exec npm-run-all -p -l dev:*",
|
||||
"dev:vite": "vite",
|
||||
@@ -62,7 +62,7 @@
|
||||
"js-yaml": "^4.1.0",
|
||||
"jsonpath-plus": "^7.0.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"lossless-json": "^1.0.5",
|
||||
"lossless-json": "^2.0.8",
|
||||
"nprogress": "^0.2.0",
|
||||
"paho-mqtt": "^1.1.0",
|
||||
"path": "^0.12.7",
|
||||
@@ -106,7 +106,7 @@
|
||||
"@graphql-codegen/urql-introspection": "^2.2.0",
|
||||
"@graphql-typed-document-node/core": "^3.1.1",
|
||||
"@iconify-json/lucide": "^1.1.40",
|
||||
"@intlify/vite-plugin-vue-i18n": "^6.0.1",
|
||||
"@intlify/vite-plugin-vue-i18n": "^7.0.0",
|
||||
"@rushstack/eslint-patch": "^1.1.4",
|
||||
"@types/js-yaml": "^4.0.5",
|
||||
"@types/lodash-es": "^4.17.6",
|
||||
|
||||
34
packages/hoppscotch-common/src/components.d.ts
vendored
34
packages/hoppscotch-common/src/components.d.ts
vendored
@@ -57,6 +57,7 @@ declare module '@vue/runtime-core' {
|
||||
EnvironmentsMy: typeof import('./components/environments/my/index.vue')['default']
|
||||
EnvironmentsMyDetails: typeof import('./components/environments/my/Details.vue')['default']
|
||||
EnvironmentsMyEnvironment: typeof import('./components/environments/my/Environment.vue')['default']
|
||||
EnvironmentsSelector: typeof import('./components/environments/Selector.vue')['default']
|
||||
EnvironmentsTeams: typeof import('./components/environments/teams/index.vue')['default']
|
||||
EnvironmentsTeamsDetails: typeof import('./components/environments/teams/Details.vue')['default']
|
||||
EnvironmentsTeamsEnvironment: typeof import('./components/environments/teams/Environment.vue')['default']
|
||||
@@ -73,6 +74,25 @@ declare module '@vue/runtime-core' {
|
||||
History: typeof import('./components/history/index.vue')['default']
|
||||
HistoryGraphqlCard: typeof import('./components/history/graphql/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']
|
||||
HoppSmartItem: typeof import('@hoppscotch/ui')['HoppSmartItem']
|
||||
HoppSmartLink: typeof import('@hoppscotch/ui')['HoppSmartLink']
|
||||
HoppSmartModal: typeof import('@hoppscotch/ui')['HoppSmartModal']
|
||||
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']
|
||||
HoppSmartWindow: typeof import('@hoppscotch/ui')['HoppSmartWindow']
|
||||
HoppSmartWindows: typeof import('@hoppscotch/ui')['HoppSmartWindows']
|
||||
HttpAuthorization: typeof import('./components/http/Authorization.vue')['default']
|
||||
HttpAuthorizationApiKey: typeof import('./components/http/authorization/ApiKey.vue')['default']
|
||||
HttpAuthorizationBasic: typeof import('./components/http/authorization/Basic.vue')['default']
|
||||
@@ -98,6 +118,20 @@ declare module '@vue/runtime-core' {
|
||||
HttpTestResultReport: typeof import('./components/http/TestResultReport.vue')['default']
|
||||
HttpTests: typeof import('./components/http/Tests.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']
|
||||
IconLucideUser: typeof import('~icons/lucide/user')['default']
|
||||
IconLucideUsers: typeof import('~icons/lucide/users')['default']
|
||||
LensesHeadersRenderer: typeof import('./components/lenses/HeadersRenderer.vue')['default']
|
||||
LensesHeadersRendererEntry: typeof import('./components/lenses/HeadersRendererEntry.vue')['default']
|
||||
LensesRenderersHTMLLensRenderer: typeof import('./components/lenses/renderers/HTMLLensRenderer.vue')['default']
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref, watch } from "vue"
|
||||
import { nextTick, reactive, ref, watch } from "vue"
|
||||
import { cloneDeep } from "lodash-es"
|
||||
import {
|
||||
HoppGQLRequest,
|
||||
@@ -126,12 +126,22 @@ const emit = defineEmits<{
|
||||
}>()
|
||||
|
||||
const gqlRequestName = useGQLRequestName()
|
||||
const requestName = computedWithControl(
|
||||
() => [currentActiveTab.value, gqlRequestName.value],
|
||||
() =>
|
||||
props.mode === "rest"
|
||||
? currentActiveTab.value.document.request.name
|
||||
: gqlRequestName.value
|
||||
const restRequestName = computedWithControl(
|
||||
() => currentActiveTab.value,
|
||||
() => currentActiveTab.value.document.request.name
|
||||
)
|
||||
|
||||
const requestName = ref(
|
||||
props.mode === "rest" ? restRequestName.value : gqlRequestName.value
|
||||
)
|
||||
|
||||
watch(
|
||||
() => [currentActiveTab.value.document.request.name, gqlRequestName.value],
|
||||
() => {
|
||||
if (props.mode === "rest")
|
||||
requestName.value = currentActiveTab.value.document.request.name
|
||||
else requestName.value = gqlRequestName.value
|
||||
}
|
||||
)
|
||||
|
||||
const requestData = reactive({
|
||||
@@ -192,6 +202,8 @@ const saveRequestAs = async () => {
|
||||
? cloneDeep(currentActiveTab.value.document.request)
|
||||
: cloneDeep(getGQLSession().request)
|
||||
|
||||
requestUpdated.name = requestName.value
|
||||
|
||||
if (picked.value.pickedType === "my-collection") {
|
||||
if (!isHoppRESTRequest(requestUpdated))
|
||||
throw new Error("requestUpdated is not a REST Request")
|
||||
@@ -373,6 +385,9 @@ const updateTeamCollectionOrFolder = (
|
||||
|
||||
const requestSaved = () => {
|
||||
toast.success(`${t("request.added")}`)
|
||||
nextTick(() => {
|
||||
currentActiveTab.value.document.isDirty = false
|
||||
})
|
||||
hideModal()
|
||||
}
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
'!flex': draggingToRoot && currentReorderingStatus.type !== 'request',
|
||||
}"
|
||||
>
|
||||
<component :is="IconListEnd" class="svg-icons !w-8 !h-8" />
|
||||
<icon-lucide-list-end class="svg-icons !w-8 !h-8" />
|
||||
</div>
|
||||
<CollectionsAdd
|
||||
:show="showModalAdd"
|
||||
@@ -221,7 +221,6 @@ import * as E from "fp-ts/Either"
|
||||
import { platform } from "~/platform"
|
||||
import { createCollectionGists } from "~/helpers/gist"
|
||||
import { workspaceStatus$ } from "~/newstore/workspace"
|
||||
import IconListEnd from "~icons/lucide/list-end"
|
||||
import {
|
||||
createNewTab,
|
||||
currentActiveTab,
|
||||
|
||||
@@ -0,0 +1,203 @@
|
||||
<template>
|
||||
<tippy
|
||||
interactive
|
||||
trigger="click"
|
||||
theme="popover"
|
||||
:on-shown="() => tippyActions!.focus()"
|
||||
>
|
||||
<span
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="`${t('environment.select')}`"
|
||||
class="bg-transparent border-b border-dividerLight select-wrapper"
|
||||
>
|
||||
<HoppButtonSecondary
|
||||
v-if="selectedEnv.type !== 'NO_ENV_SELECTED'"
|
||||
:label="selectedEnv.name"
|
||||
class="flex-1 !justify-start pr-8 rounded-none"
|
||||
/>
|
||||
<HoppButtonSecondary
|
||||
v-else
|
||||
:label="`${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
|
||||
:label="`${t('environment.no_environment')}`"
|
||||
:info-icon="
|
||||
selectedEnvironmentIndex.type === 'NO_ENV_SELECTED'
|
||||
? IconCheck
|
||||
: undefined
|
||||
"
|
||||
class="my-2"
|
||||
:active-info-icon="
|
||||
selectedEnvironmentIndex.type === 'NO_ENV_SELECTED'
|
||||
"
|
||||
@click="
|
||||
() => {
|
||||
setSelectedEnvironmentIndex({ type: 'NO_ENV_SELECTED' })
|
||||
hide()
|
||||
}
|
||||
"
|
||||
/>
|
||||
<HoppSmartTabs
|
||||
v-model="selectedEnvTab"
|
||||
styles="sticky overflow-x-auto flex-shrink-0 bg-primary z-10 top-0"
|
||||
render-inactive-tabs
|
||||
>
|
||||
<HoppSmartTab
|
||||
:id="'my-environments'"
|
||||
:label="`${t('environment.my_environments')}`"
|
||||
>
|
||||
<hr v-if="myEnvironments.length > 0" />
|
||||
<HoppSmartItem
|
||||
v-for="(gen, index) in myEnvironments"
|
||||
:key="`gen-${index}`"
|
||||
:label="gen.name"
|
||||
:info-icon="index === selectedEnv.index ? IconCheck : undefined"
|
||||
:active-info-icon="index === selectedEnv.index"
|
||||
@click="
|
||||
() => {
|
||||
setSelectedEnvironmentIndex({
|
||||
type: 'MY_ENV',
|
||||
index,
|
||||
})
|
||||
|
||||
hide()
|
||||
}
|
||||
"
|
||||
/>
|
||||
</HoppSmartTab>
|
||||
<HoppSmartTab
|
||||
:id="'team-environments'"
|
||||
:label="`${t('environment.team_environments')}`"
|
||||
:disabled="
|
||||
!isTeamSelected ||
|
||||
teamEnvLoading ||
|
||||
teamEnvironmentList.length === 0 ||
|
||||
environmentType === 'my-environments'
|
||||
"
|
||||
>
|
||||
<div
|
||||
v-if="teamEnvLoading"
|
||||
class="flex flex-col items-center justify-center p-4"
|
||||
>
|
||||
<HoppSmartSpinner class="my-4" />
|
||||
<span class="text-secondaryLight">{{ t("state.loading") }}</span>
|
||||
</div>
|
||||
<hr v-if="teamEnvironmentList.length > 0" />
|
||||
<div v-if="isTeamSelected" class="flex flex-col">
|
||||
<HoppSmartItem
|
||||
v-for="(gen, index) in teamEnvironmentList"
|
||||
:key="`gen-team-${index}`"
|
||||
:label="gen.environment.name"
|
||||
:info-icon="
|
||||
gen.id === selectedEnv.teamEnvID ? IconCheck : undefined
|
||||
"
|
||||
:active-info-icon="gen.id === selectedEnv.teamEnvID"
|
||||
@click="
|
||||
() => {
|
||||
setSelectedEnvironmentIndex({
|
||||
type: 'TEAM_ENV',
|
||||
teamEnvID: gen.id,
|
||||
teamID: gen.teamID,
|
||||
environment: gen.environment,
|
||||
})
|
||||
hide()
|
||||
}
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</HoppSmartTab>
|
||||
</HoppSmartTabs>
|
||||
</div>
|
||||
</template>
|
||||
</tippy>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref, watch } from "vue"
|
||||
import IconCheck from "~icons/lucide/check"
|
||||
import { TippyComponent } from "vue-tippy"
|
||||
import { useI18n } from "~/composables/i18n"
|
||||
import { GQLError } from "~/helpers/backend/GQLClient"
|
||||
import { Environment } from "@hoppscotch/data"
|
||||
import { TeamEnvironment } from "~/helpers/teams/TeamEnvironment"
|
||||
import { useStream } from "~/composables/stream"
|
||||
import {
|
||||
selectedEnvironmentIndex$,
|
||||
setSelectedEnvironmentIndex,
|
||||
} from "~/newstore/environments"
|
||||
|
||||
const t = useI18n()
|
||||
|
||||
type EnvironmentType = "my-environments" | "team-environments"
|
||||
|
||||
const props = defineProps<{
|
||||
environmentType: EnvironmentType
|
||||
myEnvironments: Environment[]
|
||||
teamEnvironmentList: TeamEnvironment[]
|
||||
teamEnvLoading: boolean
|
||||
isAdapterError: boolean
|
||||
errorMessage: GQLError<string>
|
||||
isTeamSelected: boolean
|
||||
}>()
|
||||
|
||||
const selectedEnvTab = ref<EnvironmentType>("my-environments")
|
||||
|
||||
const selectedEnvironmentIndex = useStream(
|
||||
selectedEnvironmentIndex$,
|
||||
{ type: "NO_ENV_SELECTED" },
|
||||
setSelectedEnvironmentIndex
|
||||
)
|
||||
|
||||
watch(
|
||||
() => props.environmentType,
|
||||
(newVal) => {
|
||||
if (newVal === "my-environments") {
|
||||
selectedEnvTab.value = "my-environments"
|
||||
} else {
|
||||
selectedEnvTab.value = "team-environments"
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
const selectedEnv = computed(() => {
|
||||
console.log("selectedEnvironmentIndex", selectedEnvironmentIndex.value)
|
||||
if (selectedEnvironmentIndex.value.type === "MY_ENV") {
|
||||
return {
|
||||
type: "MY_ENV",
|
||||
index: selectedEnvironmentIndex.value.index,
|
||||
name: props.myEnvironments[selectedEnvironmentIndex.value.index].name,
|
||||
}
|
||||
} else if (selectedEnvironmentIndex.value.type === "TEAM_ENV") {
|
||||
const teamEnv = props.teamEnvironmentList.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 {
|
||||
return { type: "NO_ENV_SELECTED" }
|
||||
}
|
||||
})
|
||||
|
||||
// Template refs
|
||||
const tippyActions = ref<TippyComponent | null>(null)
|
||||
</script>
|
||||
@@ -4,153 +4,15 @@
|
||||
class="sticky top-0 z-10 flex flex-col flex-shrink-0 overflow-x-auto bg-primary"
|
||||
>
|
||||
<WorkspaceCurrent :section="t('tab.environments')" />
|
||||
<tippy
|
||||
v-if="environmentType.type === 'my-environments'"
|
||||
interactive
|
||||
trigger="click"
|
||||
theme="popover"
|
||||
:on-shown="() => tippyActions!.focus()"
|
||||
>
|
||||
<span
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="`${t('environment.select')}`"
|
||||
class="bg-transparent border-b border-dividerLight select-wrapper"
|
||||
>
|
||||
<HoppButtonSecondary
|
||||
v-if="
|
||||
selectedEnv.type === 'MY_ENV' && selectedEnv.index !== undefined
|
||||
"
|
||||
:label="myEnvironments[selectedEnv.index].name"
|
||||
class="flex-1 !justify-start pr-8 rounded-none"
|
||||
/>
|
||||
<HoppButtonSecondary
|
||||
v-else
|
||||
:label="`${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
|
||||
:label="`${t('environment.no_environment')}`"
|
||||
:info-icon="
|
||||
selectedEnvironmentIndex.type !== 'MY_ENV'
|
||||
? IconCheck
|
||||
: undefined
|
||||
"
|
||||
:active-info-icon="selectedEnvironmentIndex.type !== 'MY_ENV'"
|
||||
@click="
|
||||
() => {
|
||||
selectedEnvironmentIndex = { type: 'NO_ENV_SELECTED' }
|
||||
hide()
|
||||
}
|
||||
"
|
||||
/>
|
||||
<hr v-if="myEnvironments.length > 0" />
|
||||
<HoppSmartItem
|
||||
v-for="(gen, index) in myEnvironments"
|
||||
:key="`gen-${index}`"
|
||||
:label="gen.name"
|
||||
:info-icon="index === selectedEnv.index ? IconCheck : undefined"
|
||||
:active-info-icon="index === selectedEnv.index"
|
||||
@click="
|
||||
() => {
|
||||
selectedEnvironmentIndex = { type: 'MY_ENV', index: index }
|
||||
hide()
|
||||
}
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</tippy>
|
||||
<tippy v-else interactive trigger="click" theme="popover">
|
||||
<span
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="`${t('environment.select')}`"
|
||||
class="bg-transparent border-b border-dividerLight select-wrapper"
|
||||
>
|
||||
<HoppButtonSecondary
|
||||
v-if="selectedEnv.name"
|
||||
:label="selectedEnv.name"
|
||||
class="flex-1 !justify-start pr-8 rounded-none"
|
||||
/>
|
||||
<HoppButtonSecondary
|
||||
v-else
|
||||
:label="`${t('environment.select')}`"
|
||||
class="flex-1 !justify-start pr-8 rounded-none"
|
||||
/>
|
||||
</span>
|
||||
<template #content="{ hide }">
|
||||
<div
|
||||
class="flex flex-col"
|
||||
role="menu"
|
||||
tabindex="0"
|
||||
@keyup.escape="hide()"
|
||||
>
|
||||
<HoppSmartItem
|
||||
:label="`${t('environment.no_environment')}`"
|
||||
:info-icon="
|
||||
selectedEnvironmentIndex.type !== 'TEAM_ENV'
|
||||
? IconCheck
|
||||
: undefined
|
||||
"
|
||||
:active-info-icon="selectedEnvironmentIndex.type !== 'TEAM_ENV'"
|
||||
@click="
|
||||
() => {
|
||||
selectedEnvironmentIndex = { type: 'NO_ENV_SELECTED' }
|
||||
hide()
|
||||
}
|
||||
"
|
||||
/>
|
||||
<div
|
||||
v-if="loading"
|
||||
class="flex flex-col items-center justify-center p-4"
|
||||
>
|
||||
<HoppSmartSpinner class="my-4" />
|
||||
<span class="text-secondaryLight">{{ t("state.loading") }}</span>
|
||||
</div>
|
||||
<hr v-if="teamEnvironmentList.length > 0" />
|
||||
<div
|
||||
v-if="environmentType.selectedTeam !== undefined"
|
||||
class="flex flex-col"
|
||||
>
|
||||
<HoppSmartItem
|
||||
v-for="(gen, index) in teamEnvironmentList"
|
||||
:key="`gen-team-${index}`"
|
||||
: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>
|
||||
<div
|
||||
v-if="!loading && adapterError"
|
||||
class="flex flex-col items-center py-4"
|
||||
>
|
||||
<icon-lucide-help-circle class="mb-4 svg-icons" />
|
||||
{{ getErrorMessage(adapterError) }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</tippy>
|
||||
<EnvironmentsSelector
|
||||
:environment-type="environmentType.type"
|
||||
:my-environments="myEnvironments"
|
||||
:team-env-loading="loading"
|
||||
:team-environment-list="teamEnvironmentList"
|
||||
:is-adapter-error="adapterError !== null"
|
||||
:error-message="adapterError ? getErrorMessage(adapterError) : ''"
|
||||
:is-team-selected="environmentType.selectedTeam !== undefined"
|
||||
/>
|
||||
<EnvironmentsMyEnvironment
|
||||
environment-index="Global"
|
||||
:environment="globalEnvironment"
|
||||
@@ -191,8 +53,6 @@ import {
|
||||
} from "~/newstore/environments"
|
||||
import TeamEnvironmentAdapter from "~/helpers/teams/TeamEnvironmentAdapter"
|
||||
import { GQLError } from "~/helpers/backend/GQLClient"
|
||||
import IconCheck from "~icons/lucide/check"
|
||||
import { TippyComponent } from "vue-tippy"
|
||||
import { defineActionHandler } from "~/helpers/actions"
|
||||
import { workspaceStatus$ } from "~/newstore/workspace"
|
||||
import TeamListAdapter from "~/helpers/teams/TeamListAdapter"
|
||||
@@ -249,7 +109,9 @@ watch(
|
||||
teamListFetched.value = true
|
||||
if (REMEMBERED_TEAM_ID.value && currentUser.value) {
|
||||
const team = newTeams.find((t) => t.id === REMEMBERED_TEAM_ID.value)
|
||||
if (team) updateSelectedTeam(team)
|
||||
if (team) {
|
||||
updateSelectedTeam(team)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -295,10 +157,21 @@ watch(
|
||||
(teamID) => {
|
||||
if (!teamID) {
|
||||
switchToMyEnvironments()
|
||||
|
||||
// If the user selected a team environment, and then switch to personal workspace,
|
||||
// we need to reset the selected environment
|
||||
if (selectedEnvironmentIndex.value.type === "TEAM_ENV") {
|
||||
setSelectedEnvironmentIndex({
|
||||
type: "NO_ENV_SELECTED",
|
||||
})
|
||||
}
|
||||
} else if (teamID) {
|
||||
const team = myTeams.value?.find((t) => t.id === teamID)
|
||||
if (team) {
|
||||
updateSelectedTeam(team)
|
||||
setSelectedEnvironmentIndex({
|
||||
type: "NO_ENV_SELECTED",
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -388,35 +261,6 @@ watch(
|
||||
{ deep: true }
|
||||
)
|
||||
|
||||
const selectedEnv = computed(() => {
|
||||
if (selectedEnvironmentIndex.value.type === "MY_ENV") {
|
||||
return {
|
||||
type: "MY_ENV",
|
||||
index: selectedEnvironmentIndex.value.index,
|
||||
}
|
||||
} 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 {
|
||||
selectedEnvironmentIndex.value = { type: "NO_ENV_SELECTED" }
|
||||
return { type: "NO_ENV_SELECTED" }
|
||||
}
|
||||
} else {
|
||||
selectedEnvironmentIndex.value = { type: "NO_ENV_SELECTED" }
|
||||
return { type: "NO_ENV_SELECTED" }
|
||||
}
|
||||
})
|
||||
|
||||
const getErrorMessage = (err: GQLError<string>) => {
|
||||
if (err.type === "network_error") {
|
||||
return t("error.network_error")
|
||||
@@ -429,7 +273,4 @@ const getErrorMessage = (err: GQLError<string>) => {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Template refs
|
||||
const tippyActions = ref<TippyComponent | null>(null)
|
||||
</script>
|
||||
|
||||
@@ -802,9 +802,3 @@ defineActionHandler("request.send-cancel", runQuery)
|
||||
defineActionHandler("request.save", saveRequest)
|
||||
defineActionHandler("request.reset", clearGQLQuery)
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.cm-panels) {
|
||||
top: var(--upper-tertiary-sticky-fold) !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -120,9 +120,3 @@ const downloadResponse = () => {
|
||||
defineActionHandler("response.file.download", () => downloadResponse())
|
||||
defineActionHandler("response.copy", () => copyResponse())
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.cm-panels) {
|
||||
top: var(--sidebar-primary-sticky-fold) !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -470,9 +470,3 @@ const handleUseHistory = (entry: GQLHistoryEntry) => {
|
||||
props.conn.reset()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.cm-panels) {
|
||||
top: var(--lower-primary-sticky-fold) !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -191,9 +191,3 @@ const isContentTypeAlreadyExist = () => {
|
||||
// Template refs
|
||||
const tippyActions = ref<any | null>(null)
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.cm-panels) {
|
||||
top: var(--request-body-sticky-fold) !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -273,9 +273,3 @@ const filteredCodegenDefinitions = computed(() => {
|
||||
const { copyIcon, copyResponse } = useCopyResponse(requestCode)
|
||||
const { downloadIcon, downloadResponse } = useDownloadResponse("", requestCode)
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.cm-panels) {
|
||||
top: -1rem !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -508,9 +508,3 @@ const changeTab = (tab: ComputedHeader["source"]) => {
|
||||
else emit("change-tab", "bodyParams")
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.cm-panels) {
|
||||
top: var(--upper-tertiary-sticky-fold) !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -405,9 +405,3 @@ const clearContent = () => {
|
||||
bulkParams.value = ""
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.cm-panels) {
|
||||
top: var(--upper-tertiary-sticky-fold) !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -110,9 +110,3 @@ const clearContent = () => {
|
||||
preRequestScript.value = ""
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.cm-panels) {
|
||||
top: var(--upper-tertiary-sticky-fold) !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -220,9 +220,3 @@ const prettifyXML = (xml: string) => {
|
||||
.join("\r\n")
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.cm-panels) {
|
||||
top: var(--request-body-sticky-fold) !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
class="flex p-4 bg-error text-secondaryDark"
|
||||
role="alert"
|
||||
>
|
||||
<component :is="IconAlertTriangle" class="mr-4 svg-icons" />
|
||||
<icon-lucide-alert-triangle class="mr-4 svg-icons" />
|
||||
<div class="flex flex-col">
|
||||
<p>
|
||||
{{ t("environment.no_environment_description") }}
|
||||
@@ -220,7 +220,6 @@ import { HoppTestResult } from "~/helpers/types/HoppTestResult"
|
||||
|
||||
import IconTrash2 from "~icons/lucide/trash-2"
|
||||
import IconExternalLink from "~icons/lucide/external-link"
|
||||
import IconAlertTriangle from "~icons/lucide/alert-triangle"
|
||||
import IconCheck from "~icons/lucide/check"
|
||||
import IconClose from "~icons/lucide/x"
|
||||
|
||||
|
||||
@@ -106,9 +106,3 @@ const clearContent = () => {
|
||||
testScript.value = ""
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.cm-panels) {
|
||||
top: var(--upper-tertiary-sticky-fold) !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -432,9 +432,3 @@ const clearContent = () => {
|
||||
bulkUrlEncodedParams.value = ""
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.cm-panels) {
|
||||
top: var(--request-body-sticky-fold) !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -123,9 +123,3 @@ watch(selectedLensTab, (newLensID) => {
|
||||
selectedTabPreference.value = newLensID
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.cm-panels) {
|
||||
top: var(--lower-tertiary-sticky-fold) !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
<template>
|
||||
<div
|
||||
class="flex flex-col flex-1"
|
||||
:class="{ 'showing-event-field': showEventField }"
|
||||
>
|
||||
<div class="flex flex-col flex-1">
|
||||
<div
|
||||
v-if="showEventField"
|
||||
class="sticky z-10 flex items-center justify-center flex-shrink-0 overflow-x-auto border-b bg-primary border-dividerLight"
|
||||
@@ -274,13 +271,3 @@ const prettifyRequestBody = () => {
|
||||
|
||||
defineActionHandler("request.send-cancel", sendMessage)
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.cm-panels) {
|
||||
top: var(--upper-tertiary-sticky-fold) !important;
|
||||
}
|
||||
|
||||
.showing-event-field :deep(.cm-panels) {
|
||||
top: var(--request-body-sticky-fold) !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -167,7 +167,7 @@
|
||||
v-if="!teamDetails.loading && E.isLeft(teamDetails.data)"
|
||||
class="flex flex-col items-center"
|
||||
>
|
||||
<component :is="IconHelpCircle" class="mb-4 svg-icons" />
|
||||
<icon-lucide-help-circle class="mb-4 svg-icons" />
|
||||
{{ t("error.something_went_wrong") }}
|
||||
</div>
|
||||
</div>
|
||||
@@ -220,7 +220,6 @@ import IconCircleDot from "~icons/lucide/circle-dot"
|
||||
import IconCircle from "~icons/lucide/circle"
|
||||
import IconUserPlus from "~icons/lucide/user-plus"
|
||||
import IconUserMinus from "~icons/lucide/user-minus"
|
||||
import IconHelpCircle from "~icons/lucide/help-circle"
|
||||
|
||||
const t = useI18n()
|
||||
const colorMode = useColorMode()
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
v-if="!pendingInvites.loading && E.isLeft(pendingInvites.data)"
|
||||
class="flex flex-col items-center p-4"
|
||||
>
|
||||
<component :is="IconHelpCircle" class="mb-4 svg-icons" />
|
||||
<icon-lucide-help-circle class="mb-4 svg-icons" />
|
||||
{{ t("error.something_went_wrong") }}
|
||||
</div>
|
||||
</div>
|
||||
@@ -248,8 +248,7 @@
|
||||
<span
|
||||
class="flex items-center justify-center px-2 py-1 mb-4 font-semibold border rounded-full bg-primaryDark border-divider"
|
||||
>
|
||||
<component
|
||||
:is="IconHelpCircle"
|
||||
<icon-lucide-help-circle
|
||||
class="mr-2 text-secondaryLight svg-icons"
|
||||
/>
|
||||
{{ t("profile.roles") }}
|
||||
@@ -368,7 +367,6 @@ import { useColorMode } from "~/composables/theming"
|
||||
|
||||
import IconTrash from "~icons/lucide/trash"
|
||||
import IconPlus from "~icons/lucide/plus"
|
||||
import IconHelpCircle from "~icons/lucide/help-circle"
|
||||
import IconAlertTriangle from "~icons/lucide/alert-triangle"
|
||||
import IconMailCheck from "~icons/lucide/mail-check"
|
||||
import IconCircleDot from "~icons/lucide/circle-dot"
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
/>
|
||||
</div>
|
||||
<div v-if="!loading && adapterError" class="flex flex-col items-center">
|
||||
<component :is="IconHelpCircle" class="mb-4 svg-icons" />
|
||||
<icon-lucide-help-circle class="mb-4 svg-icons" />
|
||||
{{ t("error.something_went_wrong") }}
|
||||
</div>
|
||||
</div>
|
||||
@@ -82,8 +82,6 @@ import { useI18n } from "@composables/i18n"
|
||||
import { useReadonlyStream } from "@composables/stream"
|
||||
import { useColorMode } from "@composables/theming"
|
||||
|
||||
import IconHelpCircle from "~icons/lucide/help-circle"
|
||||
|
||||
const t = useI18n()
|
||||
|
||||
const colorMode = useColorMode()
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
v-if="!loading && teamListAdapterError"
|
||||
class="flex flex-col items-center py-4"
|
||||
>
|
||||
<i class="mb-4 material-icons">help_outline</i>
|
||||
<icon-lucide-help-circle class="mb-4 svg-icons" />
|
||||
{{ t("error.something_went_wrong") }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -63,7 +63,6 @@ export const baseTheme = EditorView.theme({
|
||||
".cm-panels": {
|
||||
backgroundColor: "var(--primary-light-color)",
|
||||
color: "var(--secondary-light-color)",
|
||||
zIndex: "1",
|
||||
},
|
||||
".cm-panels.cm-panels-top": {
|
||||
borderBottom: "1px solid var(--divider-light-color)",
|
||||
@@ -199,7 +198,6 @@ export const inputTheme = EditorView.theme({
|
||||
".cm-panels": {
|
||||
backgroundColor: "var(--primary-light-color)",
|
||||
color: "var(--secondary-light-color)",
|
||||
zIndex: "1",
|
||||
},
|
||||
".cm-panels.cm-panels-top": {
|
||||
borderBottom: "1px solid var(--divider-light-color)",
|
||||
|
||||
@@ -7,7 +7,6 @@ import { HoppModule } from "."
|
||||
|
||||
import languages from "../../languages.json"
|
||||
|
||||
import en from "../../locales/en.json"
|
||||
import { throwError } from "~/helpers/functional/error"
|
||||
import { getLocalConfig, setLocalConfig } from "~/newstore/localpersistence"
|
||||
|
||||
@@ -123,11 +122,6 @@ export default <HoppModule>{
|
||||
fallbackLocale: "en",
|
||||
legacy: false,
|
||||
allowComposition: true,
|
||||
|
||||
// TODO: Fix this to allow for dynamic imports
|
||||
messages: {
|
||||
en,
|
||||
},
|
||||
})
|
||||
|
||||
app.use(i18n)
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
/* eslint-disable no-restricted-globals, no-restricted-syntax */
|
||||
|
||||
import { clone, assign, isEmpty } from "lodash-es"
|
||||
import * as O from "fp-ts/Option"
|
||||
import { pipe } from "fp-ts/function"
|
||||
import {
|
||||
translateToNewRESTCollection,
|
||||
translateToNewGQLCollection,
|
||||
@@ -51,7 +49,30 @@ import {
|
||||
} from "~/helpers/rest/tab"
|
||||
|
||||
function checkAndMigrateOldSettings() {
|
||||
if (window.localStorage.getItem("selectedEnvIndex")) {
|
||||
const index = window.localStorage.getItem("selectedEnvIndex")
|
||||
if (index) {
|
||||
if (index === "-1") {
|
||||
window.localStorage.setItem(
|
||||
"selectedEnvIndex",
|
||||
JSON.stringify({
|
||||
type: "NO_ENV_SELECTED",
|
||||
})
|
||||
)
|
||||
} else if (Number(index) >= 0) {
|
||||
window.localStorage.setItem(
|
||||
"selectedEnvIndex",
|
||||
JSON.stringify({
|
||||
type: "MY_ENV",
|
||||
index: parseInt(index),
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const vuexData = JSON.parse(window.localStorage.getItem("vuex") || "{}")
|
||||
|
||||
if (isEmpty(vuexData)) return
|
||||
|
||||
const { postwoman } = vuexData
|
||||
@@ -210,35 +231,21 @@ function setupEnvironmentsPersistence() {
|
||||
}
|
||||
|
||||
function setupSelectedEnvPersistence() {
|
||||
const selectedEnvIndex = pipe(
|
||||
// Value from local storage can be nullable
|
||||
O.fromNullable(window.localStorage.getItem("selectedEnvIndex")),
|
||||
O.map(parseInt), // If not null, parse to integer
|
||||
O.chain(
|
||||
O.fromPredicate(
|
||||
Number.isInteger // Check if the number is proper int (not NaN)
|
||||
)
|
||||
),
|
||||
O.getOrElse(() => -1) // If all the above conditions pass, we are good, else set default value (-1)
|
||||
const selectedEnvIndex = JSON.parse(
|
||||
window.localStorage.getItem("selectedEnvIndex") ?? "null"
|
||||
)
|
||||
// Check if current environment index is -1 ie. no environment is selected
|
||||
if (selectedEnvIndex === -1) {
|
||||
setSelectedEnvironmentIndex({
|
||||
type: "NO_ENV_SELECTED",
|
||||
})
|
||||
|
||||
// If there is a selected env index, set it to the store else set it to null
|
||||
if (selectedEnvIndex) {
|
||||
setSelectedEnvironmentIndex(selectedEnvIndex)
|
||||
} else {
|
||||
setSelectedEnvironmentIndex({
|
||||
type: "MY_ENV",
|
||||
index: selectedEnvIndex,
|
||||
type: "NO_ENV_SELECTED",
|
||||
})
|
||||
}
|
||||
|
||||
selectedEnvironmentIndex$.subscribe((envIndex) => {
|
||||
if (envIndex.type === "MY_ENV") {
|
||||
window.localStorage.setItem("selectedEnvIndex", envIndex.index.toString())
|
||||
} else {
|
||||
window.localStorage.setItem("selectedEnvIndex", "-1")
|
||||
}
|
||||
window.localStorage.setItem("selectedEnvIndex", JSON.stringify(envIndex))
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -38,10 +38,15 @@
|
||||
<template #suffix>
|
||||
<span
|
||||
v-if="tab.document.isDirty"
|
||||
class="text-green-600 text-[8px] group-hover:hidden w-4"
|
||||
class="flex items-center justify-center text-secondary group-hover:hidden w-4"
|
||||
>
|
||||
<svg viewBox="0 0 24 24" width="1.2em" height="1.2em">
|
||||
<circle cx="12" cy="12" r="10" fill="currentColor"></circle>
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
width="1.2em"
|
||||
height="1.2em"
|
||||
class="h-1.5 w-1.5"
|
||||
>
|
||||
<circle cx="12" cy="12" r="12" fill="currentColor"></circle>
|
||||
</svg>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@hoppscotch/selfhost-web",
|
||||
"private": true,
|
||||
"version": "2023.4.0",
|
||||
"version": "2023.4.1",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev:vite": "vite",
|
||||
@@ -46,7 +46,7 @@
|
||||
"@graphql-codegen/typescript-urql-graphcache": "^2.3.1",
|
||||
"@graphql-codegen/urql-introspection": "^2.2.0",
|
||||
"@graphql-typed-document-node/core": "^3.1.1",
|
||||
"@intlify/vite-plugin-vue-i18n": "^6.0.1",
|
||||
"@intlify/vite-plugin-vue-i18n": "^7.0.0",
|
||||
"@rushstack/eslint-patch": "^1.1.4",
|
||||
"@typescript-eslint/eslint-plugin": "^5.19.0",
|
||||
"@typescript-eslint/parser": "^5.19.0",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "hoppscotch-sh-admin",
|
||||
"private": true,
|
||||
"version": "2023.4.0",
|
||||
"version": "2023.4.1",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "pnpm exec npm-run-all -p -l dev:*",
|
||||
|
||||
@@ -131,10 +131,7 @@
|
||||
<span
|
||||
class="flex items-center justify-center px-2 py-1 mb-4 font-semibold border rounded-full bg-primaryDark border-divider"
|
||||
>
|
||||
<component
|
||||
:is="IconHelpCircle"
|
||||
class="mr-2 text-secondaryLight svg-icons"
|
||||
/>
|
||||
<icon-lucide-help-circle class="mr-2 text-secondaryLight svg-icons" />
|
||||
Roles
|
||||
</span>
|
||||
<p>
|
||||
@@ -208,7 +205,6 @@ import { useMutation, useQuery } from '@urql/vue';
|
||||
import { Email, EmailCodec } from '~/helpers/backend/Email';
|
||||
import IconTrash from '~icons/lucide/trash';
|
||||
import IconPlus from '~icons/lucide/plus';
|
||||
import IconHelpCircle from '~icons/lucide/help-circle';
|
||||
import IconCircleDot from '~icons/lucide/circle-dot';
|
||||
import IconCircle from '~icons/lucide/circle';
|
||||
import { computed } from 'vue';
|
||||
|
||||
@@ -133,7 +133,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!fetching && !team" class="flex flex-col items-center">
|
||||
<component :is="IconHelpCircle" class="mb-4 svg-icons" />
|
||||
<icon-lucide-help-circle class="mb-4 svg-icons" />
|
||||
Something went wrong. Please try again later.
|
||||
</div>
|
||||
</div>
|
||||
@@ -159,7 +159,6 @@ import IconCircleDot from '~icons/lucide/circle-dot';
|
||||
import IconCircle from '~icons/lucide/circle';
|
||||
import IconUserPlus from '~icons/lucide/user-plus';
|
||||
import IconUserMinus from '~icons/lucide/user-minus';
|
||||
import IconHelpCircle from '~icons/lucide/help-circle';
|
||||
import IconChevronDown from '~icons/lucide/chevron-down';
|
||||
import { useClientHandle, useMutation } from '@urql/vue';
|
||||
import { computed, onMounted, onUnmounted, ref, watch } from 'vue';
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
<span class="text-center"> No pending invites </span>
|
||||
</div>
|
||||
<div v-if="!fetching && error" class="flex flex-col items-center p-4">
|
||||
<component :is="IconHelpCircle" class="mb-4 svg-icons" />
|
||||
<icon-lucide-help-circle class="mb-4 svg-icons" />
|
||||
Something went wrong. Please try again later.
|
||||
</div>
|
||||
</div>
|
||||
@@ -53,7 +53,6 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import IconTrash from '~icons/lucide/trash';
|
||||
import IconHelpCircle from '~icons/lucide/help-circle';
|
||||
import { useMutation, useClientHandle } from '@urql/vue';
|
||||
import { ref, onMounted } from 'vue';
|
||||
import {
|
||||
|
||||
@@ -1,22 +1,6 @@
|
||||
<template>
|
||||
<span class="chip">
|
||||
<component :is="IconFile" class="opacity-75 svg-icons" />
|
||||
<span class="inline-flex items-center justify-center rounded pl-2 pr-0.5 bg-primaryDark">
|
||||
<icon-lucide-file class="opacity-75 svg-icons" />
|
||||
<span class="px-2 truncate max-w-54"><slot></slot></span>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import IconFile from "~icons/lucide/file"
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.chip {
|
||||
@apply inline-flex;
|
||||
@apply items-center;
|
||||
@apply justify-center;
|
||||
@apply rounded;
|
||||
@apply pl-2;
|
||||
@apply pr-0.5;
|
||||
@apply bg-primaryDark;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
ref="scrollContainer"
|
||||
>
|
||||
<div
|
||||
class="flex justify-between divide-x divide-dividerLight"
|
||||
class="flex justify-between divide-x divide-divider"
|
||||
@wheel.prevent="scroll"
|
||||
>
|
||||
<div class="flex">
|
||||
@@ -50,7 +50,12 @@
|
||||
<component :is="tabMeta.tabhead" />
|
||||
</div>
|
||||
|
||||
<component v-if="tabMeta.suffix" :is="tabMeta.suffix" />
|
||||
<div
|
||||
v-if="tabMeta.suffix"
|
||||
class="flex items-center justify-center"
|
||||
>
|
||||
<component :is="tabMeta.suffix" />
|
||||
</div>
|
||||
|
||||
<HoppButtonSecondary
|
||||
v-if="tabMeta.isRemovable"
|
||||
@@ -67,7 +72,7 @@
|
||||
},
|
||||
'close',
|
||||
]"
|
||||
class="!p-0.5"
|
||||
class="!p-0.25 rounded"
|
||||
@click.stop="emit('removeTab', tabID)"
|
||||
/>
|
||||
</button>
|
||||
@@ -80,13 +85,13 @@
|
||||
<slot name="actions">
|
||||
<span
|
||||
v-if="canAddNewTab"
|
||||
class="flex items-center justify-center px-2 py-1.5 bg-primaryLight z-8 h-full"
|
||||
class="flex items-center justify-center px-3 bg-primaryLight z-8 h-full"
|
||||
>
|
||||
<HoppButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="newText ?? t?.('action.new') ?? 'New'"
|
||||
:icon="IconPlus"
|
||||
class="rounded !p-1"
|
||||
class="rounded !text-secondaryDark !p-1"
|
||||
filled
|
||||
@click="addTab"
|
||||
/>
|
||||
@@ -223,9 +228,6 @@ const removeTabEntry = (tabID: string) => {
|
||||
O.chain((index) => pipe(tabEntries.value, A.deleteAt(index))),
|
||||
O.getOrElseW(() => throwError(`Failed to remove tab entry: ${tabID}`))
|
||||
)
|
||||
// If we tried to remove the active tabEntries, switch to first tab entry
|
||||
if (props.modelValue === tabID)
|
||||
if (tabEntries.value.length > 0) selectTab(tabEntries.value[0][0])
|
||||
}
|
||||
const sortTabs = (e: {
|
||||
oldDraggableIndex: number
|
||||
@@ -340,43 +342,48 @@ watch(thumbPosition, (newVal) => {
|
||||
@apply opacity-50;
|
||||
|
||||
&.active {
|
||||
@apply opacity-80;
|
||||
@apply opacity-100;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$slider-height: 4px;
|
||||
|
||||
.slider {
|
||||
--thumb-width: 300px;
|
||||
-webkit-appearance: none;
|
||||
width: 100%;
|
||||
--thumb-width: 0;
|
||||
|
||||
height: $slider-height;
|
||||
background: transparent;
|
||||
outline: none;
|
||||
opacity: 0;
|
||||
-webkit-transition: 0.2s;
|
||||
transition: opacity 0.2s;
|
||||
|
||||
@apply appearance-none;
|
||||
@apply w-full;
|
||||
@apply bg-transparent;
|
||||
@apply outline-none;
|
||||
@apply opacity-0;
|
||||
@apply transition;
|
||||
|
||||
&::-webkit-slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
min-width: 300px;
|
||||
@apply appearance-none;
|
||||
@apply min-w-0;
|
||||
@apply bg-dividerDark;
|
||||
@apply hover:bg-secondaryLight;
|
||||
|
||||
width: var(--thumb-width);
|
||||
height: $slider-height;
|
||||
background: gray;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&::-moz-range-thumb {
|
||||
min-width: 300px;
|
||||
@apply appearance-none;
|
||||
@apply min-w-0;
|
||||
@apply bg-dividerDark;
|
||||
@apply hover:bg-secondaryLight;
|
||||
|
||||
width: var(--thumb-width);
|
||||
height: $slider-height;
|
||||
background: gray;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.group-tabs:hover .slider {
|
||||
opacity: 0.8;
|
||||
@apply opacity-100;
|
||||
}
|
||||
</style>
|
||||
|
||||
102
pnpm-lock.yaml
generated
102
pnpm-lock.yaml
generated
@@ -485,8 +485,8 @@ importers:
|
||||
specifier: ^4.17.21
|
||||
version: 4.17.21
|
||||
lossless-json:
|
||||
specifier: ^1.0.5
|
||||
version: 1.0.5
|
||||
specifier: ^2.0.8
|
||||
version: 2.0.8
|
||||
nprogress:
|
||||
specifier: ^0.2.0
|
||||
version: 0.2.0
|
||||
@@ -612,8 +612,8 @@ importers:
|
||||
specifier: ^1.1.40
|
||||
version: 1.1.40
|
||||
'@intlify/vite-plugin-vue-i18n':
|
||||
specifier: ^6.0.1
|
||||
version: 6.0.1(vite@3.1.4)(vue-i18n@9.2.2)
|
||||
specifier: ^7.0.0
|
||||
version: 7.0.0(vite@3.1.4)(vue-i18n@9.2.2)
|
||||
'@rushstack/eslint-patch':
|
||||
specifier: ^1.1.4
|
||||
version: 1.1.4
|
||||
@@ -891,8 +891,8 @@ importers:
|
||||
specifier: ^3.1.1
|
||||
version: 3.1.1(graphql@15.8.0)
|
||||
'@intlify/vite-plugin-vue-i18n':
|
||||
specifier: ^6.0.1
|
||||
version: 6.0.1(vite@3.1.4)(vue-i18n@9.2.2)
|
||||
specifier: ^7.0.0
|
||||
version: 7.0.0(vite@3.1.4)(vue-i18n@9.2.2)
|
||||
'@rushstack/eslint-patch':
|
||||
specifier: ^1.1.4
|
||||
version: 1.1.4
|
||||
@@ -1203,7 +1203,7 @@ importers:
|
||||
version: 1.1.40
|
||||
'@intlify/vite-plugin-vue-i18n':
|
||||
specifier: ^6.0.1
|
||||
version: 6.0.1(vite@3.1.4)(vue-i18n@9.2.2)
|
||||
version: 6.0.1(vite@3.2.4)
|
||||
'@rushstack/eslint-patch':
|
||||
specifier: ^1.1.4
|
||||
version: 1.1.4
|
||||
@@ -1700,7 +1700,7 @@ packages:
|
||||
convert-source-map: 1.8.0
|
||||
debug: 4.3.4(supports-color@9.2.2)
|
||||
gensync: 1.0.0-beta.2
|
||||
json5: 2.2.1
|
||||
json5: 2.2.3
|
||||
semver: 6.3.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
@@ -1729,7 +1729,7 @@ packages:
|
||||
resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/types': 7.18.7
|
||||
'@babel/types': 7.21.2
|
||||
dev: true
|
||||
|
||||
/@babel/helper-builder-binary-assignment-operator-visitor@7.18.6:
|
||||
@@ -1831,14 +1831,14 @@ packages:
|
||||
resolution: {integrity: sha512-CeHxqwwipekotzPDUuJOfIMtcIHBuc7WAzLmTYWctVigqS5RktNMQ5bEwQSuGewzYnCtTWa3BARXeiLxDTv+Ng==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/types': 7.18.7
|
||||
'@babel/types': 7.21.2
|
||||
dev: true
|
||||
|
||||
/@babel/helper-module-imports@7.18.6:
|
||||
resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/types': 7.18.7
|
||||
'@babel/types': 7.21.2
|
||||
dev: true
|
||||
|
||||
/@babel/helper-module-transforms@7.18.6:
|
||||
@@ -1861,7 +1861,7 @@ packages:
|
||||
resolution: {integrity: sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/types': 7.18.7
|
||||
'@babel/types': 7.21.2
|
||||
dev: true
|
||||
|
||||
/@babel/helper-plugin-utils@7.18.6:
|
||||
@@ -1897,7 +1897,7 @@ packages:
|
||||
'@babel/helper-member-expression-to-functions': 7.18.6
|
||||
'@babel/helper-optimise-call-expression': 7.18.6
|
||||
'@babel/traverse': 7.18.6
|
||||
'@babel/types': 7.18.7
|
||||
'@babel/types': 7.21.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
@@ -1906,14 +1906,14 @@ packages:
|
||||
resolution: {integrity: sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/types': 7.18.7
|
||||
'@babel/types': 7.21.2
|
||||
dev: true
|
||||
|
||||
/@babel/helper-skip-transparent-expression-wrappers@7.18.6:
|
||||
resolution: {integrity: sha512-4KoLhwGS9vGethZpAhYnMejWkX64wsnHPDwvOsKWU6Fg4+AlK2Jz3TyjQLMEPvz+1zemi/WBdkYxCD0bAfIkiw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/types': 7.18.7
|
||||
'@babel/types': 7.21.2
|
||||
dev: true
|
||||
|
||||
/@babel/helper-split-export-declaration@7.18.6:
|
||||
@@ -2897,7 +2897,7 @@ packages:
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.18.6
|
||||
'@babel/parser': 7.18.6
|
||||
'@babel/parser': 7.21.2
|
||||
'@babel/types': 7.18.7
|
||||
dev: true
|
||||
|
||||
@@ -5414,7 +5414,27 @@ packages:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@intlify/bundle-utils@6.0.0(vue-i18n@9.2.2):
|
||||
/@intlify/bundle-utils@3.4.0(vue-i18n@9.2.2):
|
||||
resolution: {integrity: sha512-2UQkqiSAOSPEHMGWlybqWm4G2K0X+FyYho5AwXz6QklSX1EY5EDmOSxZmwscn2qmKBnp6OYsme5kUrnN9xrWzQ==}
|
||||
engines: {node: '>= 12'}
|
||||
peerDependencies:
|
||||
petite-vue-i18n: '*'
|
||||
vue-i18n: '*'
|
||||
peerDependenciesMeta:
|
||||
petite-vue-i18n:
|
||||
optional: true
|
||||
vue-i18n:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@intlify/message-compiler': 9.3.0-beta.17
|
||||
'@intlify/shared': 9.3.0-beta.17
|
||||
jsonc-eslint-parser: 1.4.1
|
||||
source-map: 0.6.1
|
||||
vue-i18n: 9.2.2(vue@3.2.37)
|
||||
yaml-eslint-parser: 0.3.2
|
||||
dev: true
|
||||
|
||||
/@intlify/bundle-utils@6.0.0:
|
||||
resolution: {integrity: sha512-c8nTDgsTrBqVk3LPoF/YEarqeqcW0XAY5Y0UmFl5VKWKRNQh47jzvHRDmeRWhos5bUw1zIdiTixrs99FMJ9j5g==}
|
||||
engines: {node: '>= 14.16'}
|
||||
peerDependencies:
|
||||
@@ -5435,7 +5455,6 @@ packages:
|
||||
magic-string: 0.30.0
|
||||
mlly: 1.2.0
|
||||
source-map: 0.6.1
|
||||
vue-i18n: 9.2.2(vue@3.2.37)
|
||||
yaml-eslint-parser: 0.3.2
|
||||
dev: true
|
||||
|
||||
@@ -5478,7 +5497,7 @@ packages:
|
||||
engines: {node: '>= 14'}
|
||||
dev: true
|
||||
|
||||
/@intlify/vite-plugin-vue-i18n@6.0.1(vite@3.1.4)(vue-i18n@9.2.2):
|
||||
/@intlify/vite-plugin-vue-i18n@6.0.1(vite@3.2.4):
|
||||
resolution: {integrity: sha512-FFVcxVU4bR9vdDLNbltM5mrhndnXMErO01i0RrpdyMegEt3Nu/YLoH0sFdjRun7/RY4vaEnhTnFvVf9uO0dQvg==}
|
||||
engines: {node: '>= 14.6'}
|
||||
peerDependencies:
|
||||
@@ -5493,12 +5512,39 @@ packages:
|
||||
vue-i18n:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@intlify/bundle-utils': 6.0.0(vue-i18n@9.2.2)
|
||||
'@intlify/bundle-utils': 6.0.0
|
||||
'@intlify/shared': 9.3.0-beta.17
|
||||
'@rollup/pluginutils': 4.2.1
|
||||
debug: 4.3.4(supports-color@9.2.2)
|
||||
fast-glob: 3.2.11
|
||||
source-map: 0.6.1
|
||||
vite: 3.2.4(@types/node@17.0.45)(sass@1.53.0)(terser@5.14.1)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@intlify/vite-plugin-vue-i18n@7.0.0(vite@3.1.4)(vue-i18n@9.2.2):
|
||||
resolution: {integrity: sha512-2TbDOQ8XD+vkc0s5OFmr+IY/k4mYMC7pzvx0xGQn+cU/ev314+yi7Z7N7rWcBgiYk1WOUalbGSo3d4nJDxOOyw==}
|
||||
engines: {node: '>= 14.6'}
|
||||
deprecated: This plugin support until Vite 3. If you would like to use on Vite 4, please use @intlify/unplugin-vue-i18n
|
||||
peerDependencies:
|
||||
petite-vue-i18n: '*'
|
||||
vite: ^2.9.0 || ^3.0.0
|
||||
vue-i18n: '*'
|
||||
peerDependenciesMeta:
|
||||
petite-vue-i18n:
|
||||
optional: true
|
||||
vite:
|
||||
optional: true
|
||||
vue-i18n:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@intlify/bundle-utils': 3.4.0(vue-i18n@9.2.2)
|
||||
'@intlify/shared': 9.3.0-beta.17
|
||||
'@rollup/pluginutils': 4.2.1
|
||||
debug: 4.3.4(supports-color@9.2.2)
|
||||
fast-glob: 3.2.12
|
||||
source-map: 0.6.1
|
||||
vite: 3.1.4(sass@1.53.0)(terser@5.14.1)
|
||||
vue-i18n: 9.2.2(vue@3.2.37)
|
||||
transitivePeerDependencies:
|
||||
@@ -7039,7 +7085,7 @@ packages:
|
||||
/@types/babel__core@7.1.19:
|
||||
resolution: {integrity: sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==}
|
||||
dependencies:
|
||||
'@babel/parser': 7.18.6
|
||||
'@babel/parser': 7.21.2
|
||||
'@babel/types': 7.18.7
|
||||
'@types/babel__generator': 7.6.4
|
||||
'@types/babel__template': 7.4.1
|
||||
@@ -7049,14 +7095,14 @@ packages:
|
||||
/@types/babel__generator@7.6.4:
|
||||
resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==}
|
||||
dependencies:
|
||||
'@babel/types': 7.18.7
|
||||
'@babel/types': 7.21.2
|
||||
dev: true
|
||||
|
||||
/@types/babel__template@7.4.1:
|
||||
resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==}
|
||||
dependencies:
|
||||
'@babel/parser': 7.18.6
|
||||
'@babel/types': 7.18.7
|
||||
'@babel/parser': 7.21.2
|
||||
'@babel/types': 7.21.2
|
||||
dev: true
|
||||
|
||||
/@types/babel__traverse@7.17.1:
|
||||
@@ -9373,7 +9419,7 @@ packages:
|
||||
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
|
||||
dependencies:
|
||||
'@babel/template': 7.18.6
|
||||
'@babel/types': 7.18.7
|
||||
'@babel/types': 7.21.2
|
||||
'@types/babel__core': 7.1.19
|
||||
'@types/babel__traverse': 7.17.1
|
||||
dev: true
|
||||
@@ -9383,7 +9429,7 @@ packages:
|
||||
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||
dependencies:
|
||||
'@babel/template': 7.18.6
|
||||
'@babel/types': 7.18.7
|
||||
'@babel/types': 7.21.2
|
||||
'@types/babel__core': 7.1.19
|
||||
'@types/babel__traverse': 7.17.1
|
||||
dev: true
|
||||
@@ -15891,8 +15937,8 @@ packages:
|
||||
js-tokens: 4.0.0
|
||||
dev: true
|
||||
|
||||
/lossless-json@1.0.5:
|
||||
resolution: {integrity: sha512-RicKUuLwZVNZ6ZdJHgIZnSeA05p8qWc5NW0uR96mpPIjN9WDLUg9+kj1esQU1GkPn9iLZVKatSQK5gyiaFHgJA==}
|
||||
/lossless-json@2.0.8:
|
||||
resolution: {integrity: sha512-7/GaZldUc7H5oNZlSk6bF06cRbtA7oF8zWXwbfMZm8yrYC2debx0KvWTBbQIbj6fh08LsXTWg+YtHJshXgYKow==}
|
||||
dev: false
|
||||
|
||||
/loupe@2.3.6:
|
||||
|
||||
Reference in New Issue
Block a user