diff --git a/src/clue/components/clue-app-header.tsx b/src/clue/components/clue-app-header.tsx index ef39da545..56a09e76a 100644 --- a/src/clue/components/clue-app-header.tsx +++ b/src/clue/components/clue-app-header.tsx @@ -9,6 +9,7 @@ import { ToggleGroup } from "@concord-consortium/react-components"; import { GroupModelType, GroupUserModelType } from "../../models/stores/groups"; import { CustomSelect } from "./custom-select"; import { useStores } from "../../hooks/use-stores"; +import { getDevId } from "../../lib/root-id"; // cf. https://mattferderer.com/use-sass-variables-in-typescript-and-javascript import styles from "./toggle-buttons.scss"; @@ -29,6 +30,7 @@ export const ClueAppHeaderComponent: React.FC = observer(function ClueAp const getUserTitle = () => { switch(appMode){ case "dev": + return `Firebase Root: ${getDevId()}`; case "qa": case "test": return `Firebase UID: ${db.firebase.userId}`; diff --git a/src/lib/firebase.test.ts b/src/lib/firebase.test.ts index b8732e95e..20cad35f3 100644 --- a/src/lib/firebase.test.ts +++ b/src/lib/firebase.test.ts @@ -1,5 +1,6 @@ import { DB } from "./db"; import { Firebase } from "./firebase"; +import { kClueDevIDKey } from "./root-id"; const mockStores = { appMode: "authed", @@ -22,6 +23,12 @@ describe("Firebase class", () => { const firebase = new Firebase(mockDB); expect(firebase.getRootFolder()).toBe("/authed/portals/test-portal/"); }); + it("should handle the dev appMode", () => { + window.localStorage.setItem(kClueDevIDKey, "random-id"); + const stores = {...mockStores, appMode: "dev"}; + const firestore = new Firebase({stores} as DB); + expect(firestore.getRootFolder()).toBe("/dev/random-id/portals/test-portal/"); + }); describe("should handle the demo appMode", () => { it("handles basic demo name", () => { const stores = {...mockStores, diff --git a/src/lib/firestore.test.ts b/src/lib/firestore.test.ts index 956c689ca..78fe1f6c2 100644 --- a/src/lib/firestore.test.ts +++ b/src/lib/firestore.test.ts @@ -1,5 +1,6 @@ import { DB } from "./db"; import { Firestore } from "./firestore"; +import { kClueDevIDKey } from "./root-id"; const mockStores = { appMode: "authed", @@ -65,6 +66,12 @@ describe("Firestore class", () => { const firestore = new Firestore(mockDB); expect(firestore.getRootFolder()).toBe("/authed/test-portal/"); }); + it("should handle the dev appMode", () => { + window.localStorage.setItem(kClueDevIDKey, "random-id"); + const stores = {...mockStores, appMode: "dev"}; + const firestore = new Firestore({stores} as DB); + expect(firestore.getRootFolder()).toBe("/dev/random-id/"); + }); describe("should handle the demo appMode", () => { it("handles basic demo name", () => { const stores = {...mockStores, diff --git a/src/lib/root-id.ts b/src/lib/root-id.ts index f2d14f1a1..c75e476ac 100644 --- a/src/lib/root-id.ts +++ b/src/lib/root-id.ts @@ -1,6 +1,19 @@ +import { nanoid } from "nanoid"; import { IStores } from "../models/stores/stores"; import { escapeKey } from "./fire-utils"; +export const kClueDevIDKey = "clue-dev-id"; + +export function getDevId() { + let devId = window.localStorage.getItem(kClueDevIDKey); + if (!devId) { + const newDevId = nanoid(); + window.localStorage.setItem(kClueDevIDKey, newDevId); + devId = newDevId; + } + return devId; +} + type IRootDocIdStores = Pick; export function getRootId(stores: IRootDocIdStores, firebaseUserId: string) { @@ -22,7 +35,10 @@ export function getRootId(stores: IRootDocIdStores, firebaseUserId: string) { const escapedDemoName = demoName ? escapeKey(demoName) : demoName; return escapedDemoName || escapedPortal || "demo"; } - // "dev", "qa", and "test" + case "dev": { + return getDevId(); + } + // "test" and "qa" default: { return firebaseUserId; }