Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
eff4420
Update TODO list
dmose Mar 23, 2025
374cd7a
Add basic instructions for copilot case sensitivity.
dmose Mar 23, 2025
ead3234
Refactor page.tsx to call fetchData and pass params
dmose Mar 23, 2025
98576f8
Fixup Android calling of Dashboard component.
dmose Mar 23, 2025
66f3f86
Made localData optional to Dashboard component
dmose Mar 23, 2025
cd8a8b5
Make the file case instructions clearer
dmose Mar 23, 2025
76fa477
Fixup dashboard test
dmose Mar 23, 2025
758d0ae
Move platform to a union type
dmose Mar 23, 2025
c53a3aa
Refactor fetchData to its own file
dmose Mar 23, 2025
dec5807
Renamed fetchData.tsx to fetchData.ts
dmose Mar 23, 2025
46ae4b3
Export compareDatesFn to fix the app
dmose Mar 23, 2025
6be99d2
Remove obsolete fetchData.tsx
dmose Mar 23, 2025
b3794cd
Move getASRouterLocalMessageIntoFromFile to fetchData.ts
dmose Mar 23, 2025
a44bd0f
Move getASRouterLocalColumnFromJSON to fetchData.ts
dmose Mar 23, 2025
dc31513
Remove extra copy of getMsgExpRecipeCollection from dashboard.tsx
dmose Mar 23, 2025
19484fc
Remove dead code
dmose Mar 23, 2025
afc6501
Move appendFxMSTelemetryData to fetchData.ts
dmose Mar 23, 2025
d915b0f
Move functions to fetchData and clean up
dmose Mar 23, 2025
5f2f2b7
Appease prettier
dmose Mar 23, 2025
5365958
Update comment about fetchData file home
dmose Mar 23, 2025
56d6fd3
Formatting tweaks
dmose Mar 23, 2025
ca9ab23
Update TODO list
dmose Mar 23, 2025
96aaed6
Flesh out Android standup plan
dmose Mar 23, 2025
0157aad
Minor TODO update
dmose Mar 24, 2025
88614f0
Add WIP MOBILE-EPICS list
dmose Mar 24, 2025
6b8cdfb
Update mobile epics
dmose Mar 24, 2025
ce82b5a
Appease prettier
dmose Mar 24, 2025
d093b8b
Create platformInfo object
dmose Mar 25, 2025
c24d048
Added a test to check for correct URL construction
dmose Mar 26, 2025
3c1e9c5
Move experiments path component to a more sensible env var
dmose Mar 26, 2025
601d3cd
Standarize platform typing to the nimbus platform slug strings
dmose Mar 26, 2025
d0e1f07
Fix platformDisplayName use
dmose Mar 26, 2025
5eb6134
Remove some env vars for modularity
dmose Mar 27, 2025
ae61832
Appease prettier
dmose Mar 27, 2025
312b432
Add in a couple of mobile surfaces
dmose Mar 27, 2025
d32f0b7
Make fetchData for mobile default to live
dmose Mar 30, 2025
cb93e41
Add some mobile surfaces + getAndroidBranchInfo
dmose Mar 30, 2025
12b9157
Update TODO and EPICS
dmose Mar 30, 2025
40f431b
Add dashboard link and update TODO/EPICS
dmose Mar 31, 2025
771d840
Disable dashboard where it's not yet work
dmose Mar 31, 2025
f4725d2
Update MOBILE-EPICS.md
dmose Apr 8, 2025
07aad9d
Appease prettier
dmose Apr 8, 2025
c58a8c0
Merge branch 'main' into 2android
dmose Apr 10, 2025
9ef4703
Merge branch 'main' into 2android
dmose Apr 11, 2025
f08fe1a
Update EPICs
dmose Apr 11, 2025
b57e061
prettier
dmose Apr 11, 2025
6c34a6a
Update MOBILE-EPICS
sarahhjchung Apr 17, 2025
5e4290a
Add notes on onboarding dashboard in MOBILE-EPICS
sarahhjchung Apr 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 1 addition & 10 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,7 @@

