fix: avoid rapid polling while fetching teams in selector (#5485)
This commit is contained in:
parent
53e8b28459
commit
aa1583763a
7 changed files with 55 additions and 24 deletions
|
|
@ -203,7 +203,7 @@
|
|||
class="!focus-visible:text-blue-600 !hover:text-blue-600 h-8 rounded border border-blue-600/25 bg-blue-500/10 pr-8 !text-blue-500 hover:border-blue-600/20 hover:bg-blue-600/20 focus-visible:border-blue-600/20 focus-visible:bg-blue-600/20"
|
||||
/>
|
||||
</HoppSmartSelectWrapper>
|
||||
<template #content="{ hide }">
|
||||
<template #content="{ hide, state }">
|
||||
<div
|
||||
ref="accountActions"
|
||||
class="flex flex-col focus:outline-none"
|
||||
|
|
@ -211,7 +211,7 @@
|
|||
@keyup.escape="hide()"
|
||||
@click="hide()"
|
||||
>
|
||||
<WorkspaceSelector />
|
||||
<WorkspaceSelector :state="state" />
|
||||
</div>
|
||||
</template>
|
||||
</tippy>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div ref="rootEl">
|
||||
<div class="flex flex-col">
|
||||
<div class="flex flex-col">
|
||||
<div class="flex flex-col">
|
||||
<HoppSmartItem
|
||||
|
|
@ -81,6 +81,7 @@
|
|||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, watch } from "vue"
|
||||
import { useReadonlyStream } from "~/composables/stream"
|
||||
|
|
@ -96,11 +97,16 @@ import { useLocalState } from "~/newstore/localstate"
|
|||
import { defineActionHandler, invokeAction } from "~/helpers/actions"
|
||||
import { WorkspaceService } from "~/services/workspace.service"
|
||||
import { useService } from "dioc/vue"
|
||||
import { useElementVisibility, useIntervalFn } from "@vueuse/core"
|
||||
import { useIntervalFn, watchDebounced } from "@vueuse/core"
|
||||
import { TippyState } from "~/modules/tippy"
|
||||
|
||||
const t = useI18n()
|
||||
const colorMode = useColorMode()
|
||||
|
||||
const props = defineProps<{
|
||||
state: TippyState | null
|
||||
}>()
|
||||
|
||||
const showModalAdd = ref(false)
|
||||
|
||||
const currentUser = useReadonlyStream(
|
||||
|
|
@ -116,27 +122,35 @@ const teamListAdapterError = useReadonlyStream(teamListadapter.error$, null)
|
|||
const REMEMBERED_TEAM_ID = useLocalState("REMEMBERED_TEAM_ID")
|
||||
const teamListFetched = ref(false)
|
||||
|
||||
const rootEl = ref<HTMLElement>()
|
||||
const elVisible = useElementVisibility(rootEl)
|
||||
|
||||
const { pause: pauseListPoll, resume: resumeListPoll } = useIntervalFn(() => {
|
||||
if (teamListadapter.isInitialized) {
|
||||
teamListadapter.fetchList()
|
||||
}
|
||||
}, 10000)
|
||||
|
||||
watch(
|
||||
elVisible,
|
||||
const {
|
||||
pause: pauseListPoll,
|
||||
resume: resumeListPoll,
|
||||
isActive: isListPolling,
|
||||
} = useIntervalFn(
|
||||
() => {
|
||||
if (elVisible.value) {
|
||||
if (teamListadapter.isInitialized) {
|
||||
teamListadapter.fetchList()
|
||||
}
|
||||
},
|
||||
10000,
|
||||
{ immediate: false }
|
||||
)
|
||||
|
||||
resumeListPoll()
|
||||
// A debounced watcher to avoid rapid polling when component is mounted.
|
||||
// only poll when the component is visible and pause when not visible.
|
||||
watchDebounced(
|
||||
() => props.state?.isVisible,
|
||||
(isVisible) => {
|
||||
if (isVisible) {
|
||||
if (!isListPolling.value) {
|
||||
teamListadapter.fetchList()
|
||||
resumeListPoll()
|
||||
}
|
||||
} else {
|
||||
pauseListPoll()
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
{ debounce: 200 }
|
||||
)
|
||||
|
||||
watch(myTeams, (teams) => {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import {
|
|||
getDefaultRESTRequest,
|
||||
translateToNewRESTCollection,
|
||||
HoppGQLRequest,
|
||||
translateToNewGQLCollection
|
||||
translateToNewGQLCollection,
|
||||
} from "@hoppscotch/data"
|
||||
import * as A from "fp-ts/Array"
|
||||
import * as O from "fp-ts/Option"
|
||||
|
|
|
|||
|
|
@ -6,6 +6,14 @@ import "tippy.js/animations/scale-subtle.css"
|
|||
import "tippy.js/dist/border.css"
|
||||
import "tippy.js/dist/svg-arrow.css"
|
||||
|
||||
export type TippyState = {
|
||||
isEnabled: boolean
|
||||
isVisible: boolean
|
||||
isDestroyed: boolean
|
||||
isMounted: boolean
|
||||
isShown: boolean
|
||||
}
|
||||
|
||||
export default <HoppModule>{
|
||||
onVueAppInit(app) {
|
||||
app.use(VueTippy)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import {
|
|||
HoppRESTHeaders,
|
||||
HoppRESTRequest,
|
||||
makeCollection,
|
||||
GQLHeader
|
||||
GQLHeader,
|
||||
} from "@hoppscotch/data"
|
||||
import { cloneDeep } from "lodash-es"
|
||||
import { pluck } from "rxjs/operators"
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
import { Service } from "dioc"
|
||||
import { markRaw } from "vue"
|
||||
import {
|
||||
body,
|
||||
relayRequestToNativeAdapter,
|
||||
import {
|
||||
body,
|
||||
relayRequestToNativeAdapter,
|
||||
RelayRequest,
|
||||
RelayResponse,
|
||||
RelayCapabilities
|
||||
RelayCapabilities,
|
||||
} from "@hoppscotch/kernel"
|
||||
import * as E from "fp-ts/Either"
|
||||
import { pipe } from "fp-ts/function"
|
||||
|
|
|
|||
|
|
@ -1059,6 +1059,15 @@ export class TeamCollectionsService extends Service<void> {
|
|||
collections.forEach((coll) => this.entityIDs.add(`collection-${coll.id}`))
|
||||
requests.forEach((req) => this.entityIDs.add(`request-${req.id}`))
|
||||
|
||||
this.collections.value = [...tree]
|
||||
} catch (error) {
|
||||
console.error(`Error expanding collection ${collectionID}:`, error)
|
||||
|
||||
// Set empty arrays instead of leaving as null to prevent future expansion attempts
|
||||
// This prevents the infinite loop by ensuring the collection is marked as expanded
|
||||
collection.children = []
|
||||
collection.requests = []
|
||||
|
||||
this.collections.value = [...tree]
|
||||
} finally {
|
||||
this.loadingCollections.value = this.loadingCollections.value.filter(
|
||||
|
|
|
|||
Loading…
Reference in a new issue