Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 7 additions & 10 deletions src/App.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
<template>
<WorkspaceAuthGate>
<router-view />
<ProgressSpinner
v-if="isLoading"
class="absolute inset-0 flex h-[unset] items-center justify-center"
/>
<GlobalDialog />
<BlockUI full-screen :blocked="isLoading" />
</WorkspaceAuthGate>
<router-view />
<ProgressSpinner
v-if="isLoading"
class="absolute inset-0 flex h-[unset] items-center justify-center"
/>
<GlobalDialog />
<BlockUI full-screen :blocked="isLoading" />
</template>

<script setup lang="ts">
Expand All @@ -16,7 +14,6 @@ import BlockUI from 'primevue/blockui'
import ProgressSpinner from 'primevue/progressspinner'
import { computed, onMounted } from 'vue'

import WorkspaceAuthGate from '@/components/auth/WorkspaceAuthGate.vue'
import GlobalDialog from '@/components/dialog/GlobalDialog.vue'
import config from '@/config'
import { t } from '@/i18n'
Expand Down
11 changes: 7 additions & 4 deletions src/components/auth/WorkspaceAuthGate.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
import { promiseTimeout, until } from '@vueuse/core'
import { storeToRefs } from 'pinia'
import ProgressSpinner from 'primevue/progressspinner'
import { ref } from 'vue'
import { onMounted, ref } from 'vue'

import { useFeatureFlags } from '@/composables/useFeatureFlags'
import { isCloud } from '@/platform/distribution/types'
Expand Down Expand Up @@ -120,7 +120,10 @@ async function initializeWorkspaceMode(): Promise<void> {
}
}

// Start initialization immediately during component setup
// (not in onMounted, so initialization starts before DOM is ready)
void initialize()
// Initialize on mount. This gate should be placed on the authenticated layout
// (LayoutDefault) so it mounts fresh after login and unmounts on logout.
// The router guard ensures only authenticated users reach this layout.
onMounted(() => {
void initialize()
})
</script>
7 changes: 4 additions & 3 deletions src/extensions/core/cloudRemoteConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,16 @@ useExtensionService().registerExtension({
const { isLoggedIn } = useCurrentUser()
const { isActiveSubscription } = useSubscription()

// Refresh config when subscription status changes
// Initial auth-aware refresh happens in WorkspaceAuthGate before app renders
// Refresh config when auth or subscription status changes
// Primary auth refresh is handled by WorkspaceAuthGate on mount
// This watcher handles subscription changes and acts as a backup for auth
watchDebounced(
[isLoggedIn, isActiveSubscription],
() => {
if (!isLoggedIn.value) return
void refreshRemoteConfig()
},
{ debounce: 256 }
{ debounce: 256, immediate: true }
)

// Poll for config updates every 10 minutes (with auth)
Expand Down
10 changes: 7 additions & 3 deletions src/views/layouts/LayoutDefault.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
<template>
<main class="relative h-full w-full overflow-hidden">
<router-view />
</main>
<WorkspaceAuthGate>
<main class="relative h-full w-full overflow-hidden">
<router-view />
</main>
</WorkspaceAuthGate>
</template>

<script setup lang="ts">
import { useFavicon } from '@vueuse/core'

import WorkspaceAuthGate from '@/components/auth/WorkspaceAuthGate.vue'

useFavicon('/assets/favicon.ico')
</script>
Loading