# Base URL for the experimenter API (defaults to the production instance)
#
EXPERIMENTER_API_PREFIX="https://experimenter.services.mozilla.com/api/v7/"

# API calls with parameters to fetch experiments we want to display.
# https://htmlpreview.github.io/?https://github.com/mozilla/experimenter/blob/main/docs/experimenter/swagger-ui.html has more info.
#
# Live experiments
EXPERIMENTER_API_CALL_LIVE="experiments/?status=Live&application=firefox-desktop"

# Completed experiments
EXPERIMENTER_API_CALL_COMPLETED="experiments/?status=Complete&application=firefox-desktop"
EXPERIMENTER_API_PREFIX="https://experimenter.services.mozilla.com/api/v7/experiments/"

# Looker configurables
IS_LOOKER_ENABLED=false
Expand Down
5 changes: 3 additions & 2 deletions .env.sample
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# Copy this to .env.local to set local variables

# Preview
# EXPERIMENTER_API_CALL="experiments/?status=Preview&application=firefox-desktop"
# Base URL for the experimenter API (defaults to the production instance)
#
EXPERIMENTER_API_PREFIX="https://experimenter.services.mozilla.com/api/v7/experiments/"

# Disable Auth0 for dev && preview environments
IS_AUTH_ENABLED='false'
Expand Down
25 changes: 25 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# GitHub Copilot Instructions

## Case-Sensitive Filesystem

Some of our development happens on a case-sensitive filesystem. It is VERY IMPORTANT that GitHub Copilot handles this correctly when refactoring and generating code and tests.

### Guidelines

1. **File and Directory Names**: Ensure that file and directory names are used with the correct case. For example, `MyFile.ts` and `myfile.ts` are different files on a case-sensitive filesystem.
2. **Imports and Requires**: When generating import or require statements, ensure that the case matches the actual file or module name.
3. **Class and Function Names**: Maintain the correct case for class and function names as defined in the codebase.
4. **Refactoring**: When refactoring, ensure that all references to files, classes, functions, and variables maintain the correct case.

### Specific Instructions for Component Files

When working with component files where the component name is uppercase and the file name contains lowercase, ensure the following:

1. **Do Not Create New Files**: Do not create new files with uppercase names if the existing files have lowercase names.
2. **Correct File Names**: Use the existing files with the correct case.
3. **Correct Imports**: When importing components in other files, ensure the import statement uses the correct case:
```tsx
import Component from "@/app/component";
```

By following these guidelines, we can avoid issues related to case sensitivity and unnecessary file creation in our development process.
25 changes: 25 additions & 0 deletions .github/copilot-test-generation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# GitHub Copilot Instructions

## Case-Sensitive Filesystem

Some of our development happens on a case-sensitive filesystem. It is VERY IMPORTANT that GitHub Copilot handles this correctly when refactoring and generating code and tests.

### Guidelines

1. **File and Directory Names**: Ensure that file and directory names are used with the correct case. For example, `MyFile.ts` and `myfile.ts` are different files on a case-sensitive filesystem.
2. **Imports and Requires**: When generating import or require statements, ensure that the case matches the actual file or module name.
3. **Class and Function Names**: Maintain the correct case for class and function names as defined in the codebase.
4. **Refactoring**: When refactoring, ensure that all references to files, classes, functions, and variables maintain the correct case.

### Specific Instructions for Component Files

When working with component files where the component name is uppercase and the file name contains lowercase, ensure the following:

1. **Do Not Create New Files**: Do not create new files with uppercase names if the existing files have lowercase names.
2. **Correct File Names**: Use the existing files with the correct case.
3. **Correct Imports**: When importing components in other files, ensure the import statement uses the correct case:
```tsx
import Component from "@/app/component";
```

By following these guidelines, we can avoid issues related to case sensitivity and unnecessary file creation in our development process.
77 changes: 77 additions & 0 deletions MOBILE-EPICS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
Top-level bullets are user story epics, 2nd-level bullet are regular user stories

# Android

1. Looker Dashboard
1. Make messaging feature Looker dashboard (3: DONE)
2. Shared folder, permissions & docs) (LATER)
2. Stand up viewable (though incorrect) Skylight dashboard route (3: DONE)
3. Make things work for Android & Desktop enough to see Android msg rollouts:

