Skip to content

Commit fc02934

Browse files
authored
feat: add rich-text node (#160)
* add rich-text node * save content to db * add back @emotion/xxx packages * fix level color condition
1 parent efc7e7c commit fc02934

File tree

7 files changed

+2697
-43
lines changed

7 files changed

+2697
-43
lines changed

ui/package.json

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,16 @@
66
"@apollo/client": "^3.7.0",
77
"@dnd-kit/core": "^6.0.5",
88
"@emotion/css": "^11.10.0",
9-
"@emotion/react": "^11.10.4",
10-
"@emotion/styled": "^11.10.4",
9+
"@emotion/react": "^11.10.5",
10+
"@emotion/styled": "^11.10.5",
1111
"@mui/icons-material": "^5.10.9",
1212
"@mui/material": "^5.10.10",
13+
"@remirror/extension-react-tables": "^2.2.9",
14+
"@remirror/extension-sub": "^2.0.9",
15+
"@remirror/extension-text-highlight": "^2.0.10",
16+
"@remirror/pm": "^2.0.2",
17+
"@remirror/react": "^2.0.22",
18+
"@remirror/react-editors": "^1.0.22",
1319
"@testing-library/jest-dom": "^5.14.1",
1420
"@testing-library/react": "^13.0.0",
1521
"@testing-library/user-event": "^13.2.1",
@@ -36,6 +42,7 @@
3642
"react-router-dom": "^6.4.2",
3743
"react-scripts": "5.0.1",
3844
"reactflow": "^11.3.0",
45+
"remirror": "^2.0.21",
3946
"slate": "^0.82.1",
4047
"slate-history": "^0.66.0",
4148
"slate-react": "^0.83.2",

ui/src/components/Canvas.tsx

Lines changed: 58 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ import { useApolloClient } from "@apollo/client";
6060
import { CanvasContextMenu } from "./CanvasContextMenu";
6161
import styles from "./canvas.style.js";
6262
import { ShareProjDialog } from "./ShareProjDialog";
63+
import { RichNode } from "./RichNode";
6364

6465
const nanoid = customAlphabet(lowercase + numbers, 20);
6566

@@ -741,7 +742,7 @@ const CodeNode = memo<Props>(function ({
741742
);
742743
});
743744

744-
const nodeTypes = { scope: ScopeNode, code: CodeNode };
745+
const nodeTypes = { scope: ScopeNode, code: CodeNode, rich: RichNode };
745746

746747
const level2color = {
747748
0: "rgba(187, 222, 251, 0.5)",
@@ -768,6 +769,39 @@ function getAbsPos({ node, nodesMap }) {
768769
}
769770
}
770771

772+
/**
773+
* For historical reason, the state.pod.type and DB schema pod.type are "CODE",
774+
* "DECK", "WYSIWYG", while the node types in react-flow are "code", "scope",
775+
* "rich". These two functions document this and handle the conversion.
776+
* @param dbtype
777+
* @returns
778+
*/
779+
function dbtype2nodetype(dbtype: string) {
780+
switch (dbtype) {
781+
case "CODE":
782+
return "code";
783+
case "DECK":
784+
return "scope";
785+
case "WYSIWYG":
786+
return "rich";
787+
default:
788+
throw new Error(`unknown dbtype ${dbtype}`);
789+
}
790+
}
791+
792+
function nodetype2dbtype(nodetype: string) {
793+
switch (nodetype) {
794+
case "code":
795+
return "CODE";
796+
case "scope":
797+
return "DECK";
798+
case "rich":
799+
return "WYSIWYG";
800+
default:
801+
throw new Error(`unknown nodetype ${nodetype}`);
802+
}
803+
}
804+
771805
export function Canvas() {
772806
const [nodes, setNodes, onNodesChange] = useNodesStateSynced([]);
773807
const [edges, setEdges] = useState<any[]>([]);
@@ -795,7 +829,7 @@ export function Canvas() {
795829
if (id !== "ROOT") {
796830
res.push({
797831
id: id,
798-
type: pod.type === "CODE" ? "code" : "scope",
832+
type: dbtype2nodetype(pod.type),
799833
data: {
800834
// label: `ID: ${id}, parent: ${pods[id].parent}, pos: ${pods[id].x}, ${pods[id].y}`,
801835
label: id,
@@ -809,7 +843,7 @@ export function Canvas() {
809843
level,
810844
style: {
811845
backgroundColor:
812-
pod.type === "CODE"
846+
pod.type !== "DECK"
813847
? undefined
814848
: level2color[level] || level2color["default"],
815849
width: pod.width || undefined,
@@ -904,23 +938,28 @@ export function Canvas() {
904938
);
905939

906940
const addNode = useCallback(
907-
(x: number, y: number, type: string) => {
941+
(x: number, y: number, type: "code" | "scope" | "rich") => {
908942
const reactFlowBounds = reactFlowWrapper.current.getBoundingClientRect();
909943
let style;
910944

911-
// if (type === "code") type = "default";
912-
if (type === "scope") {
913-
style = {
914-
backgroundColor: level2color[0],
915-
width: 600,
916-
height: 600,
917-
};
918-
} else {
919-
style = {
920-
width: 300,
921-
// we must not set the height here, otherwise the auto layout will not work
922-
height: undefined,
923-
};
945+
switch (type) {
946+
case "scope":
947+
style = {
948+
backgroundColor: level2color[0],
949+
width: 600,
950+
height: 600,
951+
};
952+
break;
953+
case "code":
954+
case "rich":
955+
style = {
956+
width: 300,
957+
// we must not set the height here, otherwise the auto layout will not work
958+
height: undefined,
959+
};
960+
break;
961+
default:
962+
throw new Error(`unknown type ${type}`);
924963
}
925964

926965
const position = reactFlowInstance.project({
@@ -951,7 +990,7 @@ export function Canvas() {
951990
addPod(apolloClient, {
952991
id,
953992
parent: "ROOT",
954-
type: type === "code" ? "CODE" : "DECK",
993+
type: nodetype2dbtype(type),
955994
lang: "python",
956995
x: position.x,
957996
y: position.y,
@@ -1405,6 +1444,7 @@ export function Canvas() {
14051444
y={points.y}
14061445
addCode={() => addNode(client.x, client.y, "code")}
14071446
addScope={() => addNode(client.x, client.y, "scope")}
1447+
addRich={() => addNode(client.x, client.y, "rich")}
14081448
onShareClick={() => {
14091449
setShareOpen(true);
14101450
}}

ui/src/components/CanvasContextMenu.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import MenuItem from "@mui/material/MenuItem";
88
import React, { useContext } from "react";
99
import CodeIcon from "@mui/icons-material/Code";
1010
import PostAddIcon from "@mui/icons-material/PostAdd";
11+
import NoteIcon from "@mui/icons-material/Note";
1112
import FormatListNumberedIcon from "@mui/icons-material/FormatListNumbered";
1213

1314
const paneMenuStyle = (left, top) => {
@@ -51,6 +52,14 @@ export function CanvasContextMenu(props) {
5152
<ListItemText>New Code</ListItemText>
5253
</MenuItem>
5354
)}
55+
{role !== RoleType.GUEST && (
56+
<MenuItem onClick={props.addRich} sx={ItemStyle}>
57+
<ListItemIcon>
58+
<NoteIcon />
59+
</ListItemIcon>
60+
<ListItemText>New Note</ListItemText>
61+
</MenuItem>
62+
)}
5463
{role !== RoleType.GUEST && (
5564
<MenuItem onClick={props.addScope} sx={ItemStyle}>
5665
<ListItemIcon>

0 commit comments

Comments
 (0)