From 706544197215eb463c9cd0ecd104caca922ef39a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Malfait?= Date: Thu, 28 May 2026 12:23:26 +0200 Subject: [PATCH] fix: refresh admin panel feature flags after toggling (#21007) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Add `refetchQueries` to the `updateWorkspaceFeatureFlag` mutation in the admin workspace detail page so the toggle reflects the new value after toggling. - Rename `useFeatureFlagState` → `useAdminUpdateFeatureFlag` since the hook lives under `admin-panel` and is only consumed by the admin workspace detail page. ## Bug In the admin panel, toggling a feature flag for a workspace other than the admin's own workspace sent the backend mutation successfully, but the toggle in the UI remained unchanged. The displayed value is derived from: ```tsx const currentWorkspaceValue = currentWorkspace?.id === workspaceId ? currentWorkspace?.featureFlags?.find((f) => f.key === flag.key)?.value : undefined; const displayedValue = currentWorkspaceValue ?? flag.value; ``` When viewing a different workspace, `currentWorkspaceValue` is `undefined` so the toggle reads `flag.value` from the `WORKSPACE_LOOKUP_ADMIN_PANEL` query. That query was never refetched after the mutation, so the displayed value stayed stale. The existing optimistic Jotai update on `currentWorkspaceState` still runs — it is needed so the rest of the app (anything consuming `useIsFeatureEnabled`) reacts immediately when an admin toggles a flag on their own workspace. ## Test plan - [ ] Open the admin panel → pick a workspace that is not your own → Feature Flags tab → toggle a flag → toggle visually flips after the mutation completes. - [ ] Same flow on your own workspace → toggle flips, and any UI gated on that flag also reacts. - [ ] If the mutation fails, the toggle reverts (existing `onError` rollback path). --- ...useFeatureFlagState.ts => useAdminUpdateFeatureFlag.ts} | 2 +- .../settings/admin-panel/SettingsAdminWorkspaceDetail.tsx | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) rename packages/twenty-front/src/modules/settings/admin-panel/hooks/{useFeatureFlagState.ts => useAdminUpdateFeatureFlag.ts} (94%) diff --git a/packages/twenty-front/src/modules/settings/admin-panel/hooks/useFeatureFlagState.ts b/packages/twenty-front/src/modules/settings/admin-panel/hooks/useAdminUpdateFeatureFlag.ts similarity index 94% rename from packages/twenty-front/src/modules/settings/admin-panel/hooks/useFeatureFlagState.ts rename to packages/twenty-front/src/modules/settings/admin-panel/hooks/useAdminUpdateFeatureFlag.ts index 3eb65af785..3cac29f34d 100644 --- a/packages/twenty-front/src/modules/settings/admin-panel/hooks/useFeatureFlagState.ts +++ b/packages/twenty-front/src/modules/settings/admin-panel/hooks/useAdminUpdateFeatureFlag.ts @@ -3,7 +3,7 @@ import { useAtomState } from '@/ui/utilities/state/jotai/hooks/useAtomState'; import { isDefined } from 'twenty-shared/utils'; import { type FeatureFlagKey } from '~/generated-admin/graphql'; -export const useFeatureFlagState = () => { +export const useAdminUpdateFeatureFlag = () => { const [currentWorkspace, setCurrentWorkspace] = useAtomState( currentWorkspaceState, ); diff --git a/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminWorkspaceDetail.tsx b/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminWorkspaceDetail.tsx index 2f49b6fb4b..a2f82505fe 100644 --- a/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminWorkspaceDetail.tsx +++ b/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminWorkspaceDetail.tsx @@ -16,7 +16,7 @@ import { SettingsAdminWorkspaceContent } from '@/settings/admin-panel/components import { SettingsSectionSkeletonLoader } from '@/settings/components/SettingsSectionSkeletonLoader'; import { GET_ADMIN_WORKSPACE_CHAT_THREADS } from '@/settings/admin-panel/graphql/queries/getAdminWorkspaceChatThreads'; import { WORKSPACE_LOOKUP_ADMIN_PANEL } from '@/settings/admin-panel/graphql/queries/workspaceLookupAdminPanel'; -import { useFeatureFlagState } from '@/settings/admin-panel/hooks/useFeatureFlagState'; +import { useAdminUpdateFeatureFlag } from '@/settings/admin-panel/hooks/useAdminUpdateFeatureFlag'; import { useHandleImpersonate } from '@/settings/admin-panel/hooks/useHandleImpersonate'; import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; import { SettingsSkeletonLoader } from '@/settings/components/SettingsSkeletonLoader'; @@ -78,10 +78,13 @@ export const SettingsAdminWorkspaceDetail = () => { const isBillingEnabled = billing?.isBillingEnabled ?? false; const canManageFeatureFlags = useAtomStateValue(canManageFeatureFlagsState); const { enqueueErrorSnackBar } = useSnackBar(); - const { updateFeatureFlagState } = useFeatureFlagState(); + const { updateFeatureFlagState } = useAdminUpdateFeatureFlag(); const { handleImpersonate, impersonatingUserId } = useHandleImpersonate(); const [updateFeatureFlag] = useMutation(UpdateWorkspaceFeatureFlagDocument, { client: apolloAdminClient, + refetchQueries: [ + { query: WORKSPACE_LOOKUP_ADMIN_PANEL, variables: { workspaceId } }, + ], }); const { data: workspaceData, loading: isLoadingWorkspace } =