123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- import {Component} from 'react';
- import {experimentConfig, unassignedValue} from 'sentry/data/experimentConfig';
- import ConfigStore from 'sentry/stores/configStore';
- import {Organization} from 'sentry/types';
- import {
- ExperimentAssignment,
- ExperimentKey,
- Experiments,
- ExperimentType,
- OrgExperiments,
- UserExperiments,
- } from 'sentry/types/experiments';
- import {logExperiment} from 'sentry/utils/analytics';
- import getDisplayName from 'sentry/utils/getDisplayName';
- type Options<E extends ExperimentKey, L extends boolean> = {
-
- experiment: E;
-
- injectLogExperiment?: L;
- };
- type ExpectedProps<T extends ExperimentType> = T extends 'organization'
- ? {organization: Organization}
- : {};
- type InjectedExperimentProps<E extends ExperimentKey, L extends boolean> = {
-
- experimentAssignment: ExperimentAssignment[E];
- } & (L extends true ? LogExperimentProps : {});
- type LogExperimentProps = {
-
- logExperiment: () => void;
- };
- function withExperiment<
- E extends ExperimentKey,
- L extends boolean,
- P extends InjectedExperimentProps<E, L>
- >(
- ExperimentComponent: React.ComponentType<P>,
- {experiment, injectLogExperiment}: Options<E, L>
- ) {
- type Props = Omit<P, keyof InjectedExperimentProps<E, L>> &
- ExpectedProps<Experiments[E]['type']>;
- return class extends Component<Props> {
- static displayName = `withExperiment[${experiment}](${getDisplayName(
- ExperimentComponent
- )})`;
-
-
-
-
-
-
-
-
- componentDidMount() {
- if (!injectLogExperiment) {
- this.logExperiment();
- }
- }
- getProps<Q extends ExperimentType>() {
- return this.props as unknown as ExpectedProps<Q>;
- }
- get config() {
- return experimentConfig[experiment];
- }
- get experimentAssignment() {
- const {type} = this.config;
- if (type === ExperimentType.Organization) {
- const key = experiment as keyof OrgExperiments;
- return this.getProps<typeof type>().organization.experiments[key];
- }
- if (type === ExperimentType.User) {
- const key = experiment as keyof UserExperiments;
- return ConfigStore.get('user').experiments[key];
- }
- return unassignedValue;
- }
- logExperiment = () =>
- logExperiment({
- key: experiment,
- organization: this.getProps<ExperimentType.Organization>().organization,
- });
- render() {
- const WrappedComponent = ExperimentComponent as React.JSXElementConstructor<any>;
- const props = {
- experimentAssignment: this.experimentAssignment,
- ...(injectLogExperiment ? {logExperiment: this.logExperiment} : {}),
- ...this.props,
- } as unknown;
- return <WrappedComponent {...(props as P)} />;
- }
- };
- }
- export default withExperiment;
|