Skip to content

Commit 820f7cd

Browse files
committed
AXON-144: added experiment support in atlascode
1 parent 734f180 commit 820f7cd

File tree

5 files changed

+86
-7
lines changed

5 files changed

+86
-7
lines changed

src/lib/ipc/toUI/common.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@ export enum CommonMessageType {
55
OnlineStatus = 'onlineStatus',
66
PMFStatus = 'pmfStatus',
77
UpdateFeatureFlags = 'updateFeatureFlags',
8+
UpdateExperimentValues = 'updateExperimentValues',
89
}
910

1011
export type CommonMessage =
1112
| ReducerAction<CommonMessageType.Error, HostErrorMessage>
1213
| ReducerAction<CommonMessageType.OnlineStatus, OnlineStatusMessage>
1314
| ReducerAction<CommonMessageType.PMFStatus, PMFMessage>
14-
| ReducerAction<CommonMessageType.UpdateFeatureFlags, UpdateFeatureFlagsMessage>;
15+
| ReducerAction<CommonMessageType.UpdateFeatureFlags, UpdateFeatureFlagsMessage>
16+
| ReducerAction<CommonMessageType.UpdateExperimentValues, UpdateExperimentValuesMessage>;
1517

1618
export interface HostErrorMessage {
1719
reason: string;
@@ -28,3 +30,7 @@ export interface PMFMessage {
2830
export interface UpdateFeatureFlagsMessage {
2931
featureFlags: { [key: string]: boolean };
3032
}
33+
34+
export interface UpdateExperimentValuesMessage {
35+
experimentValues: { [key: string]: any };
36+
}

src/react/atlascode/onboarding/OnboardingPage.tsx

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { CommonMessageType } from 'src/lib/ipc/toUI/common';
2121
import { OnboardingActionType } from 'src/lib/ipc/fromUI/onboarding';
2222
import { JiraOnboarding } from './JiraOnboarding';
2323
import { BitbucketOnboarding } from './BitbucketOnboarding';
24+
import { Experiments } from 'src/util/featureFlags/features';
2425

2526
const useStyles = makeStyles((theme: Theme) => ({
2627
root: {
@@ -61,6 +62,7 @@ export const OnboardingPage: React.FunctionComponent = () => {
6162
const { authDialogController, authDialogOpen, authDialogProduct, authDialogEntry } = useAuthDialog();
6263
const [activeStep, setActiveStep] = React.useState(0);
6364
const [useAuthUI, setUseAuthUI] = React.useState(false);
65+
const [useAuthExperiment, setUseAuthExperiment] = React.useState(false);
6466
const [jiraSignInText, setJiraSignInText] = useState('Sign In to Jira Cloud');
6567
const [bitbucketSignInText, setBitbucketSignInText] = useState('Sign In to Bitbucket Cloud');
6668
const [jiraSignInFlow, setJiraSignInFlow] = useState(jiraValueSet.cloud);
@@ -72,9 +74,21 @@ export const OnboardingPage: React.FunctionComponent = () => {
7274
if (message.command === CommonMessageType.UpdateFeatureFlags) {
7375
const featureValue = message.featureFlags[Features.EnableAuthUI];
7476
setUseAuthUI(featureValue);
77+
} else if (message.command === CommonMessageType.UpdateExperimentValues) {
78+
let experimentValue: boolean;
79+
try {
80+
experimentValue = message.experimentValues[Experiments.NewAuthUIAA] as boolean;
81+
} catch {
82+
controller.postMessage({
83+
type: OnboardingActionType.Error,
84+
error: new Error(`Experiment value not found`),
85+
});
86+
experimentValue = false;
87+
}
88+
setUseAuthExperiment(experimentValue);
7589
}
7690
});
77-
}, []);
91+
}, [controller]);
7892
function getSteps() {
7993
if (useAuthUI) {
8094
return ['Setup Jira', 'Setup BitBucket', 'Explore'];
@@ -362,7 +376,7 @@ export const OnboardingPage: React.FunctionComponent = () => {
362376
padding: '24px',
363377
}}
364378
>
365-
{useAuthUI ? authUI_v1 : oldAuthUI}
379+
{useAuthUI && useAuthExperiment ? authUI_v1 : oldAuthUI}
366380
</Box>
367381
</div>
368382
</Container>

src/util/featureFlags/client.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { AnalyticsClient } from '../../analytics-node-client/src/client.min';
22

33
import FeatureGates, { FeatureGateEnvironment, Identifiers } from '@atlaskit/feature-gate-js-client';
44
import { AnalyticsClientMapper, EventBuilderInterface } from './analytics';
5-
import { Features } from './features';
5+
import { ExperimentGates, Experiments, Features } from './features';
66

77
export type FeatureFlagClientOptions = {
88
analyticsClient: AnalyticsClient;
@@ -66,6 +66,22 @@ export class FeatureFlagClient {
6666
return gateValue;
6767
}
6868

69+
public static checkExperimentValue(experiment: string): any {
70+
let gateValue: any = undefined;
71+
if (FeatureGates === null) {
72+
console.warn('FeatureGates: FeatureGates is not initialized. Defaulting to Undefined');
73+
} else {
74+
console.log(ExperimentGates[experiment]);
75+
gateValue = FeatureGates.getExperimentValue(
76+
ExperimentGates[experiment].gate,
77+
ExperimentGates[experiment].parameter,
78+
ExperimentGates[experiment].defaultValue,
79+
);
80+
}
81+
console.log(`ExperimentGateValue: ${experiment} -> ${gateValue}`);
82+
return gateValue;
83+
}
84+
6985
public static async evaluateFeatures() {
7086
const featureFlags = await Promise.all(
7187
Object.values(Features).map(async (feature) => {
@@ -78,4 +94,16 @@ export class FeatureFlagClient {
7894

7995
return featureFlags.reduce((acc, val) => ({ ...acc, ...val }), {});
8096
}
97+
98+
public static async evaluateExperiments() {
99+
const experimentGates = await Promise.all(
100+
Object.values(Experiments).map(async (experiment) => {
101+
return {
102+
[experiment]: await this.checkExperimentValue(experiment),
103+
};
104+
}),
105+
);
106+
107+
return experimentGates.reduce((acc, val) => ({ ...acc, ...val }), {});
108+
}
81109
}

src/util/featureFlags/features.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,23 @@ export enum Features {
22
EnableNewUriHandler = 'atlascode-enable-new-uri-handler',
33
EnableAuthUI = 'atlascode-enable-auth-ui',
44
}
5+
6+
export enum Experiments {
7+
NewAuthUI = 'atlascode_new_auth_ui',
8+
NewAuthUIAA = 'atlascode_new_auth_ui_aa',
9+
}
10+
11+
export const ExperimentGates: ExperimentGate = {
12+
[Experiments.NewAuthUI]: {
13+
gate: 'atlascode_new_auth_ui',
14+
parameter: 'isEnabled',
15+
defaultValue: false,
16+
},
17+
[Experiments.NewAuthUIAA]: {
18+
gate: 'atlascode_new_auth_ui_aa',
19+
parameter: 'isEnabled',
20+
defaultValue: `bruh`,
21+
},
22+
};
23+
24+
type ExperimentGate = { [key: string]: { gate: string; parameter: string; defaultValue: any } };

src/webview/singleViewFactory.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,20 @@ export class SingleWebview<FD, R> implements ReactWebview<FD> {
133133
}
134134

135135
// Send feature gates to the panel in a message
136-
const featureFlags = await FeatureFlagClient.evaluateFeatures();
137-
console.log(`FeatureGates: sending ${JSON.stringify(featureFlags)}`);
138-
this.postMessage({ command: CommonMessageType.UpdateFeatureFlags, featureFlags: featureFlags });
136+
this.fireFeatureGates();
137+
this.fireExperimentGates();
138+
}
139+
140+
private async fireFeatureGates() {
141+
const featureGates = await FeatureFlagClient.evaluateFeatures();
142+
console.log(`FeatureGates: sending ${JSON.stringify(featureGates)}`);
143+
this.postMessage({ command: CommonMessageType.UpdateFeatureFlags, featureFlags: featureGates });
144+
}
145+
146+
private async fireExperimentGates() {
147+
const experimentValues = await FeatureFlagClient.evaluateExperiments();
148+
console.log(`ExperimentValues: sending ${JSON.stringify(experimentValues)}`);
149+
this.postMessage({ command: CommonMessageType.UpdateExperimentValues, experimentValues });
139150
}
140151

141152
private onViewStateChanged(e: WebviewPanelOnDidChangeViewStateEvent) {

0 commit comments

Comments
 (0)