Fixed an app creator file bug and added execution testing to workflow
This commit is contained in:
@@ -2166,10 +2166,87 @@ class AppBase:
|
|||||||
self.logger.info(f"[ERROR] Liquid Template error: {e}")
|
self.logger.info(f"[ERROR] Liquid Template error: {e}")
|
||||||
error = True
|
error = True
|
||||||
error_msg = e
|
error_msg = e
|
||||||
|
|
||||||
|
self.action["parameters"].append({
|
||||||
|
"name": "liquid_template_error",
|
||||||
|
"value": f"There was a Liquid input error (1). Details: {e}",
|
||||||
|
})
|
||||||
|
|
||||||
|
self.action_result["action"] = self.action
|
||||||
|
except SyntaxError as e:
|
||||||
|
self.logger.info(f"[ERROR] Liquid Syntax error: {e}")
|
||||||
|
error = True
|
||||||
|
error_msg = e
|
||||||
|
|
||||||
|
self.action["parameters"].append({
|
||||||
|
"name": "liquid_python_syntax_error",
|
||||||
|
"value": f"There was a syntax error in your Liquid input (2). Details: {e}",
|
||||||
|
})
|
||||||
|
|
||||||
|
self.action_result["action"] = self.action
|
||||||
|
except IndentationError as e:
|
||||||
|
self.logger.info(f"[ERROR] Liquid IndentationError: {e}")
|
||||||
|
error = True
|
||||||
|
error_msg = e
|
||||||
|
|
||||||
|
self.action["parameters"].append({
|
||||||
|
"name": "liquid_indentiation_error",
|
||||||
|
"value": f"There was an indentation error in your Liquid input (2). Details: {e}",
|
||||||
|
})
|
||||||
|
|
||||||
|
self.action_result["action"] = self.action
|
||||||
except jinja2.exceptions.TemplateSyntaxError as e:
|
except jinja2.exceptions.TemplateSyntaxError as e:
|
||||||
self.logger.info(f"[ERROR] Liquid Syntax error: {e}")
|
self.logger.info(f"[ERROR] Liquid Syntax error: {e}")
|
||||||
error = True
|
error = True
|
||||||
error_msg = e
|
error_msg = e
|
||||||
|
|
||||||
|
self.action["parameters"].append({
|
||||||
|
"name": "liquid_syntax_error",
|
||||||
|
"value": f"There was a syntax error in your Liquid input (2). Details: {e}",
|
||||||
|
})
|
||||||
|
|
||||||
|
self.action_result["action"] = self.action
|
||||||
|
except json.decoder.JSONDecodeError as e:
|
||||||
|
self.logger.info(f"[ERROR] Liquid JSON Syntax error: {e}")
|
||||||
|
|
||||||
|
replace = False
|
||||||
|
skip_next = False
|
||||||
|
newlines = []
|
||||||
|
thisline = []
|
||||||
|
for line in template.split("\n"):
|
||||||
|
#print("LINE: %s" % repr(line))
|
||||||
|
if "\"\"\"" in line or "\'\'\'" in line:
|
||||||
|
if replace:
|
||||||
|
skip_next = True
|
||||||
|
else:
|
||||||
|
replace = not replace
|
||||||
|
|
||||||
|
if replace == True:
|
||||||
|
thisline.append(line)
|
||||||
|
if skip_next == True:
|
||||||
|
if len(thisline) > 0:
|
||||||
|
#print(thisline)
|
||||||
|
newlines.append(" ".join(thisline))
|
||||||
|
thisline = []
|
||||||
|
|
||||||
|
replace = False
|
||||||
|
else:
|
||||||
|
newlines.append(line)
|
||||||
|
|
||||||
|
new_template = "\n".join(newlines)
|
||||||
|
if new_template != template:
|
||||||
|
#check_template(new_template)
|
||||||
|
return parse_liquid(new_template, self)
|
||||||
|
else:
|
||||||
|
error = True
|
||||||
|
error_msg = e
|
||||||
|
|
||||||
|
self.action["parameters"].append({
|
||||||
|
"name": "liquid_json_error",
|
||||||
|
"value": f"There was a syntax error in your input JSON(2). This is typically an issue with escaping newlines. Details: {e}",
|
||||||
|
})
|
||||||
|
|
||||||
|
self.action_result["action"] = self.action
|
||||||
except TypeError as e:
|
except TypeError as e:
|
||||||
try:
|
try:
|
||||||
if "string as left operand" in f"{e}":
|
if "string as left operand" in f"{e}":
|
||||||
@@ -2194,6 +2271,13 @@ class AppBase:
|
|||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"SubError in Liquid: {e}")
|
print(f"SubError in Liquid: {e}")
|
||||||
|
|
||||||
|
self.action["parameters"].append({
|
||||||
|
"name": "liquid_general_error",
|
||||||
|
"value": f"There was general error Liquid input (2). Details: {e}",
|
||||||
|
})
|
||||||
|
|
||||||
|
self.action_result["action"] = self.action
|
||||||
#return template
|
#return template
|
||||||
|
|
||||||
self.logger.info(f"[ERROR] Liquid TypeError error: {e}")
|
self.logger.info(f"[ERROR] Liquid TypeError error: {e}")
|
||||||
@@ -2205,6 +2289,13 @@ class AppBase:
|
|||||||
error = True
|
error = True
|
||||||
error_msg = e
|
error_msg = e
|
||||||
|
|
||||||
|
self.action["parameters"].append({
|
||||||
|
"name": "liquid_general_exception",
|
||||||
|
"value": f"There was general exception Liquid input (2). Details: {e}",
|
||||||
|
})
|
||||||
|
|
||||||
|
self.action_result["action"] = self.action
|
||||||
|
|
||||||
if "fmt" in error_msg and "liquid_date" in error_msg:
|
if "fmt" in error_msg and "liquid_date" in error_msg:
|
||||||
return template
|
return template
|
||||||
|
|
||||||
|
|||||||
@@ -395,6 +395,40 @@ func handleGetStreamResults(resp http.ResponseWriter, request *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, action := range workflowExecution.Workflow.Actions {
|
||||||
|
found := false
|
||||||
|
for _, result := range workflowExecution.Results {
|
||||||
|
if result.Action.ID == action.ID {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if found {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
//log.Printf("[DEBUG] Maybe not handled yet: %s", action.ID)
|
||||||
|
cacheId := fmt.Sprintf("%s_%s_result", workflowExecution.ExecutionId, action.ID)
|
||||||
|
cache, err := shuffle.GetCache(ctx, cacheId)
|
||||||
|
if err != nil {
|
||||||
|
//log.Printf("[WARNING] Couldn't find in fix exec %s (2): %s", cacheId, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
actionResult := shuffle.ActionResult{}
|
||||||
|
cacheData := []byte(cache.([]uint8))
|
||||||
|
|
||||||
|
// Just ensuring the data is good
|
||||||
|
err = json.Unmarshal(cacheData, &actionResult)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
log.Printf("[DEBUG] APPENDING %s result to send to app or something\n\n\n\n", action.ID)
|
||||||
|
workflowExecution.Results = append(workflowExecution.Results, actionResult)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
newjson, err := json.Marshal(workflowExecution)
|
newjson, err := json.Marshal(workflowExecution)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.WriteHeader(401)
|
resp.WriteHeader(401)
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ const WorkflowSearch = props => {
|
|||||||
var counted = 0
|
var counted = 0
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Grid container spacing={0} style={{border: "1px solid rgba(255,255,255,0.2)", maxHeight: 250, minHeight: 250, overflowY: "auto", overflowX: "hidden",}}>
|
<Grid container spacing={0} style={{border: "1px solid rgba(255,255,255,0.2)", maxHeight: 250, minHeight: 250, overflowY: "auto", overflowX: "hidden", }}>
|
||||||
{hits.map((data, index) => {
|
{hits.map((data, index) => {
|
||||||
const paperStyle = {
|
const paperStyle = {
|
||||||
backgroundColor: index === mouseHoverIndex ? "rgba(255,255,255,0.8)" : theme.palette.inputColor,
|
backgroundColor: index === mouseHoverIndex ? "rgba(255,255,255,0.8)" : theme.palette.inputColor,
|
||||||
@@ -131,6 +131,8 @@ const WorkflowSearch = props => {
|
|||||||
position: "relative",
|
position: "relative",
|
||||||
overflow: "hidden",
|
overflow: "hidden",
|
||||||
width: "100%",
|
width: "100%",
|
||||||
|
minHeight: 37,
|
||||||
|
maxHeight: 52,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (counted === 12/xs*rowHandler) {
|
if (counted === 12/xs*rowHandler) {
|
||||||
|
|||||||
@@ -164,7 +164,14 @@ const AuthenticationOauth2 = (props) => {
|
|||||||
state += `%26refresh_uri%3d${authentication_url}`;
|
state += `%26refresh_uri%3d${authentication_url}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const url = `${authenticationType.redirect_uri}?client_id=${client_id}&redirect_uri=${redirectUri}&response_type=code&scope=${resources}&prompt=consent&state=${state}&access_type=offline`;
|
// Force new consent
|
||||||
|
//const url = `${authenticationType.redirect_uri}?client_id=${client_id}&redirect_uri=${redirectUri}&response_type=code&scope=${resources}&prompt=consent&state=${state}&access_type=offline`;
|
||||||
|
|
||||||
|
// Admin consent
|
||||||
|
//const url = `${authenticationType.redirect_uri}?client_id=${client_id}&redirect_uri=${redirectUri}&response_type=code&scope=${resources}&prompt=admin_consent&state=${state}&access_type=offline`;
|
||||||
|
|
||||||
|
// Skip consent
|
||||||
|
const url = `${authenticationType.redirect_uri}?client_id=${client_id}&redirect_uri=${redirectUri}&response_type=code&scope=${resources}&state=${state}&access_type=offline`;
|
||||||
|
|
||||||
//const url = `https://accounts.zoho.com/oauth/v2/auth?response_type=code&client_id=${client_id}&scope=AaaServer.profile.Read&redirect_uri=${redirectUri}&prompt=consent`
|
//const url = `https://accounts.zoho.com/oauth/v2/auth?response_type=code&client_id=${client_id}&scope=AaaServer.profile.Read&redirect_uri=${redirectUri}&prompt=consent`
|
||||||
//console.log("Full URI: ", url)
|
//console.log("Full URI: ", url)
|
||||||
@@ -373,7 +380,7 @@ const AuthenticationOauth2 = (props) => {
|
|||||||
"efe4c3fe-84a1-4821-a84f-23a6cfe8e72d",
|
"efe4c3fe-84a1-4821-a84f-23a6cfe8e72d",
|
||||||
"",
|
"",
|
||||||
"https://graph.microsoft.com",
|
"https://graph.microsoft.com",
|
||||||
["Mail.ReadWrite"],
|
["Mail.ReadWrite", "Mail.Send"],
|
||||||
);
|
);
|
||||||
} else if (selectedApp.name.toLowerCase() == "gmail") {
|
} else if (selectedApp.name.toLowerCase() == "gmail") {
|
||||||
handleOauth2Request(
|
handleOauth2Request(
|
||||||
|
|||||||
@@ -88,9 +88,9 @@ import {
|
|||||||
|
|
||||||
import Autocomplete from "@material-ui/lab/Autocomplete";
|
import Autocomplete from "@material-ui/lab/Autocomplete";
|
||||||
|
|
||||||
import CodeMirror from "@uiw/react-codemirror";
|
//import CodeMirror from "@uiw/react-codemirror";
|
||||||
import "codemirror/keymap/sublime";
|
//import "codemirror/keymap/sublime";
|
||||||
import "codemirror/theme/gruvbox-dark.css";
|
//import "codemirror/theme/gruvbox-dark.css";
|
||||||
import ShuffleCodeEditor from "../components/ShuffleCodeEditor.jsx";
|
import ShuffleCodeEditor from "../components/ShuffleCodeEditor.jsx";
|
||||||
|
|
||||||
const useStyles = makeStyles({
|
const useStyles = makeStyles({
|
||||||
@@ -1515,6 +1515,7 @@ const ParsedAction = (props) => {
|
|||||||
setcodedata={setcodedata}
|
setcodedata={setcodedata}
|
||||||
expansionModalOpen={expansionModalOpen}
|
expansionModalOpen={expansionModalOpen}
|
||||||
setExpansionModalOpen={setExpansionModalOpen}
|
setExpansionModalOpen={setExpansionModalOpen}
|
||||||
|
globalUrl={globalUrl}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import React, {useState, useEffect, useLayoutEffect} from 'react';
|
import React, {useState, useEffect, useLayoutEffect} from 'react';
|
||||||
import {
|
import {
|
||||||
|
CircularProgress,
|
||||||
IconButton,
|
IconButton,
|
||||||
Dialog,
|
Dialog,
|
||||||
Modal,
|
Modal,
|
||||||
@@ -29,6 +30,7 @@ import {
|
|||||||
SquareFoot as SquareFootIcon,
|
SquareFoot as SquareFootIcon,
|
||||||
Circle as CircleIcon,
|
Circle as CircleIcon,
|
||||||
Add as AddIcon,
|
Add as AddIcon,
|
||||||
|
PlayArrow as PlayArrowIcon,
|
||||||
} from '@mui/icons-material';
|
} from '@mui/icons-material';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -67,7 +69,8 @@ const pythonFilters = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
const CodeEditor = (props) => {
|
const CodeEditor = (props) => {
|
||||||
const { fieldCount, setFieldCount, actionlist, changeActionParameterCodeMirror, expansionModalOpen, setExpansionModalOpen, codedata, setcodedata, isFileEditor, runUpdateText } = props
|
const { globalUrl, fieldCount, setFieldCount, actionlist, changeActionParameterCodeMirror, expansionModalOpen, setExpansionModalOpen, codedata, setcodedata, isFileEditor, runUpdateText } = props
|
||||||
|
|
||||||
const [localcodedata, setlocalcodedata] = React.useState(codedata === undefined || codedata === null || codedata.length === 0 ? "" : codedata);
|
const [localcodedata, setlocalcodedata] = React.useState(codedata === undefined || codedata === null || codedata.length === 0 ? "" : codedata);
|
||||||
// const {codelang, setcodelang} = props
|
// const {codelang, setcodelang} = props
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
@@ -92,6 +95,13 @@ const CodeEditor = (props) => {
|
|||||||
const [menuPosition, setMenuPosition] = useState(null);
|
const [menuPosition, setMenuPosition] = useState(null);
|
||||||
const [showAutocomplete, setShowAutocomplete] = React.useState(false);
|
const [showAutocomplete, setShowAutocomplete] = React.useState(false);
|
||||||
|
|
||||||
|
const baseResult = ""
|
||||||
|
const [executionResult, setExecutionResult] = useState({
|
||||||
|
"valid": false,
|
||||||
|
"result": baseResult,
|
||||||
|
})
|
||||||
|
const [executing, setExecuting] = useState(false)
|
||||||
|
|
||||||
const liquidOpen = Boolean(anchorEl);
|
const liquidOpen = Boolean(anchorEl);
|
||||||
const mathOpen = Boolean(anchorEl2);
|
const mathOpen = Boolean(anchorEl2);
|
||||||
const pythonOpen = Boolean(anchorEl3);
|
const pythonOpen = Boolean(anchorEl3);
|
||||||
@@ -384,7 +394,7 @@ const CodeEditor = (props) => {
|
|||||||
// return
|
// return
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//console.log(found)
|
//console.log("FOUND: ", found)
|
||||||
|
|
||||||
// Whelp this is inefficient af. Single loop pls
|
// Whelp this is inefficient af. Single loop pls
|
||||||
// When the found array is empty.
|
// When the found array is empty.
|
||||||
@@ -395,6 +405,7 @@ const CodeEditor = (props) => {
|
|||||||
const fixedVariable = fixVariable(found[i])
|
const fixedVariable = fixVariable(found[i])
|
||||||
//var correctVariable = availableVariables.includes(fixedVariable)
|
//var correctVariable = availableVariables.includes(fixedVariable)
|
||||||
|
|
||||||
|
//
|
||||||
var valuefound = false
|
var valuefound = false
|
||||||
for (var j = 0; j < actionlist.length; j++) {
|
for (var j = 0; j < actionlist.length; j++) {
|
||||||
if(fixedVariable.slice(1,).toLowerCase() === actionlist[j].autocomplete.toLowerCase()){
|
if(fixedVariable.slice(1,).toLowerCase() === actionlist[j].autocomplete.toLowerCase()){
|
||||||
@@ -423,22 +434,31 @@ const CodeEditor = (props) => {
|
|||||||
// actionlist[k].example = "TMP"
|
// actionlist[k].example = "TMP"
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
var new_input = ""
|
||||||
try {
|
try {
|
||||||
var new_input = FindJsonPath(fullpath, actionlist[k].example)
|
new_input = FindJsonPath(fullpath, actionlist[k].example)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("ERR IN INPUT: ", e)
|
console.log("ERR IN INPUT: ", e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log("Got input: ", new_input, actionlist[k].example, typeof new_input)
|
||||||
|
|
||||||
if (typeof new_input === "object") {
|
if (typeof new_input === "object") {
|
||||||
new_input = JSON.stringify(new_input)
|
new_input = JSON.stringify(new_input)
|
||||||
} else {
|
} else {
|
||||||
if (typeof new_input === "string") {
|
if (typeof new_input === "string") {
|
||||||
new_input = new_input
|
new_input = new_input
|
||||||
} else {
|
} else {
|
||||||
new_input = ""
|
console.log("NO TYPE? ", typeof new_input)
|
||||||
|
try {
|
||||||
|
new_input = new_input.toString()
|
||||||
|
} catch (e) {
|
||||||
|
new_input = ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//console.log("FOUND2: ", fixedVariable, actionlist[j].example)
|
||||||
input = input.replace(fixedVariable, new_input)
|
input = input.replace(fixedVariable, new_input)
|
||||||
|
|
||||||
//} catch (e) {
|
//} catch (e) {
|
||||||
@@ -461,7 +481,6 @@ const CodeEditor = (props) => {
|
|||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("Outer replace error: ", e)
|
console.log("Outer replace error: ", e)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const tmpValidation = validateJson(input.valueOf())
|
const tmpValidation = validateJson(input.valueOf())
|
||||||
@@ -515,6 +534,67 @@ const CodeEditor = (props) => {
|
|||||||
setAnchorEl3(null)
|
setAnchorEl3(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const executeSingleAction = (inputdata) => {
|
||||||
|
//if (serverside === true) {
|
||||||
|
// return
|
||||||
|
//}
|
||||||
|
|
||||||
|
if (validation === true) {
|
||||||
|
inputdata = JSON.stringify(inputdata)
|
||||||
|
}
|
||||||
|
|
||||||
|
const appid = "3e2bdf9d5069fe3f4746c29d68785a6a"
|
||||||
|
const actiondata = {"description":"Repeats the call parameter","id":"","name":"repeat_back_to_me","label":"","node_type":"","environment":"","sharing":false,"private_id":"","public_id":"","app_id":"3e2bdf9d5069fe3f4746c29d68785a6a","tags":null,"authentication":[],"tested":false,"parameters":[{"description":"The message to repeat","id":"","name":"call","example":"REPEATING: Hello world","value":inputdata,"multiline":true,"options":null,"action_field":"","variant":"STATIC_VALUE","required":true,"configuration":false,"tags":null,"schema":{"type":"string"},"skip_multicheck":false,"value_replace":null,"unique_toggled":false,"autocompleted":false}],"execution_variable":{"description":"","id":"","name":"","value":""},"returns":{"description":"","example":"","id":"","schema":{"type":"string"}},"authentication_id":"","example":"","auth_not_required":false,"source_workflow":"","run_magic_output":false,"run_magic_input":false,"execution_delay":0,"app_name":"Shuffle Tools","app_version":"1.2.0","selectedAuthentication":{}}
|
||||||
|
|
||||||
|
setExecutionResult({
|
||||||
|
"valid": false,
|
||||||
|
"result": baseResult,
|
||||||
|
})
|
||||||
|
|
||||||
|
setExecuting(true)
|
||||||
|
|
||||||
|
fetch(globalUrl+"/api/v1/apps/"+appid+"/execute", {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Accept': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(actiondata),
|
||||||
|
credentials: "include",
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (response.status !== 200) {
|
||||||
|
console.log("Status not 200 for stream results :O!")
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.json()
|
||||||
|
})
|
||||||
|
.then((responseJson) => {
|
||||||
|
//console.log("RESPONSE: ", responseJson)
|
||||||
|
if (responseJson.success === true && responseJson.result !== null && responseJson.result !== undefined && responseJson.result.length > 0) {
|
||||||
|
const result = responseJson.result.slice(0, 50)+"..."
|
||||||
|
//alert.info("SUCCESS: "+result)
|
||||||
|
|
||||||
|
const validate = validateJson(responseJson.result)
|
||||||
|
setExecutionResult(validate)
|
||||||
|
} else if (responseJson.success === false && responseJson.reason !== undefined && responseJson.reason !== null) {
|
||||||
|
alert.error(responseJson.reason)
|
||||||
|
setExecutionResult({"valid": false, "result": responseJson.reason})
|
||||||
|
} else if (responseJson.success === true) {
|
||||||
|
setExecutionResult({"valid": false, "result": "Couldn't finish execution. Please fill all the required fields, and retry the execution."})
|
||||||
|
} else {
|
||||||
|
setExecutionResult({"valid": false, "result": "Couldn't finish execution (2). Please fill all the required fields, and validate the execution."})
|
||||||
|
}
|
||||||
|
|
||||||
|
setExecuting(false)
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
//alert.error("Execution error: "+error.toString())
|
||||||
|
console.log("error: ", error)
|
||||||
|
setExecuting(false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
aria-labelledby="draggable-code-modal"
|
aria-labelledby="draggable-code-modal"
|
||||||
@@ -1068,7 +1148,6 @@ const CodeEditor = (props) => {
|
|||||||
|
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
marginBottom: -30,
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{/*
|
{/*
|
||||||
@@ -1136,129 +1215,158 @@ const CodeEditor = (props) => {
|
|||||||
*/}
|
*/}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{isFileEditor ? null :
|
{isFileEditor ? null : (
|
||||||
<div>
|
<div>
|
||||||
{isMobile ? null :
|
{isMobile ? null :
|
||||||
<DialogTitle
|
<DialogTitle
|
||||||
|
style={{
|
||||||
|
marginTop: 20,
|
||||||
|
paddingLeft: 10,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
color: "white"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Expected Output
|
||||||
|
</span>
|
||||||
|
<IconButton disabled={executing} color="primary" style={{border: `1px solid ${theme.palette.primary.main}`, marginLeft: 300, padding: 8}} variant="contained" onClick={() => {
|
||||||
|
executeSingleAction(expOutput)
|
||||||
|
}}>
|
||||||
|
<Tooltip title="Try it! This runs Shuffle Tools' 'repeat back to me' action with the expected output." placement="top">
|
||||||
|
{executing ? <CircularProgress style={{height: 18, width: 18, }} /> : <PlayArrowIcon style={{height: 18, width: 18, }} /> }
|
||||||
|
|
||||||
|
</Tooltip>
|
||||||
|
</IconButton>
|
||||||
|
</DialogTitle>
|
||||||
|
}
|
||||||
|
{isMobile ? null :
|
||||||
|
validation === true ?
|
||||||
|
<ReactJson
|
||||||
|
src={expOutput}
|
||||||
|
theme={theme.palette.jsonTheme}
|
||||||
|
style={{
|
||||||
|
borderRadius: 5,
|
||||||
|
border: `2px solid ${theme.palette.inputColor}`,
|
||||||
|
padding: 10,
|
||||||
|
maxHeight: 250,
|
||||||
|
minheight: 250,
|
||||||
|
overflow: "auto",
|
||||||
|
}}
|
||||||
|
collapsed={false}
|
||||||
|
enableClipboard={(copy) => {
|
||||||
|
//handleReactJsonClipboard(copy);
|
||||||
|
}}
|
||||||
|
displayDataTypes={false}
|
||||||
|
onSelect={(select) => {
|
||||||
|
//HandleJsonCopy(validate.result, select, "exec");
|
||||||
|
}}
|
||||||
|
name={"JSON autocompletion"}
|
||||||
|
/>
|
||||||
|
:
|
||||||
|
<p
|
||||||
|
id='expOutput'
|
||||||
|
style={{
|
||||||
|
whiteSpace: "pre-wrap",
|
||||||
|
color: "#f85a3e",
|
||||||
|
fontFamily: "monospace",
|
||||||
|
backgroundColor: "#282828",
|
||||||
|
padding: 20,
|
||||||
|
marginTop: -2,
|
||||||
|
border: `2px solid ${theme.palette.inputColor}`,
|
||||||
|
borderRadius: theme.palette.borderRadius,
|
||||||
|
maxHeight: 250,
|
||||||
|
overflow: "auto",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{expOutput}
|
||||||
|
</p>
|
||||||
|
}
|
||||||
|
{executionResult.valid === true ?
|
||||||
|
<ReactJson
|
||||||
|
src={executionResult.result}
|
||||||
|
theme={theme.palette.jsonTheme}
|
||||||
|
style={{
|
||||||
|
borderRadius: 5,
|
||||||
|
border: `2px solid ${theme.palette.inputColor}`,
|
||||||
|
padding: 10,
|
||||||
|
maxHeight: 100,
|
||||||
|
minheight: 100,
|
||||||
|
overflow: "auto",
|
||||||
|
}}
|
||||||
|
collapsed={false}
|
||||||
|
enableClipboard={(copy) => {
|
||||||
|
//handleReactJsonClipboard(copy);
|
||||||
|
}}
|
||||||
|
displayDataTypes={false}
|
||||||
|
onSelect={(select) => {
|
||||||
|
//HandleJsonCopy(validate.result, select, "exec");
|
||||||
|
}}
|
||||||
|
name={"Test result"}
|
||||||
|
/>
|
||||||
|
:
|
||||||
|
<span>
|
||||||
|
{executionResult.result.length > 0 ?
|
||||||
|
<Typography variant="body2" style={{maxHeight: 100, overflow: "auto",}}>
|
||||||
|
Test output: {executionResult.result}
|
||||||
|
</Typography>
|
||||||
|
: null}
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
paddingTop : 30, // maybe handle this as well?
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<button
|
||||||
style={{
|
style={{
|
||||||
paddingTop: 30,
|
color: "white",
|
||||||
paddingLeft: 10,
|
background: "#383b49",
|
||||||
|
border: "none",
|
||||||
|
height: 35,
|
||||||
|
flex: 1,
|
||||||
|
marginLeft: 5,
|
||||||
|
marginTop: 20,
|
||||||
|
cursor: "pointer"
|
||||||
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
setExpansionModalOpen(false);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span
|
Cancel
|
||||||
style={{
|
</button>
|
||||||
color: "white"
|
<button
|
||||||
}}
|
style={{
|
||||||
>
|
color: "white",
|
||||||
Expected Output
|
background: "#f85a3e",
|
||||||
</span>
|
border: "none",
|
||||||
</DialogTitle>
|
|
||||||
}
|
|
||||||
{isMobile ? null :
|
|
||||||
validation === true ?
|
|
||||||
<ReactJson
|
|
||||||
src={expOutput}
|
|
||||||
theme={theme.palette.jsonTheme}
|
|
||||||
style={{
|
|
||||||
borderRadius: 5,
|
|
||||||
border: `2px solid ${theme.palette.inputColor}`,
|
|
||||||
padding: 10,
|
|
||||||
maxHeight: 250,
|
|
||||||
minheight: 250,
|
|
||||||
overflow: "auto",
|
|
||||||
}}
|
|
||||||
collapsed={false}
|
|
||||||
enableClipboard={(copy) => {
|
|
||||||
//handleReactJsonClipboard(copy);
|
|
||||||
}}
|
|
||||||
displayDataTypes={false}
|
|
||||||
onSelect={(select) => {
|
|
||||||
//HandleJsonCopy(validate.result, select, "exec");
|
|
||||||
}}
|
|
||||||
name={"JSON autocompletion"}
|
|
||||||
/>
|
|
||||||
:
|
|
||||||
<p
|
|
||||||
id='expOutput'
|
|
||||||
style={{
|
|
||||||
whiteSpace: "pre-wrap",
|
|
||||||
color: "#f85a3e",
|
|
||||||
fontFamily: "monospace",
|
|
||||||
backgroundColor: "#282828",
|
|
||||||
padding: 20,
|
|
||||||
marginTop: -2,
|
|
||||||
border: `2px solid ${theme.palette.inputColor}`,
|
|
||||||
borderRadius: theme.palette.borderRadius,
|
|
||||||
maxHeight: 250,
|
|
||||||
overflow: "auto",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{expOutput}
|
|
||||||
</p>
|
|
||||||
}
|
|
||||||
<p
|
|
||||||
style={{
|
|
||||||
color: "white",
|
|
||||||
fontFamily: "monospace",
|
|
||||||
margin: 20,
|
|
||||||
marginTop: 30,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
JSON Validation: {validation ? "Correct" : "Incorrect"}
|
|
||||||
</p>
|
|
||||||
</div> }
|
|
||||||
|
|
||||||
<div
|
height: 35,
|
||||||
style={{
|
flex: 1,
|
||||||
display: 'flex',
|
marginLeft: 10,
|
||||||
paddingTop : 30, // maybe handle this as well?
|
marginTop: 20,
|
||||||
}}
|
cursor: "pointer"
|
||||||
>
|
}}
|
||||||
<button
|
onClick={(event) => {
|
||||||
style={{
|
// console.log(codedata)
|
||||||
color: "white",
|
// console.log(fieldCount)
|
||||||
background: "#383b49",
|
if (isFileEditor === true){
|
||||||
border: "none",
|
runUpdateText(localcodedata);
|
||||||
height: 35,
|
setcodedata(localcodedata);
|
||||||
flex: 1,
|
setExpansionModalOpen(false)
|
||||||
marginLeft: 5,
|
}
|
||||||
marginTop: 20,
|
else {
|
||||||
cursor: "pointer"
|
changeActionParameterCodeMirror(event, fieldCount, localcodedata)
|
||||||
}}
|
|
||||||
onClick={() => {
|
|
||||||
setExpansionModalOpen(false);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Cancel
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
style={{
|
|
||||||
color: "white",
|
|
||||||
background: "#f85a3e",
|
|
||||||
border: "none",
|
|
||||||
|
|
||||||
height: 35,
|
|
||||||
flex: 1,
|
|
||||||
marginLeft: 10,
|
|
||||||
marginTop: 20,
|
|
||||||
cursor: "pointer"
|
|
||||||
}}
|
|
||||||
onClick={(event) => {
|
|
||||||
// console.log(codedata)
|
|
||||||
// console.log(fieldCount)
|
|
||||||
if (isFileEditor === true){
|
|
||||||
runUpdateText(localcodedata);
|
|
||||||
setcodedata(localcodedata);
|
|
||||||
setExpansionModalOpen(false)
|
setExpansionModalOpen(false)
|
||||||
}
|
setcodedata(localcodedata)}
|
||||||
else {
|
}}
|
||||||
changeActionParameterCodeMirror(event, fieldCount, localcodedata)
|
>
|
||||||
setExpansionModalOpen(false)
|
Done
|
||||||
setcodedata(localcodedata)}
|
</button>
|
||||||
}}
|
|
||||||
>
|
|
||||||
Done
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</Dialog>)
|
</Dialog>)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4804,6 +4804,11 @@ const Admin = (props) => {
|
|||||||
<IconButton
|
<IconButton
|
||||||
style={{}}
|
style={{}}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
if (environment.Type === "cloud") {
|
||||||
|
alert.info("No Orborus necessary for environment cloud. Create and use a different environment to run executions on-premises.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const elementName = "copy_element_shuffle";
|
const elementName = "copy_element_shuffle";
|
||||||
const auth = environment.auth === "" ? 'cb5st3d3Z!3X3zaJ*Pc' : environment.auth
|
const auth = environment.auth === "" ? 'cb5st3d3Z!3X3zaJ*Pc' : environment.auth
|
||||||
const commandData = `docker run -d --volume "/var/run/docker.sock:/var/run/docker.sock" -e ENVIRONMENT_NAME="${environment.Name}" -e 'AUTH=${auth}' -e ORG="${props.userdata.active_org.id}" -e DOCKER_API_VERSION=1.40 -e BASE_URL="https://shuffler.io" ghcr.io/frikky/shuffle-orborus:latest`
|
const commandData = `docker run -d --volume "/var/run/docker.sock:/var/run/docker.sock" -e ENVIRONMENT_NAME="${environment.Name}" -e 'AUTH=${auth}' -e ORG="${props.userdata.active_org.id}" -e DOCKER_API_VERSION=1.40 -e BASE_URL="https://shuffler.io" ghcr.io/frikky/shuffle-orborus:latest`
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ import theme from '../theme';
|
|||||||
import { isMobile } from "react-device-detect"
|
import { isMobile } from "react-device-detect"
|
||||||
import aa from 'search-insights'
|
import aa from 'search-insights'
|
||||||
|
|
||||||
|
import { InstantSearch, Configure, connectSearchBox, connectHits, Index } from 'react-instantsearch-dom';
|
||||||
|
import algoliasearch from 'algoliasearch/lite';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Zoom,
|
Zoom,
|
||||||
Avatar,
|
Avatar,
|
||||||
@@ -51,6 +54,11 @@ import {
|
|||||||
SwipeableDrawer,
|
SwipeableDrawer,
|
||||||
Switch,
|
Switch,
|
||||||
Chip,
|
Chip,
|
||||||
|
Card,
|
||||||
|
List,
|
||||||
|
ListItem,
|
||||||
|
ListItemText,
|
||||||
|
ListItemAvatar,
|
||||||
} from "@material-ui/core";
|
} from "@material-ui/core";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -58,6 +66,8 @@ import {
|
|||||||
} from "@mui/material"
|
} from "@mui/material"
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
Folder as FolderIcon,
|
||||||
|
LibraryBooks as LibraryBooksIcon,
|
||||||
OpenInNew as OpenInNewIcon,
|
OpenInNew as OpenInNewIcon,
|
||||||
Undo as UndoIcon,
|
Undo as UndoIcon,
|
||||||
GetApp as GetAppIcon,
|
GetApp as GetAppIcon,
|
||||||
@@ -228,6 +238,7 @@ const svgSize = 24;
|
|||||||
//const referenceUrl = "https://shuffler.io/functions/webhooks/"
|
//const referenceUrl = "https://shuffler.io/functions/webhooks/"
|
||||||
//const referenceUrl = window.location.origin+"/api/v1/hooks/"
|
//const referenceUrl = window.location.origin+"/api/v1/hooks/"
|
||||||
|
|
||||||
|
const searchClient = algoliasearch("JNSS5CFDZZ", "db08e40265e2941b9a7d8f644b6e5240")
|
||||||
const AngularWorkflow = (defaultprops) => {
|
const AngularWorkflow = (defaultprops) => {
|
||||||
const { globalUrl, isLoggedIn, isLoaded, userdata } = defaultprops;
|
const { globalUrl, isLoggedIn, isLoaded, userdata } = defaultprops;
|
||||||
const referenceUrl = globalUrl + "/api/v1/hooks/";
|
const referenceUrl = globalUrl + "/api/v1/hooks/";
|
||||||
@@ -1287,7 +1298,7 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
if (responseJson.reason !== undefined && responseJson.reason !== null) {
|
if (responseJson.reason !== undefined && responseJson.reason !== null) {
|
||||||
alert.error("Failed to save: " + responseJson.reason);
|
alert.error("Failed to save: " + responseJson.reason);
|
||||||
} else {
|
} else {
|
||||||
alert.error("Failed to save. Please contact your admin if this is unexpected.")
|
alert.error("Failed to save. Please contact your support@shuffler.io or your local admin if this is unexpected.")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (
|
if (
|
||||||
@@ -2158,9 +2169,14 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nodedata.parameters === undefined) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const workflow_id = nodedata.parameters.find(
|
const workflow_id = nodedata.parameters.find(
|
||||||
(param) => param.name === "workflow"
|
(param) => param.name === "workflow"
|
||||||
);
|
);
|
||||||
|
|
||||||
if (workflow.id === workflow_id.valu) {
|
if (workflow.id === workflow_id.valu) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2815,10 +2831,7 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
cy.on("free", "node", (e) => onNodeDragStop(e, curaction));
|
cy.on("free", "node", (e) => onNodeDragStop(e, curaction));
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("Object: ", environments, curaction.environment)
|
|
||||||
if (environments !== undefined && environments !== null && (typeof environments === "array" || typeof environments === "object")) {
|
if (environments !== undefined && environments !== null && (typeof environments === "array" || typeof environments === "object")) {
|
||||||
console.log("Type: ", typeof(environments))
|
|
||||||
|
|
||||||
var parsedenv = environments
|
var parsedenv = environments
|
||||||
//if (typeof environments === "object") {
|
//if (typeof environments === "object") {
|
||||||
// parsedenv = [environments]
|
// parsedenv = [environments]
|
||||||
@@ -2826,13 +2839,10 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
|
|
||||||
const envs = parsedenv.find((a) => a.Name === curaction.environment);
|
const envs = parsedenv.find((a) => a.Name === curaction.environment);
|
||||||
var env = environments[defaultEnvironmentIndex]
|
var env = environments[defaultEnvironmentIndex]
|
||||||
console.log("Inner envs: ", envs, curaction.environment)
|
|
||||||
if (envs !== undefined && envs !== null) {
|
if (envs !== undefined && envs !== null) {
|
||||||
env = envs
|
env = envs
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("env: ", env)
|
|
||||||
|
|
||||||
setSelectedActionEnvironment(env);
|
setSelectedActionEnvironment(env);
|
||||||
}
|
}
|
||||||
} else if (data.type === "TRIGGER") {
|
} else if (data.type === "TRIGGER") {
|
||||||
@@ -2898,7 +2908,7 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const activateApp = (appid) => {
|
const activateApp = (appid, refresh) => {
|
||||||
fetch(globalUrl+"/api/v1/apps/"+appid+"/activate", {
|
fetch(globalUrl+"/api/v1/apps/"+appid+"/activate", {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
headers: {
|
headers: {
|
||||||
@@ -2918,7 +2928,11 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
if (responseJson.success === false) {
|
if (responseJson.success === false) {
|
||||||
alert.error("Failed to activate the app")
|
alert.error("Failed to activate the app")
|
||||||
} else {
|
} else {
|
||||||
alert.success("App activated for your organization!")
|
alert.success("App activated for your organization! Refresh the page to use the app.")
|
||||||
|
|
||||||
|
if (refresh === true) {
|
||||||
|
getApps()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
@@ -3925,7 +3939,7 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
var found = false;
|
var found = false;
|
||||||
var showEnvCnt = 0;
|
var showEnvCnt = 0;
|
||||||
for (var key in responseJson) {
|
for (var key in responseJson) {
|
||||||
if (responseJson[key].default) {
|
if (responseJson[key].default && !found) {
|
||||||
setDefaultEnvironmentIndex(key);
|
setDefaultEnvironmentIndex(key);
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
@@ -3950,7 +3964,6 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
|
|
||||||
// FIXME: Don't allow multiple in cloud yet. Cloud -> Onprem isn't stable.
|
// FIXME: Don't allow multiple in cloud yet. Cloud -> Onprem isn't stable.
|
||||||
if (isCloud) {
|
if (isCloud) {
|
||||||
console.log("Envs: ", responseJson)
|
|
||||||
if (responseJson !== undefined && responseJson !== null && responseJson.length > 0) {
|
if (responseJson !== undefined && responseJson !== null && responseJson.length > 0) {
|
||||||
setEnvironments(responseJson);
|
setEnvironments(responseJson);
|
||||||
} else {
|
} else {
|
||||||
@@ -5685,7 +5698,7 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
//const activateApp = (appid) => {
|
//const activateApp = (appid) => {
|
||||||
if (newAppData.activated === false) {
|
if (newAppData.activated === false) {
|
||||||
console.log("SHOULD ACTIVATE!")
|
console.log("SHOULD ACTIVATE!")
|
||||||
activateApp(newAppData.app_id)
|
activateApp(newAppData.app_id, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AUTHENTICATION
|
// AUTHENTICATION
|
||||||
@@ -6161,6 +6174,233 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const SearchBox = ({currentRefinement, refine, isSearchStalled, } ) => {
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (document !== undefined) {
|
||||||
|
const appsearchValue = document.getElementById("appsearch")
|
||||||
|
if (appsearchValue !== undefined && appsearchValue !== null) {
|
||||||
|
console.log("Value2: ", appsearchValue.value)
|
||||||
|
if (appsearchValue.value !== undefined && appsearchValue.value !== null && appsearchValue.value.length > 0) {
|
||||||
|
refine(appsearchValue.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form id="search_form" noValidate type="searchbox" action="" role="search" style={{margin: 0, display: "none",}} onClick={() => {
|
||||||
|
}}>
|
||||||
|
<TextField
|
||||||
|
fullWidth
|
||||||
|
style={{backgroundColor: theme.palette.inputColor, borderRadius: theme.palette.borderRadius, maxWidth: leftBarSize-20,}}
|
||||||
|
InputProps={{
|
||||||
|
style:{
|
||||||
|
color: "white",
|
||||||
|
fontSize: "1em",
|
||||||
|
height: 50,
|
||||||
|
margin: 0,
|
||||||
|
},
|
||||||
|
startAdornment: (
|
||||||
|
<InputAdornment position="start">
|
||||||
|
<SearchIcon style={{marginLeft: 5}}/>
|
||||||
|
</InputAdornment>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
autoComplete='off'
|
||||||
|
type="search"
|
||||||
|
color="primary"
|
||||||
|
placeholder="Find Public Apps, Workflows, Documentation and more"
|
||||||
|
value={currentRefinement}
|
||||||
|
id="shuffle_search_field"
|
||||||
|
onClick={(event) => {
|
||||||
|
console.log("Click!")
|
||||||
|
}}
|
||||||
|
onBlur={(event) => {
|
||||||
|
//setSearchOpen(false)
|
||||||
|
}}
|
||||||
|
onChange={(event) => {
|
||||||
|
//if (event.currentTarget.value.length > 0 && !searchOpen) {
|
||||||
|
// setSearchOpen(true)
|
||||||
|
//}
|
||||||
|
|
||||||
|
refine(event.currentTarget.value)
|
||||||
|
}}
|
||||||
|
limit={5}
|
||||||
|
/>
|
||||||
|
{/*isSearchStalled ? 'My search is stalled' : ''*/}
|
||||||
|
</form>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const AppHits = ({ hits }) => {
|
||||||
|
const [mouseHoverIndex, setMouseHoverIndex] = useState(0)
|
||||||
|
|
||||||
|
//var tmp = searchOpen
|
||||||
|
//if (!searchOpen) {
|
||||||
|
// return null
|
||||||
|
//}
|
||||||
|
|
||||||
|
const positionInfo = document.activeElement.getBoundingClientRect()
|
||||||
|
const outerlistitemStyle = {
|
||||||
|
width: "100%",
|
||||||
|
overflowX: "hidden",
|
||||||
|
overflowY: "hidden",
|
||||||
|
borderBottom: "1px solid rgba(255,255,255,0.4)",
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hits.length > 4) {
|
||||||
|
hits = hits.slice(0, 4)
|
||||||
|
}
|
||||||
|
|
||||||
|
var type = "app"
|
||||||
|
const baseImage = <LibraryBooksIcon />
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{position: "relative", marginTop: 15, marginLeft: 0, marginRight: 10, position: "absolute", color: "white", zIndex: 1001, backgroundColor: theme.palette.inputColor, minWidth: leftBarSize-10, maxWidth: leftBarSize-10, boxShadows: "none", overflowX: "hidden", }}>
|
||||||
|
<List style={{backgroundColor: theme.palette.inputColor, }}>
|
||||||
|
{hits.length === 0 ?
|
||||||
|
<ListItem style={outerlistitemStyle}>
|
||||||
|
<ListItemAvatar onClick={() => console.log(hits)}>
|
||||||
|
<Avatar>
|
||||||
|
<FolderIcon />
|
||||||
|
</Avatar>
|
||||||
|
</ListItemAvatar>
|
||||||
|
<ListItemText
|
||||||
|
primary={"No public apps found."}
|
||||||
|
secondary={"Try a broader search term"}
|
||||||
|
/>
|
||||||
|
</ListItem>
|
||||||
|
:
|
||||||
|
hits.map((hit, index) => {
|
||||||
|
const innerlistitemStyle = {
|
||||||
|
width: positionInfo.width+35,
|
||||||
|
overflowX: "hidden",
|
||||||
|
overflowY: "hidden",
|
||||||
|
borderBottom: "1px solid rgba(255,255,255,0.4)",
|
||||||
|
backgroundColor: mouseHoverIndex === index ? "#1f2023" : "inherit",
|
||||||
|
cursor: "pointer",
|
||||||
|
marginLeft: 0,
|
||||||
|
marginRight: 0,
|
||||||
|
maxHeight: 75,
|
||||||
|
minHeight: 75,
|
||||||
|
maxWidth: 420,
|
||||||
|
minWidth: "100%",
|
||||||
|
}
|
||||||
|
|
||||||
|
const name = hit.name === undefined ?
|
||||||
|
hit.filename.charAt(0).toUpperCase() + hit.filename.slice(1).replaceAll("_", " ") + " - " + hit.title :
|
||||||
|
(hit.name.charAt(0).toUpperCase()+hit.name.slice(1)).replaceAll("_", " ")
|
||||||
|
|
||||||
|
var secondaryText = hit.data !== undefined ? hit.data.slice(0, 40)+"..." : ""
|
||||||
|
const avatar = hit.image_url === undefined ?
|
||||||
|
baseImage
|
||||||
|
:
|
||||||
|
<Avatar
|
||||||
|
src={hit.image_url}
|
||||||
|
variant="rounded"
|
||||||
|
/>
|
||||||
|
|
||||||
|
//console.log(hit)
|
||||||
|
if (hit.categories !== undefined && hit.categories !== null && hit.categories.length > 0) {
|
||||||
|
secondaryText = hit.categories.slice(0,3).map((data, index) => {
|
||||||
|
if (index === 0) {
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
return ", "+data
|
||||||
|
|
||||||
|
/*
|
||||||
|
<Chip
|
||||||
|
key={index}
|
||||||
|
style={chipStyle}
|
||||||
|
label={data}
|
||||||
|
onClick={() => {
|
||||||
|
//handleChipClick
|
||||||
|
}}
|
||||||
|
variant="outlined"
|
||||||
|
color="primary"
|
||||||
|
/>
|
||||||
|
*/
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var parsedUrl = isCloud ? `/apps/${hit.objectID}` : `https://shuffler.io/apps/${hit.objectID}`
|
||||||
|
parsedUrl += `?queryID=${hit.__queryID}`
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{textDecoration: "none", color: "white",}} onClick={(event) => {
|
||||||
|
if (!isCloud) {
|
||||||
|
alert.info("Since this is an on-prem instance. You will need to activate the app yourself. Opening link to download it in a new window.")
|
||||||
|
setTimeout(() => {
|
||||||
|
event.preventDefault()
|
||||||
|
window.open(parsedUrl, '_blank')
|
||||||
|
}, 2000)
|
||||||
|
} else {
|
||||||
|
alert.info(`Activating ${name} and refreshing apps.`)
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("CLICK: ", hit)
|
||||||
|
|
||||||
|
const queryID = hit.__queryID
|
||||||
|
console.log("QUERY: ", queryID)
|
||||||
|
|
||||||
|
if (queryID !== undefined && queryID !== null) {
|
||||||
|
aa('init', {
|
||||||
|
appId: "JNSS5CFDZZ",
|
||||||
|
apiKey: "db08e40265e2941b9a7d8f644b6e5240",
|
||||||
|
})
|
||||||
|
|
||||||
|
const timestamp = new Date().getTime()
|
||||||
|
aa('sendEvents', [
|
||||||
|
{
|
||||||
|
eventType: 'conversion',
|
||||||
|
eventName: 'Public App Activated',
|
||||||
|
index: 'appsearch',
|
||||||
|
objectIDs: [hit.objectID],
|
||||||
|
timestamp: timestamp,
|
||||||
|
queryID: queryID,
|
||||||
|
userToken: userdata === undefined || userdata === null || userdata.id === undefined ? "unauthenticated" : userdata.id,
|
||||||
|
}
|
||||||
|
])
|
||||||
|
} else {
|
||||||
|
console.log("No query to handle when activating")
|
||||||
|
}
|
||||||
|
|
||||||
|
activateApp(hit.objectID, true)
|
||||||
|
}}>
|
||||||
|
<ListItem key={hit.objectID} style={innerlistitemStyle} onMouseOver={() => {
|
||||||
|
setMouseHoverIndex(index)
|
||||||
|
}}>
|
||||||
|
<ListItemAvatar>
|
||||||
|
{avatar}
|
||||||
|
</ListItemAvatar>
|
||||||
|
<ListItemText
|
||||||
|
primary={name}
|
||||||
|
secondary={secondaryText}
|
||||||
|
/>
|
||||||
|
{/*
|
||||||
|
<ListItemSecondaryAction>
|
||||||
|
<IconButton edge="end" aria-label="delete">
|
||||||
|
<DeleteIcon />
|
||||||
|
</IconButton>
|
||||||
|
</ListItemSecondaryAction>
|
||||||
|
*/}
|
||||||
|
</ListItem>
|
||||||
|
</div>
|
||||||
|
)})
|
||||||
|
}
|
||||||
|
</List>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const CustomSearchBox = connectSearchBox(SearchBox)
|
||||||
|
const CustomAppHits = connectHits(AppHits)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={appViewStyle}>
|
<div style={appViewStyle}>
|
||||||
<div style={{ flex: "1" }}>
|
<div style={{ flex: "1" }}>
|
||||||
@@ -6197,7 +6437,9 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onBlur={(event) => {
|
onBlur={(event) => {
|
||||||
console.log("BLUR: ", event.target.value);
|
|
||||||
|
//navigate(`?q=${event.target.value}`)
|
||||||
|
|
||||||
runSearch(event.target.value);
|
runSearch(event.target.value);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@@ -6232,10 +6474,21 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
) : apps.length > 0 ? (
|
) : apps.length > 0 ? (
|
||||||
<div
|
<div
|
||||||
style={{ textAlign: "center", width: leftBarSize, marginTop: 10 }}
|
style={{ textAlign: "center", width: leftBarSize, marginTop: 10 }}
|
||||||
|
onLoad={() => {
|
||||||
|
console.log("Should load in extra apps?")
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Typography variant="body1" color="textSecondary">
|
<Typography variant="body1" color="textSecondary">
|
||||||
Couldn't find app. Is it active?
|
Couldn't find an Activated app with that name. Searching unactivated apps. Click one to Activate it for your organization.
|
||||||
</Typography>
|
</Typography>
|
||||||
|
<InstantSearch searchClient={searchClient} indexName="appsearch" onClick={() => {
|
||||||
|
console.log("CLICKED")
|
||||||
|
}}>
|
||||||
|
<CustomSearchBox />
|
||||||
|
<Index indexName="appsearch">
|
||||||
|
<CustomAppHits />
|
||||||
|
</Index>
|
||||||
|
</InstantSearch>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div style={{ textAlign: "center", width: leftBarSize }}>
|
<div style={{ textAlign: "center", width: leftBarSize }}>
|
||||||
@@ -6479,6 +6732,14 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
event.target.value = event.target.value.replaceAll(".", "");
|
event.target.value = event.target.value.replaceAll(".", "");
|
||||||
event.target.value = event.target.value.replaceAll(",", "");
|
event.target.value = event.target.value.replaceAll(",", "");
|
||||||
event.target.value = event.target.value.replaceAll(" ", "_");
|
event.target.value = event.target.value.replaceAll(" ", "_");
|
||||||
|
event.target.value = event.target.value.replaceAll("^", "_");
|
||||||
|
event.target.value = event.target.value.replaceAll("'", "_");
|
||||||
|
event.target.value = event.target.value.replaceAll("\"", "_");
|
||||||
|
event.target.value = event.target.value.replaceAll("\\", "_");
|
||||||
|
event.target.value = event.target.value.replaceAll(":", "_");
|
||||||
|
event.target.value = event.target.value.replaceAll(";", "_");
|
||||||
|
event.target.value = event.target.value.replaceAll("=", "_");
|
||||||
|
event.target.value = event.target.value.replaceAll("+", "_");
|
||||||
|
|
||||||
selectedAction.label = event.target.value;
|
selectedAction.label = event.target.value;
|
||||||
setSelectedAction(selectedAction);
|
setSelectedAction(selectedAction);
|
||||||
@@ -7842,7 +8103,7 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
console.log("BRANCH: ", branch);
|
console.log("BRANCH: ", branch);
|
||||||
const startnode = branch.destination_id;
|
const startnode = branch.destination_id;
|
||||||
const scopes = "https://www.googleapis.com/auth/gmail.readonly";
|
const scopes = "https://www.googleapis.com/auth/gmail.readonly";
|
||||||
const url = `https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&prompt=consent&client_id=${client_id}&redirect_uri=${redirectUri}&response_type=code&scope=${scopes}&state=workflow_id%3D${props.match.params.key}%26trigger_id%3D${selectedTrigger.id}%26username%3D${username}%26type%3Dgmail%26start%3d${startnode}`;
|
const url = `https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&client_id=${client_id}&redirect_uri=${redirectUri}&response_type=code&scope=${scopes}&state=workflow_id%3D${props.match.params.key}%26trigger_id%3D${selectedTrigger.id}%26username%3D${username}%26type%3Dgmail%26start%3d${startnode}`;
|
||||||
console.log("URL: ", url);
|
console.log("URL: ", url);
|
||||||
|
|
||||||
var newwin = window.open(url, "", "width=800,height=600");
|
var newwin = window.open(url, "", "width=800,height=600");
|
||||||
@@ -7936,7 +8197,8 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
|
|
||||||
console.log("BRANCH: ", branch);
|
console.log("BRANCH: ", branch);
|
||||||
const startnode = branch.destination_id;
|
const startnode = branch.destination_id;
|
||||||
const url = `https://login.microsoftonline.com/common/oauth2/authorize?access_type=offline&client_id=${client_id}&redirect_uri=${redirectUri}&resource=https%3A%2F%2Fgraph.microsoft.com&response_type=code&scope=Mail.Read+User.Read+https%3A%2F%2Foutlook.office.com%2Fmail.read&prompt=login&state=workflow_id%3D${props.match.params.key}%26trigger_id%3D${selectedTrigger.id}%26username%3D${username}%26type%3Doutlook%26start%3d${startnode}`;
|
// prompt=login
|
||||||
|
const url = `https://login.microsoftonline.com/common/oauth2/authorize?access_type=offline&client_id=${client_id}&redirect_uri=${redirectUri}&resource=https%3A%2F%2Fgraph.microsoft.com&response_type=code&scope=Mail.Read+User.Read+https%3A%2F%2Foutlook.office.com%2Fmail.read&state=workflow_id%3D${props.match.params.key}%26trigger_id%3D${selectedTrigger.id}%26username%3D${username}%26type%3Doutlook%26start%3d${startnode}`;
|
||||||
//const url = `https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&prompt=consent&client_id=${client_id}&redirect_uri=${redirectUri}&response_type=code&scope=${scopes}&state=workflow_id%3D${props.match.params.key}%26trigger_id%3D${selectedTrigger.id}%26username%3D${username}%26type%3Dgmail%26start%3d${startnode}`
|
//const url = `https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&prompt=consent&client_id=${client_id}&redirect_uri=${redirectUri}&response_type=code&scope=${scopes}&state=workflow_id%3D${props.match.params.key}%26trigger_id%3D${selectedTrigger.id}%26username%3D${username}%26type%3Dgmail%26start%3d${startnode}`
|
||||||
|
|
||||||
//const scopes = "https://www.googleapis.com/auth/gmail.readonly"
|
//const scopes = "https://www.googleapis.com/auth/gmail.readonly"
|
||||||
@@ -14464,6 +14726,8 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
setWorkflow={setWorkflow}
|
setWorkflow={setWorkflow}
|
||||||
modalOpen={editWorkflowModalOpen}
|
modalOpen={editWorkflowModalOpen}
|
||||||
setModalOpen={setEditWorkflowModalOpen}
|
setModalOpen={setEditWorkflowModalOpen}
|
||||||
|
isEditing={true}
|
||||||
|
userdata={userdata}
|
||||||
/>
|
/>
|
||||||
: null}
|
: null}
|
||||||
|
|
||||||
|
|||||||
@@ -3018,6 +3018,23 @@ const AppCreator = (defaultprops) => {
|
|||||||
data["file_field"] !== null &&
|
data["file_field"] !== null &&
|
||||||
data["file_field"].length > 0) || data["example_response"] === "shuffle_file_download"
|
data["file_field"].length > 0) || data["example_response"] === "shuffle_file_download"
|
||||||
|
|
||||||
|
// In case of extremely long summaries/names from OpenAPI def
|
||||||
|
//const maxlen = 35
|
||||||
|
//if (data.description === undefined || data.description === null || data.description.length === 0) {
|
||||||
|
// if (data.name !== undefined && data.name !== null && data.name.length > maxlen ) {
|
||||||
|
// var newname = []
|
||||||
|
// for (var key in data.name.split(" ")) {
|
||||||
|
// console.log("Name: ", data.name[key])
|
||||||
|
// if (newname.join(" ").length < maxlen) {
|
||||||
|
// newname.push(data.name[key])
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// data.description = data.name.valueOf()
|
||||||
|
// data.name = newname.join(" ")
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Paper key={index} style={actionListStyle}>
|
<Paper key={index} style={actionListStyle}>
|
||||||
{error}
|
{error}
|
||||||
@@ -3031,6 +3048,16 @@ const AppCreator = (defaultprops) => {
|
|||||||
overflowX: "hidden",
|
overflowX: "hidden",
|
||||||
}}
|
}}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
console.log("Data: ", data)
|
||||||
|
if (hasFile) {
|
||||||
|
setFileUploadEnabled(true);
|
||||||
|
//setActionField("headers", "")
|
||||||
|
console.log("It has a file: ", data["file_field"])
|
||||||
|
data.headers = ""
|
||||||
|
} else {
|
||||||
|
console.log("No file")
|
||||||
|
}
|
||||||
|
|
||||||
setCurrentAction(data);
|
setCurrentAction(data);
|
||||||
setCurrentActionMethod(data.method);
|
setCurrentActionMethod(data.method);
|
||||||
setUrlPathQueries(data.queries);
|
setUrlPathQueries(data.queries);
|
||||||
@@ -3043,12 +3070,10 @@ const AppCreator = (defaultprops) => {
|
|||||||
data["body"].length > 0
|
data["body"].length > 0
|
||||||
) {
|
) {
|
||||||
findBodyParams(data["body"]);
|
findBodyParams(data["body"]);
|
||||||
}
|
} else {
|
||||||
|
console.log("No body param")
|
||||||
|
}
|
||||||
|
|
||||||
if (hasFile) {
|
|
||||||
setFileUploadEnabled(true);
|
|
||||||
setActionField("headers", "")
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div style={{ display: "flex" }}>
|
<div style={{ display: "flex" }}>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { useTheme } from "@material-ui/core/styles";
|
|||||||
import ReactMarkdown from "react-markdown";
|
import ReactMarkdown from "react-markdown";
|
||||||
import { BrowserView, MobileView } from "react-device-detect";
|
import { BrowserView, MobileView } from "react-device-detect";
|
||||||
import { useParams, useNavigate, Link } from "react-router-dom";
|
import { useParams, useNavigate, Link } from "react-router-dom";
|
||||||
|
import { isMobile } from "react-device-detect";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Grid,
|
Grid,
|
||||||
@@ -53,7 +54,7 @@ const innerHrefStyle = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const Docs = (defaultprops) => {
|
const Docs = (defaultprops) => {
|
||||||
const { globalUrl, selectedDoc, serverside, isMobile } = defaultprops;
|
const { globalUrl, selectedDoc, serverside, serverMobile } = defaultprops;
|
||||||
|
|
||||||
let navigate = useNavigate();
|
let navigate = useNavigate();
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
@@ -73,7 +74,7 @@ const Docs = (defaultprops) => {
|
|||||||
}, [])
|
}, [])
|
||||||
//console.log("PARAMS: ", params)
|
//console.log("PARAMS: ", params)
|
||||||
|
|
||||||
const [mobile, setMobile] = useState(isMobile === true ? true : false);
|
const [mobile, setMobile] = useState(serverMobile === true || isMobile === true ? true : false);
|
||||||
const [data, setData] = useState("");
|
const [data, setData] = useState("");
|
||||||
const [firstrequest, setFirstrequest] = useState(true);
|
const [firstrequest, setFirstrequest] = useState(true);
|
||||||
const [list, setList] = useState([]);
|
const [list, setList] = useState([]);
|
||||||
@@ -357,6 +358,9 @@ const Docs = (defaultprops) => {
|
|||||||
overflow: "hidden",
|
overflow: "hidden",
|
||||||
paddingBottom: 100,
|
paddingBottom: 100,
|
||||||
margin: "auto",
|
margin: "auto",
|
||||||
|
maxWidth: "100%",
|
||||||
|
minWidth: "100%",
|
||||||
|
overflow: "hidden",
|
||||||
};
|
};
|
||||||
|
|
||||||
function OuterLink(props) {
|
function OuterLink(props) {
|
||||||
@@ -542,7 +546,20 @@ const Docs = (defaultprops) => {
|
|||||||
target="_blank"
|
target="_blank"
|
||||||
style={{ textDecoration: "none", color: "inherit", flex: 1, margin: 10, }}
|
style={{ textDecoration: "none", color: "inherit", flex: 1, margin: 10, }}
|
||||||
>
|
>
|
||||||
<div style={{cursor: hover ? "pointer" : "default", borderRadius: theme.palette.borderRadius, flex: 1, border: "1px solid rgba(255,255,255,0.3)", backgroundColor: hover ? theme.palette.surfaceColor : theme.palette.inputColor, padding: 25, }} onMouseOver={() => {
|
<div style={{cursor: hover ? "pointer" : "default", borderRadius: theme.palette.borderRadius, flex: 1, border: "1px solid rgba(255,255,255,0.3)", backgroundColor: hover ? theme.palette.surfaceColor : theme.palette.inputColor, padding: 25, }}
|
||||||
|
onClick={(event) => {
|
||||||
|
if (link === "" || link === undefined) {
|
||||||
|
event.preventDefault()
|
||||||
|
console.log("IN CLICK!")
|
||||||
|
if (window.drift !== undefined) {
|
||||||
|
window.drift.api.startInteraction({ interactionId: 340043 })
|
||||||
|
} else {
|
||||||
|
console.log("Couldn't find drift in window.drift and not .drift-open-chat with querySelector: ", window.drift)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log("Link defined: ", link)
|
||||||
|
}
|
||||||
|
}} onMouseOver={() => {
|
||||||
setHover(true)
|
setHover(true)
|
||||||
}}
|
}}
|
||||||
onMouseOut={() => {
|
onMouseOut={() => {
|
||||||
@@ -607,7 +624,7 @@ const Docs = (defaultprops) => {
|
|||||||
Documentation
|
Documentation
|
||||||
</Typography>
|
</Typography>
|
||||||
<div style={{display: "flex", marginTop: 25, }}>
|
<div style={{display: "flex", marginTop: 25, }}>
|
||||||
<CustomButton title="Open a Ticket" icon=<img src="/images/Shuffle_logo_new.png" style={{height: 35, width: 35, border: "", borderRadius: theme.palette.borderRadius, }} /> link="mailto:support@shuffler.io" />
|
<CustomButton title="Talk to Support" icon=<img src="/images/Shuffle_logo_new.png" style={{height: 35, width: 35, border: "", borderRadius: theme.palette.borderRadius, }} /> />
|
||||||
<CustomButton title="Ask the community" icon=<img src="/images/social/discord.png" style={{height: 35, width: 35, border: "", borderRadius: theme.palette.borderRadius, }} /> link="https://discord.gg/B2CBzUm" />
|
<CustomButton title="Ask the community" icon=<img src="/images/social/discord.png" style={{height: 35, width: 35, border: "", borderRadius: theme.palette.borderRadius, }} /> link="https://discord.gg/B2CBzUm" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -775,7 +792,7 @@ const Docs = (defaultprops) => {
|
|||||||
id="markdown_wrapper"
|
id="markdown_wrapper"
|
||||||
escapeHtml={false}
|
escapeHtml={false}
|
||||||
source={data}
|
source={data}
|
||||||
style={{}}
|
style={{maxWidth: "100%", minWidth: "100%", }}
|
||||||
renderers={{
|
renderers={{
|
||||||
link: OuterLink,
|
link: OuterLink,
|
||||||
image: Img,
|
image: Img,
|
||||||
|
|||||||
@@ -2373,12 +2373,14 @@ const GettingStarted = (props) => {
|
|||||||
</Button>
|
</Button>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
{/*
|
||||||
<div style={{position: "fixed", bottom: 110, right: 110, display: "flex", }}>
|
<div style={{position: "fixed", bottom: 110, right: 110, display: "flex", }}>
|
||||||
<Typography variant="body1" color="textSecondary" style={{marginRight: 0, maxWidth: 150, }}>
|
<Typography variant="body1" color="textSecondary" style={{marginRight: 0, maxWidth: 150, }}>
|
||||||
Need assistance? Ask our support team (it's free!).
|
Need assistance? Ask our support team (it's free!).
|
||||||
</Typography>
|
</Typography>
|
||||||
<img src="/images/Arrow.png" style={{width: 150}} />
|
<img src="/images/Arrow.png" style={{width: 150}} />
|
||||||
</div>
|
</div>
|
||||||
|
*/}
|
||||||
</div>
|
</div>
|
||||||
{/*
|
{/*
|
||||||
<div style={flexContainerStyle}>
|
<div style={flexContainerStyle}>
|
||||||
|
|||||||
@@ -6,16 +6,14 @@ import AppGrid from "../components/AppGrid.jsx"
|
|||||||
import WorkflowGrid from "../components/WorkflowGrid.jsx"
|
import WorkflowGrid from "../components/WorkflowGrid.jsx"
|
||||||
import CreatorGrid from "../components/CreatorGrid.jsx"
|
import CreatorGrid from "../components/CreatorGrid.jsx"
|
||||||
import DocsGrid from "../components/DocsGrid.jsx"
|
import DocsGrid from "../components/DocsGrid.jsx"
|
||||||
import { useNavigate, Link } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Tabs,
|
Tabs,
|
||||||
Paper,
|
|
||||||
Tab,
|
Tab,
|
||||||
} from "@material-ui/core";
|
} from "@material-ui/core";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Business as BusinessIcon,
|
|
||||||
Apps as AppsIcon,
|
Apps as AppsIcon,
|
||||||
Polymer as PolymerIcon,
|
Polymer as PolymerIcon,
|
||||||
EmojiObjects as EmojiObjectsIcon,
|
EmojiObjects as EmojiObjectsIcon,
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ const SetAuthentication = (props) => {
|
|||||||
externalData.code = params.code
|
externalData.code = params.code
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var foundScope = ""
|
||||||
if (params.state !== undefined && params.state !== null) {
|
if (params.state !== undefined && params.state !== null) {
|
||||||
const paramsplit = params.state.split("&");
|
const paramsplit = params.state.split("&");
|
||||||
console.log(paramsplit);
|
console.log(paramsplit);
|
||||||
@@ -112,6 +113,7 @@ const SetAuthentication = (props) => {
|
|||||||
|
|
||||||
if (query[0] === "scope") {
|
if (query[0] === "scope") {
|
||||||
appAuthData.fields.push({ key: "scope", value: query[1] });
|
appAuthData.fields.push({ key: "scope", value: query[1] });
|
||||||
|
foundScope = query[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query[0] === "client_id") {
|
if (query[0] === "client_id") {
|
||||||
@@ -136,145 +138,152 @@ const SetAuthentication = (props) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (externalData.handleExternal) {
|
if (foundScope !== undefined && foundScope !== null && foundScope.length > 0) {
|
||||||
console.log("RUN EXTERNAL!!: ", externalData)
|
appAuthData.label = `${foundScope}`
|
||||||
|
}
|
||||||
fetch(globalUrl + "/api/v1/triggers/github/register", {
|
|
||||||
method: "PUT",
|
const foundTab = params["error"];
|
||||||
headers: {
|
if (foundTab !== null && foundTab !== undefined && foundTab.length > 0) {
|
||||||
"Content-Type": "application/json",
|
console.log("Found error: ", foundTab, "! Skipping Shuffle requests to validate Oauth2")
|
||||||
Accept: "application/json",
|
setFailed(true)
|
||||||
},
|
setResponse(`${foundTab}`)
|
||||||
credentials: "include",
|
} else {
|
||||||
body: JSON.stringify(externalData),
|
if (externalData.handleExternal) {
|
||||||
})
|
console.log("RUN EXTERNAL!!: ", externalData)
|
||||||
.then((response) => {
|
|
||||||
const cursearch = typeof window === "undefined" || window.location === undefined ? "" : window.location.search;
|
fetch(globalUrl + "/api/v1/triggers/github/register", {
|
||||||
const tmpView = new URLSearchParams(cursearch).get("state");
|
method: "PUT",
|
||||||
if (
|
headers: {
|
||||||
tmpView !== undefined &&
|
"Content-Type": "application/json",
|
||||||
tmpView !== null &&
|
Accept: "application/json",
|
||||||
tmpView.length > 0
|
},
|
||||||
) {
|
credentials: "include",
|
||||||
console.log("State to find app name from: ", tmpView)
|
body: JSON.stringify(externalData),
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
const cursearch = typeof window === "undefined" || window.location === undefined ? "" : window.location.search;
|
||||||
|
const tmpView = new URLSearchParams(cursearch).get("state");
|
||||||
|
if (
|
||||||
|
tmpView !== undefined &&
|
||||||
|
tmpView !== null &&
|
||||||
|
tmpView.length > 0
|
||||||
|
) {
|
||||||
|
console.log("State to find app name from: ", tmpView)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.status !== 200) {
|
||||||
|
console.log("Status not 200 for oauth2 authentication");
|
||||||
|
setFailed(true);
|
||||||
|
} else {
|
||||||
|
setFinished(true);
|
||||||
|
//setTimeout(() => {
|
||||||
|
// window.close();
|
||||||
|
//}, 2500);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then((responseJson) => {
|
||||||
|
//setUserSettings(responseJson)
|
||||||
|
console.log("Resp: ", responseJson);
|
||||||
|
|
||||||
|
if (responseJson.reason !== undefined) {
|
||||||
|
setResponse(responseJson.reason);
|
||||||
|
setFinished(true);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
const cursearch = typeof window === "undefined" || window.location === undefined ? "" : window.location.search;
|
||||||
|
var tmpView = new URLSearchParams(cursearch).get("error_description");
|
||||||
|
if (
|
||||||
|
tmpView !== undefined &&
|
||||||
|
tmpView !== null &&
|
||||||
|
tmpView.length > 0
|
||||||
|
) {
|
||||||
|
setResponse(tmpView)
|
||||||
|
} else {
|
||||||
|
tmpView = new URLSearchParams(cursearch).get("error");
|
||||||
|
if (
|
||||||
|
tmpView !== undefined &&
|
||||||
|
tmpView !== null &&
|
||||||
|
tmpView.length > 0
|
||||||
|
) {
|
||||||
|
setResponse(tmpView)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.log(error);
|
||||||
|
});
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch(globalUrl + "/api/v1/apps/authentication", {
|
||||||
|
method: "PUT",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
Accept: "application/json",
|
||||||
|
},
|
||||||
|
credentials: "include",
|
||||||
|
body: JSON.stringify(appAuthData),
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
const cursearch = typeof window === "undefined" || window.location === undefined ? "" : window.location.search;
|
||||||
|
const tmpView = new URLSearchParams(cursearch).get("state");
|
||||||
|
if (
|
||||||
|
tmpView !== undefined &&
|
||||||
|
tmpView !== null &&
|
||||||
|
tmpView.length > 0
|
||||||
|
) {
|
||||||
|
console.log("State to find app name from: ", tmpView)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.status !== 200) {
|
||||||
|
console.log("Status not 200 for oauth2 authentication");
|
||||||
|
setFailed(true);
|
||||||
|
} else {
|
||||||
|
setFinished(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
window.close();
|
||||||
|
}, 2500);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response.status !== 200) {
|
return response.json();
|
||||||
console.log("Status not 200 for oauth2 authentication");
|
})
|
||||||
setFailed(true);
|
.then((responseJson) => {
|
||||||
} else {
|
//setUserSettings(responseJson)
|
||||||
setFinished(true);
|
if (responseJson.reason !== undefined) {
|
||||||
//setTimeout(() => {
|
setResponse(responseJson.reason);
|
||||||
// window.close();
|
setFinished(true);
|
||||||
//}, 2500);
|
|
||||||
}
|
|
||||||
|
|
||||||
return response.json();
|
|
||||||
})
|
|
||||||
.then((responseJson) => {
|
|
||||||
//setUserSettings(responseJson)
|
|
||||||
console.log("Resp: ", responseJson);
|
|
||||||
|
|
||||||
if (responseJson.reason !== undefined) {
|
|
||||||
setResponse(responseJson.reason);
|
|
||||||
setFinished(true);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
const cursearch = typeof window === "undefined" || window.location === undefined ? "" : window.location.search;
|
|
||||||
var tmpView = new URLSearchParams(cursearch).get("error_description");
|
|
||||||
if (
|
|
||||||
tmpView !== undefined &&
|
|
||||||
tmpView !== null &&
|
|
||||||
tmpView.length > 0
|
|
||||||
) {
|
|
||||||
setResponse(tmpView)
|
|
||||||
} else {
|
} else {
|
||||||
tmpView = new URLSearchParams(cursearch).get("error");
|
const cursearch = typeof window === "undefined" || window.location === undefined ? "" : window.location.search;
|
||||||
if (
|
var tmpView = new URLSearchParams(cursearch).get("error_description");
|
||||||
tmpView !== undefined &&
|
if (
|
||||||
tmpView !== null &&
|
tmpView !== undefined &&
|
||||||
tmpView.length > 0
|
tmpView !== null &&
|
||||||
) {
|
tmpView.length > 0
|
||||||
|
) {
|
||||||
setResponse(tmpView)
|
setResponse(tmpView)
|
||||||
|
} else {
|
||||||
|
tmpView = new URLSearchParams(cursearch).get("error");
|
||||||
|
if (
|
||||||
|
tmpView !== undefined &&
|
||||||
|
tmpView !== null &&
|
||||||
|
tmpView.length > 0
|
||||||
|
) {
|
||||||
|
setResponse(tmpView)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(appAuthData);
|
|
||||||
|
|
||||||
fetch(globalUrl + "/api/v1/apps/authentication", {
|
|
||||||
method: "PUT",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
Accept: "application/json",
|
|
||||||
},
|
|
||||||
credentials: "include",
|
|
||||||
body: JSON.stringify(appAuthData),
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
const cursearch = typeof window === "undefined" || window.location === undefined ? "" : window.location.search;
|
|
||||||
const tmpView = new URLSearchParams(cursearch).get("state");
|
|
||||||
if (
|
|
||||||
tmpView !== undefined &&
|
|
||||||
tmpView !== null &&
|
|
||||||
tmpView.length > 0
|
|
||||||
) {
|
|
||||||
console.log("State to find app name from: ", tmpView)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response.status !== 200) {
|
|
||||||
console.log("Status not 200 for oauth2 authentication");
|
|
||||||
setFailed(true);
|
|
||||||
} else {
|
|
||||||
setFinished(true);
|
|
||||||
setTimeout(() => {
|
|
||||||
window.close();
|
|
||||||
}, 2500);
|
|
||||||
}
|
|
||||||
|
|
||||||
return response.json();
|
|
||||||
})
|
|
||||||
.then((responseJson) => {
|
|
||||||
//setUserSettings(responseJson)
|
|
||||||
console.log("Resp: ", responseJson);
|
|
||||||
|
|
||||||
if (responseJson.reason !== undefined) {
|
|
||||||
setResponse(responseJson.reason);
|
|
||||||
setFinished(true);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
const cursearch = typeof window === "undefined" || window.location === undefined ? "" : window.location.search;
|
|
||||||
var tmpView = new URLSearchParams(cursearch).get("error_description");
|
|
||||||
if (
|
|
||||||
tmpView !== undefined &&
|
|
||||||
tmpView !== null &&
|
|
||||||
tmpView.length > 0
|
|
||||||
) {
|
|
||||||
setResponse(tmpView)
|
|
||||||
} else {
|
|
||||||
tmpView = new URLSearchParams(cursearch).get("error");
|
|
||||||
if (
|
|
||||||
tmpView !== undefined &&
|
|
||||||
tmpView !== null &&
|
|
||||||
tmpView.length > 0
|
|
||||||
) {
|
|
||||||
setResponse(tmpView)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
console.log(error);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -298,6 +307,9 @@ const SetAuthentication = (props) => {
|
|||||||
)}
|
)}
|
||||||
<div />
|
<div />
|
||||||
{failed ? "Failed setup. Error: " : ""} {response}
|
{failed ? "Failed setup. Error: " : ""} {response}
|
||||||
|
<br/>
|
||||||
|
<br/>
|
||||||
|
{failed ? "If the error persists, try to use fewer scopes. Contact our support at support@shuffler.io if you need further assistance. You may close this window." : ""}
|
||||||
</Typography>
|
</Typography>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user