Skip to content

Commit

Permalink
Merge branch 'stan-editor-text-hint' into create-templates-in-script-…
Browse files Browse the repository at this point in the history
…editors
  • Loading branch information
magland committed Jul 25, 2024
2 parents 406eb2e + 40812be commit fe7a9f9
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 64 deletions.
5 changes: 2 additions & 3 deletions gui/src/app/FileEditor/TextEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -255,13 +255,12 @@ const createHintTextContentWidget = (
getDomNode: () => {
const node = document.createElement("div");
node.style.width = "max-content";
node.style.fontStyle = "italic";
node.className = "EditorHintText";
if (onClick) {
const link = document.createElement("a");
link.textContent = hintText;
link.style.cursor = "pointer";
link.style.color = "gray";
link.style.textDecoration = "underline";
link.className = "EditorHintTextLink";
link.onclick = onClick;
node.appendChild(link);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,22 +38,33 @@ const DataGenerationChildWindow: FunctionComponent<
const consoleRef = useRef<HTMLDivElement | null>(null);

const handleSetData = useCallback(
(data: any) => {
update({
type: "editFile",
content: JSON.stringify(data, null, 2),
filename: ProjectKnownFiles.DATAFILE,
});
update({ type: "commitFile", filename: ProjectKnownFiles.DATAFILE });
// Use "stan-playground" prefix to distinguish from console output of the running code
writeConsoleOutToDiv(
consoleRef,
"[stan-playground] Data updated",
"stdout",
);
(newData: unknown) => {
const dataJson = JSON.stringify(newData, null, 2);

if (dataJson !== data.dataFileContent) {
update({
type: "editFile",
content: dataJson,
filename: ProjectKnownFiles.DATAFILE,
});
update({ type: "commitFile", filename: ProjectKnownFiles.DATAFILE });
// Use "stan-playground" prefix to distinguish from console output of the running code
writeConsoleOutToDiv(
consoleRef,
"[stan-playground] Data updated",
"stdout",
);
} else {
writeConsoleOutToDiv(
consoleRef,
"[stan-playground] Data unchanged",
"stdout",
);
}
},
[update, consoleRef],
[update, consoleRef, data.dataFileContent],
);

const EditorComponent =
language === "python" ? DataPyFileEditor : DataRFileEditor;
return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ const DataPyFileEditor: FunctionComponent<Props> = ({
const toolbarItems: ToolbarItem[] = useMemo(
() =>
getDataGenerationToolbarItems({
name: "pyodide",
status,
runnable: fileContent === editedFileContent,
onRun: handleRun,
Expand Down
72 changes: 27 additions & 45 deletions gui/src/app/pages/HomePage/DataGenerationWindow/DataRFileEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import {
useMemo,
useState,
} from "react";
import { WebR } from "webr";
import { RString, WebR } from "webr";
import getDataGenerationToolbarItems from "./getDataGenerationToolbarItems";
import TextEditor, { ToolbarItem } from "@SpComponents/TextEditor";
import { writeConsoleOutToDiv } from "@SpPyodide/AnalysisPyFileEditor";

type Props = {
fileName: string;
Expand Down Expand Up @@ -60,64 +61,44 @@ const DataRFileEditor: FunctionComponent<Props> = ({
try {
const webR = await loadWebRInstance();

const shelter = await new webR.Shelter();

setStatus("running");
const rCode =
`
# Create a list to store printed statements
print_log <- list()
# Check if original print function is already saved
if (!exists("sp_original_print")) {
# Save the original print function
sp_original_print <- print
}
# Override the print function
print <- function(..., sep = " ", collapse = NULL) {
# Capture the printed output
printed_output <- paste(..., sep = sep, collapse = collapse)
# Append to the print log
print_log <<- c(print_log, printed_output)
# Call the original print function
sp_original_print(printed_output)
}
# redirect install.packages to webr's version
webr::shim_install()
\n\n
` +
fileContent +
"\n\n" +
`
result <- list(data = data, print_log = print_log)
json_result <- jsonlite::toJSON(result, pretty = TRUE, auto_unbox = TRUE)
json_result
if (typeof(data) != "list") {
stop("[stan-playground] data must be a list")
}
.SP_DATA <- jsonlite::toJSON(data, pretty = TRUE, auto_unbox = TRUE)
.SP_DATA
`;
const resultJson = await webR.evalRString(rCode);
const result = JSON.parse(resultJson);

if (setData && result.data) {
setData(result.data);
}
if (outputDiv.current && result.print_log) {
result.print_log.forEach((x: string) => {
const divElement = document.createElement("div");
divElement.style.color = "blue";
const preElement = document.createElement("pre");
divElement.appendChild(preElement);
preElement.textContent = x;
outputDiv.current?.appendChild(divElement);
try {
const ret = await shelter.captureR(rCode);
ret.output.forEach(({ type, data }) => {
if (type === "stdout" || type === "stderr") {
writeConsoleOutToDiv(outputDiv, data, type);
}
});

const result = JSON.parse(await (ret.result as RString).toString());
if (setData) {
setData(result);
}
} finally {
shelter.purge();
}
setStatus("completed");
} catch (e: any) {
console.error(e);
if (outputDiv.current) {
const divElement = document.createElement("div");
divElement.style.color = "red";
const preElement = document.createElement("pre");
divElement.appendChild(preElement);
preElement.textContent = e.toString();
outputDiv.current.appendChild(divElement);
}
writeConsoleOutToDiv(outputDiv, e.toString(), "stderr");
setStatus("failed");
}
}, [editedFileContent, fileContent, status, setData, outputDiv]);
Expand All @@ -131,6 +112,7 @@ json_result
const toolbarItems: ToolbarItem[] = useMemo(
() =>
getDataGenerationToolbarItems({
name: "WebR",
status,
runnable: fileContent === editedFileContent,
onRun: handleRun,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import { Help, PlayArrow } from "@mui/icons-material";

const getDataGenerationToolbarItems = (o: {
status: PyodideWorkerStatus;
name: string;
runnable: boolean;
onRun: () => void;
onHelp: () => void;
}): ToolbarItem[] => {
const { status, onRun, runnable, onHelp } = o;
const { status, onRun, runnable, onHelp, name } = o;
const ret: ToolbarItem[] = [];
ret.push({
type: "button",
Expand All @@ -29,7 +30,7 @@ const getDataGenerationToolbarItems = (o: {
let label: string;
let color: string;
if (status === "loading") {
label = "Loading pyodide...";
label = `Loading ${name}...`;
color = "blue";
} else if (status === "running") {
label = "Running...";
Expand Down
10 changes: 10 additions & 0 deletions gui/src/localStyles.css
Original file line number Diff line number Diff line change
Expand Up @@ -192,3 +192,13 @@ span.EditorTitle {
height: 100%;
overflow: auto;
}

.EditorHintText {
font-style: italic;
color: #aaa;
}

.EditorHintTextLink {
color: gray;
text-decoration: underline;
}

0 comments on commit fe7a9f9

Please sign in to comment.