diff --git a/backend/app_sdk/app_base.py b/backend/app_sdk/app_base.py index 61a7ccd4..f011c3e5 100644 --- a/backend/app_sdk/app_base.py +++ b/backend/app_sdk/app_base.py @@ -29,6 +29,8 @@ class AppBase: if isinstance(self.action, str): self.action = json.loads(self.action) + # FIXME: Add more info like logs in here. + # Docker logs: https://forums.docker.com/t/docker-logs-inside-the-docker-container/68190/2 def send_result(self, action_result, headers, stream_path): if action_result["status"] == "EXECUTING": action_result["status"] = "FAILURE" @@ -187,7 +189,7 @@ class AppBase: paramlist.append(baseitem) - print("PARAMLIST: %s" % paramlist) + #print("PARAMLIST: %s" % paramlist) #newlist[subitem[0]] #if len(newlist) > 0: @@ -198,7 +200,7 @@ class AppBase: #print("Listlengths: %s" % listlengths) #paramlist = [baseparams] - print("Return paramlist: %s" % paramlist) + #print("[INFO] Return paramlist: %s" % paramlist) return paramlist @@ -880,14 +882,13 @@ class AppBase: actionname_lower = parsersplit[0][1:].lower() #Actionname: Start_node - - print(f"\nActionname: {actionname_lower}") + print(f"\n[INFO] Actionname: {actionname_lower}") # 1. Find the action baseresult = "" appendresult = "" - print("Parsersplit length: %d" % len(parsersplit)) + print("[INFO] Parsersplit length: %d" % len(parsersplit)) if (actionname_lower.startswith("exec ") or actionname_lower.startswith("webhook ") or actionname_lower.startswith("schedule ") or actionname_lower.startswith("userinput ") or actionname_lower.startswith("email_trigger ") or actionname_lower.startswith("trigger ")) and len(parsersplit) == 1: record = False for char in actionname_lower: @@ -1276,7 +1277,7 @@ class AppBase: except requests.exceptions.ConnectionError as e: self.logger.exception(e) - print("\n\nRETURNING BECAUSE A BRANCH FAILED\n\n") + print("\n\nRETURNING BECAUSE A BRANCH FAILED: %s\n\n" % tmpresult) return # Replace name cus there might be issues @@ -1324,7 +1325,7 @@ class AppBase: if parameter["name"] == "body": bodyindex = counter - print("PARAM: %s" % parameter) + #print("PARAM: %s" % parameter) try: values = parameter["value_replace"] if values != None: @@ -1601,27 +1602,27 @@ class AppBase: # "id": "body_replacement", #}) - print("APP_SDK DONE: Starting NORMAL execution of function") - print("Running with params (0): %s" % params) + print("[INFO] APP_SDK DONE: Starting NORMAL execution of function") + #print("[INFO] Running with params (0): %s" % params) newres = await func(**params) - print("Returned from execution.") + print("[INFO] Returned from execution.") if isinstance(newres, tuple): - print("Handling return as tuple") + print("[INFO] Handling return as tuple") # Handles files. filedata = "" file_ids = [] print("TUPLE: %s" % newres[1]) if isinstance(newres[1], list): - print("HANDLING LIST FROM RET") + print("[INFO] HANDLING LIST FROM RET") file_ids = self.set_files(newres[1]) elif isinstance(newres[1], object): - print("Handling JSON from ret") + print("[INFO] Handling JSON from ret") file_ids = self.set_files([newres[1]]) elif isinstance(newres[1], str): - print("Handling STRING from ret") + print("[INFO] Handling STRING from ret") file_ids = self.set_files([newres[1]]) else: - print("NO FILES TO HANDLE") + print("[INFO] NO FILES TO HANDLE") tmp_result = { "result": newres[0], @@ -1630,7 +1631,7 @@ class AppBase: result = json.dumps(tmp_result) elif isinstance(newres, str): - print("Handling return as string") + print("[INFO] Handling return as string") result += newres else: try: @@ -1639,13 +1640,13 @@ class AppBase: result += "Failed autocasting. Can't handle %s type from function. Must be string" % type(newres) print("Can't handle type %s value from function" % (type(newres))) - print("POST NEWRES RESULT: ", result) + print("[INFO] POST NEWRES RESULT: ", result) else: - print("APP_SDK DONE: Starting MULTI execution (length: %d) with values %s" % (minlength, multi_parameters)) + print("[INFO] APP_SDK DONE: Starting MULTI execution (length: %d) with values %s" % (minlength, multi_parameters)) # 1. Use number of executions based on the arrays being similar # 2. Find the right value from the parsed multi_params - print("Running WITHOUT outer loop") + print("[INFO] Running WITHOUT outer loop") json_object = False results = await self.run_recursed_items(func, multi_parameters, {}) if isinstance(results, dict) or isinstance(results, list): diff --git a/backend/app_sdk/build.sh b/backend/app_sdk/build.sh index 67c75fd7..e91d8f44 100644 --- a/backend/app_sdk/build.sh +++ b/backend/app_sdk/build.sh @@ -1,6 +1,6 @@ #!/bin/bash NAME=shuffle-app_sdk -VERSION=0.8.42 +VERSION=0.8.43 docker rmi docker.pkg.github.com/frikky/shuffle/$NAME:$VERSION --force docker build . -t frikky/shuffle:app_sdk -t frikky/$NAME:$VERSION -t docker.pkg.github.com/frikky/shuffle/$NAME:$VERSION -t ghcr.io/frikky/$NAME:$VERSION diff --git a/backend/go-app/walkoff.go b/backend/go-app/walkoff.go index 560a2178..ec25bb2f 100644 --- a/backend/go-app/walkoff.go +++ b/backend/go-app/walkoff.go @@ -486,10 +486,11 @@ func increaseStatisticsField(ctx context.Context, fieldname, id string, amount i statisticsItem.Data = append(statisticsItem.Data, newData) // New struct, to not add body, author etc - if _, err := dbclient.Put(ctx, key, &statisticsItem); err != nil { - log.Printf("Error stats to %s: %s", fieldname, err) - return err - } + // FIXME - reintroduce + //if _, err := dbclient.Put(ctx, key, &statisticsItem); err != nil { + // log.Printf("Error stats to %s: %s", fieldname, err) + // return err + //} //log.Printf("Stats: %#v", statisticsItem) @@ -939,7 +940,6 @@ func handleWorkflowQueue(resp http.ResponseWriter, request *http.Request) { if workflowExecution.Status == "FINISHED" { log.Printf("Workflowexecution is already FINISHED. No further action can be taken") - resp.WriteHeader(401) resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Workflowexecution is already finished because of %s with status %s"}`, workflowExecution.LastNode, workflowExecution.Status))) return @@ -1025,6 +1025,8 @@ func runWorkflowExecutionTransaction(ctx context.Context, attempts int64, workfl return } resultLength := len(workflowExecution.Results) + dbSave := false + setExecution := true //tx, err := dbclient.NewTransaction(ctx) //if err != nil { // log.Printf("client.NewTransaction: %v", err) @@ -1044,15 +1046,17 @@ func runWorkflowExecutionTransaction(ctx context.Context, attempts int64, workfl //} if actionResult.Status == "ABORTED" || actionResult.Status == "FAILURE" { - log.Printf("[WARNING] Actionresult is %s for node %s in %s. Should set workflowExecution and exit all running functions", actionResult.Status, actionResult.Action.ID, workflowExecution.ExecutionId) + dbSave = true newResults := []ActionResult{} childNodes := []string{} if workflowExecution.Workflow.Configuration.ExitOnError { + log.Printf("[WARNING] Actionresult is %s for node %s in %s. Should set workflowExecution and exit all running functions", actionResult.Status, actionResult.Action.ID, workflowExecution.ExecutionId) workflowExecution.Status = actionResult.Status workflowExecution.LastNode = actionResult.Action.ID // Find underlying nodes and add them } else { + log.Printf("[WARNING] Actionresult is %s for node %s in %s. Continuing anyway because of workflow configuration.", actionResult.Status, actionResult.Action.ID, workflowExecution.ExecutionId) // Finds ALL childnodes to set them to SKIPPED childNodes = findChildNodes(*workflowExecution, actionResult.Action.ID) // Remove duplicates @@ -1077,40 +1081,50 @@ func runWorkflowExecutionTransaction(ctx context.Context, attempts int64, workfl continue } - // Check parents are done here. Only add it IF all parents are skipped - skipNodeAdd := false - for _, branch := range workflowExecution.Workflow.Branches { - if branch.DestinationID == nodeId { - // If the branch's source node is NOT in childNodes, it's not a skipped parent - sourceNodeFound := false - for _, item := range childNodes { - if item == branch.SourceID { - sourceNodeFound = true - break - } - } - - if !sourceNodeFound { - log.Printf("Not setting node %s to SKIPPED", nodeId) - skipNodeAdd = true - break - } + resultExists := false + for _, result := range workflowExecution.Results { + if result.Action.ID == curAction.ID { + resultExists = true + break } } - if !skipNodeAdd { - newResult := ActionResult{ - Action: curAction, - ExecutionId: actionResult.ExecutionId, - Authorization: actionResult.Authorization, - Result: "Skipped because of previous node", - StartedAt: 0, - CompletedAt: 0, - Status: "SKIPPED", + if !resultExists { + // Check parents are done here. Only add it IF all parents are skipped + skipNodeAdd := false + for _, branch := range workflowExecution.Workflow.Branches { + if branch.DestinationID == nodeId { + // If the branch's source node is NOT in childNodes, it's not a skipped parent + sourceNodeFound := false + for _, item := range childNodes { + if item == branch.SourceID { + sourceNodeFound = true + break + } + } + + if !sourceNodeFound { + log.Printf("Not setting node %s to SKIPPED", nodeId) + skipNodeAdd = true + break + } + } } - newResults = append(newResults, newResult) - increaseStatisticsField(ctx, "workflow_execution_actions_skipped", workflowExecution.Workflow.ID, 1, workflowExecution.ExecutionOrg) + if !skipNodeAdd { + newResult := ActionResult{ + Action: curAction, + ExecutionId: actionResult.ExecutionId, + Authorization: actionResult.Authorization, + Result: "Skipped because of previous node", + StartedAt: 0, + CompletedAt: 0, + Status: "SKIPPED", + } + + newResults = append(newResults, newResult) + increaseStatisticsField(ctx, "workflow_execution_actions_skipped", workflowExecution.Workflow.ID, 1, workflowExecution.ExecutionOrg) + } } } } @@ -1119,9 +1133,13 @@ func runWorkflowExecutionTransaction(ctx context.Context, attempts int64, workfl lastResult := "" // type ActionResult struct { for _, result := range workflowExecution.Results { + if actionResult.Action.ID == result.Action.ID { + continue + } + if result.Status == "EXECUTING" { result.Status = actionResult.Status - result.Result = "Aborted because of error in another node" + result.Result = "Aborted because of error in another node (2)" } if len(result.Result) > 0 { @@ -1152,17 +1170,24 @@ func runWorkflowExecutionTransaction(ctx context.Context, attempts int64, workfl // Find the appropriate action if len(workflowExecution.Results) > 0 { // FIXME + skip := false found := false outerindex := 0 for index, item := range workflowExecution.Results { if item.Action.ID == actionResult.Action.ID { found = true + if item.Status == actionResult.Status { + skip = true + } + outerindex = index break } } - if found { + if skip { + //log.Printf("Both are %s. Skipping this node", item.Status) + } else if found { // If result exists and execution variable exists, update execution value //log.Printf("Exec var backend: %s", workflowExecution.Results[outerindex].Action.ExecutionVariable.Name) actionVarName := workflowExecution.Results[outerindex].Action.ExecutionVariable.Name @@ -1178,14 +1203,14 @@ func runWorkflowExecutionTransaction(ctx context.Context, attempts int64, workfl } } - log.Printf("[INFO] Updating %s in %s from %s to %s", actionResult.Action.ID, workflowExecution.ExecutionId, workflowExecution.Results[outerindex].Status, actionResult.Status) + log.Printf("[INFO] Updating %s in workflow %s from %s to %s", actionResult.Action.ID, workflowExecution.ExecutionId, workflowExecution.Results[outerindex].Status, actionResult.Status) workflowExecution.Results[outerindex] = actionResult } else { - log.Printf("[INFO] Setting value of %s in %s to %s", actionResult.Action.ID, workflowExecution.ExecutionId, actionResult.Status) + log.Printf("[INFO] Setting value of %s in workflow %s to %s", actionResult.Action.ID, workflowExecution.ExecutionId, actionResult.Status) workflowExecution.Results = append(workflowExecution.Results, actionResult) } } else { - log.Printf("[INFO] Setting value of %s in %s to %s", actionResult.Action.ID, workflowExecution.ExecutionId, actionResult.Status) + log.Printf("[INFO] Setting value of %s in workflow %s to %s", actionResult.Action.ID, workflowExecution.ExecutionId, actionResult.Status) workflowExecution.Results = append(workflowExecution.Results, actionResult) } @@ -1268,6 +1293,7 @@ func runWorkflowExecutionTransaction(ctx context.Context, attempts int64, workfl _ = skippedNodes if finished { + dbSave = true log.Printf("[INFO] Execution of %s finished.", workflowExecution.ExecutionId) //log.Println("Might be finished based on length of results and everything being SUCCESS or FINISHED - VERIFY THIS. Setting status to finished.") @@ -1299,6 +1325,7 @@ func runWorkflowExecutionTransaction(ctx context.Context, attempts int64, workfl tmpJson, err := json.Marshal(workflowExecution) if err == nil { if len(tmpJson) >= 1048487 { + dbSave = true log.Printf("[ERROR] Result length is too long! Need to reduce result size") // Result string `json:"result" datastore:"result,noindex"` @@ -1319,24 +1346,25 @@ func runWorkflowExecutionTransaction(ctx context.Context, attempts int64, workfl // Validating that action results hasn't changed // Handled using cachhing, so actually pretty fast - setExecution := true cacheKey := fmt.Sprintf("workflowexecution-%s", workflowExecution.ExecutionId) if value, found := requestCache.Get(cacheKey); found { parsedValue := value.(*WorkflowExecution) if len(parsedValue.Results) > 0 && len(parsedValue.Results) != resultLength { setExecution = false if attempts > 5 { - log.Printf("\n\nSkipping execution input - %d vs %d. Attempts: (%d)\n\n", len(parsedValue.Results), resultLength, attempts) + //log.Printf("\n\nSkipping execution input - %d vs %d. Attempts: (%d)\n\n", len(parsedValue.Results), resultLength, attempts) } attempts += 1 - runWorkflowExecutionTransaction(ctx, attempts, workflowExecutionId, actionResult, resp) - return + if len(workflowExecution.Results) <= len(workflowExecution.Workflow.Actions) { + runWorkflowExecutionTransaction(ctx, attempts, workflowExecutionId, actionResult, resp) + return + } } } if setExecution { - err = setWorkflowExecution(ctx, *workflowExecution, false) + err = setWorkflowExecution(ctx, *workflowExecution, dbSave) if err != nil { resp.WriteHeader(401) resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed setting workflowexecution actionresult: %s"}`, err))) @@ -2546,7 +2574,7 @@ func abortExecution(resp http.ResponseWriter, request *http.Request) { for _, result := range workflowExecution.Results { if result.Status == "EXECUTING" { result.Status = "ABORTED" - result.Result = "Aborted because of error in another node" + result.Result = "Aborted because of error in another node (1)" } if len(result.Result) > 0 { @@ -3916,6 +3944,7 @@ func getSpecificWorkflow(resp http.ResponseWriter, request *http.Request) { } func setWorkflowExecution(ctx context.Context, workflowExecution WorkflowExecution, dbSave bool) error { + //log.Printf("\n\n\nRESULT: %s\n\n\n", workflowExecution.Status) if len(workflowExecution.ExecutionId) == 0 { log.Printf("Workflowexeciton executionId can't be empty.") return errors.New("ExecutionId can't be empty.") @@ -3924,7 +3953,7 @@ func setWorkflowExecution(ctx context.Context, workflowExecution WorkflowExecuti cacheKey := fmt.Sprintf("workflowexecution-%s", workflowExecution.ExecutionId) //requestCache.Delete(cacheKey) requestCache.Set(cacheKey, &workflowExecution, cache.DefaultExpiration) - if !dbSave { + if !dbSave && workflowExecution.Status == "EXECUTING" && len(workflowExecution.Results) > 1 { //log.Printf("[WARNING] SHOULD skip DB saving for execution") return nil } @@ -3955,7 +3984,7 @@ func getWorkflowExecution(ctx context.Context, id string) (*WorkflowExecution, e // log.Printf("Failed unmarshalling cached value: %s", err) //} } else { - log.Printf("[ERROR] Couldn't find key %s", cacheKey) + //log.Printf("[ERROR] Couldn't find key %s", cacheKey) } key := datastore.NameKey("workflowexecution", strings.ToLower(id), nil) @@ -4011,13 +4040,14 @@ func getAllWorkflows(ctx context.Context, orgId string) ([]Workflow, error) { } func setExampleresult(ctx context.Context, result AppExecutionExample) error { - key := datastore.NameKey("example_result", result.ExampleId, nil) + // FIXME: Reintroduce this for stats + //key := datastore.NameKey("example_result", result.ExampleId, nil) - // New struct, to not add body, author etc - if _, err := dbclient.Put(ctx, key, &result); err != nil { - log.Printf("Error adding workflow: %s", err) - return err - } + //// New struct, to not add body, author etc + //if _, err := dbclient.Put(ctx, key, &result); err != nil { + // log.Printf("Error adding workflow: %s", err) + // return err + //} return nil } diff --git a/backend/tests/execute.sh b/backend/tests/execute.sh index 5d614f14..ef852bbb 100644 --- a/backend/tests/execute.sh +++ b/backend/tests/execute.sh @@ -24,25 +24,3 @@ curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c1 curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4" curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4" curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4" -curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4" -curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4" -curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4" -curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4" -curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4" -curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4" -curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4" -curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4" -curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4" -curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4" -curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4" -curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4" -curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4" -curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4" -curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4" -curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4" -curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4" -curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4" -curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4" -curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4" -curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4" -curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4" diff --git a/frontend/src/views/AngularWorkflow.jsx b/frontend/src/views/AngularWorkflow.jsx index fc9bf36b..c5df42a2 100644 --- a/frontend/src/views/AngularWorkflow.jsx +++ b/frontend/src/views/AngularWorkflow.jsx @@ -276,6 +276,7 @@ const AngularWorkflow = (props) => { // FIXME: Sort this by time setWorkflowExecutions(responseJson) } + alert.info("Refrshed executions") //setWorkflowExecutions(responseJson) }) .catch(error => { @@ -3676,6 +3677,22 @@ const AngularWorkflow = (props) => { }) } + const headerSize = 68 + const rightsidebarStyle = { + position: "fixed", + right: 0, + top: headerSize+1, + height: "100%", + bottom: 0, + minWidth: 350, + maxWidth: 350, + borderLeft: "1px solid rgb(91, 96, 100)", + overflow: "scroll", + overflowX: "auto", + overflowY: "auto", + zIndex: 1000, + } + const appApiView = Object.getOwnPropertyNames(selectedAction).length > 0 ?