From 4a1c209be702a2b74055f29d64d32dfb6dd35b1b Mon Sep 17 00:00:00 2001 From: frikky Date: Thu, 23 Mar 2023 00:53:58 +0100 Subject: [PATCH] Fixed file search issue --- backend/go-app/docker.go | 7 +- backend/go-app/go.mod | 2 +- backend/go-app/walkoff.go | 2 +- docker-compose.yml | 66 +++---- frontend/package.json | 4 +- frontend/src/App.jsx | 4 +- frontend/src/components/AppFramework.jsx | 5 +- frontend/src/components/Files.jsx | 10 +- frontend/src/components/ShuffleCodeEditor.jsx | 171 +++++++++--------- frontend/src/views/Admin.jsx | 42 ++++- frontend/src/views/AngularWorkflow.jsx | 19 +- frontend/src/views/AppCreator.jsx | 18 +- 12 files changed, 203 insertions(+), 147 deletions(-) diff --git a/backend/go-app/docker.go b/backend/go-app/docker.go index 80b4e30f..32dc2028 100644 --- a/backend/go-app/docker.go +++ b/backend/go-app/docker.go @@ -241,16 +241,15 @@ func buildImageMemory(fs billy.Filesystem, tags []string, dockerfileFolder strin BuildArgs: map[string]*string{}, Labels: labels, } - // NetworkMode: "host", httpProxy := os.Getenv("HTTP_PROXY") if len(httpProxy) > 0 { - buildOptions.BuildArgs["http_proxy"] = &httpProxy + buildOptions.BuildArgs["HTTP_PROXY"] = &httpProxy } httpsProxy := os.Getenv("HTTPS_PROXY") if len(httpProxy) > 0 { - buildOptions.BuildArgs["https_proxy"] = &httpsProxy + buildOptions.BuildArgs["HTTPS_PROXY"] = &httpsProxy } // Build the actual image @@ -352,7 +351,7 @@ func buildImage(tags []string, dockerfileFolder string) error { httpProxy := os.Getenv("HTTP_PROXY") if len(httpProxy) > 0 { - buildOptions.BuildArgs["http_proxy"] = &httpProxy + buildOptions.BuildArgs["HTTP_PROXY"] = &httpProxy } httpsProxy := os.Getenv("HTTPS_PROXY") if len(httpProxy) > 0 { diff --git a/backend/go-app/go.mod b/backend/go-app/go.mod index 4896d183..6f8eb828 100644 --- a/backend/go-app/go.mod +++ b/backend/go-app/go.mod @@ -19,7 +19,7 @@ require ( github.com/gorilla/mux v1.8.0 github.com/h2non/filetype v1.1.3 github.com/satori/go.uuid v1.2.0 - github.com/shuffle/shuffle-shared v0.3.70 + github.com/shuffle/shuffle-shared v0.3.71 golang.org/x/crypto v0.3.0 google.golang.org/api v0.103.0 google.golang.org/appengine v1.6.7 diff --git a/backend/go-app/walkoff.go b/backend/go-app/walkoff.go index bec3bf8b..8da2f602 100644 --- a/backend/go-app/walkoff.go +++ b/backend/go-app/walkoff.go @@ -369,7 +369,7 @@ func handleGetStreamResults(resp http.ResponseWriter, request *http.Request) { ctx := context.Background() workflowExecution, err := shuffle.GetWorkflowExecution(ctx, actionResult.ExecutionId) if err != nil { - log.Printf("[WARNING] Failed getting execution (streamresult) %s: %s", actionResult.ExecutionId, err) + log.Printf("[WARNING][%s] Failed getting execution (streamresult): %s", actionResult.ExecutionId, err) resp.WriteHeader(401) resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Bad authorization key or execution_id might not exist."}`))) return diff --git a/docker-compose.yml b/docker-compose.yml index f64e5899..a6c0a4c3 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,38 +1,38 @@ version: '3' services: - frontend: - image: ghcr.io/shuffle/shuffle-frontend:latest - container_name: shuffle-frontend - hostname: shuffle-frontend - ports: - - "${FRONTEND_PORT}:80" - - "${FRONTEND_PORT_HTTPS}:443" - networks: - - shuffle - environment: - - BACKEND_HOSTNAME=${BACKEND_HOSTNAME} - restart: unless-stopped - depends_on: - - backend - backend: - image: ghcr.io/shuffle/shuffle-backend:latest - container_name: shuffle-backend - hostname: ${BACKEND_HOSTNAME} - # Here for debugging: - ports: - - "${BACKEND_PORT}:5001" - networks: - - shuffle - volumes: - - /var/run/docker.sock:/var/run/docker.sock - - ${SHUFFLE_APP_HOTLOAD_LOCATION}:/shuffle-apps:z - - ${SHUFFLE_FILE_LOCATION}:/shuffle-files:z - env_file: .env - environment: - #- DOCKER_HOST=tcp://docker-socket-proxy:2375 - - SHUFFLE_APP_HOTLOAD_FOLDER=/shuffle-apps - - SHUFFLE_FILE_LOCATION=/shuffle-files - restart: unless-stopped + #frontend: + # image: ghcr.io/shuffle/shuffle-frontend:latest + # container_name: shuffle-frontend + # hostname: shuffle-frontend + # ports: + # - "${FRONTEND_PORT}:80" + # - "${FRONTEND_PORT_HTTPS}:443" + # networks: + # - shuffle + # environment: + # - BACKEND_HOSTNAME=${BACKEND_HOSTNAME} + # restart: unless-stopped + # depends_on: + # - backend + #backend: + # image: ghcr.io/shuffle/shuffle-backend:latest + # container_name: shuffle-backend + # hostname: ${BACKEND_HOSTNAME} + # # Here for debugging: + # ports: + # - "${BACKEND_PORT}:5001" + # networks: + # - shuffle + # volumes: + # - /var/run/docker.sock:/var/run/docker.sock + # - ${SHUFFLE_APP_HOTLOAD_LOCATION}:/shuffle-apps:z + # - ${SHUFFLE_FILE_LOCATION}:/shuffle-files:z + # env_file: .env + # environment: + # #- DOCKER_HOST=tcp://docker-socket-proxy:2375 + # - SHUFFLE_APP_HOTLOAD_FOLDER=/shuffle-apps + # - SHUFFLE_FILE_LOCATION=/shuffle-files + # restart: unless-stopped orborus: image: ghcr.io/shuffle/shuffle-orborus:latest container_name: shuffle-orborus diff --git a/frontend/package.json b/frontend/package.json index ae512a74..99cef706 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -8,6 +8,7 @@ "@emotion/is-prop-valid": "^1.1.1", "@emotion/react": "^11.7.0", "@emotion/styled": "^11.6.0", + "@lezer/highlight": "^1.1.3", "@material-ui/core": "^4.5.2", "@material-ui/icons": "^4.5.1", "@material-ui/lab": "^4.0.0-alpha.58", @@ -17,6 +18,7 @@ "@mui/icons-material": "^5.2.1", "@mui/material": "^5.2.3", "@mui/x-data-grid": "^5.17.11", + "@uiw/codemirror-themes": "^4.19.9", "@uiw/react-codemirror": "^3.2.1", "@use-it/interval": "^1.0.0", "algoliasearch": "^4.13.1", @@ -83,7 +85,7 @@ "zone.js": "~0.11.4" }, "scripts": { - "start": "react-scripts start", + "start": "PORT=3000 react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 16b4cb1b..06c91245 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -541,8 +541,8 @@ const App = (message, props) => { /> } /> - } /> - } /> + } /> + } /> { } //setDiscoveryData({}) - setDiscoveryWrapper({}) + if (setDiscoveryWrapper !== undefined) { + setDiscoveryWrapper({}) + } + setSelectionOpen(false) setDefaultSearch("") setPaperTitle("") diff --git a/frontend/src/components/Files.jsx b/frontend/src/components/Files.jsx index 2a248d65..09ca4547 100644 --- a/frontend/src/components/Files.jsx +++ b/frontend/src/components/Files.jsx @@ -46,7 +46,7 @@ const Files = (props) => { const [renderTextBox, setRenderTextBox] = React.useState(false); const alert = useAlert(); - const allowedFileTypes = ["txt", "py", "yaml", "yml","json", "html", "js", "csv",] + const allowedFileTypes = ["txt", "py", "yaml", "yml","json", "html", "js", "csv", "log"] var upload = ""; const handleKeyDown = (event) => { @@ -108,11 +108,7 @@ const Files = (props) => { setFiles([]); } - console.log("NAMESPACES: ", responseJson.namespaces); - if ( - responseJson.namespaces !== undefined && - responseJson.namespaces !== null - ) { + if (responseJson.namespaces !== undefined && responseJson.namespaces !== null) { setFileNamespaces(responseJson.namespaces); } }) @@ -574,7 +570,7 @@ const Files = (props) => { } const filenamesplit = file.filename.split(".") - const iseditable = file.filesize < 100000 && file.status === "active" && allowedFileTypes.includes(filenamesplit[filenamesplit.length-1]) + const iseditable = file.filesize < 2000000 && file.status === "active" && allowedFileTypes.includes(filenamesplit[filenamesplit.length-1]) return ( { } let navigate = useNavigate(); - // console.log("is it file editor? - ", isFileEditor); useEffect(() => { var allVariables = [] @@ -449,101 +448,102 @@ const CodeEditor = (props) => { const found = input.match(/[$]{1}([a-zA-Z0-9_-]+\.?){1}([a-zA-Z0-9#_-]+\.?){0,}/g) console.log("FOUND: ", found) - // Whelp this is inefficient af. Single loop pls // When the found array is empty. - try { - for (var i = 0; i < found.length; i++) { - try { - //found[i] = found[i].toLowerCase() - const fixedVariable = fixVariable(found[i]) - //var correctVariable = availableVariables.includes(fixedVariable) + if (found !== null && found !== undefined) { + try { + for (var i = 0; i < found.length; i++) { + try { + //found[i] = found[i].toLowerCase() + const fixedVariable = fixVariable(found[i]) + //var correctVariable = availableVariables.includes(fixedVariable) - // - var valuefound = false - for (var j = 0; j < actionlist.length; j++) { - if(fixedVariable.slice(1,).toLowerCase() === actionlist[j].autocomplete.toLowerCase()){ - valuefound = true + // + var valuefound = false + for (var j = 0; j < actionlist.length; j++) { + if(fixedVariable.slice(1,).toLowerCase() === actionlist[j].autocomplete.toLowerCase()){ + valuefound = true - try { - if (typeof actionlist[j].example === "object") { - input = input.replace(fixedVariable, JSON.stringify(actionlist[j].example)); + try { + if (typeof actionlist[j].example === "object") { + input = input.replace(fixedVariable, JSON.stringify(actionlist[j].example)); - } else if (actionlist[j].example.trim().startsWith("{") || actionlist[j].example.trim().startsWith("[")) { - input = input.replace(fixedVariable, JSON.stringify(actionlist[j].example)); - } else { + } else if (actionlist[j].example.trim().startsWith("{") || actionlist[j].example.trim().startsWith("[")) { + input = input.replace(fixedVariable, JSON.stringify(actionlist[j].example)); + } else { + input = input.replace(fixedVariable, actionlist[j].example) + } + } catch (e) { input = input.replace(fixedVariable, actionlist[j].example) } - } catch (e) { - input = input.replace(fixedVariable, actionlist[j].example) + } else { + // Couldn't find the correct example value } - } else { - // Couldn't find the correct example value } - } - if (!valuefound && availableVariables.includes(fixedVariable)) { - var shouldbreak = false - for (var k=0; k < actionlist.length; k++){ - var parsedPaths = [] - if (typeof actionlist[k].example === "object") { - parsedPaths = GetParsedPaths(actionlist[k].example, ""); - } + if (!valuefound && availableVariables.includes(fixedVariable)) { + var shouldbreak = false + for (var k=0; k < actionlist.length; k++){ + var parsedPaths = [] + if (typeof actionlist[k].example === "object") { + parsedPaths = GetParsedPaths(actionlist[k].example, ""); + } - for (var key in parsedPaths) { - const fullpath = "$"+actionlist[k].autocomplete.toLowerCase()+parsedPaths[key].autocomplete - if (fullpath === fixedVariable) { - //if (actionlist[k].example === undefined) { - // actionlist[k].example = "TMP" - //} + for (var key in parsedPaths) { + const fullpath = "$"+actionlist[k].autocomplete.toLowerCase()+parsedPaths[key].autocomplete + if (fullpath === fixedVariable) { + //if (actionlist[k].example === undefined) { + // actionlist[k].example = "TMP" + //} - var new_input = "" - try { - new_input = FindJsonPath(fullpath, actionlist[k].example) - } catch (e) { - console.log("ERR IN INPUT: ", e) - } + var new_input = "" + try { + new_input = FindJsonPath(fullpath, actionlist[k].example) + } catch (e) { + console.log("ERR IN INPUT: ", e) + } - //console.log("Got output for: ", fullpath, new_input, actionlist[k].example, typeof new_input) + //console.log("Got output for: ", fullpath, new_input, actionlist[k].example, typeof new_input) - if (typeof new_input === "object") { - new_input = JSON.stringify(new_input) - } else { - if (typeof new_input === "string") { - new_input = new_input + if (typeof new_input === "object") { + new_input = JSON.stringify(new_input) } else { - console.log("NO TYPE? ", typeof new_input) - try { - new_input = new_input.toString() - } catch (e) { - new_input = "" + if (typeof new_input === "string") { + new_input = new_input + } else { + console.log("NO TYPE? ", typeof new_input) + try { + new_input = new_input.toString() + } catch (e) { + new_input = "" + } } } + + //console.log("FOUND2: ", fixedVariable, actionlist[j].example) + input = input.replace(fixedVariable, new_input) + + //} catch (e) { + // input = input.replace(found[i], actionlist[k].example) + //} + + shouldbreak = true + break } + } - //console.log("FOUND2: ", fixedVariable, actionlist[j].example) - input = input.replace(fixedVariable, new_input) - - //} catch (e) { - // input = input.replace(found[i], actionlist[k].example) - //} - - shouldbreak = true + if (shouldbreak) { break } } - - if (shouldbreak) { - break - } } + } catch (e) { + console.log("Replace error: ", e) } - } catch (e) { - console.log("Replace error: ", e) } + } catch (e) { + //console.log("Outer replace error: ", e) } - } catch (e) { - //console.log("Outer replace error: ", e) } const tmpValidation = validateJson(input.valueOf()) @@ -687,15 +687,15 @@ const CodeEditor = (props) => { PaperComponent={PaperComponent} PaperProps={{ style: { - backgroundColor: theme.palette.surfaceColor, - color: "white", - 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, + color: "white", + minWidth: isMobile ? "100%" : isFileEditor ? 650 : 1200, + maxWidth: isMobile ? "100%" : isFileEditor ? 650 : 1200, + minHeight: isMobile ? "100%" : 720, + maxHeight: isMobile ? "100%" : 720, + border: theme.palette.defaultBorder, + padding: isMobile ? "25px 10px 25px 10px" : 25, + backgroundColor: theme.palette.surfaceColor, }, }} > @@ -1156,6 +1156,11 @@ const CodeEditor = (props) => { theme={shuffleTheme} value = {localcodedata} height={isFileEditor ? 450 : 700} + width={isFileEditor ? 650 : 550} + style={{ + maxWidth: isFileEditor ? 450 : 500, + wordBreak: "break-word", + }} onCursorActivity = {(value) => { // console.log(value.getCursor()) setCurrentCharacter(value.getCursor().ch) @@ -1165,6 +1170,8 @@ const CodeEditor = (props) => { highlight_variables(value) }} onChange={(value) => { + //console.log("Value: '", value.getValue(), "'") + setlocalcodedata(value.getValue()) expectedOutput(value.getValue()) @@ -1179,7 +1186,7 @@ const CodeEditor = (props) => { styleSelectedText: true, keyMap: 'sublime', mode: 'python', - lineWrapping: linewrap, + lineWrapping: true, //theme: codeTheme, // mode: {codelang}, }} diff --git a/frontend/src/views/Admin.jsx b/frontend/src/views/Admin.jsx index 6283185c..82c45147 100644 --- a/frontend/src/views/Admin.jsx +++ b/frontend/src/views/Admin.jsx @@ -43,6 +43,7 @@ import { DialogContent, CircularProgress, Box, + InputAdornment, } from "@material-ui/core"; import { Autocomplete } from "@mui/material"; @@ -67,6 +68,8 @@ import { Schedule as ScheduleIcon, Cloud as CloudIcon, Business as BusinessIcon, + Visibility as VisibilityIcon, + VisibilityOff as VisibilityOffIcon, } from "@material-ui/icons"; import { useAlert } from "react-alert"; @@ -185,6 +188,8 @@ const Admin = (props) => { const [dealerror, setDealerror] = React.useState(""); const [dealList, setDealList] = React.useState([]); const [adminTab, setAdminTab] = React.useState(1); + const [showApiKey, setShowApiKey] = useState(false); + const [billingInfo, setBillingInfo] = React.useState({}); @@ -2242,7 +2247,7 @@ const Admin = (props) => { Enable cloud features - + What does{" "} { Billing /> + + Branding + + /> Usage /> + {/* Notifications /> + */} {
+ { + setShowApiKey(!showApiKey) + }} + > + {showApiKey ? : } + + + ) }} required fullWidth={true} @@ -2631,6 +2659,7 @@ const Admin = (props) => { placeholder="Cloud Apikey" variant="outlined" defaultValue={userSettings.apikey} + type={!isCloud || showApiKey ? "text" : "password"} /> {selectedOrganization.cloud_sync_active ? (
)} - - Cloud sync features (monthly usage) + + Cloud sync features + + + If not otherwise specified, Usage will reset monthly {selectedOrganization.sync_features === undefined || diff --git a/frontend/src/views/AngularWorkflow.jsx b/frontend/src/views/AngularWorkflow.jsx index d654d48c..2b9bfa26 100644 --- a/frontend/src/views/AngularWorkflow.jsx +++ b/frontend/src/views/AngularWorkflow.jsx @@ -8320,17 +8320,15 @@ const AngularWorkflow = (defaultprops) => { var injectedData =
; - if ( - selectedEdge.conditions !== undefined && - selectedEdge.conditions !== null && - selectedEdge.conditions.length > 0 - ) { + if (selectedEdge.conditions !== undefined && selectedEdge.conditions !== null && selectedEdge.conditions.length > 0) { injectedData = selectedEdge.conditions.map((condition, index) => { return ConditionHandler(condition, index); }); } - // FIXME - remove index + // Startnode = dest node + const conditionsDisabled = false + const conditionId = uuidv4(); return (
@@ -8363,7 +8361,7 @@ const AngularWorkflow = (defaultprops) => { + + {/* Check if dest is the same as start */} + {conditionsDisabled ? + + Conditions are unavailable between triggers and the startnode. + + : null}
); }; diff --git a/frontend/src/views/AppCreator.jsx b/frontend/src/views/AppCreator.jsx index 42b3b324..dec702ea 100644 --- a/frontend/src/views/AppCreator.jsx +++ b/frontend/src/views/AppCreator.jsx @@ -1618,7 +1618,16 @@ const AppCreator = (defaultprops) => { } setProjectCategories(all_categories); + + // Rearrange them by which has action_label + const firstActions = newActions.filter(data => data.action_label !== undefined && data.action_label !== null && data.action_label !== "No Label") + console.log("First actions: ", firstActions) + const secondActions = newActions.filter(data => data.action_label === undefined || data.action_label === null || data.action_label === "No Label") + newActions = firstActions.concat(secondActions) setActions(newActions); + //data.paths[item.url][item.method.toLowerCase()]["x-label"] = item.action_label + + setFilteredActions(newActions); setIsAppLoaded(true); }; @@ -4031,12 +4040,16 @@ const AppCreator = (defaultprops) => { }} value={data.action_label} style={{ + border: data.action_label === undefined || data.action_label === "No Label" ? "" : `2px solid ${bgColor}`, + borderRadius: theme.shape.borderRadius, backgroundColor: inputColor, paddingLeft: 10, color: "white", height: 30, - maxWidth: 50, + maxWidth: 35, marginLeft: 10, + marginRight: 10, + overflow: "hidden", }} inputProps={{ name: "Method", @@ -4048,7 +4061,8 @@ const AppCreator = (defaultprops) => { {label}