Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions apps/roadmap/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"dependencies": {
"@instructure/ui": "^11.2.0",
"@instructure/ui-color-utils": "^10.2.0",
"@instructure/ui-color-utils": "^11.2.0",
"react": "^19.2.0",
"react-dom": "^19.2.0"
},
Expand All @@ -24,5 +24,5 @@
"typecheck": "tsgo --noEmit"
},
"type": "module",
"version": "1.0.3"
"version": "1.0.4"
}
6 changes: 3 additions & 3 deletions apps/roadmap/public/themeEditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
*
* Only runs on the "/pages/instructure-roadmap" path.
*
* @version 2025.10.29.00
* @version 2025.12.02.00
*
*/

Expand Down Expand Up @@ -178,14 +178,14 @@ if (matchesRoadmap || matchesCourse || matchesCourseWiki) {
}
};

const _pushState = history.pushState;
const _pushState = history.pushState.bind(history);
history.pushState = function pushState(...args) {
const ret = _pushState.apply(this, args);
window.dispatchEvent(new Event("locationchange"));
return ret;
};

const _replaceState = history.replaceState;
const _replaceState = history.replaceState.bind(history);
history.replaceState = function replaceState(...args) {
const ret = _replaceState.apply(this, args);
window.dispatchEvent(new Event("locationchange"));
Expand Down
27 changes: 16 additions & 11 deletions apps/roadmap/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Flex, InstUISettingsProvider, canvas } from "@instructure/ui";
import type { FC } from "react";
import { useEffect, useMemo, useState } from "react";
import { Card, CardOverlay, Loading } from "./components";
import type { Theme } from "@instructure/ui";
import {
getBrandConfig,
getColor,
Expand All @@ -11,14 +12,19 @@ import {
} from "./utils";
import "./App.css";

type ThemeOrOverride = Theme | Record<string, unknown>;

const App: FC = () => {
const [overlayOpen, setOverlayOpen] = useState(false);
const [selectedEntry, setSelectedEntry] = useState<PendoAPIFeature | null>(
const [selectedEntry, setSelectedEntry] = useState<
PendoAPIFeature | undefined
>(undefined);
const [brandConfig, setBrandConfig] = useState<ThemeOrOverride>();
const [roadmap, setRoadmap] = useState<RoadmapFeatures | undefined>(
undefined,
);
const [brandConfig, setBrandConfig] = useState<unknown>({});
const [roadmap, setRoadmap] = useState<RoadmapFeatures | null>(undefined);
const [isDark, setIsDark] = useState(false);
const [showLoading, setShowLoading] = useState(false);

useEffect(() => {
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
Expand All @@ -31,13 +37,13 @@ const App: FC = () => {
}, []);

useEffect(() => {
getRoadmap().then((data) => {
setRoadmap(data);
void getRoadmap().then((data) => {
setRoadmap(data ?? undefined);
});
}, []);

useEffect(() => {
getBrandConfig().then((config) => {
void getBrandConfig().then((config) => {
setBrandConfig(config);
});
}, []);
Expand Down Expand Up @@ -72,10 +78,9 @@ const App: FC = () => {
}));
}, [roadmap]);

// Debounce loading state
const [showLoading, setShowLoading] = useState(false);
useEffect(() => {
if (!roadmap) {
setShowLoading(false);
const timeout = setTimeout(() => setShowLoading(true), 1000);
return () => clearTimeout(timeout);
} else {
Expand All @@ -87,7 +92,7 @@ const App: FC = () => {
<InstUISettingsProvider
theme={{
...canvas,
...(brandConfig as object),
...brandConfig,
typography: {
...canvas.typography,
fontFamily: "Atkinson Hyperlegible Next, sans-serif",
Expand Down Expand Up @@ -121,9 +126,9 @@ const App: FC = () => {
/>
)}
</>
) : showLoading ? (
) : (showLoading ? (
<Loading isDark={isDark} />
) : null}
) : null)}
</InstUISettingsProvider>
);
};
Expand Down
2 changes: 1 addition & 1 deletion apps/roadmap/src/components/card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import Logos, { Colors } from "./logos";
const Card: FC<{
entry: PendoAPIFeature;
setSelectedEntry: React.Dispatch<
React.SetStateAction<PendoAPIFeature | null>
React.SetStateAction<PendoAPIFeature | undefined>
>;
setOverlayOpen: React.Dispatch<React.SetStateAction<boolean>>;
isDark: boolean;
Expand Down
23 changes: 1 addition & 22 deletions apps/roadmap/src/components/logos.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,6 @@
import { InlineSVG } from "@instructure/ui";
import { darken, lighten } from "@instructure/ui-color-utils";
import type { FC, ReactNode } from "react";

interface SVGInfo {
color: string;
SVG: ReactNode;
title: string;
viewBox: string;
}

interface SVGProps {
height?: string;
width?: string;
inline?: boolean;
color?: string;
valign?: "top" | "middle" | "bottom" | "unset";
}

type ColorSVGProps = SVGProps & {
children: ReactNode;
title: string;
viewBox: string;
};
import type { FC } from "react";

const ColorSVG: FC<ColorSVGProps> = ({
color = "currentColor",
Expand Down
25 changes: 24 additions & 1 deletion apps/roadmap/src/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,28 @@
/// <reference types="@instructure/ui" />

type FC<P = {}> = import("react").FC<P>;

interface SVGInfo {
color: string;
SVG: ReactNode;
title: string;
viewBox: string;
}

interface SVGProps {
height?: string;
width?: string;
inline?: boolean;
color?: string;
valign?: "top" | "middle" | "bottom" | "unset";
}

type ColorSVGProps = SVGProps & {
children: ReactNode;
title: string;
viewBox: string;
};

interface PendoAPI {
results: PendoAPIFeature[];
}
Expand All @@ -20,7 +43,7 @@ interface PendoAPIFeature {
product: {
area: string | null;
name: string;
logo: SVGIconProps | undefined;
logo: FC<SVGProps<SVGSVGElement>> | undefined;
color: string | undefined;
};
}
Expand Down
2 changes: 1 addition & 1 deletion apps/roadmap/src/utils/getBrandConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const getBrandConfig = (): Promise<BrandConfig> => {
};
window.addEventListener("message", handler);
});
brandConfigPromise.finally(() => {
void brandConfigPromise.finally(() => {
brandConfigPromise = undefined;
});
return brandConfigPromise;
Expand Down
10 changes: 4 additions & 6 deletions apps/roadmap/src/utils/getRoadmap.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
import paramsToPendo from "./paramsToPendo";

let roadmapPromise: Promise<RoadmapFeatures | null> | null;
let cachedRoadmap: RoadmapFeatures | null;
let roadmapPromise: Promise<RoadmapFeatures | null> | undefined;
let cachedRoadmap: RoadmapFeatures | null | undefined;

type RoadmapRequestEvent = MessageEvent<{ value?: string }>;

const getRoadmap = (): Promise<RoadmapFeatures | null> => {
console.debug("getRoadmap called");
if (cachedRoadmap !== null) {
if (cachedRoadmap !== undefined && cachedRoadmap !== null) {
console.debug("Returning cached roadmap");
return Promise.resolve(cachedRoadmap);
}
if (roadmapPromise) {
if (roadmapPromise !== undefined) {
console.debug("Returning existing roadmap promise");
console.log(roadmapPromise);
return roadmapPromise;
}
window.parent.postMessage({ type: "getRoadmap" }, "*");
Expand All @@ -32,7 +31,6 @@ const getRoadmap = (): Promise<RoadmapFeatures | null> => {
roadmapPromise = undefined;
resolve(result);
}
// Ignore unrelated events
};
window.addEventListener("message", handler);
});
Expand Down
16 changes: 7 additions & 9 deletions apps/roadmap/src/utils/paramsToPendo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ const isPendoAPI = (obj: unknown): obj is PendoAPI => {
);
};

const paramsToPendo = (params: string | null): RoadmapFeatures | null => {
const paramsToPendo = (params: string | null): RoadmapFeatures | undefined => {
if (!params) {
return null;
return;
}

let p: unknown;
Expand All @@ -50,20 +50,18 @@ const paramsToPendo = (params: string | null): RoadmapFeatures | null => {
}

const stages = [
...new Set((p as PendoAPI).results.map((result) => result.feature.stage)),
...new Set(p.results.map((result) => result.feature.stage)),
].filter(Boolean) as string[];
const products = [
...new Set((p as PendoAPI).results.map((result) => result.product.name)),
...new Set(p.results.map((result) => result.product.name)),
].filter(Boolean) as string[];
const productAreas = [
...new Set((p as PendoAPI).results.map((result) => result.product.area)),
...new Set(p.results.map((result) => result.product.area)),
].filter(Boolean) as string[];
const labels = [
...new Set(
(p as PendoAPI).results.flatMap((result) => result.feature.labels),
),
...new Set(p.results.flatMap((result) => result.feature.labels)),
].filter(Boolean) as string[];
const features = (p as PendoAPI).results;
const features = p.results;

const roadmap: RoadmapFeatures = {
features,
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
},
"version": "3.0.0",
"name": "@instructure.ai/shared-configs",
"packageManager": "pnpm@10.23.0",
"packageManager": "pnpm@10.24.0",
"private": true,
"type": "module",
"scripts": {
Expand Down Expand Up @@ -57,4 +57,4 @@
"type": "git",
"url": "https://github.com/instructure/instructure.ai"
}
}
}
Loading