Skip to content

Commit c758961

Browse files
Auzjdorn
andauthored
Show summary of experiment report to users (growthbook#242)
Co-authored-by: Jeremy Dorn <[email protected]>
1 parent 42ef644 commit c758961

File tree

2 files changed

+163
-0
lines changed

2 files changed

+163
-0
lines changed
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
import { FC, useState } from "react";
2+
import {
3+
ExperimentInterfaceStringDates,
4+
ExperimentPhaseStringDates,
5+
} from "back-end/types/experiment";
6+
import { datetime } from "../../services/dates";
7+
import Modal from "../Modal";
8+
import { useDefinitions } from "../../services/DefinitionsContext";
9+
import { ExperimentSnapshotInterface } from "back-end/types/experiment-snapshot";
10+
11+
const FilterSummary: FC<{
12+
experiment: ExperimentInterfaceStringDates;
13+
phase?: ExperimentPhaseStringDates;
14+
snapshot: ExperimentSnapshotInterface;
15+
}> = ({ experiment, phase, snapshot }) => {
16+
const [showExpandedFilter, setShowExpandedFilter] = useState(false);
17+
const hasFilter =
18+
snapshot.segment || snapshot.queryFilter || snapshot.activationMetric;
19+
const { getSegmentById, getMetricById, getDatasourceById } = useDefinitions();
20+
const datasource = getDatasourceById(experiment.datasource);
21+
22+
return (
23+
<>
24+
<span className="text-muted" style={{ fontSize: "0.8em" }}>
25+
<a
26+
href="#"
27+
onClick={(e) => {
28+
e.preventDefault();
29+
setShowExpandedFilter(true);
30+
}}
31+
title={
32+
hasFilter
33+
? "Custom filters applied, click to see"
34+
: "Click to see the report details"
35+
}
36+
>
37+
Report details{hasFilter && "*"}
38+
</a>
39+
</span>
40+
<Modal
41+
header={"Experiment Details and Filters"}
42+
open={showExpandedFilter}
43+
closeCta="Close"
44+
close={() => {
45+
setShowExpandedFilter(false);
46+
}}
47+
size="md"
48+
>
49+
<div className="text-gray">
50+
<div className="row mb-3">
51+
<div className="col-5">
52+
<strong className="text-gray">Tracking Key:</strong>
53+
</div>
54+
<div className="col">{experiment.trackingKey}</div>
55+
</div>
56+
{datasource?.properties?.userIds && (
57+
<div className="row mb-3">
58+
<div className="col-5">
59+
<strong className="text-gray">User Id Type:</strong>
60+
</div>
61+
<div className="col">{experiment.userIdType}</div>
62+
</div>
63+
)}
64+
{phase && (
65+
<div className="row mb-3">
66+
<div className="col-5">
67+
<strong className="text-gray">Date range:</strong>
68+
</div>
69+
<div className="col">
70+
<strong>{datetime(phase.dateStarted)}</strong> to
71+
<br />
72+
<strong>
73+
{datetime(phase.dateEnded || snapshot.dateCreated)}
74+
</strong>
75+
{!phase.dateEnded && " (last update)"}
76+
</div>
77+
</div>
78+
)}
79+
{datasource?.properties?.segments && (
80+
<div className="row mb-3">
81+
<div className="col-5">
82+
<strong className="text-gray">Segment:</strong>
83+
<small className="form-text text-muted">
84+
Only users in this segment are included in analysis
85+
</small>
86+
</div>
87+
<div className="col">
88+
{snapshot.segment ? (
89+
getSegmentById(snapshot.segment)?.name ?? "(unknown)"
90+
) : (
91+
<>
92+
<em>none</em> (all users included)
93+
</>
94+
)}
95+
</div>
96+
</div>
97+
)}
98+
<div className="row mb-3">
99+
<div className="col-5">
100+
<strong className="text-gray">Activation Metric:</strong>
101+
<small className="form-text text-muted">
102+
Users must convert on this metric before being included
103+
</small>
104+
</div>
105+
<div className="col">
106+
{snapshot.activationMetric ? (
107+
getMetricById(snapshot.activationMetric)?.name ?? "(unknown)"
108+
) : (
109+
<em>none</em>
110+
)}
111+
</div>
112+
</div>
113+
<div className="row mb-3">
114+
<div className="col-5">
115+
<strong className="text-gray">Metric Conversions:</strong>
116+
</div>
117+
<div className="col">
118+
{snapshot.skipPartialData
119+
? "Excluding In-Progress Conversions"
120+
: "Including In-Progress Conversions"}
121+
</div>
122+
</div>
123+
<div className="row mb-3">
124+
<div className="col-5">
125+
<strong className="text-gray">
126+
Users in Multiple Variations:
127+
</strong>
128+
</div>
129+
<div className="col">
130+
{experiment.removeMultipleExposures
131+
? "Removed from analysis"
132+
: "Included in analysis"}
133+
</div>
134+
</div>
135+
{datasource?.properties?.queryLanguage === "sql" && (
136+
<div className="row mb-3">
137+
<div className="col-5">
138+
<strong className="text-gray">Custom SQL Filter:</strong>
139+
</div>
140+
<div className="col">
141+
{snapshot.queryFilter ? (
142+
<code>{snapshot.queryFilter}</code>
143+
) : (
144+
<em>none</em>
145+
)}
146+
</div>
147+
</div>
148+
)}
149+
</div>
150+
</Modal>
151+
</>
152+
);
153+
};
154+
155+
export default FilterSummary;

packages/front-end/components/Experiment/Results.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import AnalysisSettingsBar from "./AnalysisSettingsBar";
1717
import ExperimentReportsList from "./ExperimentReportsList";
1818
import usePermissions from "../../hooks/usePermissions";
1919
import { useAuth } from "../../services/auth";
20+
import FilterSummary from "./FilterSummary";
2021

2122
const BreakDownResults = dynamic(() => import("./BreakDownResults"));
2223
const CompactResults = dynamic(() => import("./CompactResults"));
@@ -215,6 +216,13 @@ const Results: FC<{
215216
))}
216217
{hasData && !snapshot.dimension && (
217218
<>
219+
<div className="float-right pr-3">
220+
<FilterSummary
221+
experiment={experiment}
222+
phase={phaseObj}
223+
snapshot={snapshot}
224+
/>
225+
</div>
218226
<CompactResults
219227
id={experiment.id}
220228
isLatestPhase={phase === experiment.phases.length - 1}

0 commit comments

Comments
 (0)