From d7260b709b680f79b81804c2a402a511107da63c Mon Sep 17 00:00:00 2001 From: frikky Date: Tue, 28 Jun 2022 20:41:35 +0200 Subject: [PATCH 1/3] Fixed issues with names in conditions when changing --- backend/app_sdk/app_base.py | 4 +- frontend/src/components/ParsedAction.jsx | 112 +++++++++++++++++++++++ frontend/src/views/AngularWorkflow.jsx | 6 +- 3 files changed, 117 insertions(+), 5 deletions(-) diff --git a/backend/app_sdk/app_base.py b/backend/app_sdk/app_base.py index 354a6c55..23bde802 100644 --- a/backend/app_sdk/app_base.py +++ b/backend/app_sdk/app_base.py @@ -2025,7 +2025,6 @@ class AppBase: errors = False error_msg = "" try: - #self.logger.info("In liquid") if len(template) > 10000000: self.logger.info("[DEBUG] Skipping liquid - size too big (%d)" % len(template)) return template @@ -2240,7 +2239,6 @@ class AppBase: #self.logger.info("STATIC PARSED: %s" % actualitem) #self.logger.info("[INFO] Done with regex matching") if len(actualitem) > 0: - #self.logger.info("[DEBUG] Matches: ", actualitem) for replace in actualitem: try: to_be_replaced = replace[0] @@ -2798,7 +2796,7 @@ class AppBase: })) if parameter["name"] == "body": - self.logger.info("[INFO] Should debug field with liquid and other checks as it's BODY: %s" % value) + self.logger.info(f"[INFO] Should debug field with liquid and other checks as it's BODY: {value}") # Custom format for ${name[0,1,2,...]}$ #submatch = "([${]{2}([0-9a-zA-Z_-]+)(\[.*\])[}$]{2})" diff --git a/frontend/src/components/ParsedAction.jsx b/frontend/src/components/ParsedAction.jsx index 7ba3f923..03413bcb 100644 --- a/frontend/src/components/ParsedAction.jsx +++ b/frontend/src/components/ParsedAction.jsx @@ -2666,6 +2666,117 @@ const ParsedAction = (props) => { // Change in actions, triggers & conditions // Highlight the changes somehow with a glow? + // + // Should make it a function lol + if (workflow.branches !== undefined && workflow.branches !== null) { + for (var key in workflow.branches) { + for (var subkey in workflow.branches[key].conditions) { + const condition = workflow.branches[key].conditions[subkey] + const sourceparam = condition.source + const destinationparam = condition.destination + + // Should have a smarter way of discovering node names + // Finding index(es) and replacing at the location + if (sourceparam.value.includes("$")) { + try { + var cnt = -1 + var previous = 0 + while (true) { + cnt += 1 + // Need to make sure e.g. changing the first here doesn't change the 2nd + // $change_me + // $change_me_2 + + const foundindex = sourceparam.value.toLowerCase().indexOf(parsedBaseLabel, previous) + if (foundindex === previous && foundindex !== 0) { + break + } + + if (foundindex >= 0) { + previous = foundindex+newname.length + // Need to add diff of length to word + + // Check location: + // If it's a-zA-Z_ then don't replace + if (sourceparam.value.length > foundindex+parsedBaseLabel.length) { + const regex = /[a-zA-Z0-9_]/g; + const match = sourceparam.value[foundindex+parsedBaseLabel.length].match(regex); + if (match !== null) { + continue + } + } + + console.log("Old found: ", workflow.branches[key].conditions[subkey].source.value) + const extralength = newname.length-parsedBaseLabel.length + sourceparam.value = sourceparam.value.substring(0, foundindex) + newname + sourceparam.value.substring(foundindex-extralength+newname.length, sourceparam.value.length) + + console.log("New: ", workflow.branches[key].conditions[subkey].source.value) + } else { + break + } + + // Break no matter what after 5 replaces. May need to increase + if (cnt >= 5) { + break + } + + } + } catch (e) { + console.log("Failed value replacement based on index: ", e) + } + } + + if (destinationparam.value.includes("$")) { + try { + var cnt = -1 + var previous = 0 + while (true) { + cnt += 1 + // Need to make sure e.g. changing the first here doesn't change the 2nd + // $change_me + // $change_me_2 + + const foundindex = destinationparam.value.toLowerCase().indexOf(parsedBaseLabel, previous) + if (foundindex === previous && foundindex !== 0) { + break + } + + if (foundindex >= 0) { + previous = foundindex+newname.length + // Need to add diff of length to word + + // Check location: + // If it's a-zA-Z_ then don't replace + if (destinationparam.value.length > foundindex+parsedBaseLabel.length) { + const regex = /[a-zA-Z0-9_]/g; + const match = destinationparam.value[foundindex+parsedBaseLabel.length].match(regex); + if (match !== null) { + continue + } + } + + console.log("Old found: ", workflow.branches[key].conditions[subkey].destination.value) + const extralength = newname.length-parsedBaseLabel.length + destinationparam.value = destinationparam.value.substring(0, foundindex) + newname + destinationparam.value.substring(foundindex-extralength+newname.length, destinationparam.value.length) + + console.log("New: ", workflow.branches[key].conditions[subkey].destination.value) + } else { + break + } + + // Break no matter what after 5 replaces. May need to increase + if (cnt >= 5) { + break + } + + } + } catch (e) { + console.log("Failed value replacement based on index: ", e) + } + } + } + } + } for (var key in workflow.actions) { if (workflow.actions[key].id === selectedAction.id) { @@ -2681,6 +2792,7 @@ const ParsedAction = (props) => { // Should have a smarter way of discovering node names // Do regex? // Finding index(es) and replacing at the location + // try { var cnt = -1 diff --git a/frontend/src/views/AngularWorkflow.jsx b/frontend/src/views/AngularWorkflow.jsx index 962f3090..804c2d62 100644 --- a/frontend/src/views/AngularWorkflow.jsx +++ b/frontend/src/views/AngularWorkflow.jsx @@ -7055,8 +7055,10 @@ const AngularWorkflow = (defaultprops) => { } var currentedge = cy.getElementById(selectedEdge.id); - if (currentedge !== undefined && currentedge !== null) { - currentedge.data().label = label; + if (currentedge !== undefined && currentedge !== null && label !== undefined) { + currentedge.data("label", label) + //.label = label; + //oldstartnode[0].data("isStartNode", false); } setSelectedEdge(selectedEdge); From 76bfff84da05f283d385dc34b83502fa98079fa5 Mon Sep 17 00:00:00 2001 From: frikky Date: Sun, 3 Jul 2022 02:15:02 +0200 Subject: [PATCH 2/3] Added | escape }} liquid filter to manage strings in JSON better --- backend/app_sdk/app_base.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/backend/app_sdk/app_base.py b/backend/app_sdk/app_base.py index 23bde802..01b54a2b 100644 --- a/backend/app_sdk/app_base.py +++ b/backend/app_sdk/app_base.py @@ -117,6 +117,22 @@ def as_object(a): def ast(a): return ast.literal_eval(str(a)) +@shuffle_filters.register +def escape_string(a): + a = str(a) + return a.replace("\\\'", "\'", -1).replace("\\\"", "\"", -1).replace("'", "\\\'", -1).replace("\"", "\\\"", -1) + +@shuffle_filters.register +def json_escape(a): + a = str(a) + return a.replace("\\\'", "\'", -1).replace("\\\"", "\"", -1).replace("'", "\\\\\'", -1).replace("\"", "\\\\\"", -1) + +# By default using json escape to add all backslashes +@shuffle_filters.register +def escape(a): + a = str(a) + return json_escape(a) + #print(standard_filter_manager.filters) #print(shuffle_filters.filters) #print(Liquid("{{ '10' | plus: 1}}", filters=shuffle_filters.filters).render()) From 16e7bfcb58ee0ba7d85228532cd5f37f8ced5b59 Mon Sep 17 00:00:00 2001 From: frikky Date: Thu, 14 Jul 2022 01:16:27 +0200 Subject: [PATCH 3/3] Fixed minor bugs in app creator bodies and action names + added auto addition of headers --- backend/app_sdk/app_base.py | 4 + backend/app_sdk/build.sh | 2 +- backend/app_sdk/requirements.txt | 2 +- backend/go-app/walkoff.go | 2 +- .../src/components/DetectionFramework.jsx | 17 +- frontend/src/components/DocsGrid.jsx | 161 +++++++------ frontend/src/components/ParsedAction.jsx | 32 ++- frontend/src/components/ShuffleCodeEditor.jsx | 10 +- frontend/src/views/AngularWorkflow.jsx | 222 +++++++++--------- frontend/src/views/AppCreator.jsx | 130 +++++----- frontend/src/views/Workflows.jsx | 27 ++- 11 files changed, 340 insertions(+), 269 deletions(-) diff --git a/backend/app_sdk/app_base.py b/backend/app_sdk/app_base.py index 01b54a2b..164b515b 100644 --- a/backend/app_sdk/app_base.py +++ b/backend/app_sdk/app_base.py @@ -2109,6 +2109,9 @@ class AppBase: error = True error_msg = e + if "fmt" in error_msg and "liquid_date" in error_msg: + return template + self.logger.info("Done in liquid") if error == True: self.action_result["status"] = "FAILURE" @@ -2117,6 +2120,7 @@ class AppBase: "reason": f"Failed to parse LiquidPy: {error_msg}", "input": template, } + try: self.action_result["result"] = json.dumps(data) except Exception as e: diff --git a/backend/app_sdk/build.sh b/backend/app_sdk/build.sh index 4c39c74a..daf51e84 100644 --- a/backend/app_sdk/build.sh +++ b/backend/app_sdk/build.sh @@ -2,7 +2,7 @@ ### DEFAULT NAME=shuffle-app_sdk -VERSION=1.0.4 +VERSION=1.0.5 docker rmi docker.pkg.github.com/frikky/shuffle/$NAME:$VERSION --force docker build . -f Dockerfile -t frikky/shuffle:app_sdk -t frikky/$NAME:$VERSION -t docker.pkg.github.com/frikky/shuffle/$NAME:$VERSION -t ghcr.io/frikky/$NAME:$VERSION -t ghcr.io/frikky/$NAME:nightly diff --git a/backend/app_sdk/requirements.txt b/backend/app_sdk/requirements.txt index 93cccf66..8b181a2e 100644 --- a/backend/app_sdk/requirements.txt +++ b/backend/app_sdk/requirements.txt @@ -1,7 +1,7 @@ urllib3==1.26.5 requests==2.25.1 MarkupSafe==2.0.1 -liquidpy==0.7.3 +liquidpy==0.7.5 flask[async]==2.0.2 waitress==2.1.0 #flask==1.1.2 diff --git a/backend/go-app/walkoff.go b/backend/go-app/walkoff.go index c0f39ecd..a61ee531 100644 --- a/backend/go-app/walkoff.go +++ b/backend/go-app/walkoff.go @@ -559,7 +559,7 @@ func runWorkflowExecutionTransaction(ctx context.Context, attempts int64, workfl } //log.Printf("BASE LENGTH: %d", len(workflowExecution.Results)) - workflowExecution, dbSave, err := shuffle.ParsedExecutionResult(ctx, *workflowExecution, actionResult, false) + workflowExecution, dbSave, err := shuffle.ParsedExecutionResult(ctx, *workflowExecution, actionResult, false, 4) if err != nil { b, suberr := json.Marshal(actionResult) if suberr != nil { diff --git a/frontend/src/components/DetectionFramework.jsx b/frontend/src/components/DetectionFramework.jsx index 94ae0a80..6614513b 100644 --- a/frontend/src/components/DetectionFramework.jsx +++ b/frontend/src/components/DetectionFramework.jsx @@ -1599,18 +1599,13 @@ const Framework = (props) => {
{selectionOpen ? - isCloud && defaultSearch !== undefined && defaultSearch.length > 0 ? - - : -
- Coming soon. Register for Shuffle cloud to try an early version now. -
+ : null} -
+ : null } diff --git a/frontend/src/components/DocsGrid.jsx b/frontend/src/components/DocsGrid.jsx index a2aa63c3..bbd3537c 100644 --- a/frontend/src/components/DocsGrid.jsx +++ b/frontend/src/components/DocsGrid.jsx @@ -5,6 +5,7 @@ import { useTheme } from '@material-ui/core/styles'; import {Link} from 'react-router-dom'; import { Search as SearchIcon, CloudQueue as CloudQueueIcon, Code as CodeIcon } from '@material-ui/icons'; +import aa from 'search-insights' import algoliasearch from 'algoliasearch/lite'; import { InstantSearch, Configure, connectSearchBox, connectHits } from 'react-instantsearch-dom'; @@ -13,13 +14,20 @@ import { Grid, Paper, TextField, + Avatar, ButtonBase, InputAdornment, Typography, Button, - Tooltip + Tooltip, + List, + ListItem, + ListItemAvatar, + ListItemText, } from '@material-ui/core'; +import {Close as CloseIcon, Folder as FolderIcon, Polymer as PolymerIcon, LibraryBooks as LibraryBooksIcon} from '@material-ui/icons' + const searchClient = algoliasearch("JNSS5CFDZZ", "db08e40265e2941b9a7d8f644b6e5240") const DocsGrid = props => { const { maxRows, showName, showSuggestion, isMobile, globalUrl, parsedXs } = props @@ -139,92 +147,99 @@ const DocsGrid = props => { //} return ( - + {hits.map((data, index) => { workflowDelay += 50 - - const paperStyle = { - backgroundColor: index === mouseHoverIndex ? "rgba(255,255,255,0.8)" : theme.palette.inputColor, - color: index === mouseHoverIndex ? theme.palette.inputColor : "rgba(255,255,255,0.8)", - border: `1px solid ${innerColor}`, - padding: 15, + + const innerlistitemStyle = { + width: "100%", + overflowX: "hidden", + overflowY: "hidden", + borderBottom: "1px solid rgba(255,255,255,0.4)", + backgroundColor: mouseHoverIndex === index ? "#1f2023" : "inherit", cursor: "pointer", - position: "relative", - minHeight: 116, - } - - if (counted === 12/xs*rowHandler) { - return null + marginLeft: 5, + marginRight: 5, + maxHeight: 75, + minHeight: 75, + maxWidth: 420, + minWidth: "100%", } + //if (counted === 12/xs*rowHandler) { + // return null + //} + + console.log("DATA: ", data) + counted += 1 - var parsedname = "" - for (var key = 0; key < data.name.length; key++) { - var character = data.name.charAt(key) - if (character === character.toUpperCase()) { - //console.log(data.name[key], data.name[key+1]) - if (data.name.charAt(key+1) !== undefined && data.name.charAt(key+1) === data.name.charAt(key+1).toUpperCase()) { - } else { - parsedname += " " - } - } + var name = data.name === undefined ? + data.filename.charAt(0).toUpperCase() + data.filename.slice(1).replaceAll("_", " ") + " - " + data.title : + (data.name.charAt(0).toUpperCase()+data.name.slice(1)).replaceAll("_", " ") - parsedname += character + if (name.length > 100) { + name = name.slice(0, 100)+"..." } - - parsedname = (parsedname.charAt(0).toUpperCase()+parsedname.substring(1)).replaceAll("_", " ") + + const secondaryText = data.data !== undefined ? data.data.slice(0, 100)+"..." : "" + const baseImage = + const avatar = data.image_url === undefined ? + baseImage + : + + + var parsedUrl = data.urlpath !== undefined ? data.urlpath : "" + parsedUrl += `?queryID=${data.__queryID}` return ( - - - { - setMouseHoverIndex(index) - /* - ReactGA.event({ - category: "app_grid_view", - action: `search_bar_click`, - label: "", - }) - */ - }} onMouseOut={() => { - setMouseHoverIndex(-1) - }} onClick={() => { - ReactGA.event({ - category: "docs_grid_view", - action: `docs_${parsedname}_${data.id}_click`, - label: "", - }) - }}> - - {data.name} - -
- {index === mouseHoverIndex || showName === true ? - parsedname - : - null - } - {data.generated ? - - {data.invalid ? - - : - - } - - : - - - - } - - - + { + aa('init', { + appId: searchClient.appId, + apiKey: searchClient.transporter.queryParameters["x-algolia-api-key"] + }) + + const timestamp = new Date().getTime() + aa('sendEvents', [ + { + eventType: 'click', + eventName: 'Product Clicked Appgrid', + index: 'documentation', + objectIDs: [data.objectID], + timestamp: timestamp, + queryID: data.__queryID, + positions: [data.__position], + } + ]) + + console.log("CLICK") + }}> + { + setMouseHoverIndex(index) + }}> + + {avatar} + + + {/* + + + + + + */} + + ) })} - + ) } diff --git a/frontend/src/components/ParsedAction.jsx b/frontend/src/components/ParsedAction.jsx index 03413bcb..888e0e52 100644 --- a/frontend/src/components/ParsedAction.jsx +++ b/frontend/src/components/ParsedAction.jsx @@ -1295,6 +1295,19 @@ const ParsedAction = (props) => { if (data.name === "url" && data.value !== undefined && data.value !== null && data.value.length === 0) { data.value = data.example; } + + if (data.value.length === 0) { + if (data.name.toLowerCase() === "headers") { + data.value = data.example + } + } + + /* + if (data.name !== "queries" && data.name !== "key" && data.name !== "value" ) { + data.value = data.example + } + } + */ } if (data.name.startsWith("${") && data.name.endsWith("}")) { @@ -3269,13 +3282,30 @@ const ParsedAction = (props) => { for (var line in descSplit) { if (descSplit[line].includes("http") && descSplit[line].includes("://")) { const urlsplit = descSplit[line].split("/") - extraUrl = "/"+urlsplit.slice(3, urlsplit.length-1).join("/") + try { + extraUrl = "/"+urlsplit.slice(3, urlsplit.length).join("/") + } catch (e) { + console.log("Failed - running with -1") + extraUrl = "/"+urlsplit.slice(3, urlsplit.length-1).join("/") + } + + + console.log("NO BASEURL TOO!! Why missing last one in certain scenarios (sevco)?", extraUrl, urlsplit, descSplit[line]) break } } if (extraUrl.length > 0) { + if (extraUrl.includes(" ")) { + extraUrl = extraUrl.split(" ")[0] + } + + if (extraUrl.includes("#")) { + extraUrl = extraUrl.split("#")[0] + } extraDescription = `${method} ${extraUrl}` + } else { + console.log("No url found. Check again :)") } } diff --git a/frontend/src/components/ShuffleCodeEditor.jsx b/frontend/src/components/ShuffleCodeEditor.jsx index bd8c83ed..7093fa57 100644 --- a/frontend/src/components/ShuffleCodeEditor.jsx +++ b/frontend/src/components/ShuffleCodeEditor.jsx @@ -41,6 +41,7 @@ import { padding, textAlign } from '@mui/system'; const liquidFilters = [ {"name": "Size", "value": "size", "example": ""}, {"name": "Date", "value": `date: "%Y%M%d"`, "example": `{{ "now" | date: "%s" }}`}, + {"name": "Escape String", "value": `{{ \"\"\"'string with weird'" quotes\"\"\" | escape_string }}`, "example": ``}, ] const mathFilters = [ @@ -50,7 +51,7 @@ const mathFilters = [ const pythonFilters = [ {"name": "Hello World", "value": `{% python %}\nprint("hello world")\n{% endpython %}`, "example": ``}, - {"name": "Handle JSON", "value": `{% python %}\nimport json\njsondata = json.loads("""$nodename""")\n{% endpython %}`, "example": ``}, + {"name": "Handle JSON", "value": `{% python %}\nimport json\njsondata = json.loads(r"""$nodename""")\n{% endpython %}`, "example": ``}, ] const CodeEditor = (props) => { @@ -348,7 +349,7 @@ const CodeEditor = (props) => { return } - if (!item.value.includes("{%")) { + if (!item.value.includes("{%") && !item.value.includes("{{")) { setlocalcodedata(localcodedata+" | "+item.value+" }}") } else { setlocalcodedata(localcodedata+item.value) @@ -582,7 +583,7 @@ const CodeEditor = (props) => { }} /> - {editorPopupOpen ? + {/*editorPopupOpen ? { }} > {data.substring(0, 25)} - {/* {Object.keys(data.example).forEach(key => key)} */}
) })}
- : null} + : null*/}
{ } curworkflowTrigger.position = cyelements[key].position(); + if (curworkflowTrigger.canConnect === false) { + continue + } newTriggers.push(curworkflowTrigger); } else if (type === "COMMENT") { @@ -11433,114 +11436,114 @@ const AngularWorkflow = (defaultprops) => {
) : ( -
-
{ - setLeftViewOpen(true); - setLeftBarSize(350); - }} - > - - - -
-
-); - -const executionPaperStyle = { - minWidth: "95%", - maxWidth: "95%", - marginTop: "5px", - color: "white", - marginBottom: 10, - padding: 5, - backgroundColor: surfaceColor, - cursor: "pointer", - display: "flex", - minHeight: 40, - maxHeight: 40, -}; - -const parsedExecutionArgument = () => { - var showResult = executionData.execution_argument.trim(); - const validate = validateJson(showResult); - - if (validate.valid) { - if (typeof validate.result === "string") { - try { - validate.result = JSON.parse(validate.result); - } catch (e) { - console.log("Error: ", e); - validate.valid = false; - } - } - - return ( -
- { - setSelectedResult({ - "action": { - "label": "Execution Argument", - "name": "Execution Argument", - "large_image": theme.palette.defaultImage, - "image": theme.palette.defaultImage, - }, - "result": validate.valid ? JSON.stringify(validate.result) : validate.result, - "status": "SUCCESS" - }) - setCodeModalOpen(true); - }} - > - - - - - { - handleReactJsonClipboard(copy); - }} - displayDataTypes={false} - onSelect={(select) => { - HandleJsonCopy(validate.result, select, "exec"); - }} - name={"Execution Argument"} - /> +
+
{ + setLeftViewOpen(true); + setLeftBarSize(350); + }} + > + + +
- ) - } +
+ ); - return ( -
-

Execution Argument

-
- {executionData.execution_argument} -
-
- ); + const executionPaperStyle = { + minWidth: "95%", + maxWidth: "95%", + marginTop: "5px", + color: "white", + marginBottom: 10, + padding: 5, + backgroundColor: surfaceColor, + cursor: "pointer", + display: "flex", + minHeight: 40, + maxHeight: 40, + }; + + const parsedExecutionArgument = () => { + var showResult = executionData.execution_argument.trim(); + const validate = validateJson(showResult); + + if (validate.valid) { + if (typeof validate.result === "string") { + try { + validate.result = JSON.parse(validate.result); + } catch (e) { + console.log("Error: ", e); + validate.valid = false; + } + } + + return ( +
+ { + setSelectedResult({ + "action": { + "label": "Execution Argument", + "name": "Execution Argument", + "large_image": theme.palette.defaultImage, + "image": theme.palette.defaultImage, + }, + "result": validate.valid ? JSON.stringify(validate.result) : validate.result, + "status": "SUCCESS" + }) + setCodeModalOpen(true); + }} + > + + + + + { + handleReactJsonClipboard(copy); + }} + displayDataTypes={false} + onSelect={(select) => { + HandleJsonCopy(validate.result, select, "exec"); + }} + name={"Execution Argument"} + /> +
+ ) + } + + return ( +
+

Execution Argument

+
+ {executionData.execution_argument} +
+
+ ); }; const getExecutionSourceImage = (execution) => { @@ -12175,7 +12178,12 @@ const parsedExecutionArgument = () => { executionData.execution_argument, executionData.start, lastSaved - ); + ) + + if (executionText === undefined || executionText === null || executionText.length === 0) { + setExecutionText(executionData.execution_argument) + } + setExecutionModalOpen(false); }} > diff --git a/frontend/src/views/AppCreator.jsx b/frontend/src/views/AppCreator.jsx index 74340ee8..127f719a 100644 --- a/frontend/src/views/AppCreator.jsx +++ b/frontend/src/views/AppCreator.jsx @@ -1814,6 +1814,10 @@ const AppCreator = (defaultprops) => { for (var querykey in item.queries) { const queryitem = item.queries[querykey]; + if (queryitem === undefined || queryitem === null || queryitem.name === undefined || queryitem.name === null) { + continue + } + // A fix for duplicate items if (querynames.includes(queryitem.name.toLowerCase())) { continue @@ -1967,70 +1971,76 @@ const AppCreator = (defaultprops) => { } } - if ( - item.body !== undefined && - item.body !== null && - item.body.length > 0 - ) { - const required = false; - newitem = { - in: "body", - name: "body", - multiline: true, - description: "Generated by shuffler.io OpenAPI", - required: required, - example: item.body, - schema: { - type: "string", - }, - }; + const methodname = item.method.toLowerCase() + if (methodname === "post" || methodname === "put" || methodname === "patch") { + if ( + item.body !== undefined && + item.body !== null && + item.body.length > 0 + ) { + console.log("GOT BODY: ", item.url, item.method) + //var pathjoin = item.url+"_"+item.method.toLowerCase() - // FIXME - add application/json if JSON example? - data.paths[item.url][item.method.toLowerCase()]["requestBody"] = { - description: "Generated by Shuffler.io", - required: required, - content: { - example: { - example: item.body, - }, - }, - }; + const required = false; + newitem = { + in: "body", + name: "body", + multiline: true, + description: "Generated by shuffler.io OpenAPI", + required: required, + example: item.body, + schema: { + type: "string", + }, + }; - data.paths[item.url][item.method.toLowerCase()].parameters.push( - newitem - ); - } else if (actionBodyRequest.includes(item.method.toUpperCase())) { - // Appending an empty field - const required = false; - newitem = { - in: "body", - name: "body", - multiline: true, - description: "Generated by shuffler.io OpenAPI", - required: required, - example: "", - schema: { - type: "string", - }, - }; + // FIXME - add application/json if JSON example? + data.paths[item.url][item.method.toLowerCase()]["requestBody"] = { + description: "Generated by Shuffler.io", + required: required, + content: { + example: { + example: item.body, + }, + }, + }; - // FIXME - add application/json if JSON example? - data.paths[item.url][item.method.toLowerCase()]["requestBody"] = { - description: "Generated by Shuffler.io", - required: required, - content: { - example: { - example: "", - }, - }, - }; + data.paths[item.url][item.method.toLowerCase()].parameters.push( + newitem + ); + } else if (actionBodyRequest.includes(item.method.toUpperCase())) { + // Appending an empty field + const required = false; + newitem = { + in: "body", + name: "body", + multiline: true, + description: "Generated by shuffler.io OpenAPI", + required: required, + example: "", + schema: { + type: "string", + }, + }; - data.paths[item.url][item.method.toLowerCase()].parameters.push( - newitem - ); - } else { - //console.log("Nothing to append?") - } + // FIXME - add application/json if JSON example? + data.paths[item.url][item.method.toLowerCase()]["requestBody"] = { + description: "Generated by Shuffler.io", + required: required, + content: { + example: { + example: "", + }, + }, + }; + + data.paths[item.url][item.method.toLowerCase()].parameters.push( + newitem + ); + } else { + //console.log("Nothing to append?") + } + } // https://swagger.io/docs/specification/describing-request-body/file-upload/ if ( diff --git a/frontend/src/views/Workflows.jsx b/frontend/src/views/Workflows.jsx index c69e9e00..177fbf18 100644 --- a/frontend/src/views/Workflows.jsx +++ b/frontend/src/views/Workflows.jsx @@ -8,7 +8,6 @@ import SecurityFramework from '../components/SecurityFramework.jsx'; import { ShepherdTour, ShepherdTourContext } from 'react-shepherd' import { isMobile } from "react-device-detect" - import { Badge, Avatar, @@ -88,6 +87,7 @@ import { useAlert } from "react-alert"; import ChipInput from "material-ui-chip-input"; import { v4 as uuidv4 } from "uuid"; + const inputColor = "#383B40"; const surfaceColor = "#27292D"; const svgSize = 24; @@ -133,8 +133,8 @@ export const GetIconInfo = (action) => { const iconList = [ { key: "cache_add", values: ["set_cache"] }, { key: "cache_get", values: ["get_cache"] }, - { key: "filter", values: ["filter", "route", "router"] }, - { key: "merge", values: ["join", "merge"] }, + { key: "filter", values: ["filter"] }, + { key: "merge", values: ["join", "merge", "route", "router"] }, { key: "search", values: ["search", "find", "locate", "index", "analyze", "anal", "match", "check cache", "check", "verify", "validate"], @@ -412,6 +412,7 @@ export const validateJson = (showResult) => { jsonvalid = false } } catch (e) { + console.log("Bug1: ", e) showResult = showResult.split("'").join('"'); try { @@ -419,14 +420,17 @@ export const validateJson = (showResult) => { jsonvalid = false; } } catch (e) { + console.log("Bug2: ", e) + jsonvalid = false; } } var result = showResult; try { - result = jsonvalid ? JSON.parse(showResult) : showResult; + result = jsonvalid ? JSON.parse(showResult, {"storeAsString": true}) : showResult; } catch (e) { + console.log("Bug3: ", e) ////console.log("Failed parsing JSON even though its valid: ", e) jsonvalid = false; } @@ -444,6 +448,7 @@ export const validateJson = (showResult) => { result = JSON.parse(newstr) jsonvalid = true } catch (e) { + console.log("Bug4: ", e) //console.log("Failed parsing JSON even though its valid (2): ", e) jsonvalid = false @@ -477,7 +482,6 @@ export const validateJson = (showResult) => { } } - //console.log("VALID: ", jsonvalid, result, typeof result) return { valid: jsonvalid, result: result, @@ -1116,10 +1120,15 @@ const Workflows = (props) => { justifyContent: "space-between", }; - const exportAllWorkflows = () => { - for (var key in workflows) { - exportWorkflow(workflows[key], false); + const exportAllWorkflows = (allWorkflows) => { + for (var i = 0; i < allWorkflows.length; i++) { + setTimeout(() => { + console.log(workflows[i].name) + exportWorkflow(workflows[i], false) + }, i * 200); } + + alert.info(`exporting and keeping original for all ${workflows.length} workflows`); }; const deduplicateIds = (data) => { @@ -2811,7 +2820,7 @@ const Workflows = (props) => { style={{}} variant="text" onClick={() => { - exportAllWorkflows(); + exportAllWorkflows(workflows); }} >