From 8ab60dd30a99d38d623d2e7c785a1108b73c5838 Mon Sep 17 00:00:00 2001 From: frikky Date: Tue, 26 May 2020 18:10:23 +0200 Subject: [PATCH 01/15] Bugfixes found Shuffle blog part 2 --- backend/app_sdk/app_base.py | 1 + backend/go-app/codegen.go | 1 + backend/go-app/main.go | 2 +- backend/go-app/walkoff.go | 15 ++++++++++++--- frontend/src/AngularWorkflow.js | 4 ++-- frontend/src/AppCreator.js | 2 +- frontend/src/Workflows.js | 6 +++--- 7 files changed, 21 insertions(+), 10 deletions(-) diff --git a/backend/app_sdk/app_base.py b/backend/app_sdk/app_base.py index d15792a0..03a71e01 100644 --- a/backend/app_sdk/app_base.py +++ b/backend/app_sdk/app_base.py @@ -588,6 +588,7 @@ class AppBase: logging.basicConfig(format="{asctime} - {name} - {levelname}:{message}", style='{') logger = logging.getLogger(f"{cls.__name__}") logger.setLevel(logging.DEBUG) + print("Started execution!!") app = cls(redis=None, logger=logger, console_logger=logger) diff --git a/backend/go-app/codegen.go b/backend/go-app/codegen.go index abe03fa8..c8e4e6ee 100644 --- a/backend/go-app/codegen.go +++ b/backend/go-app/codegen.go @@ -637,6 +637,7 @@ func getRunner(classname string) string { return fmt.Sprintf(` # Run the actual thing after we've checked params def run(request): + print("Started execution!") action = request.get_json() print(action) print(type(action)) diff --git a/backend/go-app/main.go b/backend/go-app/main.go index dc73b5c4..53d21219 100644 --- a/backend/go-app/main.go +++ b/backend/go-app/main.go @@ -5748,10 +5748,10 @@ func runInit(ctx context.Context) { } } + //log.Printf("Schedule time: every %d seconds", schedule.Seconds) jobret, err := newscheduler.Every(schedule.Seconds).Seconds().NotImmediately().Run(job) if err != nil { log.Printf("Failed to schedule workflow: %s", err) - // FIXME: what now? lol:w } scheduledJobs[schedule.Id] = jobret diff --git a/backend/go-app/walkoff.go b/backend/go-app/walkoff.go index 07ae2c18..af100687 100644 --- a/backend/go-app/walkoff.go +++ b/backend/go-app/walkoff.go @@ -2340,7 +2340,16 @@ func scheduleWorkflow(resp http.ResponseWriter, request *http.Request) { return } - log.Printf("Schedulearg: %s", string(scheduleArg)) + // Clean up garbage. This might be wrong in some very specific use-cases + parsedBody := string(scheduleArg) + parsedBody = strings.Replace(parsedBody, "\\\"", "\"", -1) + if len(parsedBody) > 0 { + if string(parsedBody[0]) == `"` && string(parsedBody[len(parsedBody)-1]) == "\"" { + parsedBody = parsedBody[1 : len(parsedBody)-1] + } + } + + log.Printf("Schedulearg: %s", parsedBody) err = createSchedule( ctx, @@ -2348,7 +2357,7 @@ func scheduleWorkflow(resp http.ResponseWriter, request *http.Request) { workflow.ID, schedule.Name, schedule.Frequency, - scheduleArg, + []byte(parsedBody), ) // FIXME - real error message lol @@ -3325,7 +3334,6 @@ func iterateOpenApiGithub(fs billy.Filesystem, dir []os.FileInfo, extra string, // Check the file filename := file.Name() if strings.Contains(filename, "yaml") || strings.Contains(filename, "yml") { - appCounter += 1 //log.Printf("File: %s", filename) //log.Printf("Found file: %s", filename) tmpExtra := fmt.Sprintf("%s%s/", extra, file.Name()) @@ -3395,6 +3403,7 @@ func iterateOpenApiGithub(fs billy.Filesystem, dir []os.FileInfo, extra string, log.Printf("Failed setting workflowapp in loop: %s", err) continue } else { + appCounter += 1 log.Printf("Added %s:%s to the database from OpenAPI repo", api.Name, api.AppVersion) // Set OpenAPI datastore diff --git a/frontend/src/AngularWorkflow.js b/frontend/src/AngularWorkflow.js index bc9d99fe..46996c91 100644 --- a/frontend/src/AngularWorkflow.js +++ b/frontend/src/AngularWorkflow.js @@ -4118,7 +4118,7 @@ const AngularWorkflow = (props) => {
- Run how often (seconds)? + Interval (seconds)
{

Executing Workflow

{executionData.execution_argument !== undefined && executionData.execution_argument.length > 0 ?
-

Execution Argument:

{executionText} +

Execution Argument:

{executionData.execution_argument}
: null } {executionData.status !== undefined && executionData.status.length > 0 ? diff --git a/frontend/src/AppCreator.js b/frontend/src/AppCreator.js index 24ab8353..6ccd9d35 100644 --- a/frontend/src/AppCreator.js +++ b/frontend/src/AppCreator.js @@ -600,7 +600,7 @@ const AppCreator = (props) => { console.log("Location: ", parameterLocation) console.log("Name: ", parameterName) const apiKey = authenticationOption === "API key" ? -
+

API key

{
-

Welcome to Shuffle!

+

Welcome to Shuffle

- Shuffle is a flexible, easy to use, automation framework allowing users to integrate their services and devices to reduce the amount of manual labor required for those tasks. Click here for more information. + Shuffle is a flexible, easy to use, automation platform allowing users to integrate their services and devices freely. It's made to significantly reduce the amount of manual labor, and is focused on security applications. Click here to learn more.

- If you want to jump straight into it, click the following button to create your first workflow: + If you want to jump straight into it, click here to create your first workflow:
From d032005bb50b6c82df9d9a48725213d935531313 Mon Sep 17 00:00:00 2001 From: frikky Date: Thu, 28 May 2020 19:18:10 +0200 Subject: [PATCH 02/15] Fixed Issue #40 --- frontend/src/AngularWorkflow.js | 82 ++++++++++++++++----------------- 1 file changed, 40 insertions(+), 42 deletions(-) diff --git a/frontend/src/AngularWorkflow.js b/frontend/src/AngularWorkflow.js index 46996c91..6185fa3a 100644 --- a/frontend/src/AngularWorkflow.js +++ b/frontend/src/AngularWorkflow.js @@ -798,16 +798,16 @@ const AngularWorkflow = (props) => { } const onUnselect = (event) => { - //console.log("Unselect?") console.time("UNSELECT") // FIXME - check if they have value before overriding like this for no reason. // Would save a lot of time (400~ ms -> 30ms) - //setSelectedActionName({}) - setSelectedAction({}) - setSelectedApp({}) - setSelectedTrigger({}) - setSelectedEdge({}) + //setSelectedAction({}) + //setSelectedApp({}) + //setSelectedTrigger({}) + //setSelectedEdge({}) + + // setSelectedTriggerIndex(-1) //setSelectedActionEnvironment({}) //setSelectedEdge({}) @@ -821,6 +821,7 @@ const AngularWorkflow = (props) => { } const onEdgeSelect = (event) => { + setRightSideBarOpen(true) const triggercheck = workflow.triggers.find(trigger => trigger.id === event.target.data()["source"]) if (triggercheck === undefined) { setSelectedEdgeIndex(workflow.branches.findIndex(data => data.id === event.target.data()["id"])) @@ -837,7 +838,7 @@ const AngularWorkflow = (props) => { if (data.type === "ACTION") { // FIXME - unselect //console.log(cy.elements('[_id!="${data._id}"]`)) - console.time('ACTIONSTART'); + // Does it choose the wrong action? const curaction = workflow.actions.find(a => a.id === data.id) if (!curaction || curaction === undefined) { //console.log("Action not found error") @@ -855,25 +856,24 @@ const AngularWorkflow = (props) => { env = environments[0] } - console.log("Selected: ", data.id) - console.log(curaction) - - setRequiresAuthentication(curapp.authentication.required) setSelectedApp(curapp) + setSelectedAction(curaction) setSelectedActionEnvironment(env) setSelectedActionName(curaction.name) - setSelectedAction(curaction) + setRequiresAuthentication(curapp.authentication.required) } else if (data.type === "TRIGGER") { //console.log("Should handle trigger "+data.triggertype) //console.log(data) setSelectedTriggerIndex(workflow.triggers.findIndex(a => a.id === data.id)) setSelectedTrigger(data) - setSelectedActionEnvironment(data.env) setSelectedActionName(data.name) + setSelectedActionEnvironment(data.env) } else { - console.log("Should handle type "+data.type) + alert.error("Can't handle "+data.type) } + + setRightSideBarOpen(true) } const onEdgeAdded = (event) => { @@ -2103,8 +2103,9 @@ const AngularWorkflow = (props) => { const setNewSelectedAction = (e) => { const newaction = selectedApp.actions.find(a => a.name === e.target.value) + // Does this one find the wrong one? selectedAction.name = newaction.name - selectedAction.parameters = newaction.parameters + selectedAction.parameters = JSON.parse(JSON.stringify(newaction.parameters)) // FIXME - this is broken sometimes lol //var env = environments.find(a => a.name === newaction.environment) @@ -2180,7 +2181,7 @@ const AngularWorkflow = (props) => { // Dropdown -> static, action, local env, global env // VALUE (JSON) // {data.name}, {data.description}, {data.required}, {data.schema.type} - const AppActionArguments = () => { + const AppActionArguments = (props) => { const [selectedActionParameters, setSelectedActionParameters] = React.useState([]) const [selectedVariableParameter, setSelectedVariableParameter] = React.useState() @@ -2189,11 +2190,15 @@ const AngularWorkflow = (props) => { if (requiresAuthentication) { console.log("ADD AUTHENTICATION FIELDS") } - setSelectedActionParameters(selectedAction.parameters) + + if (selectedAction.parameters !== null && selectedAction.parameters.length > 0) { + setSelectedActionParameters(selectedAction.parameters) + } } if ((selectedVariableParameter === null || selectedVariableParameter === undefined) && (workflow.workflow_variables !== null && workflow.workflow_variables.length > 0)) { // FIXME - this is the bad thing + console.log("Does it go here or what?") setSelectedVariableParameter(workflow.workflow_variables[0].name) } @@ -2201,20 +2206,20 @@ const AngularWorkflow = (props) => { const changeActionParameter = (event, count) => { selectedActionParameters[count].value = event.target.value - selectedAction.parameters = selectedActionParameters + selectedAction.parameters[count].value = event.target.value setSelectedAction(selectedAction) + //setUpdate(event.target.value) } - const changeActionParameterVariable = (fieldvalue, count) => { setSelectedVariableParameter(fieldvalue) // this isn't updated anywhere in the workflow - setSelectedActionName({}) - setSelectedAction({}) - setSelectedTrigger({}) - setSelectedApp({}) - setSelectedEdge({}) + // setSelectedActionName({}) + // setSelectedAction({}) + // setSelectedTrigger({}) + // setSelectedApp({}) + // setSelectedEdge({}) selectedActionParameters[count].action_field = fieldvalue selectedAction.parameters = selectedActionParameters @@ -2222,6 +2227,7 @@ const AngularWorkflow = (props) => { setSelectedActionName(selectedActionName) setSelectedApp(selectedApp) setSelectedAction(selectedAction) + setUpdate(fieldvalue) } // Sets ACTION_RESULT things @@ -2236,11 +2242,6 @@ const AngularWorkflow = (props) => { selectedActionParameters[count].action_field = fieldvalue selectedAction.parameters = selectedActionParameters - setSelectedActionName({}) - setSelectedAction({}) - setSelectedTrigger({}) - setSelectedApp({}) - setSelectedEdge({}) // FIXME - check if startnode // Set value @@ -2248,6 +2249,7 @@ const AngularWorkflow = (props) => { setSelectedApp(selectedApp) setSelectedAction(selectedAction) + setUpdate(fieldvalue) } const changeActionParameterVariant = (data, count) => { @@ -2283,7 +2285,8 @@ const AngularWorkflow = (props) => { setSelectedAction(selectedAction) } - if (Object.getOwnPropertyNames(selectedAction).length > 0 && selectedActionParameters) { + // FIXME: Issue #40 - selectedActionParameters not reset + if (Object.getOwnPropertyNames(selectedAction).length > 0 && selectedActionParameters.length > 0) { return (
Arguments @@ -2300,7 +2303,7 @@ const AngularWorkflow = (props) => { multiline = true } - if (data.value.startsWith("{") && data.value.endsWith("}")) { + if (data.value !== undefined && data.value.startsWith("{") && data.value.endsWith("}")) { multiline = true } @@ -2577,7 +2580,7 @@ const AngularWorkflow = (props) => { />
- Environment: + Environment
- +
@@ -4323,9 +4326,12 @@ const AngularWorkflow = (props) => { } const RightSideBar = () => { + if (!rightSideBarOpen) { + return null + } + setLastSaved(false) if (Object.getOwnPropertyNames(selectedAction).length > 0 && Object.getOwnPropertyNames(selectedApp).length > 0) { - setRightSideBarOpen(true) //console.time('ACTIONSTART'); return(
@@ -4334,7 +4340,6 @@ const AngularWorkflow = (props) => { ) } else if (Object.getOwnPropertyNames(selectedTrigger).length > 0) { if (selectedTrigger.trigger_type === "SCHEDULE") { - setRightSideBarOpen(true) console.log("SCHEDULE") return(
@@ -4342,24 +4347,18 @@ const AngularWorkflow = (props) => {
) } else if (selectedTrigger.trigger_type === "WEBHOOK") { - setRightSideBarOpen(true) - console.log("WEBHOOK") return(
) } else if (selectedTrigger.trigger_type === "EMAIL") { - setRightSideBarOpen(true) - console.log("EMAIL") return(
) } else if (selectedTrigger.trigger_type === "USERINPUT") { - setRightSideBarOpen(true) - console.log("USER INPUT SIDEBAR") return(
@@ -4372,7 +4371,6 @@ const AngularWorkflow = (props) => { return null } } else if (Object.getOwnPropertyNames(selectedEdge).length > 0) { - setRightSideBarOpen(true) return(
From 571b7e432cfb77eb80edc10324aefbd75516b099 Mon Sep 17 00:00:00 2001 From: frikky Date: Thu, 28 May 2020 19:20:19 +0200 Subject: [PATCH 03/15] Fixed branch bug after #40 --- frontend/src/AngularWorkflow.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frontend/src/AngularWorkflow.js b/frontend/src/AngularWorkflow.js index 6185fa3a..ec1c481b 100644 --- a/frontend/src/AngularWorkflow.js +++ b/frontend/src/AngularWorkflow.js @@ -822,10 +822,14 @@ const AngularWorkflow = (props) => { const onEdgeSelect = (event) => { setRightSideBarOpen(true) + const triggercheck = workflow.triggers.find(trigger => trigger.id === event.target.data()["source"]) if (triggercheck === undefined) { setSelectedEdgeIndex(workflow.branches.findIndex(data => data.id === event.target.data()["id"])) setSelectedEdge(event.target.data()) + + setSelectedAction({}) + setSelectedTrigger({}) } else { alert.info("Can't edit branches from triggers") } From 186559ef1394d8134772406facf7f0f44c12aaf3 Mon Sep 17 00:00:00 2001 From: frikky Date: Thu, 28 May 2020 19:41:54 +0200 Subject: [PATCH 04/15] Added basic check for #39 --- frontend/package-lock.json | 549 +++++++++++++++++--------------- frontend/package.json | 5 +- frontend/src/AngularWorkflow.js | 11 +- 3 files changed, 307 insertions(+), 258 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 94f34ac5..a249ae8d 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -960,9 +960,9 @@ "integrity": "sha512-b0JQb10Lie07iW2/9uKCQSrXif262d6zfYBstCLLJUk0JVA+7o/yLDg5p2+GkjgJbmodjHozIXs4Bi34RRhL8Q==" }, "@emotion/hash": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.7.3.tgz", - "integrity": "sha512-14ZVlsB9akwvydAdaEnVnvqu6J2P6ySv39hYyl/aoB6w/V+bXX0tay8cF6paqbgZsN2n5Xh15uF4pE+GvE+itw==" + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", + "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==" }, "@emotion/is-prop-valid": { "version": "0.8.3", @@ -988,37 +988,87 @@ "integrity": "sha512-XiUPoS79r1G7PcpnNtq85TJ7inJWe0v+b5oZJZKb0pGHNIV6+UiNeQWiFGmuQ0aj7GEhnD/v9iqxIsjuRKtEnQ==" }, "@material-ui/core": { - "version": "3.9.3", - "resolved": "https://registry.npmjs.org/@material-ui/core/-/core-3.9.3.tgz", - "integrity": "sha512-REIj62+zEvTgI/C//YL4fZxrCVIySygmpZglsu/Nl5jPqy3CDjZv1F9ubBYorHqmRgeVPh64EghMMWqk4egmfg==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.10.0.tgz", + "integrity": "sha512-yVlHe4b8AaoiTHhCOZeszHZ+T2iHU5DncdMGeNcQaaaO+q/Qrq0hxP3iFzTbgjRWnWwftEVQL668GRxcPJVRaQ==", "requires": { - "@babel/runtime": "^7.2.0", - "@material-ui/system": "^3.0.0-alpha.0", - "@material-ui/utils": "^3.0.0-alpha.2", - "@types/jss": "^9.5.6", - "@types/react-transition-group": "^2.0.8", - "brcast": "^3.0.1", - "classnames": "^2.2.5", - "csstype": "^2.5.2", - "debounce": "^1.1.0", - "deepmerge": "^3.0.0", - "dom-helpers": "^3.2.1", - "hoist-non-react-statics": "^3.2.1", - "is-plain-object": "^2.0.4", - "jss": "^9.8.7", - "jss-camel-case": "^6.0.0", - "jss-default-unit": "^8.0.2", - "jss-global": "^3.0.0", - "jss-nested": "^6.0.1", - "jss-props-sort": "^6.0.0", - "jss-vendor-prefixer": "^7.0.0", - "normalize-scroll-left": "^0.1.2", - "popper.js": "^1.14.1", - "prop-types": "^15.6.0", - "react-event-listener": "^0.6.2", - "react-transition-group": "^2.2.1", - "recompose": "0.28.0 - 0.30.0", - "warning": "^4.0.1" + "@babel/runtime": "^7.4.4", + "@material-ui/styles": "^4.10.0", + "@material-ui/system": "^4.9.14", + "@material-ui/types": "^5.1.0", + "@material-ui/utils": "^4.9.12", + "@types/react-transition-group": "^4.2.0", + "clsx": "^1.0.4", + "hoist-non-react-statics": "^3.3.2", + "popper.js": "^1.16.1-lts", + "prop-types": "^15.7.2", + "react-is": "^16.8.0", + "react-transition-group": "^4.4.0" + }, + "dependencies": { + "csstype": { + "version": "2.6.10", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.10.tgz", + "integrity": "sha512-D34BqZU4cIlMCY93rZHbrq9pjTAQJ3U8S8rfBqjwHxkGPThWFjzZDQpgMJY0QViLxth6ZKYiwFBo14RdN44U/w==" + }, + "dom-helpers": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.1.4.tgz", + "integrity": "sha512-TjMyeVUvNEnOnhzs6uAn9Ya47GmMo3qq7m+Lr/3ON0Rs5kHvb8I+SQYjLUSYn7qhEm0QjW0yrBkvz9yOrwwz1A==", + "requires": { + "@babel/runtime": "^7.8.7", + "csstype": "^2.6.7" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.1.tgz", + "integrity": "sha512-nQbbCbQc9u/rpg1XCxoMYQTbSMVZjCDxErQ1ClCn9Pvcmv1lGads19ep0a2VsEiIJeHqjZley6EQGEC3Yo1xMA==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + } + } + }, + "hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "requires": { + "react-is": "^16.7.0" + } + }, + "popper.js": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz", + "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==" + }, + "react-transition-group": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.1.tgz", + "integrity": "sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw==", + "requires": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.1.tgz", + "integrity": "sha512-nQbbCbQc9u/rpg1XCxoMYQTbSMVZjCDxErQ1ClCn9Pvcmv1lGads19ep0a2VsEiIJeHqjZley6EQGEC3Yo1xMA==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + } + } + }, + "regenerator-runtime": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==" + } } }, "@material-ui/icons": { @@ -1030,84 +1080,62 @@ } }, "@material-ui/styles": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.5.0.tgz", - "integrity": "sha512-O0NSAECHK9f3DZK6wy56PZzp8b/7KSdfpJs8DSC7vnXUAoMPCTtchBKLzMtUsNlijiJFeJjSxNdQfjWXgyur5A==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.10.0.tgz", + "integrity": "sha512-XPwiVTpd3rlnbfrgtEJ1eJJdFCXZkHxy8TrdieaTvwxNYj42VnnCyFzxYeNW9Lhj4V1oD8YtQ6S5Gie7bZDf7Q==", "requires": { "@babel/runtime": "^7.4.4", - "@emotion/hash": "^0.7.1", - "@material-ui/types": "^4.1.1", - "@material-ui/utils": "^4.1.0", - "clsx": "^1.0.2", + "@emotion/hash": "^0.8.0", + "@material-ui/types": "^5.1.0", + "@material-ui/utils": "^4.9.6", + "clsx": "^1.0.4", "csstype": "^2.5.2", - "deepmerge": "^4.0.0", - "hoist-non-react-statics": "^3.2.1", - "jss": "^10.0.0", - "jss-plugin-camel-case": "^10.0.0", - "jss-plugin-default-unit": "^10.0.0", - "jss-plugin-global": "^10.0.0", - "jss-plugin-nested": "^10.0.0", - "jss-plugin-props-sort": "^10.0.0", - "jss-plugin-rule-value-function": "^10.0.0", - "jss-plugin-vendor-prefixer": "^10.0.0", + "hoist-non-react-statics": "^3.3.2", + "jss": "^10.0.3", + "jss-plugin-camel-case": "^10.0.3", + "jss-plugin-default-unit": "^10.0.3", + "jss-plugin-global": "^10.0.3", + "jss-plugin-nested": "^10.0.3", + "jss-plugin-props-sort": "^10.0.3", + "jss-plugin-rule-value-function": "^10.0.3", + "jss-plugin-vendor-prefixer": "^10.0.3", "prop-types": "^15.7.2" }, "dependencies": { - "@material-ui/utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-4.4.0.tgz", - "integrity": "sha512-UXoQVwArQEQWXxf2FPs0iJGT+MePQpKr0Qh0CPoLc1OdF0GSMTmQczcqCzwZkeHxHAOq/NkIKM1Pb/ih1Avicg==", + "hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", "requires": { - "@babel/runtime": "^7.4.4", - "prop-types": "^15.7.2", - "react-is": "^16.8.6" - } - }, - "deepmerge": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.0.tgz", - "integrity": "sha512-/pED+kD8V9n15L1lon8DXEiWLQMW4tTiegn1kIWIQ+DBudOkFitz1cfjWQiSeKMPBQOknT3LpueyAmMVJ1Ho2g==" - }, - "jss": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/jss/-/jss-10.0.0.tgz", - "integrity": "sha512-TPpDFsiBjuERiL+dFDq8QCdiF9oDasPcNqCKLGCo/qED3fNYOQ8PX2lZhknyTiAt3tZrfOFbb0lbQ9lTjPZxsQ==", - "requires": { - "@babel/runtime": "^7.3.1", - "csstype": "^2.6.5", - "is-in-browser": "^1.1.3", - "tiny-warning": "^1.0.2" + "react-is": "^16.7.0" } } } }, "@material-ui/system": { - "version": "3.0.0-alpha.2", - "resolved": "https://registry.npmjs.org/@material-ui/system/-/system-3.0.0-alpha.2.tgz", - "integrity": "sha512-odmxQ0peKpP7RQBQ8koly06YhsPzcoVib1vByVPBH4QhwqBXuYoqlCjt02846fYspAqkrWzjxnWUD311EBbxOA==", + "version": "4.9.14", + "resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.9.14.tgz", + "integrity": "sha512-oQbaqfSnNlEkXEziDcJDDIy8pbvwUmZXWNqlmIwDqr/ZdCK8FuV3f4nxikUh7hvClKV2gnQ9djh5CZFTHkZj3w==", "requires": { - "@babel/runtime": "^7.2.0", - "deepmerge": "^3.0.0", - "prop-types": "^15.6.0", - "warning": "^4.0.1" + "@babel/runtime": "^7.4.4", + "@material-ui/utils": "^4.9.6", + "csstype": "^2.5.2", + "prop-types": "^15.7.2" } }, "@material-ui/types": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@material-ui/types/-/types-4.1.1.tgz", - "integrity": "sha512-AN+GZNXytX9yxGi0JOfxHrRTbhFybjUJ05rnsBVjcB+16e466Z0Xe5IxawuOayVZgTBNDxmPKo5j4V6OnMtaSQ==", - "requires": { - "@types/react": "*" - } + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@material-ui/types/-/types-5.1.0.tgz", + "integrity": "sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A==" }, "@material-ui/utils": { - "version": "3.0.0-alpha.3", - "resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-3.0.0-alpha.3.tgz", - "integrity": "sha512-rwMdMZptX0DivkqBuC+Jdq7BYTXwqKai5G5ejPpuEDKpWzi1Oxp+LygGw329FrKpuKeiqpcymlqJTjmy+quWng==", + "version": "4.9.12", + "resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-4.9.12.tgz", + "integrity": "sha512-/0rgZPEOcZq5CFA4+4n6Q6zk7fi8skHhH2Bcra8R3epoJEYy5PL55LuMazPtPH1oKeRausDV/Omz4BbgFsn1HQ==", "requires": { - "@babel/runtime": "^7.2.0", - "prop-types": "^15.6.0", - "react-is": "^16.6.3" + "@babel/runtime": "^7.4.4", + "prop-types": "^15.7.2", + "react-is": "^16.8.0" } }, "@mrmlnc/readdir-enhanced": { @@ -1337,9 +1365,9 @@ } }, "@types/react-transition-group": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-2.9.2.tgz", - "integrity": "sha512-5Fv2DQNO+GpdPZcxp2x/OQG/H19A01WlmpjVD9cKvVFmoVLOZ9LvBgSWG6pSXIU4og5fgbvGPaCV5+VGkWAEHA==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.0.tgz", + "integrity": "sha512-/QfLHGpu+2fQOqQaXh8MG9q03bFENooTb/it4jr5kKaZlDQfWvjqWZg48AwzPVMBHlRuTRAY7hRHCEOXz5kV6w==", "requires": { "@types/react": "*" } @@ -4788,11 +4816,27 @@ "integrity": "sha1-g4NCMMyfdMRX3lnuvRVD/uuDt+w=" }, "css-vendor": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-0.3.8.tgz", - "integrity": "sha1-ZCHP0wNM5mT+dnOXL9ARn8KJQfo=", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz", + "integrity": "sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==", "requires": { + "@babel/runtime": "^7.8.3", "is-in-browser": "^1.0.2" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.1.tgz", + "integrity": "sha512-nQbbCbQc9u/rpg1XCxoMYQTbSMVZjCDxErQ1ClCn9Pvcmv1lGads19ep0a2VsEiIJeHqjZley6EQGEC3Yo1xMA==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "regenerator-runtime": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==" + } } }, "css-what": { @@ -5504,9 +5548,9 @@ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" }, "deepmerge": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-3.2.1.tgz", - "integrity": "sha512-+hbDSzTqEW0fWgnlKksg7XAOtT+ddZS5lHZJ6f6MdixRs9wQy+50fm1uUCVb1IkvjLUYX/SfFO021ZNwriURTw==" + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-3.3.0.tgz", + "integrity": "sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA==" }, "default-gateway": { "version": "2.7.2", @@ -11052,23 +11096,14 @@ } }, "jss": { - "version": "9.8.7", - "resolved": "https://registry.npmjs.org/jss/-/jss-9.8.7.tgz", - "integrity": "sha512-awj3XRZYxbrmmrx9LUSj5pXSUfm12m8xzi/VKeqI1ZwWBtQ0kVPTs3vYs32t4rFw83CgFDukA8wKzOE9sMQnoQ==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/jss/-/jss-10.1.1.tgz", + "integrity": "sha512-Xz3qgRUFlxbWk1czCZibUJqhVPObrZHxY3FPsjCXhDld4NOj1BgM14Ir5hVm+Qr6OLqVljjGvoMcCdXNOAbdkQ==", "requires": { + "@babel/runtime": "^7.3.1", + "csstype": "^2.6.5", "is-in-browser": "^1.1.3", - "symbol-observable": "^1.1.0", - "warning": "^3.0.0" - }, - "dependencies": { - "warning": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", - "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=", - "requires": { - "loose-envify": "^1.0.0" - } - } + "tiny-warning": "^1.0.2" } }, "jss-camel-case": { @@ -11108,179 +11143,69 @@ } }, "jss-plugin-camel-case": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.0.0.tgz", - "integrity": "sha512-yALDL00+pPR4FJh+k07A8FeDvfoPPuXU48HLy63enAubcVd3DnS+2rgqPXglHDGixIDVkCSXecl/l5GAMjzIbA==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.1.1.tgz", + "integrity": "sha512-MDIaw8FeD5uFz1seQBKz4pnvDLnj5vIKV5hXSVdMaAVq13xR6SVTVWkIV/keyTs5txxTvzGJ9hXoxgd1WTUlBw==", "requires": { "@babel/runtime": "^7.3.1", "hyphenate-style-name": "^1.0.3", - "jss": "10.0.0" - }, - "dependencies": { - "jss": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/jss/-/jss-10.0.0.tgz", - "integrity": "sha512-TPpDFsiBjuERiL+dFDq8QCdiF9oDasPcNqCKLGCo/qED3fNYOQ8PX2lZhknyTiAt3tZrfOFbb0lbQ9lTjPZxsQ==", - "requires": { - "@babel/runtime": "^7.3.1", - "csstype": "^2.6.5", - "is-in-browser": "^1.1.3", - "tiny-warning": "^1.0.2" - } - } + "jss": "10.1.1" } }, "jss-plugin-default-unit": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.0.0.tgz", - "integrity": "sha512-sURozIOdCtGg9ap18erQ+ijndAfEGtTaetxfU3H4qwC18Bi+fdvjlY/ahKbuu0ASs7R/+WKCP7UaRZOjUDMcdQ==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.1.1.tgz", + "integrity": "sha512-UkeVCA/b3QEA4k0nIKS4uWXDCNmV73WLHdh2oDGZZc3GsQtlOCuiH3EkB/qI60v2MiCq356/SYWsDXt21yjwdg==", "requires": { "@babel/runtime": "^7.3.1", - "jss": "10.0.0" - }, - "dependencies": { - "jss": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/jss/-/jss-10.0.0.tgz", - "integrity": "sha512-TPpDFsiBjuERiL+dFDq8QCdiF9oDasPcNqCKLGCo/qED3fNYOQ8PX2lZhknyTiAt3tZrfOFbb0lbQ9lTjPZxsQ==", - "requires": { - "@babel/runtime": "^7.3.1", - "csstype": "^2.6.5", - "is-in-browser": "^1.1.3", - "tiny-warning": "^1.0.2" - } - } + "jss": "10.1.1" } }, "jss-plugin-global": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.0.0.tgz", - "integrity": "sha512-80ofWKSQUo62bxLtRoTNe0kFPtHgUbAJeOeR36WEGgWIBEsXLyXOnD5KNnjPqG4heuEkz9eSLccjYST50JnI7Q==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.1.1.tgz", + "integrity": "sha512-VBG3wRyi3Z8S4kMhm8rZV6caYBegsk+QnQZSVmrWw6GVOT/Z4FA7eyMu5SdkorDlG/HVpHh91oFN56O4R9m2VA==", "requires": { "@babel/runtime": "^7.3.1", - "jss": "10.0.0" - }, - "dependencies": { - "jss": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/jss/-/jss-10.0.0.tgz", - "integrity": "sha512-TPpDFsiBjuERiL+dFDq8QCdiF9oDasPcNqCKLGCo/qED3fNYOQ8PX2lZhknyTiAt3tZrfOFbb0lbQ9lTjPZxsQ==", - "requires": { - "@babel/runtime": "^7.3.1", - "csstype": "^2.6.5", - "is-in-browser": "^1.1.3", - "tiny-warning": "^1.0.2" - } - } + "jss": "10.1.1" } }, "jss-plugin-nested": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.0.0.tgz", - "integrity": "sha512-waxxwl/po1hN3azTyixKnr8ReEqUv5WK7WsO+5AWB0bFndML5Yqnt8ARZ90HEg8/P6WlqE/AB2413TkCRZE8bA==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.1.1.tgz", + "integrity": "sha512-ozEu7ZBSVrMYxSDplPX3H82XHNQk2DQEJ9TEyo7OVTPJ1hEieqjDFiOQOxXEj9z3PMqkylnUbvWIZRDKCFYw5Q==", "requires": { "@babel/runtime": "^7.3.1", - "jss": "10.0.0", + "jss": "10.1.1", "tiny-warning": "^1.0.2" - }, - "dependencies": { - "jss": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/jss/-/jss-10.0.0.tgz", - "integrity": "sha512-TPpDFsiBjuERiL+dFDq8QCdiF9oDasPcNqCKLGCo/qED3fNYOQ8PX2lZhknyTiAt3tZrfOFbb0lbQ9lTjPZxsQ==", - "requires": { - "@babel/runtime": "^7.3.1", - "csstype": "^2.6.5", - "is-in-browser": "^1.1.3", - "tiny-warning": "^1.0.2" - } - } } }, "jss-plugin-props-sort": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.0.0.tgz", - "integrity": "sha512-41mf22CImjwNdtOG3r+cdC8+RhwNm616sjHx5YlqTwtSJLyLFinbQC/a4PIFk8xqf1qpFH1kEAIw+yx9HaqZ3g==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.1.1.tgz", + "integrity": "sha512-g/joK3eTDZB4pkqpZB38257yD4LXB0X15jxtZAGbUzcKAVUHPl9Jb47Y7lYmiGsShiV4YmQRqG1p2DHMYoK91g==", "requires": { "@babel/runtime": "^7.3.1", - "jss": "10.0.0" - }, - "dependencies": { - "jss": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/jss/-/jss-10.0.0.tgz", - "integrity": "sha512-TPpDFsiBjuERiL+dFDq8QCdiF9oDasPcNqCKLGCo/qED3fNYOQ8PX2lZhknyTiAt3tZrfOFbb0lbQ9lTjPZxsQ==", - "requires": { - "@babel/runtime": "^7.3.1", - "csstype": "^2.6.5", - "is-in-browser": "^1.1.3", - "tiny-warning": "^1.0.2" - } - } + "jss": "10.1.1" } }, "jss-plugin-rule-value-function": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.0.0.tgz", - "integrity": "sha512-Jw+BZ8JIw1f12V0SERqGlBT1JEPWax3vuZpMym54NAXpPb7R1LYHiCTIlaJUyqvIfEy3kiHMtgI+r2whGgRIxQ==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.1.1.tgz", + "integrity": "sha512-ClV1lvJ3laU9la1CUzaDugEcwnpjPTuJ0yGy2YtcU+gG/w9HMInD5vEv7xKAz53Bk4WiJm5uLOElSEshHyhKNw==", "requires": { "@babel/runtime": "^7.3.1", - "jss": "10.0.0" - }, - "dependencies": { - "jss": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/jss/-/jss-10.0.0.tgz", - "integrity": "sha512-TPpDFsiBjuERiL+dFDq8QCdiF9oDasPcNqCKLGCo/qED3fNYOQ8PX2lZhknyTiAt3tZrfOFbb0lbQ9lTjPZxsQ==", - "requires": { - "@babel/runtime": "^7.3.1", - "csstype": "^2.6.5", - "is-in-browser": "^1.1.3", - "tiny-warning": "^1.0.2" - } - } + "jss": "10.1.1" } }, "jss-plugin-vendor-prefixer": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.0.0.tgz", - "integrity": "sha512-qslqvL0MUbWuzXJWdUxpj6mdNUX8jr4FFTo3aZnAT65nmzWL7g8oTr9ZxmTXXgdp7ANhS1QWE7036/Q2isFBpw==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.1.1.tgz", + "integrity": "sha512-09MZpQ6onQrhaVSF6GHC4iYifQ7+4YC/tAP6D4ZWeZotvCMq1mHLqNKRIaqQ2lkgANjlEot2JnVi1ktu4+L4pw==", "requires": { "@babel/runtime": "^7.3.1", - "css-vendor": "^2.0.6", - "jss": "10.0.0" - }, - "dependencies": { - "css-vendor": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.7.tgz", - "integrity": "sha512-VS9Rjt79+p7M0WkPqcAza4Yq1ZHrsHrwf7hPL/bjQB+c1lwmAI+1FXxYTYt818D/50fFVflw0XKleiBN5RITkg==", - "requires": { - "@babel/runtime": "^7.6.2", - "is-in-browser": "^1.0.2" - }, - "dependencies": { - "@babel/runtime": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.6.3.tgz", - "integrity": "sha512-kq6anf9JGjW8Nt5rYfEuGRaEAaH1mkv3Bbu6rYvLOpPh/RusSJXuKPEAoZ7L7gybZkchE8+NV5g9vKF4AGAtsA==", - "requires": { - "regenerator-runtime": "^0.13.2" - } - } - } - }, - "jss": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/jss/-/jss-10.0.0.tgz", - "integrity": "sha512-TPpDFsiBjuERiL+dFDq8QCdiF9oDasPcNqCKLGCo/qED3fNYOQ8PX2lZhknyTiAt3tZrfOFbb0lbQ9lTjPZxsQ==", - "requires": { - "@babel/runtime": "^7.3.1", - "csstype": "^2.6.5", - "is-in-browser": "^1.1.3", - "tiny-warning": "^1.0.2" - } - } + "css-vendor": "^2.0.7", + "jss": "10.1.1" } }, "jss-props-sort": { @@ -11294,6 +11219,16 @@ "integrity": "sha512-Agd+FKmvsI0HLcYXkvy8GYOw3AAASBUpsmIRvVQheps+JWaN892uFOInTr0DRydwaD91vSSUCU4NssschvF7MA==", "requires": { "css-vendor": "^0.3.8" + }, + "dependencies": { + "css-vendor": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-0.3.8.tgz", + "integrity": "sha1-ZCHP0wNM5mT+dnOXL9ARn8KJQfo=", + "requires": { + "is-in-browser": "^1.0.2" + } + } } }, "jsx-ast-utils": { @@ -11753,6 +11688,102 @@ "react-transition-group": "4.0.1" }, "dependencies": { + "@material-ui/core": { + "version": "3.9.3", + "resolved": "https://registry.npmjs.org/@material-ui/core/-/core-3.9.3.tgz", + "integrity": "sha512-REIj62+zEvTgI/C//YL4fZxrCVIySygmpZglsu/Nl5jPqy3CDjZv1F9ubBYorHqmRgeVPh64EghMMWqk4egmfg==", + "requires": { + "@babel/runtime": "^7.2.0", + "@material-ui/system": "^3.0.0-alpha.0", + "@material-ui/utils": "^3.0.0-alpha.2", + "@types/jss": "^9.5.6", + "@types/react-transition-group": "^2.0.8", + "brcast": "^3.0.1", + "classnames": "^2.2.5", + "csstype": "^2.5.2", + "debounce": "^1.1.0", + "deepmerge": "^3.0.0", + "dom-helpers": "^3.2.1", + "hoist-non-react-statics": "^3.2.1", + "is-plain-object": "^2.0.4", + "jss": "^9.8.7", + "jss-camel-case": "^6.0.0", + "jss-default-unit": "^8.0.2", + "jss-global": "^3.0.0", + "jss-nested": "^6.0.1", + "jss-props-sort": "^6.0.0", + "jss-vendor-prefixer": "^7.0.0", + "normalize-scroll-left": "^0.1.2", + "popper.js": "^1.14.1", + "prop-types": "^15.6.0", + "react-event-listener": "^0.6.2", + "react-transition-group": "^2.2.1", + "recompose": "0.28.0 - 0.30.0", + "warning": "^4.0.1" + }, + "dependencies": { + "react-transition-group": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz", + "integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==", + "requires": { + "dom-helpers": "^3.4.0", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2", + "react-lifecycles-compat": "^3.0.4" + } + } + } + }, + "@material-ui/system": { + "version": "3.0.0-alpha.2", + "resolved": "https://registry.npmjs.org/@material-ui/system/-/system-3.0.0-alpha.2.tgz", + "integrity": "sha512-odmxQ0peKpP7RQBQ8koly06YhsPzcoVib1vByVPBH4QhwqBXuYoqlCjt02846fYspAqkrWzjxnWUD311EBbxOA==", + "requires": { + "@babel/runtime": "^7.2.0", + "deepmerge": "^3.0.0", + "prop-types": "^15.6.0", + "warning": "^4.0.1" + } + }, + "@material-ui/utils": { + "version": "3.0.0-alpha.3", + "resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-3.0.0-alpha.3.tgz", + "integrity": "sha512-rwMdMZptX0DivkqBuC+Jdq7BYTXwqKai5G5ejPpuEDKpWzi1Oxp+LygGw329FrKpuKeiqpcymlqJTjmy+quWng==", + "requires": { + "@babel/runtime": "^7.2.0", + "prop-types": "^15.6.0", + "react-is": "^16.6.3" + } + }, + "@types/react-transition-group": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-2.9.2.tgz", + "integrity": "sha512-5Fv2DQNO+GpdPZcxp2x/OQG/H19A01WlmpjVD9cKvVFmoVLOZ9LvBgSWG6pSXIU4og5fgbvGPaCV5+VGkWAEHA==", + "requires": { + "@types/react": "*" + } + }, + "jss": { + "version": "9.8.7", + "resolved": "https://registry.npmjs.org/jss/-/jss-9.8.7.tgz", + "integrity": "sha512-awj3XRZYxbrmmrx9LUSj5pXSUfm12m8xzi/VKeqI1ZwWBtQ0kVPTs3vYs32t4rFw83CgFDukA8wKzOE9sMQnoQ==", + "requires": { + "is-in-browser": "^1.1.3", + "symbol-observable": "^1.1.0", + "warning": "^3.0.0" + }, + "dependencies": { + "warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", + "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=", + "requires": { + "loose-envify": "^1.0.0" + } + } + } + }, "moment": { "version": "2.24.0", "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", @@ -18083,6 +18114,14 @@ "pure-color": "^1.2.0" } }, + "react-beforeunload": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/react-beforeunload/-/react-beforeunload-2.2.1.tgz", + "integrity": "sha512-qydpYQuGUaB1C5EP2EFN0YjPo9kgV10Z4suIZ79GIhp0DWNJxHyuR8BiTViOBltTIn9PwlpSqX4fE3uprsdqKA==", + "requires": { + "prop-types": "^15.7.2" + } + }, "react-chartjs-2": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-2.8.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index d9e800a9..cb2263b1 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -4,9 +4,9 @@ "version": "0.3.0", "private": true, "dependencies": { - "@material-ui/core": "^3.9.3", + "@material-ui/core": "^4.5.2", "@material-ui/icons": "^4.5.1", - "@material-ui/styles": "^4.5.0", + "@material-ui/styles": "^4.5.2", "@use-it/interval": "^0.1.3", "class-transformer": "^0.2.0", "create-react-app": "^2.0.3", @@ -32,6 +32,7 @@ "react": "^16.10.2", "react-alert": "^5.5.0", "react-alert-template-basic": "^1.0.0", + "react-beforeunload": "^2.2.1", "react-chartjs-2": "^2.8.0", "react-cookie": "^4.0.1", "react-cytoscapejs": "^1.2.0", diff --git a/frontend/src/AngularWorkflow.js b/frontend/src/AngularWorkflow.js index ec1c481b..8a4adeb6 100644 --- a/frontend/src/AngularWorkflow.js +++ b/frontend/src/AngularWorkflow.js @@ -4,6 +4,7 @@ import { useInterval } from 'react-powerhooks'; import uuid from "uuid"; import {Link} from 'react-router-dom'; +import { Prompt } from 'react-router' import TextField from '@material-ui/core/TextField'; import Drawer from '@material-ui/core/Drawer'; import Button from '@material-ui/core/Button'; @@ -28,6 +29,7 @@ import Checkbox from '@material-ui/core/Checkbox'; import Breadcrumbs from '@material-ui/core/Breadcrumbs'; import CircularProgress from '@material-ui/core/CircularProgress'; import ReactJson from 'react-json-view' +import { useBeforeunload } from 'react-beforeunload'; import DirectionsRunIcon from '@material-ui/icons/DirectionsRun'; import PolymerIcon from '@material-ui/icons/Polymer'; @@ -169,6 +171,9 @@ const AngularWorkflow = (props) => { const [update, setUpdate] = useState(""); const [workflowExecutions, setWorkflowExecutions] = React.useState([]); + const unloadText = 'Are you sure you want to leave?' + useBeforeunload(() => unloadText) + const [elements, setElements] = useState([]) const { start, stop } = useInterval({ duration: 2500, @@ -176,7 +181,7 @@ const AngularWorkflow = (props) => { callback: () => { fetchUpdates() } - }); + }) const getWorkflowExecution = (id) => { fetch(globalUrl+"/api/v1/workflows/"+id+"/executions", { @@ -4843,6 +4848,10 @@ const AngularWorkflow = (props) => { return (
+ {loadedCheck}
) From 8fe024440169722fb3970351c8f46a341a94aeb0 Mon Sep 17 00:00:00 2001 From: frikky Date: Sat, 30 May 2020 11:49:23 +0200 Subject: [PATCH 05/15] Updated OpenAPI app creation process --- backend/go-app/codegen.go | 192 ++++++++++++++++-- backend/go-app/main.go | 6 +- backend/go-app/walkoff.go | 1 + frontend/package.json | 1 + frontend/src/AppCreator.js | 402 +++++++++++++++++++++++++++++++------ frontend/src/Apps.js | 73 ++++--- 6 files changed, 555 insertions(+), 120 deletions(-) diff --git a/backend/go-app/codegen.go b/backend/go-app/codegen.go index c8e4e6ee..368ae854 100644 --- a/backend/go-app/codegen.go +++ b/backend/go-app/codegen.go @@ -4,12 +4,14 @@ import ( "archive/zip" "bytes" "context" + "encoding/json" "errors" "fmt" "io" "io/ioutil" "log" "os" + "strconv" "strings" "cloud.google.com/go/storage" @@ -365,6 +367,20 @@ func generateYaml(swagger *openapi3.Swagger, newmd5 string) (WorkflowApp, []stri // Setting up security schemes extraParameters := []WorkflowAppActionParameter{} + if val, ok := swagger.Info.ExtensionProps.Extensions["x-logo"]; ok { + j, err := json.Marshal(&val) + if err == nil { + if j[0] == 0x22 && j[len(j)-1] == 0x22 { + j = j[1 : len(j)-1] + } + + //log.Printf("%s", j) + api.SmallImage = string(j) + api.LargeImage = string(j) + log.Printf("Set images!") + } + } + securitySchemes := swagger.Components.SecuritySchemes if securitySchemes != nil { //log.Printf("%#v", securitySchemes) @@ -719,6 +735,24 @@ func handleConnect(swagger *openapi3.Swagger, api WorkflowApp, extraParameters [ }, } + // FIXME: Example & Multiline + if param.Value.Example != nil { + curParam.Example = param.Value.Example.(string) + + if param.Value.Name == "body" { + curParam.Value = param.Value.Example.(string) + } + } + if val, ok := param.Value.ExtensionProps.Extensions["multiline"]; ok { + j, err := json.Marshal(&val) + if err == nil { + b, err := strconv.ParseBool(string(j)) + if err == nil { + curParam.Multiline = b + } + } + } + if param.Value.Required { action.Parameters = append(action.Parameters, curParam) } else { @@ -809,6 +843,24 @@ func handleGet(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wor }, } + // FIXME: Example & Multiline + if param.Value.Example != nil { + curParam.Example = param.Value.Example.(string) + + if param.Value.Name == "body" { + curParam.Value = param.Value.Example.(string) + } + } + if val, ok := param.Value.ExtensionProps.Extensions["multiline"]; ok { + j, err := json.Marshal(&val) + if err == nil { + b, err := strconv.ParseBool(string(j)) + if err == nil { + curParam.Multiline = b + } + } + } + if param.Value.Required { action.Parameters = append(action.Parameters, curParam) } else { @@ -894,6 +946,24 @@ func handleHead(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wo }, } + // FIXME: Example & Multiline + if param.Value.Example != nil { + curParam.Example = param.Value.Example.(string) + + if param.Value.Name == "body" { + curParam.Value = param.Value.Example.(string) + } + } + if val, ok := param.Value.ExtensionProps.Extensions["multiline"]; ok { + j, err := json.Marshal(&val) + if err == nil { + b, err := strconv.ParseBool(string(j)) + if err == nil { + curParam.Multiline = b + } + } + } + if param.Value.Required { action.Parameters = append(action.Parameters, curParam) } else { @@ -979,6 +1049,24 @@ func handleDelete(swagger *openapi3.Swagger, api WorkflowApp, extraParameters [] }, } + // FIXME: Example & Multiline + if param.Value.Example != nil { + curParam.Example = param.Value.Example.(string) + + if param.Value.Name == "body" { + curParam.Value = param.Value.Example.(string) + } + } + if val, ok := param.Value.ExtensionProps.Extensions["multiline"]; ok { + j, err := json.Marshal(&val) + if err == nil { + b, err := strconv.ParseBool(string(j)) + if err == nil { + curParam.Multiline = b + } + } + } + if param.Value.Required { action.Parameters = append(action.Parameters, curParam) } else { @@ -1049,23 +1137,27 @@ func handlePost(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wo firstQuery = true optionalQueries := []string{} parameters := []string{} - optionalParameters := []WorkflowAppActionParameter{ - WorkflowAppActionParameter{ - Name: "body", - Description: "The body to use", - Multiline: true, - Required: false, - Example: `{"username": "test"}`, - Schema: SchemaDefinition{ - Type: "string", + optionalParameters := []WorkflowAppActionParameter{} + /* + WorkflowAppActionParameter{ + Name: "body", + Description: "The body to use", + Multiline: true, + Required: false, + Example: `{"username": "test"}`, + Schema: SchemaDefinition{ + Type: "string", + }, }, - }, - } + } + */ if len(path.Post.Parameters) > 0 { for _, param := range path.Post.Parameters { if param.Value.Schema == nil { continue } + + log.Printf("PARAM: %#v", param.Value) curParam := WorkflowAppActionParameter{ Name: param.Value.Name, Description: param.Value.Description, @@ -1076,6 +1168,24 @@ func handlePost(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wo }, } + // FIXME: Example & Multiline + if param.Value.Example != nil { + curParam.Example = param.Value.Example.(string) + + if param.Value.Name == "body" { + curParam.Value = param.Value.Example.(string) + } + } + if val, ok := param.Value.ExtensionProps.Extensions["multiline"]; ok { + j, err := json.Marshal(&val) + if err == nil { + b, err := strconv.ParseBool(string(j)) + if err == nil { + curParam.Multiline = b + } + } + } + if param.Value.Required { action.Parameters = append(action.Parameters, curParam) } else { @@ -1172,6 +1282,24 @@ func handlePatch(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []W }, } + // FIXME: Example & Multiline + if param.Value.Example != nil { + curParam.Example = param.Value.Example.(string) + + if param.Value.Name == "body" { + curParam.Value = param.Value.Example.(string) + } + } + if val, ok := param.Value.ExtensionProps.Extensions["multiline"]; ok { + j, err := json.Marshal(&val) + if err == nil { + b, err := strconv.ParseBool(string(j)) + if err == nil { + curParam.Multiline = b + } + } + } + if param.Value.Required { action.Parameters = append(action.Parameters, curParam) } else { @@ -1241,18 +1369,20 @@ func handlePut(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wor firstQuery = true optionalQueries := []string{} parameters := []string{} - optionalParameters := []WorkflowAppActionParameter{ - WorkflowAppActionParameter{ - Name: "body", - Description: "The body to use", - Multiline: true, - Required: false, - Example: `{"username": "test"}`, - Schema: SchemaDefinition{ - Type: "string", + optionalParameters := []WorkflowAppActionParameter{} + /* + WorkflowAppActionParameter{ + Name: "body", + Description: "The body to use", + Multiline: true, + Required: false, + Example: `{"username": "test"}`, + Schema: SchemaDefinition{ + Type: "string", + }, }, - }, - } + } + */ if len(path.Put.Parameters) > 0 { for _, param := range path.Put.Parameters { if param.Value.Schema == nil { @@ -1268,6 +1398,24 @@ func handlePut(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wor }, } + // FIXME: Example & Multiline + if param.Value.Example != nil { + curParam.Example = param.Value.Example.(string) + + if param.Value.Name == "body" { + curParam.Value = param.Value.Example.(string) + } + } + if val, ok := param.Value.ExtensionProps.Extensions["multiline"]; ok { + j, err := json.Marshal(&val) + if err == nil { + b, err := strconv.ParseBool(string(j)) + if err == nil { + curParam.Multiline = b + } + } + } + if param.Value.Required { action.Parameters = append(action.Parameters, curParam) } else { diff --git a/backend/go-app/main.go b/backend/go-app/main.go index 53d21219..356e0e4a 100644 --- a/backend/go-app/main.go +++ b/backend/go-app/main.go @@ -5543,10 +5543,6 @@ func verifySwagger(resp http.ResponseWriter, request *http.Request) { } api.Owner = user.Id - if len(test.Image) > 0 { - api.SmallImage = test.Image - api.LargeImage = test.Image - } err = dumpApi(basePath, api) if err != nil { @@ -5569,7 +5565,7 @@ func verifySwagger(resp http.ResponseWriter, request *http.Request) { identifier = strings.Replace(identifier, " ", "-", -1) identifier = strings.Replace(identifier, "_", "-", -1) - log.Printf("Successfully uploaded %s to bucket. Proceeding to cloud function", identifier) + log.Printf("Successfully parsed %s. Proceeding to docker container", identifier) // Now that the baseline is setup, we need to make it into a cloud function // 1. Upload the API to datastore for use diff --git a/backend/go-app/walkoff.go b/backend/go-app/walkoff.go index af100687..3ddf336e 100644 --- a/backend/go-app/walkoff.go +++ b/backend/go-app/walkoff.go @@ -2744,6 +2744,7 @@ func getWorkflowAppConfig(resp http.ResponseWriter, request *http.Request) { resp.Write([]byte(`{"success": false}`)) return } + log.Printf("API: %#v", parsedApi) //log.Printf("Parsed API: %#v", parsedApi) if len(parsedApi.ID) > 0 { diff --git a/frontend/package.json b/frontend/package.json index cb2263b1..a7f6e0b1 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -51,6 +51,7 @@ "react-router-dom": "^4.3.1", "react-scripts": "^2.1.8", "reactstrap": "^7.1.0", + "shellwords": "^0.1.1", "simplebar": "^4.2.3", "styled-components": "^4.4.0", "websocket": "^1.0.30", diff --git a/frontend/src/AppCreator.js b/frontend/src/AppCreator.js index 6ccd9d35..c27008da 100644 --- a/frontend/src/AppCreator.js +++ b/frontend/src/AppCreator.js @@ -2,6 +2,7 @@ import React, {useState, useEffect} from 'react'; import { makeStyles } from '@material-ui/styles'; import {BrowserView, MobileView} from "react-device-detect"; +import {Link} from 'react-router-dom'; import Paper from '@material-ui/core/Paper'; import Button from '@material-ui/core/Button'; import Divider from '@material-ui/core/Divider'; @@ -18,6 +19,7 @@ import CheckCircleIcon from '@material-ui/icons/CheckCircle'; import ErrorOutline from '@material-ui/icons/ErrorOutline'; import { useAlert } from "react-alert"; +import words from "shellwords" const surfaceColor = "#27292D" const inputColor = "#383B40" @@ -55,7 +57,118 @@ const useStyles = makeStyles({ notchedOutline: { borderColor: "#f85a3e !important" }, -}); +}) + + +function rewrite(args) { + return args.reduce(function(args, a){ + if (0 == a.indexOf('-X')) { + args.push('-X') + args.push(a.slice(2)) + } else { + args.push(a) + } + + return args + }, []) +} + +function parseField(s) { + return s.split(/: (.+)/) +} + +function isURL(s) { + return /^https?:\/\//.test(s) +} + +const parseCurl = (s) => { + //console.log("CURL: ", s) + + if (0 != s.indexOf('curl ')) { + console.log("Not curl start") + return "" + } + + var args = rewrite(words.split(s)) + var out = { method: 'GET', header: {} } + var state = '' + + args.forEach(function(arg){ + switch (true) { + case isURL(arg): + out.url = arg + break; + + case arg == '-A' || arg == '--user-agent': + state = 'user-agent' + break; + + case arg == '-H' || arg == '--header': + state = 'header' + break; + + case arg == '-d' || arg == '--data' || arg == '--data-ascii': + state = 'data' + break; + + case arg == '-u' || arg == '--user': + state = 'user' + break; + + case arg == '-I' || arg == '--head': + out.method = 'HEAD' + break; + + case arg == '-X' || arg == '--request': + state = 'method' + break; + + case arg == '-b' || arg =='--cookie': + state = 'cookie' + break; + + case arg == '--compressed': + out.header['Accept-Encoding'] = out.header['Accept-Encoding'] || 'deflate, gzip' + break; + + case !!arg: + switch (state) { + case 'header': + var field = parseField(arg) + out.header[field[0]] = field[1] + state = '' + break; + case 'user-agent': + out.header['User-Agent'] = arg + state = '' + break; + case 'data': + if (out.method == 'GET' || out.method == 'HEAD') out.method = 'POST' + out.header['Content-Type'] = out.header['Content-Type'] || 'application/x-www-form-urlencoded' + out.body = out.body + ? out.body + '&' + arg + : arg + state = '' + break; + case 'user': + out.header['Authorization'] = 'Basic ' + btoa(arg) + state = '' + break; + case 'method': + out.method = arg + state = '' + break; + case 'cookie': + out.header['Set-Cookie'] = arg + state = '' + break; + } + break; + } + }) + + return out +} // Should be different if logged in :| const AppCreator = (props) => { @@ -144,13 +257,13 @@ const AppCreator = (props) => { const handleEditApp = () => { fetch(globalUrl+"/api/v1/apps/"+props.match.params.appid+"/config", { - method: 'GET', + method: 'GET', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, - credentials: "include", - }) + credentials: "include", + }) .then((response) => { if (response.status !== 200) { window.location.pathname = "/apps" @@ -164,9 +277,7 @@ const AppCreator = (props) => { alert.error("Failed to get the app") } else { const data = JSON.parse(responseJson.body) - console.log("LOADED IMAGE: ", data.image) - setFileBase64(data.image) - parseOpenapiData(data) + parseIncomingOpenapiData(data) } }) .catch(error => { @@ -184,13 +295,13 @@ const AppCreator = (props) => { } fetch(globalUrl+"/api/v1/get_openapi/"+urlParams.get("id"), { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - 'Accept': 'application/json', - }, - credentials: "include", - }) + method: 'GET', + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + }, + credentials: "include", + }) .then((response) => { if (response.status !== 200) { throw new Error("NOT 200 :O") @@ -199,12 +310,12 @@ const AppCreator = (props) => { return response.json() }) .then((responseJson) => { - setIsAppLoaded(true) + setIsAppLoaded(true) if (!responseJson.success) { alert.error("Failed to verify") } else { const data = JSON.parse(responseJson.body) - parseOpenapiData(data) + parseIncomingOpenapiData(data) } }) .catch(error => { @@ -227,14 +338,20 @@ const AppCreator = (props) => { } // Sets the data up as it should be at later points - const parseOpenapiData = (data) => { + // This is the data FROM the database, not what's being saved + const parseIncomingOpenapiData = (data) => { setBasedata(data) - setName(data.info.title) setDescription(data.info.description) document.title = "Apps - "+data.info.title + console.log(data.info["x-logo"]) + if (data.info !== null && data.info !== undefined && data.info["x-logo"] !== undefined) { + setFileBase64(data.info["x-logo"]) + console.log("IMG: ", data.inf0["x-logo"]) + } + if (data.info.contact != undefined) { setContact(data.info.contact) } @@ -243,7 +360,7 @@ const AppCreator = (props) => { setBaseUrl(data.servers[0].url) } - console.log(data) + // This is annoying (: var securitySchemes = data.components.securityDefinitions @@ -295,9 +412,6 @@ const AppCreator = (props) => { "errors": [], } - //console.log(`${path}: ${method}`); - //console.log(methodvalue) - for (var key in methodvalue.parameters) { const parameter = methodvalue.parameters[key] if (parameter.in === "query") { @@ -323,12 +437,12 @@ const AppCreator = (props) => { } } - console.log(newActions) setActions(newActions) } + // Saving the app that's been configured. const submitApp = () => { - alert.info("Uploading private app " + name) + alert.info("Uploading and building app " + name) setErrorCode("") // Format the information @@ -336,6 +450,7 @@ const AppCreator = (props) => { const host = splitBase[2] const schemes = [splitBase[0]] const basePath = "/"+(splitBase.slice(3, )).join("/") + console.log("IMAGE: ", fileBase64) const data = { "swagger": "3.0", @@ -343,6 +458,7 @@ const AppCreator = (props) => { "title": name, "description": description, "version": "1.0", + "x-logo": fileBase64, }, "servers": [{"url": baseUrl}], "host": host, @@ -353,7 +469,6 @@ const AppCreator = (props) => { "components": { "securitySchemes": {}, }, - "image": fileBase64, "id": props.match.params.appid, "securityDefinitions": {}, } @@ -368,7 +483,7 @@ const AppCreator = (props) => { data.info["contact"] = contact } - console.log("LOADED IMAGE: ", data.image) + //console.log("LOADED IMAGE: ", data.image) for (var key in actions) { const item = actions[key] @@ -440,6 +555,23 @@ const AppCreator = (props) => { //console.log(queryitem) } } + + if (item.body.length > 0) { + console.log("HANDLE BODY!") + newitem = { + "in": "body", + "name": "body", + "multiline": true, + "description": "Generated by shuffler.io OpenAPI", + "required": false, + "example": item.body, + "schema": { + "type": "string", + }, + } + + data.paths[item.url][item.method.toLowerCase()].parameters.push(newitem) + } } if (authenticationOption === "API key") { @@ -462,7 +594,7 @@ const AppCreator = (props) => { } fetch(globalUrl+"/api/v1/verify_openapi", { - method: 'POST', + method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', @@ -495,9 +627,9 @@ const AppCreator = (props) => { } const bearerAuth = authenticationOption === "Bearer auth" ? -
+

- + Bearer auth

@@ -508,9 +640,9 @@ const AppCreator = (props) => { // Basicauth const basicAuth = authenticationOption === "Basic auth" ? -
+

- + Basic authentication

@@ -596,9 +728,9 @@ const AppCreator = (props) => { setActions(actions) } - console.log("Option: ", authenticationOption) - console.log("Location: ", parameterLocation) - console.log("Name: ", parameterName) + //console.log("Option: ", authenticationOption) + //console.log("Location: ", parameterLocation) + //console.log("Name: ", parameterName) const apiKey = authenticationOption === "API key" ?

API key

@@ -818,13 +950,30 @@ const AppCreator = (props) => { } const UrlPathParameters = () => { + var paths = [] + var queries = [] + if (urlPath.includes("{") && urlPath.includes("}")) { - var values = [] var tmpWord = "" var record = false + + var query = false for (var key in urlPath) { + if (urlPath[key] === "?") { + query = true + } + if (urlPath[key] === "}") { - values.push(tmpWord) + if (tmpWord === parameterName) { + tmpWord = "" + record = false + continue + } else if (query) { + queries.push(tmpWord) + } else { + paths.push(tmpWord) + } + tmpWord = "" record = false } @@ -833,24 +982,75 @@ const AppCreator = (props) => { tmpWord += urlPath[key] } - if (urlPath[key] === "{" && urlPath[key-1] === "/") { + //if (urlPath[key] === "{" && urlPath[key-1] === "/") { + if (urlPath[key] === "{") { record = true } } - - if (!currentAction.paths === values) { - currentAction.paths = values - setCurrentAction(currentAction) - } - - return ( -
- Required parameters: {values.join(", ")} -
- ) } - return null + if (urlPath.includes("<") && urlPath.includes(">")) { + var tmpWord = "" + var record = false + + var query = false + for (var key in urlPath) { + if (urlPath[key] === "?") { + query = true + } + + if (urlPath[key] === ">") { + if (tmpWord === parameterName) { + tmpWord = "" + record = false + continue + } else if (query) { + queries.push(tmpWord) + } else { + paths.push(tmpWord) + } + + tmpWord = "" + record = false + } + + if (record) { + tmpWord += urlPath[key] + } + + //if (urlPath[key] === "{" && urlPath[key-1] === "/") { + if (urlPath[key] === "<") { + record = true + } + } + } + + if (currentAction.paths !== paths) { + setActionField("paths", paths) + } + + console.log("QUERIES: ", queries) + var tmpQueries = [] + + // No overlapping of names + for (var key in queries) { + const tmpquery = queries[key] + const found = tmpQueries.find(query => query.name === tmpquery) + if (found === undefined) { + tmpQueries.push({"name": queries[key], required: true}) + } + } + + // FIXME: Frontend isn't updating.. + if (JSON.stringify(tmpQueries) !== JSON.stringify(urlPathQueries)) { + setUrlPathQueries(tmpQueries) + } + + return paths.length > 0 ? +
+ Required parameters: {paths.join(", ")} +
+ : null } const newActionModal = @@ -878,7 +1078,7 @@ const AppCreator = (props) => {
New action
- Learn more about app creation + Learn more about actions
Name { margin="normal" variant="outlined" defaultValue={currentAction["name"]} - onChange={e => setActionField("name", e.target.value)} + onChange={e => { + // Fix basic issues in frontend. Python functions run a-zA-Z0-9_ + const regex = /[A-Z-a-z0-9 _]/g; + const found = e.target.value.match(regex); + if (found !== null) { + setActionField("name", found.join("")) + } + }} key={currentAction} InputProps={{ classes: { @@ -951,7 +1158,7 @@ const AppCreator = (props) => { ))}
- URL path + URL path / Curl statement { setUrlPath(e.target.value) console.log(e.target.value) }} - helperText={
The path to use. Must start with /. Add {"{variable}"} to have path variables
} + helperText={
The path to use. Must start with /. Use {"{variablename}"} to have path variables
} InputProps={{ classes: { notchedOutline: classes.notchedOutline, @@ -976,6 +1183,55 @@ const AppCreator = (props) => { color: "white", }, }} + onBlur={event => { + var parsedurl = event.target.value + if (parsedurl.startsWith("curl")) { + const request = parseCurl(event.target.value) + console.log(request) + if (request.method.toUpperCase() !== currentAction.Method) { + setCurrentActionMethod(request.method.toUpperCase()) + setActionField("method", request.method.toUpperCase()) + } + + if (request.header !== undefined && request.header !== null) { + var headers = "" + for (let [key, value] of Object.entries(request.header)) { + headers += key+"="+value+"\n" + } + + setActionField("headers", headers) + } + + if (request.body !== undefined && request.body !== null) { + setActionField("body", request.body) + } + + // Parse URL + parsedurl = request.url + } + + if (parsedurl.startsWith("http") || parsedurl.startsWith("ftp")) { + if (parsedurl !== undefined && parsedurl.includes(parameterName)) { + // Remove <> etc. + // + + console.log("IT HAS THE PARAM NAME!") + const newurl = new URL(encodeURI(parsedurl)) + newurl.searchParams.delete(parameterName) + parsedurl = decodeURI(newurl.href) + } + + // Remove the base URL itself + if (parsedurl !== undefined && baseUrl !== undefined && baseUrl.length > 0 && parsedurl.includes(baseUrl)) { + parsedurl = parsedurl.replace(baseUrl, "") + } + + // Check URL query && headers + setActionField("url", parsedurl) + setUrlPath(parsedurl) + } + //console.log("URL: ", request.url) + }} /> {loopQueries} @@ -1029,7 +1285,7 @@ const AppCreator = (props) => {

Actions

Actions are the tasks performed by an app. Read more about actions and apps - here. + here.
{loopActions} + : null + var editButton = selectedApp.activated && selectedApp.private_id !== undefined && selectedApp.private_id.length > 0 && selectedApp.generated ? : null var activateButton = selectedApp.generated && !selectedApp.activated ? @@ -312,7 +329,7 @@ const Apps = (props) => { variant="contained" component="label" color="primary" - style={{marginTop: "10px"}} + style={{marginTop: 10}} > Activate App : null @@ -327,7 +344,7 @@ const Apps = (props) => { deleteApp(selectedApp.id) }} > - Delete app + : null var imageline = selectedApp.large_image === undefined || selectedApp.large_image.length === 0 ? @@ -348,6 +365,7 @@ const Apps = (props) => {
{activateButton} + {downloadButton} {editButton} {deleteButton} @@ -464,8 +482,8 @@ const Apps = (props) => { ) } - const handleSearchChange = (event) => { - const searchfield = event.target.value.toLowerCase() + const handleSearchChange = (search) => { + const searchfield = search.toLowerCase() const newapps = apps.filter(data => data.name.toLowerCase().includes(searchfield) || data.description.toLowerCase().includes(searchfield)) if ((newapps.length === 0 || searchBackend) && !appSearchLoading) { @@ -495,7 +513,10 @@ const Apps = (props) => { Search OpenAPI
- control={ {setSearchBackend(!searchBackend)}} />} + control={ { + handleSearchChange("") + setSearchBackend(!searchBackend)} + } />} />
- Headers + Headers - static for the action { "errors": [], "method": actionNonBodyRequest[0], }) - setCurrentActionMethod(actionNonBodyRequest[0]) + setCurrentActionMethod(actionNonBodyRequest[0]) setActionsModalOpen(true) }}>New action
From 67273e611f9f77fcaf3bf96e4fe118d12ca0c59e Mon Sep 17 00:00:00 2001 From: frikky Date: Mon, 1 Jun 2020 11:01:50 +0200 Subject: [PATCH 10/15] Fixed POST, PATCH and PUT with JSON parsing --- backend/go-app/codegen.go | 73 +++++++++++++++++++++++++++++++-- frontend/src/AngularWorkflow.js | 2 +- frontend/src/AppCreator.js | 6 +++ 3 files changed, 76 insertions(+), 5 deletions(-) diff --git a/backend/go-app/codegen.go b/backend/go-app/codegen.go index 0a6a9811..67507d14 100644 --- a/backend/go-app/codegen.go +++ b/backend/go-app/codegen.go @@ -247,6 +247,8 @@ func makePythoncode(swagger *openapi3.Swagger, name, url, method string, paramet queryString := "" queryData := "" + log.Printf("URL START: %s", url) + // FIXME - this might break - need to check if ? or & should be set as query parameterData := "" if len(optionalQueries) > 0 { @@ -279,7 +281,13 @@ func makePythoncode(swagger *openapi3.Swagger, name, url, method string, paramet if swagger.Components.SecuritySchemes["ApiKeyAuth"].Value.In == "header" { authenticationSetup = fmt.Sprintf("headers[\"%s\"] = apikey", swagger.Components.SecuritySchemes["ApiKeyAuth"].Value.Name) } else if swagger.Components.SecuritySchemes["ApiKeyAuth"].Value.In == "query" { - authenticationSetup = fmt.Sprintf("url+=f\"?%s={apikey}\"", swagger.Components.SecuritySchemes["ApiKeyAuth"].Value.Name) + // This might suck lol + key := "?" + if strings.Contains(url, "?") { + key = "&" + } + + authenticationSetup = fmt.Sprintf("url+=f\"%s%s={apikey}\"", key, swagger.Components.SecuritySchemes["ApiKeyAuth"].Value.Name) } } } @@ -308,25 +316,53 @@ func makePythoncode(swagger *openapi3.Swagger, name, url, method string, paramet bodyParameter := "" bodyAddin := "" + bodyFormatter := "" postParameters := []string{"post", "patch", "put"} for _, item := range postParameters { if method == item { bodyParameter = ", body=\"\"" - bodyAddin = ", json=body" + bodyAddin = ", data=body" + + // FIXME: Does JSON data work? + bodyFormatter = ` + if (body.startswith("{") and body.endswith("}")) or (body.startswith("[") and body.endswith("]")): + try: + body = json.dumps(body) + except: + pass + ` break } } // Extra param for url if it's changeable // Extra param for authentication scheme(s) - + log.Printf("URL OTHER: %s", url) data := fmt.Sprintf(` async def %s(self%s%s%s%s%s): headers={} url=f"%s%s" %s %s + %s return requests.%s(url, headers=headers%s%s).text - `, functionname, authenticationParameter, urlParameter, parameterData, queryString, bodyParameter, urlInline, url, authenticationSetup, queryData, method, authenticationAddin, bodyAddin) + `, + functionname, + authenticationParameter, + urlParameter, + parameterData, + queryString, + bodyParameter, + urlInline, + url, + authenticationSetup, + queryData, + bodyFormatter, + method, + authenticationAddin, + bodyAddin, + ) + + log.Printf("DATA: %s", data) //log.Println(data) //log.Println(functionname) @@ -776,6 +812,10 @@ func handleConnect(swagger *openapi3.Swagger, api WorkflowApp, extraParameters [ parameters = append(parameters, param.Value.Name) + if strings.Contains(baseUrl, fmt.Sprintf("%s={%s}", param.Value.Name, param.Value.Name)) { + continue + } + if firstQuery { baseUrl = fmt.Sprintf("%s?%s={%s}", baseUrl, param.Value.Name, param.Value.Name) firstQuery = false @@ -883,6 +923,11 @@ func handleGet(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wor parameters = append(parameters, param.Value.Name) + // Skipping simial + if strings.Contains(baseUrl, fmt.Sprintf("%s={%s}", param.Value.Name, param.Value.Name)) { + continue + } + if firstQuery { baseUrl = fmt.Sprintf("%s?%s={%s}", baseUrl, param.Value.Name, param.Value.Name) firstQuery = false @@ -986,6 +1031,10 @@ func handleHead(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wo parameters = append(parameters, param.Value.Name) + if strings.Contains(baseUrl, fmt.Sprintf("%s={%s}", param.Value.Name, param.Value.Name)) { + continue + } + if firstQuery { baseUrl = fmt.Sprintf("%s?%s={%s}", baseUrl, param.Value.Name, param.Value.Name) firstQuery = false @@ -1089,6 +1138,10 @@ func handleDelete(swagger *openapi3.Swagger, api WorkflowApp, extraParameters [] parameters = append(parameters, param.Value.Name) + if strings.Contains(baseUrl, fmt.Sprintf("%s={%s}", param.Value.Name, param.Value.Name)) { + continue + } + if firstQuery { baseUrl = fmt.Sprintf("%s?%s={%s}", baseUrl, param.Value.Name, param.Value.Name) firstQuery = false @@ -1197,6 +1250,10 @@ func handlePost(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wo parameters = append(parameters, param.Value.Name) + if strings.Contains(baseUrl, fmt.Sprintf("%s={%s}", param.Value.Name, param.Value.Name)) { + continue + } + if firstQuery { baseUrl = fmt.Sprintf("%s?%s={%s}", baseUrl, param.Value.Name, param.Value.Name) firstQuery = false @@ -1300,6 +1357,10 @@ func handlePatch(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []W parameters = append(parameters, param.Value.Name) + if strings.Contains(baseUrl, fmt.Sprintf("%s={%s}", param.Value.Name, param.Value.Name)) { + continue + } + if firstQuery { baseUrl = fmt.Sprintf("%s?%s={%s}", baseUrl, param.Value.Name, param.Value.Name) firstQuery = false @@ -1404,6 +1465,10 @@ func handlePut(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wor parameters = append(parameters, param.Value.Name) + if strings.Contains(baseUrl, fmt.Sprintf("%s={%s}", param.Value.Name, param.Value.Name)) { + continue + } + if firstQuery { baseUrl = fmt.Sprintf("%s?%s={%s}", baseUrl, param.Value.Name, param.Value.Name) firstQuery = false diff --git a/frontend/src/AngularWorkflow.js b/frontend/src/AngularWorkflow.js index 8a4adeb6..e09aed33 100644 --- a/frontend/src/AngularWorkflow.js +++ b/frontend/src/AngularWorkflow.js @@ -4485,7 +4485,7 @@ const AngularWorkflow = (props) => { }
: -
+

{setExecutionModalView(0)}}> diff --git a/frontend/src/AppCreator.js b/frontend/src/AppCreator.js index c8b99057..a02317ba 100644 --- a/frontend/src/AppCreator.js +++ b/frontend/src/AppCreator.js @@ -1262,6 +1262,11 @@ const AppCreator = (props) => { parsedurl = request.url } + if (parsedurl.includes("<") && parsedurl.includes(">")) { + parsedurl = parsedurl.split("<").join("{") + parsedurl = parsedurl.split(">").join("}") + } + if (parsedurl.startsWith("http") || parsedurl.startsWith("ftp")) { if (parsedurl !== undefined && parsedurl.includes(parameterName)) { // Remove <> etc. @@ -1282,6 +1287,7 @@ const AppCreator = (props) => { setActionField("url", parsedurl) setUrlPath(parsedurl) } + //console.log("URL: ", request.url) }} /> From 604451e098611ec41654d00ef91bc2f958866036 Mon Sep 17 00:00:00 2001 From: frikky Date: Mon, 1 Jun 2020 13:54:19 +0200 Subject: [PATCH 11/15] Fixed app creator sizes --- frontend/src/AngularWorkflow.js | 1 - frontend/src/AppCreator.js | 4 +++- frontend/src/defaultCytoscapeStyle.js | 2 ++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/frontend/src/AngularWorkflow.js b/frontend/src/AngularWorkflow.js index e09aed33..a6f51927 100644 --- a/frontend/src/AngularWorkflow.js +++ b/frontend/src/AngularWorkflow.js @@ -2207,7 +2207,6 @@ const AngularWorkflow = (props) => { if ((selectedVariableParameter === null || selectedVariableParameter === undefined) && (workflow.workflow_variables !== null && workflow.workflow_variables.length > 0)) { // FIXME - this is the bad thing - console.log("Does it go here or what?") setSelectedVariableParameter(workflow.workflow_variables[0].name) } diff --git a/frontend/src/AppCreator.js b/frontend/src/AppCreator.js index a02317ba..e34e3945 100644 --- a/frontend/src/AppCreator.js +++ b/frontend/src/AppCreator.js @@ -369,6 +369,7 @@ const AppCreator = (props) => { securitySchemes = data.components.securitySchemes } + // FIXME: Have multiple authentication options? if (securitySchemes !== undefined) { console.log("Am I in here?") for (const [key, value] of Object.entries(securitySchemes)) { @@ -377,7 +378,6 @@ const AppCreator = (props) => { break } else if (value.type === "apiKey") { setAuthenticationOption("API key") - setParameterName(value.name) value.in = value.in.charAt(0).toUpperCase() + value.in.slice(1); setParameterLocation(value.in) @@ -385,6 +385,8 @@ const AppCreator = (props) => { console.log("APIKEY SELECT: ", apikeySelection) alert.error("Might be error in setting up API key authentication") } + + setParameterName(value.name) break } else if (value.scheme === "basic") { setAuthenticationOption("Basic auth") diff --git a/frontend/src/defaultCytoscapeStyle.js b/frontend/src/defaultCytoscapeStyle.js index 5621a377..4e3c0b24 100644 --- a/frontend/src/defaultCytoscapeStyle.js +++ b/frontend/src/defaultCytoscapeStyle.js @@ -35,6 +35,8 @@ const data = [{ 'shape': 'square', 'background-color': '#213243', 'border-color': '#81c784', + 'background-width': '100%', + 'background-height': '100%', }, }, { From acb4b3da8c2d8430d82060eba55138fcb9ee8d82 Mon Sep 17 00:00:00 2001 From: frikky Date: Mon, 1 Jun 2020 13:56:49 +0200 Subject: [PATCH 12/15] Fixed appcreator image size --- frontend/src/AppCreator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/AppCreator.js b/frontend/src/AppCreator.js index e34e3945..c073d10d 100644 --- a/frontend/src/AppCreator.js +++ b/frontend/src/AppCreator.js @@ -1421,7 +1421,7 @@ const AppCreator = (props) => { // const imageData = file.length > 0 ? file : fileBase64 - const imageInfo = + const imageInfo = // Random names for type & autoComplete. Didn't research :^) const landingpageDataBrowser = From e11d58c23908061e2c04766b00184efe48fc3870 Mon Sep 17 00:00:00 2001 From: frikky Date: Mon, 1 Jun 2020 15:57:06 +0200 Subject: [PATCH 13/15] Fixed openapi3 config download bugs --- backend/go-app/codegen.go | 30 +++++++++--------- backend/go-app/main.go | 8 +++-- backend/go-app/walkoff.go | 13 ++++---- frontend/src/AngularWorkflow.js | 35 +++++++++++---------- frontend/src/AppCreator.js | 15 ++++++++- frontend/src/Apps.js | 56 ++++++++++++++++++++++----------- 6 files changed, 97 insertions(+), 60 deletions(-) diff --git a/backend/go-app/codegen.go b/backend/go-app/codegen.go index 67507d14..5f64be9a 100644 --- a/backend/go-app/codegen.go +++ b/backend/go-app/codegen.go @@ -247,8 +247,6 @@ func makePythoncode(swagger *openapi3.Swagger, name, url, method string, paramet queryString := "" queryData := "" - log.Printf("URL START: %s", url) - // FIXME - this might break - need to check if ? or & should be set as query parameterData := "" if len(optionalQueries) > 0 { @@ -337,7 +335,6 @@ func makePythoncode(swagger *openapi3.Swagger, name, url, method string, paramet // Extra param for url if it's changeable // Extra param for authentication scheme(s) - log.Printf("URL OTHER: %s", url) data := fmt.Sprintf(` async def %s(self%s%s%s%s%s): headers={} url=f"%s%s" @@ -362,23 +359,21 @@ func makePythoncode(swagger *openapi3.Swagger, name, url, method string, paramet bodyAddin, ) - log.Printf("DATA: %s", data) - //log.Println(data) //log.Println(functionname) return functionname, data } -func generateYaml(swagger *openapi3.Swagger, newmd5 string) (WorkflowApp, []string, error) { +func generateYaml(swagger *openapi3.Swagger, newmd5 string) (*openapi3.Swagger, WorkflowApp, []string, error) { api := WorkflowApp{} //log.Printf("%#v", swagger.Info) if len(swagger.Info.Title) == 0 { - return WorkflowApp{}, []string{}, errors.New("Swagger.Info.Title can't be empty.") + return swagger, WorkflowApp{}, []string{}, errors.New("Swagger.Info.Title can't be empty.") } if len(swagger.Servers) == 0 { - return WorkflowApp{}, []string{}, errors.New("Swagger.Servers can't be empty. Add 'servers':[{'url':'hostname.com'}'") + return swagger, WorkflowApp{}, []string{}, errors.New("Swagger.Servers can't be empty. Add 'servers':[{'url':'hostname.com'}'") } api.Name = swagger.Info.Title @@ -512,12 +507,7 @@ func generateYaml(swagger *openapi3.Swagger, newmd5 string) (WorkflowApp, []stri // This is the python code to be generated // Could just as well be go at this point lol pythonFunctions := []string{} - for actualPath, path := range swagger.Paths { - - //log.Printf("%#v", path) - //log.Printf("%#v", actualPath) - // FIXME: Add everything from here: // https://godoc.org/github.com/getkin/kin-openapi/openapi3#PathItem firstQuery := true @@ -556,9 +546,19 @@ func generateYaml(swagger *openapi3.Swagger, newmd5 string) (WorkflowApp, []stri api.Actions = append(api.Actions, action) pythonFunctions = append(pythonFunctions, curCode) } + + // Has to be here because its used differently above. + // FIXING this is done during export instead? + //log.Printf("OLDPATH: %s", actualPath) + //if strings.Contains(actualPath, "?") { + // actualPath = strings.Split(actualPath, "?")[0] + //} + + //log.Printf("NEWPATH: %s", actualPath) + //newPaths[actualPath] = path } - return api, pythonFunctions, nil + return swagger, api, pythonFunctions, nil } // FIXME - have this give a real version? @@ -1184,7 +1184,7 @@ func handlePost(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wo } if path.Post.RequestBody != nil { - log.Printf("FUNCTION: %#v", path.Post.RequestBody) + log.Printf("RequestBody: %#v", path.Post.RequestBody) } action.Returns.Schema.Type = "string" diff --git a/backend/go-app/main.go b/backend/go-app/main.go index bfb523e8..c608949e 100644 --- a/backend/go-app/main.go +++ b/backend/go-app/main.go @@ -5528,7 +5528,7 @@ func verifySwagger(resp http.ResponseWriter, request *http.Request) { } //log.Printf("Should generate yaml") - api, pythonfunctions, err := generateYaml(swagger, newmd5) + swagger, api, pythonfunctions, err := generateYaml(swagger, newmd5) if err != nil { log.Printf("Failed building and generating yaml: %s", err) resp.WriteHeader(500) @@ -5536,8 +5536,7 @@ func verifySwagger(resp http.ResponseWriter, request *http.Request) { return } - log.Printf("PATHS: %#v", swagger.Paths["/comments/put"]) - log.Printf("Functions: %d", len(swagger.Paths)) + log.Printf("Functions: %d", swagger.Paths) log.Printf("Actions: %d", len(api.Actions)) api.Owner = user.Id @@ -5694,6 +5693,9 @@ func verifySwagger(resp http.ResponseWriter, request *http.Request) { resp.Write([]byte(fmt.Sprintf(`{"success": true, "reason": "%"}`, err))) } + // Backup every single one + setOpenApiDatastore(ctx, api.ID, parsed) + err = increaseStatisticsField(ctx, "total_apps_created", newmd5, 1) if err != nil { log.Printf("Failed to increase success execution stats: %s", err) diff --git a/backend/go-app/walkoff.go b/backend/go-app/walkoff.go index b09713c7..36a3d6b0 100644 --- a/backend/go-app/walkoff.go +++ b/backend/go-app/walkoff.go @@ -1355,15 +1355,16 @@ func saveWorkflow(resp http.ResponseWriter, request *http.Request) { curapp := WorkflowApp{} // FIXME - can this work with ONLY AppID? for _, app := range workflowApps { + log.Printf("Name Version: %s_%s, other: %s_%s", app.Name, app.AppVersion, action.AppName, action.AppVersion) if app.ID == action.AppID { curapp = app break } - if app.Name == action.AppName && app.AppVersion == action.AppVersion { - curapp = app - break - } + //if app.Name == action.AppName && app.AppVersion == action.AppVersion { + // curapp = app + // break + //} } // Check to see if the whole app is valid @@ -1377,11 +1378,11 @@ func saveWorkflow(resp http.ResponseWriter, request *http.Request) { // Check tosee if the appaction is valid curappaction := WorkflowAppAction{} for _, curAction := range curapp.Actions { + log.Printf("Same? %s - %s", action.Name, curAction.Name) if action.Name == curAction.Name { curappaction = curAction break } - log.Println(action.Name, curAction.Name) } // Check to see if the action is valid @@ -3376,7 +3377,7 @@ func iterateOpenApiGithub(fs billy.Filesystem, dir []os.FileInfo, extra string, } //log.Printf("Should generate yaml") - api, _, err := generateYaml(swagger, parsedOpenApi.ID) + swagger, api, _, err := generateYaml(swagger, parsedOpenApi.ID) if err != nil { log.Printf("Failed building and generating yaml in loop (%s): %s", filename, err) continue diff --git a/frontend/src/AngularWorkflow.js b/frontend/src/AngularWorkflow.js index a6f51927..05092d87 100644 --- a/frontend/src/AngularWorkflow.js +++ b/frontend/src/AngularWorkflow.js @@ -2639,27 +2639,28 @@ const AngularWorkflow = (props) => { SelectDisplayProps={{ style: { marginLeft: 10, + maxHeight: 200, } }} > - {selectedApp.actions.map(data => { - var newActionname = data.name - if (data.label !== undefined && data.label !== null && data.label.length > 0) { - newActionname = data.label - } - // ROFL FIXME - loop - newActionname = newActionname.replace("_", " ") - newActionname = newActionname.replace("_", " ") - newActionname = newActionname.replace("_", " ") - newActionname = newActionname.replace("_", " ") - newActionname = newActionname.charAt(0).toUpperCase()+newActionname.substring(1) - return ( - - {newActionname} + {selectedApp.actions.map(data => { + var newActionname = data.name + if (data.label !== undefined && data.label !== null && data.label.length > 0) { + newActionname = data.label + } + // ROFL FIXME - loop + newActionname = newActionname.replace("_", " ") + newActionname = newActionname.replace("_", " ") + newActionname = newActionname.replace("_", " ") + newActionname = newActionname.replace("_", " ") + newActionname = newActionname.charAt(0).toUpperCase()+newActionname.substring(1) + return ( + + {newActionname} - - ) - })} + + ) + })}
diff --git a/frontend/src/AppCreator.js b/frontend/src/AppCreator.js index c073d10d..5abdc6c3 100644 --- a/frontend/src/AppCreator.js +++ b/frontend/src/AppCreator.js @@ -16,6 +16,8 @@ import DialogActions from '@material-ui/core/DialogActions'; import TextField from '@material-ui/core/TextField'; import Tooltip from '@material-ui/core/Tooltip'; import CheckCircleIcon from '@material-ui/icons/CheckCircle'; +import Breadcrumbs from '@material-ui/core/Breadcrumbs'; +import AppsIcon from '@material-ui/icons/Apps'; import ErrorOutline from '@material-ui/icons/ErrorOutline'; import { useAlert } from "react-alert"; @@ -587,7 +589,7 @@ const AppCreator = (props) => { "required": required, "content": { "example": { - "example": "test", + "example": item.body, }, }, } @@ -1426,6 +1428,17 @@ const AppCreator = (props) => { // Random names for type & autoComplete. Didn't research :^) const landingpageDataBrowser =
+ + +

+ + Apps +

+ +

+ {name} +

+

General information

Click here to learn more about app creation diff --git a/frontend/src/Apps.js b/frontend/src/Apps.js index 5994986d..9198a301 100644 --- a/frontend/src/Apps.js +++ b/frontend/src/Apps.js @@ -2,6 +2,7 @@ import React, { useEffect} from 'react'; import { useInterval } from 'react-powerhooks'; +import AppsIcon from '@material-ui/icons/Apps'; import Grid from '@material-ui/core/Grid'; import Select from '@material-ui/core/Select'; import Paper from '@material-ui/core/Paper'; @@ -17,6 +18,7 @@ import Switch from '@material-ui/core/Switch'; import Input from '@material-ui/core/Input'; import YAML from 'yaml' import {Link} from 'react-router-dom'; +import Breadcrumbs from '@material-ui/core/Breadcrumbs'; import CloudDownload from '@material-ui/icons/CloudDownload'; import EditIcon from '@material-ui/icons/Edit'; @@ -137,13 +139,13 @@ const Apps = (props) => { alert.info("Downloading..") fetch(globalUrl+"/api/v1/apps/"+id+"/config", { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - 'Accept': 'application/json', - }, - credentials: "include", - }) + method: 'GET', + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + }, + credentials: "include", + }) .then((response) => { if (response.status !== 200) { window.location.pathname = "/apps" @@ -155,12 +157,22 @@ const Apps = (props) => { if (!responseJson.success) { alert.error("Failed to download file") } else { - const data = YAML.stringify(YAML.parse(responseJson.body)) + const inputdata = YAML.parse(responseJson.body) + const newpaths = {} + Object.keys(inputdata["paths"]).forEach(function(key) { + newpaths[key.split("?")[0]] = inputdata.paths[key] + }) - var name = inputdata.name + inputdata.paths = newpaths + console.log("INPUT: ", inputdata) + var name = inputdata.info.title name = name.replace(/ /g, "_", -1) name = name.toLowerCase() + delete inputdata.id + delete inputdata.editing + + const data = YAML.stringify(inputdata) var blob = new Blob( [ data ], { type: 'application/octet-stream' }) @@ -193,7 +205,6 @@ const Apps = (props) => { boxColor = "green" } - console.log("IMG: ", data.large_image) var imageline = data.large_image.length === 0 ? {data.title} : @@ -498,9 +509,22 @@ const Apps = (props) => { const appView = isLoggedIn ?
-
-

Upload

-
+
+ + +

+ + App upload +

+ + {selectedApp.activated && selectedApp.private_id !== undefined && selectedApp.private_id.length > 0 && selectedApp.generated ? + +

+ {selectedApp.name} +

+ + : null} +
@@ -988,11 +1012,7 @@ const Apps = (props) => {
// Maybe use gridview or something, idk - return ( -
- {loadedCheck} -
- ) + return loadedCheck } export default Apps From 12ffc1833854904376de45394a2c2af47c60ea2c Mon Sep 17 00:00:00 2001 From: frikky Date: Mon, 1 Jun 2020 18:55:19 +0200 Subject: [PATCH 14/15] Fixed App overwrites and bad app function names --- backend/go-app/codegen.go | 66 +++++++++++++++------------------ backend/go-app/main.go | 25 +++++++++++-- backend/go-app/walkoff.go | 2 +- docker-compose.yml | 4 +- frontend/src/AngularWorkflow.js | 43 ++++++++++----------- frontend/src/AppCreator.js | 37 ++++++++++++------ 6 files changed, 102 insertions(+), 75 deletions(-) diff --git a/backend/go-app/codegen.go b/backend/go-app/codegen.go index 5f64be9a..503d5f76 100644 --- a/backend/go-app/codegen.go +++ b/backend/go-app/codegen.go @@ -510,39 +510,38 @@ func generateYaml(swagger *openapi3.Swagger, newmd5 string) (*openapi3.Swagger, for actualPath, path := range swagger.Paths { // FIXME: Add everything from here: // https://godoc.org/github.com/getkin/kin-openapi/openapi3#PathItem - firstQuery := true if path.Get != nil { - action, curCode := handleGet(swagger, api, extraParameters, path, actualPath, firstQuery) + action, curCode := handleGet(swagger, api, extraParameters, path, actualPath) api.Actions = append(api.Actions, action) pythonFunctions = append(pythonFunctions, curCode) } if path.Connect != nil { - action, curCode := handleConnect(swagger, api, extraParameters, path, actualPath, firstQuery) + action, curCode := handleConnect(swagger, api, extraParameters, path, actualPath) api.Actions = append(api.Actions, action) pythonFunctions = append(pythonFunctions, curCode) } if path.Head != nil { - action, curCode := handleHead(swagger, api, extraParameters, path, actualPath, firstQuery) + action, curCode := handleHead(swagger, api, extraParameters, path, actualPath) api.Actions = append(api.Actions, action) pythonFunctions = append(pythonFunctions, curCode) } if path.Delete != nil { - action, curCode := handleDelete(swagger, api, extraParameters, path, actualPath, firstQuery) + action, curCode := handleDelete(swagger, api, extraParameters, path, actualPath) api.Actions = append(api.Actions, action) pythonFunctions = append(pythonFunctions, curCode) } if path.Post != nil { - action, curCode := handlePost(swagger, api, extraParameters, path, actualPath, firstQuery) + action, curCode := handlePost(swagger, api, extraParameters, path, actualPath) api.Actions = append(api.Actions, action) pythonFunctions = append(pythonFunctions, curCode) } if path.Patch != nil { - action, curCode := handlePatch(swagger, api, extraParameters, path, actualPath, firstQuery) + action, curCode := handlePatch(swagger, api, extraParameters, path, actualPath) api.Actions = append(api.Actions, action) pythonFunctions = append(pythonFunctions, curCode) } if path.Put != nil { - action, curCode := handlePut(swagger, api, extraParameters, path, actualPath, firstQuery) + action, curCode := handlePut(swagger, api, extraParameters, path, actualPath) api.Actions = append(api.Actions, action) pythonFunctions = append(pythonFunctions, curCode) } @@ -736,7 +735,7 @@ func fixFunctionName(functionName, actualPath string) string { return functionName } -func handleConnect(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []WorkflowAppActionParameter, path *openapi3.PathItem, actualPath string, firstQuery bool) (WorkflowAppAction, string) { +func handleConnect(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []WorkflowAppActionParameter, path *openapi3.PathItem, actualPath string) (WorkflowAppAction, string) { // What to do with this, hmm functionName := fixFunctionName(path.Connect.Summary, actualPath) @@ -756,7 +755,7 @@ func handleConnect(swagger *openapi3.Swagger, api WorkflowApp, extraParameters [ // Parameters: []WorkflowAppActionParameter{}, // FIXME - add data for POST stuff - firstQuery = true + firstQuery := true optionalQueries := []string{} parameters := []string{} optionalParameters := []WorkflowAppActionParameter{} @@ -818,11 +817,10 @@ func handleConnect(swagger *openapi3.Swagger, api WorkflowApp, extraParameters [ if firstQuery { baseUrl = fmt.Sprintf("%s?%s={%s}", baseUrl, param.Value.Name, param.Value.Name) - firstQuery = false } else { baseUrl = fmt.Sprintf("%s&%s={%s}", baseUrl, param.Value.Name, param.Value.Name) - firstQuery = false } + firstQuery = false } } @@ -843,7 +841,7 @@ func handleConnect(swagger *openapi3.Swagger, api WorkflowApp, extraParameters [ return action, curCode } -func handleGet(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []WorkflowAppActionParameter, path *openapi3.PathItem, actualPath string, firstQuery bool) (WorkflowAppAction, string) { +func handleGet(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []WorkflowAppActionParameter, path *openapi3.PathItem, actualPath string) (WorkflowAppAction, string) { // What to do with this, hmm functionName := fixFunctionName(path.Get.Summary, actualPath) @@ -863,7 +861,7 @@ func handleGet(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wor // Parameters: []WorkflowAppActionParameter{}, // FIXME - add data for POST stuff - firstQuery = true + firstQuery := true optionalQueries := []string{} // FIXME - remove this when authentication is properly introduced @@ -930,11 +928,12 @@ func handleGet(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wor if firstQuery { baseUrl = fmt.Sprintf("%s?%s={%s}", baseUrl, param.Value.Name, param.Value.Name) - firstQuery = false } else { + log.Printf("NOT FIRST QUERY!: %s", baseUrl) baseUrl = fmt.Sprintf("%s&%s={%s}", baseUrl, param.Value.Name, param.Value.Name) - firstQuery = false + log.Printf("AFTER: %s", baseUrl) } + firstQuery = false } } @@ -955,7 +954,7 @@ func handleGet(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wor return action, curCode } -func handleHead(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []WorkflowAppActionParameter, path *openapi3.PathItem, actualPath string, firstQuery bool) (WorkflowAppAction, string) { +func handleHead(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []WorkflowAppActionParameter, path *openapi3.PathItem, actualPath string) (WorkflowAppAction, string) { // What to do with this, hmm functionName := fixFunctionName(path.Head.Summary, actualPath) @@ -975,7 +974,7 @@ func handleHead(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wo // Parameters: []WorkflowAppActionParameter{}, // FIXME - add data for POST stuff - firstQuery = true + firstQuery := true optionalQueries := []string{} parameters := []string{} optionalParameters := []WorkflowAppActionParameter{} @@ -1037,11 +1036,10 @@ func handleHead(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wo if firstQuery { baseUrl = fmt.Sprintf("%s?%s={%s}", baseUrl, param.Value.Name, param.Value.Name) - firstQuery = false } else { baseUrl = fmt.Sprintf("%s&%s={%s}", baseUrl, param.Value.Name, param.Value.Name) - firstQuery = false } + firstQuery = false } } @@ -1062,7 +1060,7 @@ func handleHead(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wo return action, curCode } -func handleDelete(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []WorkflowAppActionParameter, path *openapi3.PathItem, actualPath string, firstQuery bool) (WorkflowAppAction, string) { +func handleDelete(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []WorkflowAppActionParameter, path *openapi3.PathItem, actualPath string) (WorkflowAppAction, string) { // What to do with this, hmm functionName := fixFunctionName(path.Delete.Summary, actualPath) @@ -1082,7 +1080,7 @@ func handleDelete(swagger *openapi3.Swagger, api WorkflowApp, extraParameters [] // Parameters: []WorkflowAppActionParameter{}, // FIXME - add data for POST stuff - firstQuery = true + firstQuery := true optionalQueries := []string{} parameters := []string{} optionalParameters := []WorkflowAppActionParameter{} @@ -1144,11 +1142,10 @@ func handleDelete(swagger *openapi3.Swagger, api WorkflowApp, extraParameters [] if firstQuery { baseUrl = fmt.Sprintf("%s?%s={%s}", baseUrl, param.Value.Name, param.Value.Name) - firstQuery = false } else { baseUrl = fmt.Sprintf("%s&%s={%s}", baseUrl, param.Value.Name, param.Value.Name) - firstQuery = false } + firstQuery = false } } @@ -1169,7 +1166,7 @@ func handleDelete(swagger *openapi3.Swagger, api WorkflowApp, extraParameters [] return action, curCode } -func handlePost(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []WorkflowAppActionParameter, path *openapi3.PathItem, actualPath string, firstQuery bool) (WorkflowAppAction, string) { +func handlePost(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []WorkflowAppActionParameter, path *openapi3.PathItem, actualPath string) (WorkflowAppAction, string) { // What to do with this, hmm //log.Printf("PATH: %s", actualPath) functionName := fixFunctionName(path.Post.Summary, actualPath) @@ -1192,7 +1189,7 @@ func handlePost(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wo // Parameters: []WorkflowAppActionParameter{}, // FIXME - add data for POST stuff - firstQuery = true + firstQuery := true optionalQueries := []string{} parameters := []string{} optionalParameters := []WorkflowAppActionParameter{} @@ -1256,11 +1253,10 @@ func handlePost(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wo if firstQuery { baseUrl = fmt.Sprintf("%s?%s={%s}", baseUrl, param.Value.Name, param.Value.Name) - firstQuery = false } else { baseUrl = fmt.Sprintf("%s&%s={%s}", baseUrl, param.Value.Name, param.Value.Name) - firstQuery = false } + firstQuery = false } } @@ -1281,7 +1277,7 @@ func handlePost(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wo return action, curCode } -func handlePatch(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []WorkflowAppActionParameter, path *openapi3.PathItem, actualPath string, firstQuery bool) (WorkflowAppAction, string) { +func handlePatch(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []WorkflowAppActionParameter, path *openapi3.PathItem, actualPath string) (WorkflowAppAction, string) { // What to do with this, hmm functionName := fixFunctionName(path.Patch.Summary, actualPath) @@ -1301,7 +1297,7 @@ func handlePatch(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []W // Parameters: []WorkflowAppActionParameter{}, // FIXME - add data for POST stuff - firstQuery = true + firstQuery := true optionalQueries := []string{} parameters := []string{} optionalParameters := []WorkflowAppActionParameter{} @@ -1363,11 +1359,10 @@ func handlePatch(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []W if firstQuery { baseUrl = fmt.Sprintf("%s?%s={%s}", baseUrl, param.Value.Name, param.Value.Name) - firstQuery = false } else { baseUrl = fmt.Sprintf("%s&%s={%s}", baseUrl, param.Value.Name, param.Value.Name) - firstQuery = false } + firstQuery = false } } @@ -1388,7 +1383,7 @@ func handlePatch(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []W return action, curCode } -func handlePut(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []WorkflowAppActionParameter, path *openapi3.PathItem, actualPath string, firstQuery bool) (WorkflowAppAction, string) { +func handlePut(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []WorkflowAppActionParameter, path *openapi3.PathItem, actualPath string) (WorkflowAppAction, string) { // What to do with this, hmm functionName := fixFunctionName(path.Put.Summary, actualPath) @@ -1408,7 +1403,7 @@ func handlePut(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wor // Parameters: []WorkflowAppActionParameter{}, // FIXME - add data for POST stuff - firstQuery = true + firstQuery := true optionalQueries := []string{} parameters := []string{} optionalParameters := []WorkflowAppActionParameter{} @@ -1471,11 +1466,10 @@ func handlePut(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wor if firstQuery { baseUrl = fmt.Sprintf("%s?%s={%s}", baseUrl, param.Value.Name, param.Value.Name) - firstQuery = false } else { baseUrl = fmt.Sprintf("%s&%s={%s}", baseUrl, param.Value.Name, param.Value.Name) - firstQuery = false } + firstQuery = false } } diff --git a/backend/go-app/main.go b/backend/go-app/main.go index c608949e..bac7e31a 100644 --- a/backend/go-app/main.go +++ b/backend/go-app/main.go @@ -1906,6 +1906,7 @@ func checkAdminLogin(resp http.ResponseWriter, request *http.Request) { if err != nil { resp.WriteHeader(401) resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "%s"}`, err))) + return } if count == 0 { @@ -5536,8 +5537,26 @@ func verifySwagger(resp http.ResponseWriter, request *http.Request) { return } - log.Printf("Functions: %d", swagger.Paths) - log.Printf("Actions: %d", len(api.Actions)) + // FIXME: CHECK IF SAME NAME AS NORMAL APP + // Can't overwrite existing normal app + workflowApps, err := getAllWorkflowApps(ctx) + if err != nil { + log.Printf("Failed getting all workflow apps from database to verify: %s", err) + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false, "reason": "Failed to verify existence"}`)) + return + } + + // Same name only? + lowerName := strings.ToLower(swagger.Info.Title) + for _, app := range workflowApps { + if app.Downloaded && !app.Generated && strings.ToLower(app.Name) == lowerName { + resp.WriteHeader(401) + resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Normal app with name %s already exists. Delete it first."}`, swagger.Info.Title))) + return + } + } + api.Owner = user.Id err = dumpApi(basePath, api) @@ -5843,7 +5862,7 @@ func init() { log.Printf("Running INIT process") dbclient, err = datastore.NewClient(ctx, gceProject) if err != nil { - log.Printf("DBclient error during init: %s", err) + panic(fmt.Sprintf("DBclient error during init: %s", err)) } go runInit(ctx) diff --git a/backend/go-app/walkoff.go b/backend/go-app/walkoff.go index 36a3d6b0..eea5078a 100644 --- a/backend/go-app/walkoff.go +++ b/backend/go-app/walkoff.go @@ -1355,12 +1355,12 @@ func saveWorkflow(resp http.ResponseWriter, request *http.Request) { curapp := WorkflowApp{} // FIXME - can this work with ONLY AppID? for _, app := range workflowApps { - log.Printf("Name Version: %s_%s, other: %s_%s", app.Name, app.AppVersion, action.AppName, action.AppVersion) if app.ID == action.AppID { curapp = app break } + // Has to NOT be generated //if app.Name == action.AppName && app.AppVersion == action.AppVersion { // curapp = app // break diff --git a/docker-compose.yml b/docker-compose.yml index 0fbc7c41..72dccb0c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,7 @@ version: '3' services: frontend: - #build: ./frontend + build: ./frontend image: frikky/shuffle:frontend container_name: shuffle-frontend hostname: shuffle-frontend @@ -26,7 +26,7 @@ services: volumes: - ${DB_LOCATION}:/etc/shuffle backend: - #build: ./backend + build: ./backend image: frikky/shuffle:backend container_name: shuffle-backend hostname: ${BACKEND_HOSTNAME} diff --git a/frontend/src/AngularWorkflow.js b/frontend/src/AngularWorkflow.js index 05092d87..86fb1b6c 100644 --- a/frontend/src/AngularWorkflow.js +++ b/frontend/src/AngularWorkflow.js @@ -807,12 +807,13 @@ const AngularWorkflow = (props) => { // FIXME - check if they have value before overriding like this for no reason. // Would save a lot of time (400~ ms -> 30ms) - //setSelectedAction({}) + //console.log("ACTION: ", selectedAction) + //console.log("APP: ", selectedApp) + setSelectedAction({}) //setSelectedApp({}) //setSelectedTrigger({}) //setSelectedEdge({}) - // setSelectedTriggerIndex(-1) //setSelectedActionEnvironment({}) //setSelectedEdge({}) @@ -2635,7 +2636,7 @@ const AngularWorkflow = (props) => { value={selectedActionName} fullWidth onChange={setNewSelectedAction} - style={{backgroundColor: inputColor, color: "white", height: "50px"}} + style={{backgroundColor: inputColor, color: "white", height: 50}} SelectDisplayProps={{ style: { marginLeft: 10, @@ -2643,24 +2644,24 @@ const AngularWorkflow = (props) => { } }} > - {selectedApp.actions.map(data => { - var newActionname = data.name - if (data.label !== undefined && data.label !== null && data.label.length > 0) { - newActionname = data.label - } - // ROFL FIXME - loop - newActionname = newActionname.replace("_", " ") - newActionname = newActionname.replace("_", " ") - newActionname = newActionname.replace("_", " ") - newActionname = newActionname.replace("_", " ") - newActionname = newActionname.charAt(0).toUpperCase()+newActionname.substring(1) - return ( - - {newActionname} + {selectedApp.actions.map(data => { + var newActionname = data.name + if (data.label !== undefined && data.label !== null && data.label.length > 0) { + newActionname = data.label + } + // ROFL FIXME - loop + newActionname = newActionname.replace("_", " ") + newActionname = newActionname.replace("_", " ") + newActionname = newActionname.replace("_", " ") + newActionname = newActionname.replace("_", " ") + newActionname = newActionname.charAt(0).toUpperCase()+newActionname.substring(1) + return ( + + {newActionname} - - ) - })} + + ) + })}
@@ -4521,7 +4522,7 @@ const AngularWorkflow = (props) => {
Actions
- {executionData.status !== undefined && executionData.status !== "ABORTED" && executionData.status !== "FINISHED" ? : null} + {executionData.status !== undefined && executionData.status !== "ABORTED" && executionData.status !== "FINISHED" && executionData.status !== "FAILURE" ? : null}
{executionData.results === undefined || executionData.results === null || executionData.results.length === 0 && executionData.status === "EXECUTING" ? diff --git a/frontend/src/AppCreator.js b/frontend/src/AppCreator.js index 5abdc6c3..29e98a56 100644 --- a/frontend/src/AppCreator.js +++ b/frontend/src/AppCreator.js @@ -43,6 +43,7 @@ const actionListStyle = { } const boxStyle = { + color: "white", flex: "1", marginLeft: "10px", marginRight: "10px", @@ -672,8 +673,10 @@ const AppCreator = (props) => { }) .then((responseJson) => { if (!responseJson.success) { - setErrorCode(responseJson.reason) - alert.error("Failed to verify: ") + if (responseJson.reason !== undefined) { + setErrorCode(responseJson.reason) + alert.error("Failed to verify: "+responseJson.reason) + } } else { alert.success("Successfully uploaded openapi") if (window.location.pathname.includes("/new")) { @@ -940,6 +943,9 @@ const AppCreator = (props) => { const setActionField = (field, value) => { currentAction[field] = value setCurrentAction(currentAction) + //if (updater !== value) { + // setUpdater(value) + //} } const bodyInfo = actionBodyRequest.includes(currentActionMethod) ? @@ -1114,6 +1120,7 @@ const AppCreator = (props) => { open={actionsModalOpen} fullWidth onClose={() => { + console.log("CLOSED?") setUrlPath("") setCurrentAction({ "name": "", @@ -1139,7 +1146,7 @@ const AppCreator = (props) => { Name { variant="outlined" defaultValue={currentAction["name"]} onChange={e => { + setActionField("name", e.target.value) + }} + onBlur={e => { // Fix basic issues in frontend. Python functions run a-zA-Z0-9_ - const regex = /[A-Z-a-z0-9 _]/g; + console.log(e.target.value) + const regex = /[A-Za-z0-9 _]/g; const found = e.target.value.match(regex); + console.log("FOUND: ", found) if (found !== null) { setActionField("name", found.join("")) } @@ -1165,7 +1177,7 @@ const AppCreator = (props) => { }, }} /> -
+
Description { {bodyInfo} - - + @@ -1462,7 +1475,7 @@ const AppCreator = (props) => { margin="normal" variant="outlined" value={name} - onChange={e => setName(e.target.value)} + onChange={e => setName(e.target.value)} color="primary" InputProps={{ style:{ @@ -1570,7 +1583,7 @@ const AppCreator = (props) => { }}> Save - {errorCode} + {errorCode.length > 0 ? `Error: ${errorCode}` : null}
From 380d5b31d629b25263ee99dc5499c31012432cd1 Mon Sep 17 00:00:00 2001 From: frikky Date: Tue, 2 Jun 2020 05:22:10 +0200 Subject: [PATCH 15/15] Fixed logging issues --- backend/go-app/codegen.go | 2 -- backend/go-app/walkoff.go | 1 - docker-compose.yml | 4 ++-- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/backend/go-app/codegen.go b/backend/go-app/codegen.go index 503d5f76..d1cf6ac0 100644 --- a/backend/go-app/codegen.go +++ b/backend/go-app/codegen.go @@ -929,9 +929,7 @@ func handleGet(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wor if firstQuery { baseUrl = fmt.Sprintf("%s?%s={%s}", baseUrl, param.Value.Name, param.Value.Name) } else { - log.Printf("NOT FIRST QUERY!: %s", baseUrl) baseUrl = fmt.Sprintf("%s&%s={%s}", baseUrl, param.Value.Name, param.Value.Name) - log.Printf("AFTER: %s", baseUrl) } firstQuery = false } diff --git a/backend/go-app/walkoff.go b/backend/go-app/walkoff.go index eea5078a..5ba6c7f5 100644 --- a/backend/go-app/walkoff.go +++ b/backend/go-app/walkoff.go @@ -1378,7 +1378,6 @@ func saveWorkflow(resp http.ResponseWriter, request *http.Request) { // Check tosee if the appaction is valid curappaction := WorkflowAppAction{} for _, curAction := range curapp.Actions { - log.Printf("Same? %s - %s", action.Name, curAction.Name) if action.Name == curAction.Name { curappaction = curAction break diff --git a/docker-compose.yml b/docker-compose.yml index 72dccb0c..0fbc7c41 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,7 @@ version: '3' services: frontend: - build: ./frontend + #build: ./frontend image: frikky/shuffle:frontend container_name: shuffle-frontend hostname: shuffle-frontend @@ -26,7 +26,7 @@ services: volumes: - ${DB_LOCATION}:/etc/shuffle backend: - build: ./backend + #build: ./backend image: frikky/shuffle:backend container_name: shuffle-backend hostname: ${BACKEND_HOSTNAME}