diff --git a/ui/src/components/Canvas.tsx b/ui/src/components/Canvas.tsx
index 3674b8dd..aaaf2ac7 100644
--- a/ui/src/components/Canvas.tsx
+++ b/ui/src/components/Canvas.tsx
@@ -38,6 +38,7 @@ import { RepoContext } from "../lib/store";
import { MyMonaco } from "./MyMonaco";
import { useApolloClient } from "@apollo/client";
+import { CanvasContextMenu } from "./CanvasContextMenu";
const nanoid = customAlphabet(nolookalikes, 10);
@@ -727,36 +728,12 @@ export function Canvas() {
{showContextMenu && (
-
-
-
-
-
-
+ addNode(client.x, client.y, "code")}
+ addScope={() => addNode(client.x, client.y, "scope")}
+ />
)}
diff --git a/ui/src/components/CanvasContextMenu.tsx b/ui/src/components/CanvasContextMenu.tsx
new file mode 100644
index 00000000..ac89c65c
--- /dev/null
+++ b/ui/src/components/CanvasContextMenu.tsx
@@ -0,0 +1,68 @@
+import { useStore } from "zustand";
+import { RepoContext } from "../lib/store";
+import Box from "@mui/material/Box";
+import ListItemIcon from "@mui/material/ListItemIcon";
+import ListItemText from "@mui/material/ListItemText";
+import MenuList from "@mui/material/MenuList";
+import MenuItem from "@mui/material/MenuItem";
+import React, { useContext } from "react";
+import CodeIcon from "@mui/icons-material/Code";
+import PostAddIcon from "@mui/icons-material/PostAdd";
+import FormatListNumberedIcon from "@mui/icons-material/FormatListNumbered";
+
+const paneMenuStyle = (left, top) => {
+ return {
+ left: `${left}px`,
+ top: `${top}px`,
+ zIndex: 100,
+ position: "absolute",
+ boxShadow: "0px 1px 8px 0px rgba(0, 0, 0, 0.1)",
+ // width: '200px',
+ backgroundColor: "#fff",
+ borderRadius: "5px",
+ boxSizing: "border-box",
+ } as React.CSSProperties;
+};
+
+const ItemStyle = {
+ "&:hover": {
+ background: "#f1f3f7",
+ color: "#4b00ff",
+ },
+};
+
+export function CanvasContextMenu(props) {
+ const store = useContext(RepoContext);
+ if (!store) throw new Error("Missing BearContext.Provider in the tree");
+ const showLineNumbers = useStore(store, (state) => state.showLineNumbers);
+ const flipShowLineNumbers = useStore(
+ store,
+ (state) => state.flipShowLineNumbers
+ );
+ return (
+
+
+
+
+
+
+
+ );
+}
diff --git a/ui/src/components/MyMonaco.tsx b/ui/src/components/MyMonaco.tsx
index 0ec54f1d..efd36ab7 100644
--- a/ui/src/components/MyMonaco.tsx
+++ b/ui/src/components/MyMonaco.tsx
@@ -1,7 +1,9 @@
import { Position } from "monaco-editor";
-import { useState } from "react";
+import { useState, useContext } from "react";
import MonacoEditor, { MonacoDiffEditor } from "react-monaco-editor";
import { monaco } from "react-monaco-editor";
+import { useStore } from "zustand";
+import { RepoContext } from "../lib/store";
monaco.languages.setLanguageConfiguration("julia", {
indentationRules: {
@@ -304,6 +306,10 @@ export function MyMonaco({
}) {
// console.log("rendering monaco ..");
// there's no racket language support
+ const store = useContext(RepoContext);
+ if (!store) throw new Error("Missing BearContext.Provider in the tree");
+ const showLineNumbers = useStore(store, (state) => state.showLineNumbers);
+
if (lang === "racket") {
lang = "scheme";
}
@@ -334,6 +340,7 @@ export function MyMonaco({
// autoIndent: true,
overviewRulerLanes: 0,
automaticLayout: true,
+ lineNumbers: showLineNumbers ? "on" : "off",
scrollbar: {
alwaysConsumeMouseWheel: false,
vertical: "hidden",
diff --git a/ui/src/index.css b/ui/src/index.css
index ec2585e8..3e3b6a19 100644
--- a/ui/src/index.css
+++ b/ui/src/index.css
@@ -10,4 +10,4 @@ body {
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
-}
+}
\ No newline at end of file
diff --git a/ui/src/lib/store.tsx b/ui/src/lib/store.tsx
index 01c0cc4c..4a014e34 100644
--- a/ui/src/lib/store.tsx
+++ b/ui/src/lib/store.tsx
@@ -15,8 +15,9 @@ import {
import { createRuntimeSlice, RuntimeSlice } from "./runtime";
import { ApolloClient } from "@apollo/client";
-export const RepoContext =
- createContext | null>(null);
+export const RepoContext = createContext | null>(null);
// TODO use a selector to compute and retrieve the status
// TODO this need to cooperate with syncing indicator
@@ -67,6 +68,7 @@ const initialState = {
queueProcessing: false,
socket: null,
socketIntervalId: null,
+ showLineNumbers: true,
};
export type Pod = {
@@ -125,6 +127,7 @@ export interface RepoSlice {
kernels: Record;
// queueProcessing: boolean;
socket: WebSocket | null;
+ showLineNumbers: boolean;
error: { type: string; msg: string } | null;
updatePod: ({ id, data }: { id: string; data: Partial }) => void;
remoteUpdateAllPods: (client) => void;
@@ -151,6 +154,7 @@ export interface RepoSlice {
}) => void;
setPodPosition: ({ id, x, y }: any) => void;
setPodParent: ({ id, parent }: any) => void;
+ flipShowLineNumbers: () => void;
}
type BearState = RepoSlice & RuntimeSlice;
@@ -622,6 +626,8 @@ const createRepoSlice: StateCreator<
// state.pods[action.meta.arg.id].isSyncing = false;
// state.pods[action.meta.arg.id].dirty = false;
},
+ flipShowLineNumbers: () =>
+ set((state) => ({ showLineNumbers: !state.showLineNumbers })),
});
export const createRepoStore = () =>