diff --git a/packages/hoppscotch-common/src/components/mockServer/MockServerDashboard.vue b/packages/hoppscotch-common/src/components/mockServer/MockServerDashboard.vue index 39ecdef6..5d131612 100644 --- a/packages/hoppscotch-common/src/components/mockServer/MockServerDashboard.vue +++ b/packages/hoppscotch-common/src/components/mockServer/MockServerDashboard.vue @@ -32,7 +32,7 @@
@@ -209,12 +209,14 @@ import { computed, ref } from "vue" import { TippyComponent } from "vue-tippy" import { useMockServerStatus } from "~/composables/mockServer" import { useToast } from "~/composables/toast" +import { useReadonlyStream } from "~/composables/stream" import { copyToClipboard } from "~/helpers/utils/clipboard" import type { MockServer } from "~/newstore/mockServers" import { platform } from "~/platform" import { deleteMockServer as deleteMockServerInStore, + loading$, showCreateMockServerModal$, updateMockServer as updateMockServerInStore, } from "~/newstore/mockServers" @@ -242,6 +244,7 @@ const t = useI18n() const toast = useToast() const colorMode = useColorMode() const { mockServers } = useMockServerStatus() +const isFetchingServers = useReadonlyStream(loading$, false) const loading = ref(false) const showEditModal = ref(false) const showLogsModal = ref(false) diff --git a/packages/hoppscotch-common/src/composables/mockServerWorkspace.ts b/packages/hoppscotch-common/src/composables/mockServerWorkspace.ts index 83a67149..f975ca99 100644 --- a/packages/hoppscotch-common/src/composables/mockServerWorkspace.ts +++ b/packages/hoppscotch-common/src/composables/mockServerWorkspace.ts @@ -1,9 +1,10 @@ -import { onMounted, watch } from "vue" import { useService } from "dioc/vue" -import { WorkspaceService } from "~/services/workspace.service" -import { setMockServers, loadMockServers } from "~/newstore/mockServers" +import { watch } from "vue" +import { loadMockServers, setMockServers } from "~/newstore/mockServers" import { platform } from "~/platform" +import { WorkspaceService } from "~/services/workspace.service" import { useMockServerVisibility } from "./mockServerVisibility" +import { useReadonlyStream } from "./stream" /** * Composable to handle mock server state when workspace changes @@ -13,19 +14,27 @@ import { useMockServerVisibility } from "./mockServerVisibility" export function useMockServerWorkspaceSync() { const workspaceService = useService(WorkspaceService) const { isMockServerVisible } = useMockServerVisibility() - const isAuthenticated = !!platform.auth.getCurrentUser() - // Initial load of mock servers for the current workspace - onMounted(() => { - if (!isAuthenticated || !isMockServerVisible.value) return + const currentUser = useReadonlyStream( + platform.auth.getCurrentUserStream(), + platform.auth.getCurrentUser() + ) + + const loadServers = () => { + if (!currentUser.value || !isMockServerVisible.value) return loadMockServers().catch(() => setMockServers([])) + } + + // Load mock servers when authentication or visibility changes + watch([currentUser, isMockServerVisible], loadServers, { + immediate: true, }) // Watch for workspace changes and clear mock servers immediately watch( () => workspaceService.currentWorkspace.value, (newWorkspace, oldWorkspace) => { - if (!isAuthenticated || !isMockServerVisible.value) return + if (!currentUser.value || !isMockServerVisible.value) return // Clear mock servers when workspace changes to prevent stale data if ( @@ -34,16 +43,10 @@ export function useMockServerWorkspaceSync() { oldWorkspace?.type === "team" && newWorkspace.teamID !== oldWorkspace.teamID) ) { - // Clear mock servers immediately to prevent showing stale data setMockServers([]) - - // If user is authenticated, reload mock servers for the new workspace - if (platform.auth.getCurrentUser()) { - // fire-and-forget; loadMockServers handles errors internally - loadMockServers().catch(() => setMockServers([])) - } + loadServers() } }, - { deep: true, immediate: false } + { deep: true } ) } diff --git a/packages/hoppscotch-common/src/newstore/mockServers.ts b/packages/hoppscotch-common/src/newstore/mockServers.ts index 09441e36..f27e993d 100644 --- a/packages/hoppscotch-common/src/newstore/mockServers.ts +++ b/packages/hoppscotch-common/src/newstore/mockServers.ts @@ -62,6 +62,7 @@ export type CreateMockServerModalData = { const defaultMockServerState = { mockServers: [] as MockServer[], + loading: false, } type MockServerStoreType = typeof defaultMockServerState @@ -73,6 +74,7 @@ const mockServerDispatchers = defineDispatchers({ ) { return { mockServers, + loading: false, } }, @@ -104,6 +106,12 @@ const mockServerDispatchers = defineDispatchers({ mockServers: mockServers.filter((server) => server.id !== id), } }, + + setLoading(_: MockServerStoreType, { loading }: { loading: boolean }) { + return { + loading, + } + }, }) export const mockServerStore = new DispatchingStore( @@ -112,6 +120,7 @@ export const mockServerStore = new DispatchingStore( ) export const mockServers$ = mockServerStore.subject$.pipe(pluck("mockServers")) +export const loading$ = mockServerStore.subject$.pipe(pluck("loading")) export function setMockServers(mockServers: MockServer[]) { mockServerStore.dispatch({ @@ -141,6 +150,13 @@ export function deleteMockServer(id: string) { }) } +export function setLoading(loading: boolean) { + mockServerStore.dispatch({ + dispatcher: "setLoading", + payload: { loading }, + }) +} + // Modal state management const defaultCreateMockServerModalState: CreateMockServerModalData = { show: false, @@ -161,6 +177,7 @@ export function loadMockServers(skip?: number, take?: number) { if (currentWorkspace.type === "team" && currentWorkspace.teamID) { return loadTeamMockServers(currentWorkspace.teamID, skip, take) } + setLoading(true) return pipe( getMyMockServers(skip, take), TE.match( @@ -176,6 +193,7 @@ export function loadMockServers(skip?: number, take?: number) { )() } catch (_error) { // Fallback to user mock servers if workspace service is not available + setLoading(true) return pipe( getMyMockServers(skip, take), TE.match( @@ -198,6 +216,7 @@ export function loadTeamMockServers( skip?: number, take?: number ) { + setLoading(true) return pipe( getTeamMockServers(teamID, skip, take), TE.match(