Skip to content
Draft
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
5 changes: 3 additions & 2 deletions apps/studio/src/components/content-tab-assistant.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import { StudioCodeChat } from 'src/components/studio-code-chat';
import WelcomeComponent from 'src/components/welcome-message-prompt';
import { LIMIT_OF_PROMPTS_PER_USER, TELEX_HOSTNAME, TELEX_UTM_PARAMS } from 'src/constants';
import { useAuth } from 'src/hooks/use-auth';
import { useFeatureFlags } from 'src/hooks/use-feature-flags';
import { useOffline } from 'src/hooks/use-offline';
import { useThemeDetails } from 'src/hooks/use-theme-details';
import { cx } from 'src/lib/cx';
Expand Down Expand Up @@ -359,7 +358,9 @@ const UnauthenticatedView = ( { onAuthenticate }: { onAuthenticate: () => void }
);

export function ContentTabAssistant( { selectedSite }: ContentTabAssistantProps ) {
const { enableStudioCodeUi } = useFeatureFlags();
const enableStudioCodeUi = useRootSelector(
( state ) => state.betaFeatures.features.enableStudioCodeUi
);

if ( enableStudioCodeUi ) {
return <StudioCodeChat selectedSite={ selectedSite } />;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ const snapshotTestActions = {
let testStore = createTestStore( {
preloadedState: {
betaFeatures: {
features: {},
features: {
enableStudioCodeUi: false,
},
loading: false,
},
},
Expand All @@ -49,7 +51,9 @@ function createCustomTestStore() {
const store = createTestStore( {
preloadedState: {
betaFeatures: {
features: {},
features: {
enableStudioCodeUi: false,
},
loading: false,
},
},
Expand Down
6 changes: 3 additions & 3 deletions apps/studio/src/ipc-types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,11 @@ type IpcApi = {

interface FeatureFlags {
enableBlueprints: boolean;
enableStudioCodeUi: boolean;
}

// eslint-disable-next-line @typescript-eslint/no-empty-object-type
interface BetaFeatures {}
interface BetaFeatures {
enableStudioCodeUi: boolean;
}

interface AppGlobals extends FeatureFlags {
platform: NodeJS.Platform;
Expand Down
18 changes: 13 additions & 5 deletions apps/studio/src/lib/beta-features.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { __ } from '@wordpress/i18n';
import { lockAppdata, unlockAppdata, loadUserData, saveUserData } from 'src/storage/user-data';

export interface BetaFeatureDefinition {
Expand All @@ -10,14 +11,23 @@ export interface BetaFeatureDefinition {
/**
* Default values for beta features.
*/
const BETA_FEATURE_DEFAULTS: Record< keyof BetaFeatures, boolean > = {};
const BETA_FEATURE_DEFAULTS: Record< keyof BetaFeatures, boolean > = {
enableStudioCodeUi: false,
};

/**
* Returns beta feature definitions with translated labels and descriptions.
* Must be called at runtime (not at module load) to ensure translations are loaded.
*/
export function getBetaFeaturesDefinition(): Record< keyof BetaFeatures, BetaFeatureDefinition > {
return {};
return {
enableStudioCodeUi: {
label: __( 'Studio Code Desktop' ),
key: 'enableStudioCodeUi',
default: false,
description: __( 'Try the new Studio Code Desktop assistant.' ),
},
};
}

function buildBetaFeatures( userData: BetaFeatures | undefined ): BetaFeatures {
Expand All @@ -26,7 +36,7 @@ function buildBetaFeatures( userData: BetaFeatures | undefined ): BetaFeatures {
keys.forEach( ( key ) => {
features[ key ] = userData?.[ key ] ?? BETA_FEATURE_DEFAULTS[ key ];
} );
return features;
return features as BetaFeatures;
}

export async function getBetaFeatures(): Promise< BetaFeatures > {
Expand All @@ -42,8 +52,6 @@ export async function updateBetaFeature(
await lockAppdata();
const userData = await loadUserData();
const betaFeatures = await getBetaFeatures();
// @ts-expect-error If `BetaFeatures` is empty, `key` will be `never`, and we cannot use it to
// assign to`betaFeatures`.That's fine. Just rely on type checking when this function is called.
betaFeatures[ key ] = value;
userData.betaFeatures = betaFeatures;
await saveUserData( userData );
Expand Down
6 changes: 0 additions & 6 deletions apps/studio/src/lib/feature-flags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,6 @@ export const FEATURE_FLAGS: Record< keyof FeatureFlags, FeatureFlagDefinition >
flag: 'enableBlueprints',
default: true,
},
enableStudioCodeUi: {
label: 'Enable Studio Code UI',
env: 'ENABLE_STUDIO_CODE_UI',
flag: 'enableStudioCodeUi',
default: false,
},
} as const;

export function getFeatureFlagFromEnv( flag: keyof FeatureFlags ): boolean {
Expand Down
2 changes: 1 addition & 1 deletion apps/studio/src/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ async function getAppMenu(
{
label: __( 'Beta Features' ),
submenu: betaFeaturesMenu,
enabled: false,
enabled: betaFeaturesMenu.length > 0,
},
{ type: 'separator' },
...( process.platform === 'win32'
Expand Down
4 changes: 3 additions & 1 deletion apps/studio/src/stores/beta-features-slice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ type BetaFeaturesState = {
};

const initialState: BetaFeaturesState = {
features: {},
features: {
enableStudioCodeUi: false,
},
loading: false,
};

Expand Down