From 2bda021105c16359cc5cb4bbc5b7b0f059a1a087 Mon Sep 17 00:00:00 2001 From: frikky Date: Fri, 17 Mar 2023 00:47:22 +0100 Subject: [PATCH] Finally made the code editor side-by-side as it should've been all along --- frontend/src/components/ShuffleCodeEditor.jsx | 1463 +++++++++-------- 1 file changed, 758 insertions(+), 705 deletions(-) diff --git a/frontend/src/components/ShuffleCodeEditor.jsx b/frontend/src/components/ShuffleCodeEditor.jsx index af9d5b31..e7daa155 100644 --- a/frontend/src/components/ShuffleCodeEditor.jsx +++ b/frontend/src/components/ShuffleCodeEditor.jsx @@ -14,6 +14,7 @@ import { Button, } from '@material-ui/core'; +import theme from '../theme'; import Checkbox from '@mui/material/Checkbox'; import { orange } from '@mui/material/colors'; import { isMobile } from "react-device-detect" @@ -34,10 +35,11 @@ import { } from '@mui/icons-material'; import { - AutoFixHigh as AutoFixHighIcon, CompressOutlined, QrCodeScannerOutlined, + AutoFixHigh as AutoFixHighIcon, + CompressOutlined, + QrCodeScannerOutlined, } from '@mui/icons-material'; -import { useTheme } from '@material-ui/core/styles'; import { validateJson } from "../views/Workflows.jsx"; import ReactJson from "react-json-view"; import PaperComponent from "../components/PaperComponent.jsx"; @@ -50,6 +52,9 @@ import 'codemirror/theme/duotone-light.css'; import { padding, textAlign } from '@mui/system'; import data from '../frameworkStyle.jsx'; import { useNavigate, Link, useParams } from "react-router-dom"; +import { createTheme } from '@uiw/codemirror-themes'; + +import { tags } from '@lezer/highlight'; const liquidFilters = [ {"name": "Size", "value": "size", "example": ""}, @@ -74,12 +79,44 @@ const pythonFilters = [ {"name": "Handle JSON", "value": `{% python %}\nimport json\njsondata = json.loads(r"""$nodename""")\n{% endpython %}`, "example": ``}, ] +const shuffleTheme = createTheme({ + theme: 'dark', + settings: { + background: '#282828', + foreground: '#ffffff', + caret: '#5d00ff', + selection: '#036dd626', + selectionMatch: '#036dd626', + lineHighlight: '#8a91991a', + gutterBackground: '#fff', + gutterForeground: '#8a919966', + fontSize: 18, + borderRadius: theme.palette.borderRadius, + border: `2px solid ${theme.palette.inputColor}`, + }, + styles: [ + { tag: tags.comment, color: '#787b8099' }, + { tag: tags.variableName, color: '#0080ff' }, + { tag: [tags.string, tags.special(tags.brace)], color: '#5c6166' }, + { tag: tags.number, color: '#5c6166' }, + { tag: tags.bool, color: '#5c6166' }, + { tag: tags.null, color: '#5c6166' }, + { tag: tags.keyword, color: '#5c6166' }, + { tag: tags.operator, color: '#5c6166' }, + { tag: tags.className, color: '#5c6166' }, + { tag: tags.definition(tags.typeName), color: '#5c6166' }, + { tag: tags.typeName, color: '#5c6166' }, + { tag: tags.angleBracket, color: '#5c6166' }, + { tag: tags.tagName, color: '#5c6166' }, + { tag: tags.attributeName, color: '#5c6166' }, + ], +}); + const CodeEditor = (props) => { const { globalUrl, fieldCount, setFieldCount, actionlist, changeActionParameterCodeMirror, expansionModalOpen, setExpansionModalOpen, codedata, setcodedata, isFileEditor, runUpdateText } = props const [localcodedata, setlocalcodedata] = React.useState(codedata === undefined || codedata === null || codedata.length === 0 ? "" : codedata); // const {codelang, setcodelang} = props - const theme = useTheme(); const [validation, setValidation] = React.useState(false); const [expOutput, setExpOutput] = React.useState(" "); const [linewrap, setlinewrap] = React.useState(true); @@ -298,7 +335,7 @@ const CodeEditor = (props) => { var variable_occurence = current_code_line.match(/[\\]{0,1}[$]{1}([a-zA-Z0-9_-]+\.?){1}([a-zA-Z0-9#_-]+\.?){0,}/g) if (variable_occurence === null || variable_occurence === undefined) { - console.log("No variables found. Returning") + //console.log("No variables found. Returning") continue } @@ -310,7 +347,7 @@ const CodeEditor = (props) => { } variable_occurence = new_occurences.valueOf() - console.log("Match2: ", variable_occurence) + //console.log("Match2: ", variable_occurence) // console.log(variable_occurence) // console.log() @@ -410,10 +447,6 @@ const CodeEditor = (props) => { //const found = input.match(/[$]{1}([a-zA-Z0-9_-]+\.?){1}([a-zA-Z0-9#_-]+\.?){0,}/g) const found = input.match(/[$]{1}([a-zA-Z0-9_-]+\.?){1}([a-zA-Z0-9#_-]+\.?){0,}/g) - //if (found === null || found === undefined) { - // console.log("No output found!") - // return - //} console.log("FOUND: ", found) @@ -510,7 +543,7 @@ const CodeEditor = (props) => { } } } catch (e) { - console.log("Outer replace error: ", e) + //console.log("Outer replace error: ", e) } const tmpValidation = validateJson(input.valueOf()) @@ -656,646 +689,696 @@ const CodeEditor = (props) => { style: { backgroundColor: theme.palette.surfaceColor, color: "white", - minWidth: isMobile ? "100%" : 600, - maxHeight: isMobile ? "100%" : 800, + minWidth: isMobile ? "100%" : 1200, + maxWidth: isMobile ? "100%" : 1200, + minHeight: isMobile ? "100%" : 900, + maxHeight: isMobile ? "100%" : 900, padding: isMobile ? "25px 10px 25px 10px" : 25, border: theme.palette.defaultBorder, zIndex: 12501, }, }} - > - { isFileEditor ? -
- - File Editor - -
-
- : -
-
- + { isFileEditor ? +
- Code Editor - - { - - }} - > - - - - - - - { - autoFormat(localcodedata) - }} - > - - - - -
-
} - - - { isFileEditor ? null : -
- - { - setAnchorEl(null); - }} - MenuListProps={{ - 'aria-labelledby': 'basic-button', - }} - > - {liquidFilters.map((item, index) => { - return ( - { - handleClick(item) - }}>{item.name} - ) - })} - - - { - setAnchorEl2(null); - }} - MenuListProps={{ - 'aria-labelledby': 'basic-button', - }} - > - {mathFilters.map((item, index) => { - return ( - { - handleClick(item) - }}>{item.name} - ) - })} - - - { - setAnchorEl3(null); - }} - MenuListProps={{ - 'aria-labelledby': 'basic-button', - }} - > - {pythonFilters.map((item, index) => { - return ( - { - handleClick(item) - }}>{item.name} - ) - })} - - - { - handleMenuClose(); - }} - open={!!menuPosition} - style={{ - color: "white", - marginTop: 2, - maxHeight: 650, - }} - > - {actionlist.map((innerdata) => { - const icon = - innerdata.type === "action" ? ( - - ) : innerdata.type === "workflow_variable" || - innerdata.type === "execution_variable" ? ( - - ) : ( - - ); - - const handleExecArgumentHover = (inside) => { - var exec_text_field = document.getElementById( - "execution_argument_input_field" - ); - if (exec_text_field !== null) { - if (inside) { - exec_text_field.style.border = "2px solid #f85a3e"; - } else { - exec_text_field.style.border = ""; - } - } - }; - - const handleActionHover = (inside, actionId) => { - }; - - const handleMouseover = () => { - if (innerdata.type === "Execution Argument") { - handleExecArgumentHover(true); - } else if (innerdata.type === "action") { - handleActionHover(true, innerdata.id); - } - }; - - const handleMouseOut = () => { - if (innerdata.type === "Execution Argument") { - handleExecArgumentHover(false); - } else if (innerdata.type === "action") { - handleActionHover(false, innerdata.id); - } - }; - - var parsedPaths = []; - if (typeof innerdata.example === "object") { - parsedPaths = GetParsedPaths(innerdata.example, ""); - } - - const coverColor = "#82ccc3" - //menuPosition.left -= 50 - //menuPosition.top -= 250 - //console.log("POS: ", menuPosition1) - var menuPosition1 = menuPosition - if (menuPosition1 === null) { - menuPosition1 = { - "left": 0, - "top": 0, - } - } else if (menuPosition1.top === null || menuPosition1.top === undefined) { - menuPosition1.top = 0 - } else if (menuPosition1.left === null || menuPosition1.left === undefined) { - menuPosition1.left = 0 - } - - //console.log("POS1: ", menuPosition1) - - return parsedPaths.length > 0 ? ( - - {icon} {innerdata.name} -
- } - parentMenuOpen={!!menuPosition} +
+ + File Editor + +
+
+ : +
+
+ + Code Editor + + { - console.log("CLICKED: ", innerdata); - console.log(innerdata.example) - handleItemClick([innerdata]); + }} > - + + + + + + + { + autoFormat(localcodedata) + }} + > + + + + +
+
+ } + + + { isFileEditor ? null : +
+ + { + setAnchorEl(null); + }} + MenuListProps={{ + 'aria-labelledby': 'basic-button', + }} + > + {liquidFilters.map((item, index) => { + return ( + { + handleClick(item) + }}>{item.name} + ) + })} + + + { + setAnchorEl2(null); + }} + MenuListProps={{ + 'aria-labelledby': 'basic-button', + }} + > + {mathFilters.map((item, index) => { + return ( + { + handleClick(item) + }}>{item.name} + ) + })} + + + { + setAnchorEl3(null); + }} + MenuListProps={{ + 'aria-labelledby': 'basic-button', + }} + > + {pythonFilters.map((item, index) => { + return ( + { + handleClick(item) + }}>{item.name} + ) + })} + + + { + handleMenuClose(); + }} + open={!!menuPosition} + style={{ + color: "white", + marginTop: 2, + maxHeight: 650, + }} + > + {actionlist.map((innerdata) => { + const icon = + innerdata.type === "action" ? ( + + ) : innerdata.type === "workflow_variable" || + innerdata.type === "execution_variable" ? ( + + ) : ( + + ); + + const handleExecArgumentHover = (inside) => { + var exec_text_field = document.getElementById( + "execution_argument_input_field" + ); + if (exec_text_field !== null) { + if (inside) { + exec_text_field.style.border = "2px solid #f85a3e"; + } else { + exec_text_field.style.border = ""; + } + } + }; + + const handleActionHover = (inside, actionId) => { + }; + + const handleMouseover = () => { + if (innerdata.type === "Execution Argument") { + handleExecArgumentHover(true); + } else if (innerdata.type === "action") { + handleActionHover(true, innerdata.id); + } + }; + + const handleMouseOut = () => { + if (innerdata.type === "Execution Argument") { + handleExecArgumentHover(false); + } else if (innerdata.type === "action") { + handleActionHover(false, innerdata.id); + } + }; + + var parsedPaths = []; + if (typeof innerdata.example === "object") { + parsedPaths = GetParsedPaths(innerdata.example, ""); + } + + const coverColor = "#82ccc3" + //menuPosition.left -= 50 + //menuPosition.top -= 250 + //console.log("POS: ", menuPosition1) + var menuPosition1 = menuPosition + if (menuPosition1 === null) { + menuPosition1 = { + "left": 0, + "top": 0, + } + } else if (menuPosition1.top === null || menuPosition1.top === undefined) { + menuPosition1.top = 0 + } else if (menuPosition1.left === null || menuPosition1.left === undefined) { + menuPosition1.left = 0 + } + + //console.log("POS1: ", menuPosition1) + + return parsedPaths.length > 0 ? ( + + {icon} {innerdata.name} +
+ } + parentMenuOpen={!!menuPosition} + style={{ + color: "white", + minWidth: 250, + maxWidth: 250, + maxHeight: 50, + overflow: "hidden", + }} + onClick={() => { + console.log("CLICKED: ", innerdata); + console.log(innerdata.example) + handleItemClick([innerdata]); + }} + > + + { + //console.log("HOVER: ", pathdata); + }} + onClick={() => { + handleItemClick([innerdata]); + }} + > + + {innerdata.name} + + + {parsedPaths.map((pathdata, index) => { + // FIXME: Should be recursive in here + // + const icon = + pathdata.type === "value" ? ( + + ) : pathdata.type === "list" ? ( + + ) : ( + + ); + // + + const indentation_count = (pathdata.name.match(/\./g) || []).length+1 + //const boxPadding = pathdata.type === "object" ? "10px 0px 0px 0px" : 0 + const boxPadding = 0 + const namesplit = pathdata.name.split(".") + const newname = namesplit[namesplit.length-1] + return ( + { + //console.log("HOVER: ", pathdata); + }} + onClick={() => { + handleItemClick([innerdata, pathdata]); + }} + > + +
+ {Array(indentation_count).fill().map((subdata, subindex) => { + return ( +
+ ) + })} + {icon} {newname} + {pathdata.type === "list" ? { + e.preventDefault() + e.stopPropagation() + + console.log("INNER: ", innerdata, pathdata) + + // Removing .list from autocomplete + var newname = pathdata.name + if (newname.length > 5) { + newname = newname.slice(0, newname.length-5) + } + + //selectedActionParameters[count].value += `{{ $${innerdata.name}.${newname} | size }}` + //selectedAction.parameters[count].value = selectedActionParameters[count].value; + //setSelectedAction(selectedAction); + //setShowDropdown(false); + setMenuPosition(null); + + // innerdata.name + // pathdata.name + //handleItemClick([innerdata, newpathdata]) + //console.log("CLICK LENGTH!") + }} /> : null} +
+ + + ); + })} + + + ) : ( { - //console.log("HOVER: ", pathdata); + onMouseOver={() => handleMouseover()} + onMouseOut={() => { + handleMouseOut(); }} onClick={() => { handleItemClick([innerdata]); }} > - - {innerdata.name} - + +
+ {icon} {innerdata.name} +
+
- {parsedPaths.map((pathdata, index) => { - // FIXME: Should be recursive in here - // - const icon = - pathdata.type === "value" ? ( - - ) : pathdata.type === "list" ? ( - - ) : ( - - ); - // + ); + })} + +
+ } + + { + // console.log(value.getCursor()) + setCurrentCharacter(value.getCursor().ch) + setCurrentLine(value.getCursor().line) + // console.log(value.getCursor().ch, value.getCursor().line) + findIndex(value.getCursor().line, value.getCursor().ch) + highlight_variables(value) + }} + onChange={(value) => { + setlocalcodedata(value.getValue()) + expectedOutput(value.getValue()) - const indentation_count = (pathdata.name.match(/\./g) || []).length+1 - //const boxPadding = pathdata.type === "object" ? "10px 0px 0px 0px" : 0 - const boxPadding = 0 - const namesplit = pathdata.name.split(".") - const newname = namesplit[namesplit.length-1] - return ( - { - //console.log("HOVER: ", pathdata); - }} - onClick={() => { - handleItemClick([innerdata, pathdata]); - }} - > - -
- {Array(indentation_count).fill().map((subdata, subindex) => { - return ( -
- ) - })} - {icon} {newname} - {pathdata.type === "list" ? { - e.preventDefault() - e.stopPropagation() + if(value.display.input.prevInput.startsWith('$') || value.display.input.prevInput.endsWith('$')){ + setEditorPopupOpen(true) + } - console.log("INNER: ", innerdata, pathdata) - - // Removing .list from autocomplete - var newname = pathdata.name - if (newname.length > 5) { - newname = newname.slice(0, newname.length-5) - } + // console.log(findIndex(value.getValue())) + // highlight_variables(value) + }} + options={{ + styleSelectedText: true, + keyMap: 'sublime', + mode: 'python', + lineWrapping: linewrap, + //theme: codeTheme, + // mode: {codelang}, + }} + /> + - //selectedActionParameters[count].value += `{{ $${innerdata.name}.${newname} | size }}` - //selectedAction.parameters[count].value = selectedActionParameters[count].value; - //setSelectedAction(selectedAction); - //setShowDropdown(false); - setMenuPosition(null); - - // innerdata.name - // pathdata.name - //handleItemClick([innerdata, newpathdata]) - //console.log("CLICK LENGTH!") - }} /> : null} -
- - - ); - })} - - - ) : ( - handleMouseover()} - onMouseOut={() => { - handleMouseOut(); - }} - onClick={() => { - handleItemClick([innerdata]); - }} - > - -
- {icon} {innerdata.name} + {/*editorPopupOpen ? + + {mainVariables.map((data, index) => { + // console.log(data) + return ( +
+
- - - ); - })} - - -
} - - { - // console.log(value.getCursor()) - setCurrentCharacter(value.getCursor().ch) - setCurrentLine(value.getCursor().line) - // console.log(value.getCursor().ch, value.getCursor().line) - findIndex(value.getCursor().line, value.getCursor().ch) - highlight_variables(value) - }} - onChange={(value) => { - setlocalcodedata(value.getValue()) - expectedOutput(value.getValue()) - - if(value.display.input.prevInput.startsWith('$') || value.display.input.prevInput.endsWith('$')){ - setEditorPopupOpen(true) - } - - // console.log(findIndex(value.getValue())) - // highlight_variables(value) - }} - options={{ - styleSelectedText: true, - theme: codeTheme, - keyMap: 'sublime', - mode: 'python', - lineWrapping: linewrap, - // mode: {codelang}, - }} - /> - - {/*editorPopupOpen ? - - {mainVariables.map((data, index) => { - // console.log(data) - return ( -
+ : null*/} + +
+ {/* + + Line Wrap + { + if (linewrap) { + setlinewrap(false) + } + if (!linewrap){ + setlinewrap(true) + } }} - > -
+
+ +
+ {isFileEditor ? null : +
+ {isMobile ? null : + - {data.substring(0, 25)} - -
- ) - })} - - : null*/} + + Expected Output + -
- {/* - - Line Wrap - { - if (linewrap) { - setlinewrap(false) - } - if (!linewrap){ - setlinewrap(true) - } - }} - defaultChecked - size="small" - sx={{ - color: orange[600], - '&.Mui-checked': { - color: orange[800], - }, - }} - /> - + { + executeSingleAction(expOutput) + }}> + + {executing ? : } + + + - - Dark Theme - { - if (codeTheme === "gruvbox-dark") { - setcodeTheme("duotone-light") + } - if (codeTheme === "duotone-light"){ - setcodeTheme("gruvbox-dark") - } - }} - defaultChecked - size="small" - sx={{ - color: orange[600], - '&.Mui-checked': { - color: orange[800], - }, - }} - /> - - */} -
- {isFileEditor ? null : ( -
- {isMobile ? null : - - - Expected Output - - { - executeSingleAction(expOutput) - }}> - - {executing ? : } - - - - - } - {isMobile ? null : - validation === true ? + {isMobile ? null : + validation === true ? + { + //handleReactJsonClipboard(copy); + }} + displayDataTypes={false} + onSelect={(select) => { + //HandleJsonCopy(validate.result, select, "exec"); + }} + name={"JSON autocompletion"} + /> + : +

+ {expOutput} +

+ } + + {executionResult.valid === true ? { onSelect={(select) => { //HandleJsonCopy(validate.result, select, "exec"); }} - name={"JSON autocompletion"} + name={"Test result"} /> : -

- {expOutput} -

+ + {executionResult.result.length > 0 ? + + + Test output + + + {executionResult.result} + + + : + + No test output yet. + + } + {executionResult.errors !== undefined && executionResult.errors !== null && executionResult.errors.length > 0 ? + + Errors ({executionResult.errors.length}): {executionResult.errors.join("\n")} + + : null} + + } +
+ } - {executionResult.valid === true ? - { - //handleReactJsonClipboard(copy); - }} - displayDataTypes={false} - onSelect={(select) => { - //HandleJsonCopy(validate.result, select, "exec"); - }} - name={"Test result"} - /> - : - - {executionResult.result.length > 0 ? - - Test output: {executionResult.result} - - : null} - {executionResult.errors !== undefined && executionResult.errors !== null && executionResult.errors.length > 0 ? - - Errors ({executionResult.errors.length}): {executionResult.errors.join("\n")} - - : null} - - } -
- ) - } -
+ + {/* Flexbox stop */} +
+ + +
+ - + } + else { + changeActionParameterCodeMirror(event, fieldCount, localcodedata) + setExpansionModalOpen(false) + setcodedata(localcodedata)} + }} + > + Done +
) }