diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 0f793be915..4d61a094a0 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -86,6 +86,7 @@ import PasswordExpired from './pages/PasswordExpired.vue' import TermsAndConditions from './pages/TermsAndConditions.vue' import UnverifiedEmail from './pages/UnverifiedEmail.vue' +import product from '@/services/product.js' import { useAccountAuthStore } from '@/stores/account-auth.js' import { useAccountSettingsStore } from '@/stores/account-settings.js' import { useContextStore } from '@/stores/context.js' @@ -118,7 +119,7 @@ export default { ...mapState(useAccountAuthStore, ['user']), ...mapState(useUxLoadingStore, ['appLoader', 'offline']), ...mapState(useAccountSettingsStore, ['settings']), - ...mapState(useContextStore, ['instance', 'device']), + ...mapState(useContextStore, ['instance', 'device', 'team']), pageTitleSignal () { return [this.instance?.id, this.instance?.name, this.device?.id, this.device?.name, this.$route.name] }, @@ -168,6 +169,21 @@ export default { const title = computePageTitle(this.$route, { instance: this.instance, device: this.device }) if (title) document.title = title } + }, + 'team.id': { + immediate: true, + handler (teamId, oldTeamId) { + // PostHog evaluates its flags as soon as it initialises, before we know + // which team the user is in - so anything targeting the team group comes + // back false. On a hard refresh the team is rehydrated from sessionStorage + // and account.setTeam early-returns, so nothing ever tells PostHog about + // it. Registering the group here triggers a re-evaluation. First team of + // this page load only: real team switches already go through + // product.setTeam. + if (!oldTeamId && teamId) { + product.setTeam(this.team) + } + } } }, mounted () { diff --git a/test/unit/frontend/stores/account-settings.spec.js b/test/unit/frontend/stores/account-settings.spec.js index b9b88e9176..40b466f31c 100644 --- a/test/unit/frontend/stores/account-settings.spec.js +++ b/test/unit/frontend/stores/account-settings.spec.js @@ -43,6 +43,7 @@ describe('account-settings store', () => { beforeEach(() => { setActivePinia(createPinia()) vi.clearAllMocks() + delete window.posthog mockAuth() mockTeam() }) @@ -83,6 +84,26 @@ describe('account-settings store', () => { expect(store.features).toEqual({ billing: true }) }) }) + + describe('loadPosthogFlags', () => { + it('stores the flag values PostHog reports', () => { + const onFeatureFlags = vi.fn((cb) => cb(['MCP_THIRD_PARTY'], { MCP_THIRD_PARTY: true })) + window.posthog = { onFeatureFlags } + + const store = useAccountSettingsStore() + store.loadPosthogFlags() + + expect(store.posthogFlags).toEqual({ MCP_THIRD_PARTY: true }) + }) + + it('does not throw when PostHog is unavailable', () => { + delete window.posthog + + const store = useAccountSettingsStore() + expect(() => store.loadPosthogFlags()).not.toThrow() + expect(store.posthogFlags).toEqual({}) + }) + }) }) describe('getters', () => {