Skip to content

Commit

Permalink
Disable compile buttons if no server connection
Browse files Browse the repository at this point in the history
  • Loading branch information
WardBrian committed Oct 8, 2024
1 parent 971cd3a commit 31a60ac
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,7 @@ import { Cancel, Check } from "@mui/icons-material";
import CloseableDialog, {
useDialogControls,
} from "@SpComponents/CloseableDialog";
import {
FunctionComponent,
useCallback,
useContext,
useEffect,
useState,
} from "react";
import { FunctionComponent, useCallback, useContext } from "react";
import ConfigureCompilationServerDialog from "./ConfigureCompilationServerDialog";
import IconButton from "@mui/material/IconButton";
import Typography from "@mui/material/Typography";
Expand All @@ -28,8 +22,8 @@ type CompilationServerConnectionControlProps = {
const CompilationServerConnectionControl: FunctionComponent<
CompilationServerConnectionControlProps
> = () => {
const { stanWasmServerUrl } = useContext(CompileContext);
const { isConnected, retryConnection } = useIsConnected(stanWasmServerUrl);
const { stanWasmServerUrl, isConnected, retryConnection } =
useContext(CompileContext);

const {
handleOpen: openDialog,
Expand Down Expand Up @@ -80,32 +74,4 @@ export const serverTypeForUrl = (url: string): ServerType => {
: "custom";
};

const useIsConnected = (stanWasmServerUrl: string) => {
const probeUrl = `${stanWasmServerUrl}/probe`;
const [isConnected, setIsConnected] = useState<boolean>(false);
const [retryCode, setRetryCode] = useState<number>(0);
const retryConnection = useCallback(() => {
setRetryCode((r) => r + 1);
}, []);
useEffect(() => {
setIsConnected(false);
if (!probeUrl.startsWith("http://") && !probeUrl.startsWith("https://")) {
// important to do this check because otherwise fetch may succeed because
// the server of this web app may respond with success
return;
}
(async () => {
try {
const response = await fetch(probeUrl);
if (response.status === 200) {
setIsConnected(true);
}
} catch (err) {
setIsConnected(false);
}
})();
}, [probeUrl, retryCode]);
return { isConnected, retryConnection };
};

export default CompilationServerConnectionControl;
4 changes: 4 additions & 0 deletions gui/src/app/CompileContext/CompileContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ type CompileContextType = {
setValidSyntax: (valid: boolean) => void;
stanWasmServerUrl: string;
setStanWasmServerUrl: (url: string) => void;
isConnected: boolean;
retryConnection: () => void;
};

export const CompileContext = createContext<CompileContextType>({
Expand All @@ -26,4 +28,6 @@ export const CompileContext = createContext<CompileContextType>({
setValidSyntax: () => {},
stanWasmServerUrl: "",
setStanWasmServerUrl: () => {},
isConnected: false,
retryConnection: () => {},
});
32 changes: 32 additions & 0 deletions gui/src/app/CompileContext/CompileContextProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,34 @@ type CompileContextProviderProps = {
// none
};

const useIsConnected = (stanWasmServerUrl: string) => {
const probeUrl = `${stanWasmServerUrl}/probe`;
const [isConnected, setIsConnected] = useState<boolean>(false);
const [retryCode, setRetryCode] = useState<number>(0);
const retryConnection = useCallback(() => {
setRetryCode((r) => r + 1);
}, []);
useEffect(() => {
setIsConnected(false);
if (!probeUrl.startsWith("http://") && !probeUrl.startsWith("https://")) {
// important to do this check because otherwise fetch may succeed because
// the server of this web app may respond with success
return;
}
(async () => {
try {
const response = await fetch(probeUrl);
if (response.status === 200) {
setIsConnected(true);
}
} catch (err) {
setIsConnected(false);
}
})();
}, [probeUrl, retryCode]);
return { isConnected, retryConnection };
};

const initialStanWasmServerUrl =
localStorage.getItem("stanWasmServerUrl") || publicCompilationServerUrl;

Expand Down Expand Up @@ -83,6 +111,8 @@ export const CompileContextProvider: FunctionComponent<
stanWasmServerUrl,
]);

const { isConnected, retryConnection } = useIsConnected(stanWasmServerUrl);

return (
<CompileContext.Provider
value={{
Expand All @@ -94,6 +124,8 @@ export const CompileContextProvider: FunctionComponent<
setValidSyntax,
stanWasmServerUrl,
setStanWasmServerUrl,
isConnected,
retryConnection,
}}
>
{children}
Expand Down
31 changes: 15 additions & 16 deletions gui/src/app/FileEditor/StanFileEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const StanFileEditor: FunctionComponent<Props> = ({
setEditedFileContent,
);

const { compileStatus, compileMessage, compile, validSyntax } =
const { compileStatus, compileMessage, compile, validSyntax, isConnected } =
useContext(CompileContext);

const hasWarnings = useMemo(() => {
Expand Down Expand Up @@ -89,17 +89,15 @@ const StanFileEditor: FunctionComponent<Props> = ({
});
}
if (editedFileContent && editedFileContent === fileContent) {
if (compileStatus !== "compiling") {
if (validSyntax) {
ret.push({
type: "button",
tooltip: "Compile Stan model",
label: "Compile",
icon: <Settings />,
onClick: compile,
color: "info.dark",
});
}
if (compileStatus !== "compiling" && validSyntax && isConnected) {
ret.push({
type: "button",
tooltip: "Compile Stan model",
label: "Compile",
icon: <Settings />,
onClick: compile,
color: "info.dark",
});
}
if (compileStatus !== "") {
ret.push({
Expand All @@ -118,15 +116,16 @@ const StanFileEditor: FunctionComponent<Props> = ({

return ret;
}, [
validSyntax,
editedFileContent,
hasWarnings,
readOnly,
fileContent,
compile,
requestFormat,
validSyntax,
compileStatus,
isConnected,
compile,
compileMessage,
readOnly,
hasWarnings,
]);

const isCompiling = compileStatus === "compiling";
Expand Down
42 changes: 23 additions & 19 deletions gui/src/app/RunPanel/RunPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { FunctionComponent, useCallback, useContext } from "react";
import { FunctionComponent, useCallback, useContext, useMemo } from "react";

import Button from "@mui/material/Button";
import { CompileContext } from "@SpCompileContext/CompileContext";
Expand All @@ -13,6 +13,7 @@ import StanSampler from "@SpStanSampler/StanSampler";
import { StanRun } from "@SpStanSampler/useStanSampler";
import CompiledRunPanel from "./CompiledRunPanel";
import CircularProgress from "@mui/material/CircularProgress";
import Tooltip from "@mui/material/Tooltip";

type RunPanelProps = {
sampler?: StanSampler;
Expand Down Expand Up @@ -41,23 +42,36 @@ const RunPanel: FunctionComponent<RunPanelProps> = ({
sampler.cancel();
}, [sampler]);

const { compile, compileStatus, validSyntax } = useContext(CompileContext);
const { compile, compileStatus, validSyntax, isConnected } =
useContext(CompileContext);

const { data: projectData } = useContext(ProjectContext);

const tooltip = useMemo(() => {
if (!validSyntax) return "Syntax error";
if (!isConnected) return "Not connected to compilation server";
if (!projectData.stanFileContent.trim()) return "No model to compile";
if (modelHasUnsavedChanges(projectData)) return "Model has unsaved changes";
return "";
}, [isConnected, projectData, validSyntax]);

if (!dataIsSaved) {
return <div className="RunPanelPadded">Data not saved</div>;
}

const compileDiv = (
<div>
<Button
variant="contained"
onClick={compile}
disabled={isCompileModelDisabled(projectData, validSyntax)}
>
compile model
</Button>
<Tooltip title={tooltip}>
<span>
<Button
variant="contained"
onClick={compile}
disabled={tooltip != ""}
>
compile model
</Button>
</span>
</Tooltip>
</div>
);

Expand Down Expand Up @@ -89,14 +103,4 @@ const RunPanel: FunctionComponent<RunPanelProps> = ({
);
};

const isCompileModelDisabled = (
projectData: ProjectDataModel,
validSyntax: boolean,
) => {
if (!validSyntax) return true;
if (!projectData.stanFileContent.trim()) return true;
if (modelHasUnsavedChanges(projectData)) return true;
return false;
};

export default RunPanel;

0 comments on commit 31a60ac

Please sign in to comment.