Skip to content
This repository was archived by the owner on Apr 6, 2022. It is now read-only.

Commit 2789495

Browse files
bors[bot]leplatremmythmon
authored
Merge #568
568: Ref #405 - Show link to Telemetry r=mythmon a=leplatrem Co-authored-by: Mathieu Leplatre <mathieu@mozilla.com> Co-authored-by: Michael Cooper <mythmon@gmail.com> Co-authored-by: Mike Cooper <mythmon@gmail.com>
2 parents 9351427 + 4d7aeca commit 2789495

File tree

7 files changed

+96
-1
lines changed

7 files changed

+96
-1
lines changed

content/components/pages/RecipeDetailsPage.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,13 @@ const RecipeDetailsPage: React.FC = () => {
4343
);
4444

4545
setExperimenterData({
46+
normandySlug: data.normandy_slug,
4647
publicDescription: data.public_description,
4748
proposedStartDate,
4849
proposedDuration: data.proposed_duration,
4950
proposedEndDate,
5051
startDate: data.start_date && new Date(data.start_date),
52+
status: data.status && data.status.toLowerCase(),
5153
endDate: data.end_date && new Date(data.end_date),
5254
variants: data.variants.reduce((acc, v) => {
5355
acc[v.slug] = v.description;

content/components/recipes/details/DetailsHeader.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ import React from "react";
22
import { useHistory, useParams } from "react-router-dom";
33
import { Alert, Button, Icon, IconButton, Popover, Whisper } from "rsuite";
44

5+
import TelemetryLink from "devtools/components/recipes/details/TelemetryLink";
56
import {
67
useSelectedEnvironmentState,
78
useSelectedNormandyEnvironmentAPI,
89
} from "devtools/contexts/environment";
10+
import { useExperimenterDetailsData } from "devtools/contexts/experimenterDetails";
911
import {
1012
ACTION_UPDATE_DATA,
1113
useRecipeDetailsData,
@@ -147,6 +149,11 @@ export default function DetailsHeader() {
147149
);
148150
}
149151

152+
let telemetryLink = null;
153+
if (environment.experimenterUrl && data.experimenter_slug) {
154+
telemetryLink = <TelemetryLink {...useExperimenterDetailsData()} />;
155+
}
156+
150157
let requestApprovalButton = null;
151158
let statusToggleButton = null;
152159
if (!revisionId) {
@@ -234,6 +241,7 @@ export default function DetailsHeader() {
234241
</div>
235242
<div className="d-flex align-items-center text-right">
236243
{viewExperimentButton}
244+
{telemetryLink}
237245
{pauseButton}
238246
{requestApprovalButton}
239247
{statusToggleButton}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import React from "react";
2+
import { Icon, IconButton } from "rsuite";
3+
4+
const MONITORING_URL = "https://grafana.telemetry.mozilla.org";
5+
const DASHBOARD_ID = "XspgvdxZz";
6+
7+
interface TelemetryLinkProps {
8+
endDate?: Date;
9+
normandySlug: string;
10+
startDate?: Date;
11+
status: string;
12+
}
13+
14+
const TelemetryLink: React.FC<TelemetryLinkProps> = ({
15+
startDate,
16+
endDate,
17+
normandySlug,
18+
status,
19+
}) => {
20+
let from = "";
21+
let to = "";
22+
23+
if (startDate && ["live", "complete"].includes(status)) {
24+
from = `${startDate.getTime() - 24 * 3600 * 1000}`;
25+
}
26+
27+
if (endDate && status === "complete") {
28+
to = `${endDate.getTime() + 2 * 24 * 3600 * 1000}`;
29+
}
30+
31+
const url = `${MONITORING_URL}/d/${DASHBOARD_ID}/experiment-enrollment?orgId=1&var-experiment_id=${normandySlug}&from=${from}&to=${to}`;
32+
return (
33+
<IconButton
34+
appearance="subtle"
35+
componentClass="a"
36+
href={url}
37+
icon={<Icon icon="external-link" />}
38+
target="_blank"
39+
>
40+
View Telemetry
41+
</IconButton>
42+
);
43+
};
44+
45+
export default TelemetryLink;

content/contexts/experimenterDetails.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ interface ExperimenterData {
88
startDate?: Date;
99
endDate?: Date;
1010
variants: Record<string, string>;
11+
status: string;
12+
normandySlug: string;
1113
}
1214

1315
interface ExperimenterState {
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { render, cleanup } from "@testing-library/react";
2+
import React from "react";
3+
4+
import TelemetryLink from "devtools/components/recipes/details/TelemetryLink";
5+
6+
afterEach(async () => {
7+
jest.clearAllMocks();
8+
await cleanup();
9+
});
10+
11+
describe("TelemetryLink", () => {
12+
it("should includes dates for complete experiments", () => {
13+
const day = 24 * 3600 * 1000;
14+
const start = new Date(600000000);
15+
const end = new Date(800000000);
16+
17+
const doc = render(
18+
<TelemetryLink
19+
endDate={end}
20+
normandySlug="abc"
21+
startDate={start}
22+
status="complete"
23+
/>,
24+
);
25+
26+
const url = doc.baseElement
27+
.getElementsByTagName("a")[0]
28+
.getAttribute("href");
29+
30+
expect(url).toContain("abc");
31+
expect(url).toContain(`${600000000 - 1 * day}`);
32+
expect(url).toContain(`${800000000 + 2 * day}`);
33+
});
34+
});

content/tests/factories/experiments.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ import { ExperimenterResponse } from "devtools/types/experimenterApi";
55

66
export const experimenterResponseFactory = Factory.fromFields<
77
ExperimenterResponse,
8-
{ generateVariantsCount: number }
8+
{ generateVariantsCount: number; status: string }
99
>({
1010
name: faker.lorem.words(4),
1111
normandy_id: faker.random.number(),
12+
normandy_slug: faker.lorem.word(),
1213
public_description: faker.lorem.sentence(),
1314
proposed_start_date: faker.date.past().getTime(),
1415
proposed_enrollment: faker.random.number(),
@@ -21,4 +22,5 @@ export const experimenterResponseFactory = Factory.fromFields<
2122
slug: faker.lorem.word(),
2223
description: faker.lorem.sentence(),
2324
})),
25+
status: status || "Complete",
2426
});

content/types/experimenterApi.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@ interface Variant {
66
export interface ExperimenterResponse {
77
name: string;
88
normandy_id: number;
9+
normandy_slug: string;
910
proposed_start_date: number;
1011
proposed_duration: number;
1112
proposed_enrollment: number;
1213
public_description: string;
1314
start_date?: number;
1415
end_date?: number;
1516
variants: Variant[];
17+
status: string;
1618
}

0 commit comments

Comments
 (0)