1. Page route/dashboard component (5: DONE)
2. Data fetching: (5: DONE)

4. Diagnose Viewpoint Dashboard link 0/0 CTR (DONE)

5. Start landing pieces of android branch incrementally:

1. Experimenter API client work (DONE) - landed on main
2. Publish to web so they can test (DONE)

3. Env var changes - landed on branch (DONE)
1. Draft plan; ask Emily to review
2. Create PR for main for this one change
3. Netlify deploy should be failing
4. Add new env variable to Netlify
5. Netlify deploy should start succeeding
6. Update docs (README and .env\* and CONTRIBUTING?)
7. Merge branch change
4. Feature ID list (DONE)
1. CLEAN UP slightly: Update comments in file & land eg "Cross-platform list of Nimbus feature IDs"
5. Fix existing dashboard tests on branch
6. Nimbus.GetBranchInfo (DONE - tests added)
7. Get simple dashboard links for messaging surface (DONE - tests added)
8. Show experiments & rollouts for a few key surfaces (DONE on branch) - Tests?

6. Onboarding dashboard - desktop-equivalent (WIP on branch)
- Notes:
- [Link](https://mozilla.cloud.looker.com/explore/fenix/event_counts?qid=KV1MOvKpSSGkcvLOfpIxJX&origin_space=60&toggle=fil) to the in-progress dashboard
- `sequence_id`
- https://searchfox.org/mozilla-release/source/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/onboarding/view/OnboardingPageUiData.kt#51
- Seems to be a sequence of a card type as seen above, and determines the order in which these cards are shown in the onboarding sequence
- `element_type`
- element types of `onboarding_card` can have impression actions, while element types of `primary_button` or `secondary_button` can have click actions
- `sequence_position`
- The same card can be in different positions for different experiment or treatments (?)
7. Add monthly Impressions/CTR chart to Looker `messaging` dashboard (DONE on branch)
1. Correctly label these "users impressed",
8. Add Inline Impressions/CTR to Skylight `messaging` (8 - needs breakdown or SPIKE)
\*\* TODO (Dan): draft checklist & plan for this

9. Clean up dashboards with separate stats: users impressed & clicks / User Impression Rate & CTR
10. Separate chart?

---

1. Fix $pivot by index numbers stuff in Looker dashboard
2. Make pills exclude "Firefox" on Android page, since we don't yet have production section (3?)
3. Onboarding funnel (XXXdmose add notes)
4. Fully useful surface columns
5. Completed page

6. Key Unknowns to research
7. Enumerate Nimbus telemetry feature ids to show
1. Enumerate production teletry that can be shown for each surface
8. Make a list of all-subsurfaces (of messaging) with links to telemetry
9. Which other feature ids (eg onboarding) are desired? How much work will they be?
10. Handle production telemetry (waiting on research; chat with Vasant)

11. Maybe immediate; maybe iOS first
1. Add other feature IDs? Prob at least onboarding
2. Microsurveys badge?
3. Surface-based filtering?

# iOS

1. Looker Dashboard
2. Stand up viewable Skylight dashboard route (3)
131 changes: 131 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
Goal: stand up mobile version of experiments/rollouts

Epics:

- BIG UNKNOWN: figure out outside-of-nimbus plan
- stand up android
- messaging surface
- onboarding surface
- UNKNOWN: enumerate other surfaces
- stand up iOS
- UNKNOWN: sort out surfaces
- redo android steps, but without all the refactoring

User Stories. As an Android PM, I should

- have an easy view of rollouts/branches on the messaging surface

- so I can see a bunch of what Android users see (on the message surface)
- 1-10

- research

- [surfaces & guidelines](https://mozilla-hub.atlassian.net/wiki/spaces/FIREFOX/pages/210206760/Mobile+Message+Surface+Guidelines)
- [mobile telemetry docs](https://experimenter.info/messaging/mobile-messaging/#events-emitted)
- [desktop explore](https://mozilla.cloud.looker.com/explore/user_journey/event_counts)

1. look at iOS telemetry & explores

- [iOS message probes](https://dictionary.telemetry.mozilla.org/apps/firefox_ios?page=1&search=messag)
- Note no experiments probes like Android has
- [iOS event count explore](https://mozilla.cloud.looker.com/explore/firefox_ios/event_counts?qid=OZqOXzZqTujARgvCK12NJ4)
- [recent iOS clicked events](https://mozilla.cloud.looker.com/explore/firefox_ios/event_counts?qid=jQpgYwZpBZEhW73B1dcyzu&toggle=fil,vis)
- XXX look at onboarding also

2. look at Android telemetry & explores
- [Android message probes - Glean dictionary](https://dictionary.telemetry.mozilla.org/apps/fenix?page=1&search=messaging)
- [android explore](https://mozilla.cloud.looker.com/explore/fenix/event_counts)$$
- [recent android messaing click events with most extra keys and experiments](https://mozilla.cloud.looker.com/explore/fenix/event_counts?qid=u0OKWHjWgTcstNgbzvyyBc&toggle=fil)
- [recent android onboarding events](https://mozilla.cloud.looker.com/explore/fenix/event_counts?qid=n71HDr0LIxuNS3vGX9essN&toggle=fil)
- Need to understand this telemetry compared to JSON

-
- open questions
- what does telemetry look like for onboarding? other surfaces? similar to messaging?
- Does Click telemetry on both iOS and Android alwyas mean CTA? Or something else?
- What is action_uuid extra key (see docs)?
- **Do non-experimental message send pings on iOS or Android?**

1. Draft plan for Android page

1. ?File ticket
2. Build chart for Android messaging (DONE)
3. Build 2nd chart (LATER)
4. Build dashboard (DONE: id = 2191)
5. Move to shared folder (LATER)

XXX FINISH BUILDING todo list; XXX plan team work; XXX map to calendar

6. Build Android page

1. ~~Review existing clone for "completed" (DONE)~~
2. ~~?Consider options for cloning, since we'll want Android completed page too, and iOS pages (DONE)~~
3. ~~Create new dir with new page.tsx (MUST)~~
4. ~~TDD Factor out dashboard (DONE)~~
1. Use platform search param (TRIED; TOO FIDDLY, MAYBE LATER)
2. ~~Put in separate android/ route (DONE)~~
5. ~~Refactor to not display local table on Android (DONE)~~
6. Factor "application=" out of env (DONE)
1. ~~Create PlatformInfo interface~~
1. ~~application name~~
2. ~~Create PlatformInfoDict containing (android, desktop)~~
3. ~~pull experiments path component into EXPERIMENTER_API_PREFIX~~
4. ~~Figure out how to resolve NimbusAppSlug and Platform param stuff~~
5. ~~Get application param from PlatformInfoDict; remove from env~~
6. ~~Get status param from appropriate files; remove from env~~
7. Pull platform-specific-feature-list from experimentUtils into
PlatformInfo (LATER)
8. Move nimbusRecipe.ts:getBranchInfo into own file included into PlatformInfo? (fallback: add messaging cases for now; move to PlatformInfo later - XXX DONE)
1. Detect by surface
2. Call into GetAndroidBranchInfo
1. Move existing code
2. Copy-paste proposedEndDate
3. ...
9. Fix exeriments (DONE -- for messaging & juno-onboarding)

10. Deploy to web (ALREADY WORKING)
11. Add getAndroidDashboard
12. Add getAndroidDashboardIdForTemplate
13. --
14. Build onBoarding dashboard in Amplitude
15. Link in

16. Add cases / refactor messageUtils.getDashboard (IMPT)
17. Update / move messageUtils.getDashboardIdForTemplate (IMPT)

18. Visual polish on surfaces?
19. Make pills exclude local if not on desktop (NICE)

. 2. Add cases / refactor looker.ts:getCTRPercentData (NICE)

20. Add cases / refactor templates & getSurfaceDataForTemplate (LATER)
21. Support microsurveys badge, if sensible on mobile (LATER)
22. Update columns.tsx:filterBySurface (LATER)
23. Add l10n (LATER)

24. Factor Out NimbusMessageTable (EVEN LATER)
25. Factor out high-level data fetching (EVEN LATER)

26. Pull in Android experiments using that URL
27. Build dashboard link
28. How to handle multi types
29. Build CTR
30. How to handle multi types

2. standup 2nd page

- TDD? clone for mobile

3. standup 2nd dashboard

* review mobile telemetry using glean dict
* look at explores available for those tables
* TDD? subclass recipes (desktop & mobile)

1. Separate dashboards per surface: onboarding, (messaging genrally - may need to split into message_surface dashboard)
2. 2.What about QA?

Later:

- clean up text on messaging graph
-
10 changes: 9 additions & 1 deletion __tests__/app/dashboard.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,17 @@ global.fetch = jest.fn(() =>
}),
) as jest.Mock;

const mockFetchData = {
localData: [],
experimentAndBranchInfo: [],
totalExperiments: 0,
msgRolloutInfo: [],
totalRolloutExperiments: 0,
};

describe.skip("Dashboard", () => {
it("all timeline pill ids exist in the Dashboard component in /", async () => {
const dashboard = await render(await (<Dashboard />));
const dashboard = await render(await (<Dashboard {...mockFetchData} />));

const firefox = dashboard.getByTestId("firefox");
const experiments = dashboard.getByTestId("live_experiments");
Expand Down
26 changes: 26 additions & 0 deletions __tests__/lib/nimbusRecipeCollection.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import { NimbusRecipe } from "@/lib/nimbusRecipe";
import { NimbusRecipeCollection } from "@/lib/nimbusRecipeCollection";
import { ExperimentFakes } from "@/__tests__/ExperimentFakes.mjs";
import { RecipeInfo } from "@/app/columns";
import { Platform } from "@/lib/types";

const platform: Platform = "firefox-desktop";

const fakeFetchData = [ExperimentFakes.recipe()];
global.fetch = jest.fn(() =>
Expand All @@ -27,6 +30,29 @@ describe("NimbusRecipeCollection", () => {

expect(recipes).toEqual([new NimbusRecipe(fakeFetchData[0])]);
});

it("constructs the correct URL for live experiments", async () => {
const nimbusRecipeCollection = new NimbusRecipeCollection(
false,
platform,
); //XXX YYY
await nimbusRecipeCollection.fetchRecipes();

expect(global.fetch).toHaveBeenCalledWith(
`${process.env.EXPERIMENTER_API_PREFIX}?status=Live&application=${platform}`,
{ credentials: "omit" },
);
});

it("constructs the correct URL for completed experiments", async () => {
const nimbusRecipeCollection = new NimbusRecipeCollection(true);
await nimbusRecipeCollection.fetchRecipes();

expect(global.fetch).toHaveBeenCalledWith(
`${process.env.EXPERIMENTER_API_PREFIX}?status=Complete&application=${platform}`,
{ credentials: "omit" },
);
});
});

describe("getExperimentAndBranchInfos", () => {
Expand Down
24 changes: 22 additions & 2 deletions app/android/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
import { Dashboard } from "@/app/dashboard";
import { fetchData } from "@/app/fetchData";
import { Platform } from "@/lib/types";

export default function Page() {
return <Dashboard platform={"android"} />;
const platform: Platform = "fenix";

export default async function Page() {
const {
localData,
experimentAndBranchInfo,
totalExperiments,
msgRolloutInfo,
totalRolloutExperiments,
} = await fetchData(platform);

return (
<Dashboard
platform={platform}
experimentAndBranchInfo={experimentAndBranchInfo}
totalExperiments={totalExperiments}
msgRolloutInfo={msgRolloutInfo}
totalRolloutExperiments={totalRolloutExperiments}
/>
);
}
4 changes: 2 additions & 2 deletions app/columns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ type NimbusExperiment = typeof nimbusExperimentV7Schema.properties;
export type RecipeInfo = {
product: "Desktop" | "Android";
id: string;
template?: string;
surface?: string;
template?: string; // XXX template JSON name
surface?: string; // XXX template display name
segment?: string;
ctrPercent?: number;
ctrPercentChange?: number;
Expand Down
Loading