136 lines
3.9 KiB
JavaScript
Executable file
136 lines
3.9 KiB
JavaScript
Executable file
import React from 'react';
|
|
import Flux from '../../lib/flux';
|
|
import PureRenderMixin from 'react-addons-pure-render-mixin';
|
|
import {FormSection, FormDivider, FormText, FormTextTypes, FormTitle, FormTitleTags, FormItem} from '../../uikit/form';
|
|
import Flex from '../../uikit/Flex';
|
|
import Select from '../../uikit/Select';
|
|
import ExperimentActionCreators from '../../actions/ExperimentActionCreators';
|
|
import ExperimentStore from '../../stores/ExperimentStore';
|
|
import {ExperimentBuckets} from '../../Constants';
|
|
|
|
const UserSettingsModalExperiments = React.createClass({
|
|
mixins: [PureRenderMixin, Flux.LazyStoreListenerMixin(ExperimentStore)],
|
|
|
|
getInitialState() {
|
|
return this.getStateFromStores();
|
|
},
|
|
|
|
getStateFromStores() {
|
|
return {
|
|
experiments: ExperimentStore.getRegisteredExperiments(),
|
|
overrides: ExperimentStore.getExperimentOverrides(),
|
|
};
|
|
},
|
|
|
|
renderExperimentGroup(id, i) {
|
|
const experimentGroup = this.state.experiments[id];
|
|
|
|
let {description} = experimentGroup;
|
|
if (!Array.isArray(description)) {
|
|
description = [description];
|
|
}
|
|
description = description.map((part, i) => {
|
|
return <FormText type={FormTextTypes.DESCRIPTION} key={i}>{part}</FormText>;
|
|
});
|
|
|
|
return (
|
|
<div key={i} className="margin-top-20">
|
|
<FormSection key={id}>
|
|
<FormTitle tag={FormTitleTags.H3} className="margin-bottom-8">{experimentGroup.title}</FormTitle>
|
|
{this.renderExperimentTypes(id, experimentGroup.experiments)}
|
|
<div className="margin-top-4">{description}</div>
|
|
</FormSection>
|
|
<FormDivider className="margin-top-40 margin-bottom-20" />
|
|
</div>
|
|
);
|
|
},
|
|
|
|
renderExperimentTypes(id, experiments) {
|
|
const types = Object.keys(experiments);
|
|
const override = this.state.overrides[id];
|
|
|
|
return (
|
|
<Flex>
|
|
<Flex.Child>
|
|
<FormItem title="Type Override">
|
|
<Select
|
|
value={override ? override.type : ''}
|
|
clearable={true}
|
|
searchable={false}
|
|
options={this.getExperimentTypes(types)}
|
|
onChange={option => ExperimentActionCreators.overrideType(id, option && option.value)}
|
|
/>
|
|
</FormItem>
|
|
</Flex.Child>
|
|
<Flex.Child>
|
|
<FormItem title="Bucket Override">
|
|
<Select
|
|
value={override ? override.bucket : ''}
|
|
disabled={!override || !override.type}
|
|
clearable={true}
|
|
searchable={false}
|
|
options={this.getExperimentBuckets(experiments[override ? override.type : ''])}
|
|
onChange={option => ExperimentActionCreators.overrideBucket(id, option && option.value)}
|
|
/>
|
|
</FormItem>
|
|
</Flex.Child>
|
|
</Flex>
|
|
);
|
|
},
|
|
|
|
getExperimentTypes(types) {
|
|
return types.map(type => ({
|
|
label: type.charAt(0).toUpperCase() + type.slice(1),
|
|
value: type,
|
|
}));
|
|
},
|
|
|
|
getExperimentBuckets(buckets = []) {
|
|
return buckets.map(bucket => {
|
|
let label;
|
|
|
|
if (bucket === ExperimentBuckets.CONTROL) {
|
|
label = 'Control';
|
|
} else if (bucket === ExperimentBuckets.NOT_ELIGIBLE) {
|
|
label = 'Not Eligible';
|
|
} else {
|
|
label = `Treatment ${bucket}`;
|
|
}
|
|
|
|
return {
|
|
label,
|
|
value: bucket,
|
|
};
|
|
});
|
|
},
|
|
|
|
renderEmpty() {
|
|
return (
|
|
<FormSection>
|
|
<FormText>No Experiments are currently running</FormText>
|
|
</FormSection>
|
|
);
|
|
},
|
|
|
|
render() {
|
|
const experiments = Object.keys(this.state.experiments);
|
|
let children;
|
|
if (experiments.length) {
|
|
children = experiments.map(this.renderExperimentGroup);
|
|
} else {
|
|
children = this.renderEmpty();
|
|
}
|
|
return (
|
|
<FormSection tag={FormTitleTags.H2} title="Experiments">
|
|
{children}
|
|
</FormSection>
|
|
);
|
|
},
|
|
});
|
|
|
|
export default UserSettingsModalExperiments;
|
|
|
|
|
|
|
|
// WEBPACK FOOTER //
|
|
// ./discord_app/components/user_settings/UserSettingsExperiments.js
|