Skip to content
2 changes: 2 additions & 0 deletions frontend/app/monaco/monaco-react.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export function MonacoCodeEditor({ text, readonly, language, onChange, onMount,
return () => {
sub.dispose();
if (onUnmountRef.current) onUnmountRef.current();
editor.setModel(null);
editor.dispose();
model.dispose();
console.log("[monaco] dispose model");
Expand Down Expand Up @@ -146,6 +147,7 @@ export function MonacoDiffViewer({ original, modified, language, path, options }
diff.setModel({ original: originalModel, modified: modifiedModel });

return () => {
diff.setModel(null);
diff.dispose();
originalModel.dispose();
modifiedModel.dispose();
Expand Down
12 changes: 5 additions & 7 deletions frontend/app/onboarding/onboarding-features.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { FakeLayout } from "./onboarding-layout";

type FeaturePageName = "waveai" | "durable" | "magnify" | "files";

const WaveAIPage = ({ onNext, onSkip }: { onNext: () => void; onSkip: () => void }) => {
export const WaveAIPage = ({ onNext, onSkip }: { onNext: () => void; onSkip: () => void }) => {
const isMac = isMacOS();
const shortcutKey = isMac ? "⌘-Shift-A" : "Alt-Shift-A";
const [fireClicked, setFireClicked] = useState(false);
Expand Down Expand Up @@ -106,7 +106,7 @@ const WaveAIPage = ({ onNext, onSkip }: { onNext: () => void; onSkip: () => void
);
};

const MagnifyBlocksPage = ({
export const MagnifyBlocksPage = ({
onNext,
onSkip,
onPrev,
Expand Down Expand Up @@ -149,13 +149,13 @@ const MagnifyBlocksPage = ({
better view.
</p>
<p>Use the magnify feature to work with complex outputs and large files more efficiently.</p>
<p>
<div>
You can also magnify a block by clicking on the{" "}
<span className="inline-block align-middle [&_svg_path]:!fill-foreground">
<MagnifyIcon enabled={false} />
</span>{" "}
icon in the block header.
</p>
</div>
<p>
A quick {shortcutKey}-M to magnify and another {shortcutKey}-M to unmagnify
</p>
Expand All @@ -172,11 +172,10 @@ const MagnifyBlocksPage = ({
);
};

const FilesPage = ({ onFinish, onPrev }: { onFinish: () => void; onPrev?: () => void }) => {
export const FilesPage = ({ onFinish, onPrev }: { onFinish: () => void; onPrev?: () => void }) => {
const [fireClicked, setFireClicked] = useState(false);
const isMac = isMacOS();
const [commandIndex, setCommandIndex] = useState(0);
const [key, setKey] = useState(0);

const handleFireClick = () => {
setFireClicked(!fireClicked);
Expand All @@ -200,7 +199,6 @@ const FilesPage = ({ onFinish, onPrev }: { onFinish: () => void; onPrev?: () =>
const handleCommandComplete = () => {
setTimeout(() => {
setCommandIndex((prev) => (prev + 1) % commands.length);
setKey((prev) => prev + 1);
}, 2500);
};

Expand Down
8 changes: 4 additions & 4 deletions frontend/app/onboarding/onboarding-upgrade-patch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ interface VersionConfig {
nextText?: string;
}

const versions: VersionConfig[] = [
export const UpgradeOnboardingVersions: VersionConfig[] = [
{
version: "v0.12.1",
content: () => <UpgradeOnboardingModal_v0_12_1_Content />,
Expand Down Expand Up @@ -69,11 +69,11 @@ const versions: VersionConfig[] = [
const UpgradeOnboardingPatch = () => {
const modalRef = useRef<HTMLDivElement | null>(null);
const [isCompact, setIsCompact] = useState<boolean>(window.innerHeight < 800);
const [currentIndex, setCurrentIndex] = useState<number>(versions.length - 1);
const [currentIndex, setCurrentIndex] = useState<number>(UpgradeOnboardingVersions.length - 1);

const currentVersion = versions[currentIndex];
const currentVersion = UpgradeOnboardingVersions[currentIndex];
const hasPrev = currentIndex > 0;
const hasNext = currentIndex < versions.length - 1;
const hasNext = currentIndex < UpgradeOnboardingVersions.length - 1;

const updateModalHeight = () => {
const windowHeight = window.innerHeight;
Expand Down
7 changes: 7 additions & 0 deletions frontend/app/store/global.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ import {
isBlank,
isLocalConnName,
isWslConnName,
NullAtom,
} from "@/util/util";
import { isPreviewWindow } from "./windowtype";
import { atom, Atom, PrimitiveAtom, useAtomValue } from "jotai";
import {
atoms,
Expand Down Expand Up @@ -168,6 +170,7 @@ function useOrefMetaKeyAtom<T extends keyof MetaType>(oref: string, key: T): Met
}

function getConnConfigKeyAtom<T extends keyof ConnKeywords>(connName: string, key: T): Atom<ConnKeywords[T]> {
if (isPreviewWindow()) return NullAtom as Atom<ConnKeywords[T]>;
let connCache = getSingleConnAtomCache(connName);
const keyAtomName = "#conn-" + key;
let keyAtom = connCache.get(keyAtomName);
Expand All @@ -185,6 +188,7 @@ function getConnConfigKeyAtom<T extends keyof ConnKeywords>(connName: string, ke
const settingsAtomCache = new Map<string, Atom<any>>();

function getOverrideConfigAtom<T extends keyof SettingsType>(blockId: string, key: T): Atom<SettingsType[T]> {
if (isPreviewWindow()) return NullAtom as Atom<SettingsType[T]>;
const blockCache = getSingleBlockAtomCache(blockId);
const overrideAtomName = "#settingsoverride-" + key;
let overrideAtom = blockCache.get(overrideAtomName);
Expand Down Expand Up @@ -223,6 +227,7 @@ function useOverrideConfigAtom<T extends keyof SettingsType>(blockId: string | n
}

function getSettingsKeyAtom<T extends keyof SettingsType>(key: T): Atom<SettingsType[T]> {
if (isPreviewWindow()) return NullAtom as Atom<SettingsType[T]>;
let settingsKeyAtom = settingsAtomCache.get(key) as Atom<SettingsType[T]>;
if (settingsKeyAtom == null) {
settingsKeyAtom = atom((get) => {
Expand All @@ -242,6 +247,7 @@ function useSettingsKeyAtom<T extends keyof SettingsType>(key: T): SettingsType[
}

function getSettingsPrefixAtom(prefix: string): Atom<SettingsType> {
if (isPreviewWindow()) return NullAtom as Atom<SettingsType>;
let settingsPrefixAtom = settingsAtomCache.get(prefix + ":");
if (settingsPrefixAtom == null) {
// create a stable, closured reference to use as the deepCompareReturnPrev key
Expand Down Expand Up @@ -745,6 +751,7 @@ function setActiveTab(tabId: string) {
}

function recordTEvent(event: string, props?: TEventProps) {
if (isPreviewWindow()) return;
if (props == null) {
props = {};
}
Expand Down
2 changes: 1 addition & 1 deletion frontend/preview/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ function PreviewApp() {
return (
<>
<PreviewHeader previewName={previewName} />
<div className="min-h-screen bg-background text-foreground font-sans flex flex-col items-center justify-center">
<div className="h-screen overflow-y-auto bg-background text-foreground font-sans flex flex-col items-center pt-12 pb-8">
<Suspense fallback={null}>
<PreviewComponent />
</Suspense>
Expand Down
64 changes: 64 additions & 0 deletions frontend/preview/previews/onboarding.preview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright 2026, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0

import Logo from "@/app/asset/logo.svg";
import { DurableSessionPage } from "@/app/onboarding/onboarding-durable";
import { FilesPage, MagnifyBlocksPage, WaveAIPage } from "@/app/onboarding/onboarding-features";
import { UpgradeOnboardingVersions } from "@/app/onboarding/onboarding-upgrade-patch";

function OnboardingFeaturesV() {
const noop = () => {};
return (
<div className="flex flex-col w-full gap-8">
<div className="w-[800px] rounded-[10px] p-[30px] relative overflow-hidden bg-panel">
<WaveAIPage onNext={noop} onSkip={noop} />
</div>
<div className="w-[800px] rounded-[10px] p-[30px] relative overflow-hidden bg-panel">
<DurableSessionPage onNext={noop} onSkip={noop} onPrev={noop} />
</div>
<div className="w-[800px] rounded-[10px] p-[30px] relative overflow-hidden bg-panel">
<MagnifyBlocksPage onNext={noop} onSkip={noop} onPrev={noop} />
</div>
<div className="w-[800px] rounded-[10px] p-[30px] relative overflow-hidden bg-panel">
<FilesPage onFinish={noop} onPrev={noop} />
</div>
</div>
);
}

function UpgradeOnboardingPatchV() {
return (
<div className="flex flex-col gap-6 w-full max-w-[900px]">
{UpgradeOnboardingVersions.map((version) => (
<div
key={version.version}
className="w-[650px] rounded-[10px] p-[30px] relative overflow-hidden bg-panel"
>
<div className="absolute inset-0 bg-gradient-to-br from-accent/[0.25] via-transparent to-accent/[0.05] pointer-events-none rounded-[10px]" />
<div className="flex flex-col w-full h-full relative z-10">
<header className="flex flex-col gap-2 border-b-0 p-0 mt-1 mb-6 w-full unselectable flex-shrink-0">
<div className="flex justify-center">
<Logo />
</div>
<div className="text-center text-[25px] font-normal text-foreground">
Wave {version.version} Update
</div>
</header>
<div className="flex-1">{version.content()}</div>
</div>
</div>
))}
</div>
);
}

export function OnboardingPreview() {
return (
<div className="w-full max-w-[1300px] py-10 px-4 flex flex-col gap-8">
<div className="text-sm font-mono text-muted">Onboarding features</div>
<OnboardingFeaturesV />
<div className="text-sm font-mono text-muted mt-6">Onboarding patch updates</div>
<UpgradeOnboardingPatchV />
</div>
);
}
13 changes: 10 additions & 3 deletions frontend/util/endpoints.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
// Copyright 2025, Command Line Inc.
// Copyright 2026, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0

import { isPreviewWindow } from "@/app/store/windowtype";
import { getEnv } from "./getenv";
import { lazy } from "./util";

export const WebServerEndpointVarName = "WAVE_SERVER_WEB_ENDPOINT";
export const WSServerEndpointVarName = "WAVE_SERVER_WS_ENDPOINT";

export const getWebServerEndpoint = lazy(() => `http://${getEnv(WebServerEndpointVarName)}`);
export const getWebServerEndpoint = lazy(() => {
if (isPreviewWindow()) return null;
return `http://${getEnv(WebServerEndpointVarName)}`;
});

export const getWSServerEndpoint = lazy(() => `ws://${getEnv(WSServerEndpointVarName)}`);
export const getWSServerEndpoint = lazy(() => {
if (isPreviewWindow()) return null;
return `ws://${getEnv(WSServerEndpointVarName)}`;
});
1 change: 1 addition & 0 deletions frontend/util/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,7 @@ export {
makeExternLink,
makeIconClass,
mergeMeta,
NullAtom,
parseDataUrl,
sleep,
sortByDisplayOrder,
Expand Down
Loading