More header, notifications & debugger fixes

This commit is contained in:
Frikky
2023-11-28 03:09:46 +01:00
parent ce029bfb32
commit 1373bac875
6 changed files with 271 additions and 117 deletions
+19 -41
View File
@@ -294,49 +294,26 @@ const Header = (props) => {
borderBottom: "1px solid rgba(255,255,255,0.4)", borderBottom: "1px solid rgba(255,255,255,0.4)",
}} }}
> >
{/*<Typography variant="h6"> {data.reference_url !== undefined && data.reference_url !== null && data.reference_url.length > 0 ?
{new Date(data.updated_at).toISOString()} <Link to={data.reference_url} style={{color: "#f86a3e", textDecoration: "none",}}>
</Typography >*/} <Typography variant="body1">
{data.reference_url !== undefined && {data.title} ({data.amount})
data.reference_url !== null && </Typography >
data.reference_url.length > 0 ? (
<Link
to={data.reference_url}
style={{ color: "#f86a3e", textDecoration: "none" }}
>
<Typography variant="body1">{data.title}</Typography>
</Link> </Link>
) : ( :
<Typography variant="body1" color="textSecondary"> <Typography variant="body1" color="textSecondary">
{data.title} {data.title}
</Typography> </Typography >
)} }
{data.image !== undefined && {data.image !== undefined && data.image !== null && data.image.length > 0 ?
data.image !== null && <img alt={data.title} src={data.image} style={{height: 100, width: 100, }} />
data.image.length > 0 ? ( :
<img null
alt={data.title} }
src={data.image} <Typography variant="body2" style={{marginTop: 10, maxHeight: 200, overflowX: "hidden", overflowY: "auto", }}>
style={{ height: 100, width: 100 }} {data.description}
/> </Typography >
) : null}
<Typography variant="body2">{data.description}</Typography>
{/*data.tags !== undefined && data.tags !== null && data.tags.length > 0 ?
data.tags.map((tag, index) => {
return (
<Chip
key={index}
style={chipStyle}
label={tag}
onClick={() => {
}}
variant="outlined"
color="primary"
/>
)
})
: null */}
<div style={{ display: "flex" }}> <div style={{ display: "flex" }}>
{data.read === false ? ( {data.read === false ? (
<Button <Button
@@ -429,8 +406,9 @@ const Header = (props) => {
) : null} ) : null}
</div> </div>
<Typography variant="body2"> <Typography variant="body2">
Notifications are made by Shuffle to help you discover issues or Notifications generated made by Shuffle to help you discover issues or
improvements. improvements. <a href="/docs/organizations#notifications" target="_blank" rel="noopener noreferrer" style={{color: "#f86a3e", textDecoration: "none", }}>
Learn more</a>
</Typography> </Typography>
</Paper> </Paper>
{notifications.map((data, index) => { {notifications.map((data, index) => {
+6 -2
View File
@@ -170,6 +170,7 @@ const ParsedAction = (props) => {
setEditorData, setEditorData,
setcodedata, setcodedata,
setAiQueryModalOpen,
} = props; } = props;
const classes = useStyles(); const classes = useStyles();
@@ -2913,14 +2914,17 @@ const ParsedAction = (props) => {
}} }}
disabled={autoCompleting} disabled={autoCompleting}
onClick={() => { onClick={() => {
// aiSubmit(aiMsg, undefined, undefined, newSelectedAction) //if (setAiQueryModalOpen !== undefined) {
// setAiQueryModalOpen(true)
//} else {
aiSubmit("Fill based on previous values", undefined, undefined, selectedAction) aiSubmit("Fill based on previous values", undefined, undefined, selectedAction)
//}
setAutocompleting(true) setAutocompleting(true)
}} }}
> >
<Tooltip <Tooltip
color="primary" color="primary"
title={"Autocompletes fields. Uses NAME of the action and previous values' results."} title={"Autocomplete fields. Will show a popup so that you can query how you would like to fill it in"}
placement="top" placement="top"
> >
{autoCompleting ? {autoCompleting ?
+51 -11
View File
@@ -46,11 +46,6 @@ const RuntimeDebugger = (props) => {
const classes = useStyles(); const classes = useStyles();
//const [workflowId, setWorkflowId] = useState("");
//const [status, setStatus] = useState("FINISHED");
//const [endTime, setEndTime] = useState(dayjs().subtract(0, 'day'))
//const [startTime, setStartTime] = useState(dayjs().subtract(30, 'day'))
const [workflowId, setWorkflowId] = useState("") const [workflowId, setWorkflowId] = useState("")
const [status, setStatus] = useState("") const [status, setStatus] = useState("")
const [endTime, setEndTime] = useState("") const [endTime, setEndTime] = useState("")
@@ -75,7 +70,7 @@ const RuntimeDebugger = (props) => {
const submitSearch = (workflowId, status, startTime, endTime, cursor, limit) => { const submitSearch = (workflowId, status, startTime, endTime, cursor, limit) => {
setResultRows([]) //setResultRows([])
setSearchLoading(true) setSearchLoading(true)
const fetchData = { const fetchData = {
workflow_id: workflowId, workflow_id: workflowId,
@@ -107,22 +102,29 @@ const RuntimeDebugger = (props) => {
//data.runs[key].endTimestamp = data.runs[key].ended_at.toISOString().slice(0, 19).replace('T', ' ') //data.runs[key].endTimestamp = data.runs[key].ended_at.toISOString().slice(0, 19).replace('T', ' ')
const startTimestamp = new Date(data.runs[key].started_at*1000) const startTimestamp = new Date(data.runs[key].started_at*1000)
data.runs[key].startTimestamp = startTimestamp.toISOString().slice(0, 19).replace('T', ' ') data.runs[key].startTimestamp = startTimestamp.toISOString().slice(0, 19).replace('T', ' ')
const endTimestamp = new Date(data.runs[key].completed_at*1000) const endTimestamp = new Date(data.runs[key].completed_at*1000)
data.runs[key].endTimestamp = endTimestamp.toISOString().slice(0, 19).replace('T', ' ') data.runs[key].endTimestamp = endTimestamp.toISOString().slice(0, 19).replace('T', ' ')
if (data.runs[key].completed_at === 0 || data.runs[key].completed_at === null) {
data.runs[key].endTimestamp = ""
}
} }
// Add 20 empty rows to the end of the resultRows array // Add 20 empty rows to the end of the resultRows array
// This is to make sure that the scrollbar is always visible // This is to make sure that the scrollbar is always visible
setResultRows(data.runs) setResultRows(data.runs)
} else {
toast("No results found. Keeping old runs")
} }
} else { } else {
console.error("Search error: ", data.reason) toast("Failed to search for runs. Please try again.")
} }
}) })
.catch((error) => { .catch((error) => {
setSearchLoading(false) setSearchLoading(false)
console.error("Error:", error); console.error("Error:", error);
toast("Failed to search for runs. Please try again (2)")
}) })
} }
@@ -315,13 +317,46 @@ const RuntimeDebugger = (props) => {
) )
}, },
}, },
{ field: 'startTimestamp', headerName: 'Start time (UTC)', width: 160, }, { field: 'startTimestamp', headerName: 'Start time (UTC)', width: 160,
renderCell: (params) => {
const hasError = params.row.completed_at-params.row.started_at > 300
return (
<Tooltip title={hasError ? "More than 5 minutes from start to finish" : ""} placement="top">
<span style={{cursor: "pointer", backgroundColor: !hasError ? "inherit" : "rgba(244,0,0,0.4)",}} onClick={() => {
console.log("Zoom in on end timestamp is this one: ", params.row.endTimestamp)
//setEndTimestamp(params.row.endTimestamp)
// Make a new Date() from params.row.startTimestamp and set it in the endTime
const newEndTime = new Date(params.row.startTimestamp)
if (newEndTime !== null && newEndTime !== undefined && newEndTime !== "" && newEndTime !== "Invalid Date") {
// Translate newEndTime to UTC no matter what timezone we are in. Based it on local()
// Plus 1 minute to make sure it comes in
setEndTime(dayjs(newEndTime.setMinutes(newEndTime.getMinutes()+1)))
// Use dayjs to translate it into something useful
// Remove 5 minutes from it and set startTime
//newEndTime.setMinutes(newEndTime.getMinutes()-5)
//setStartTime(dayjs(newEndTime))
}
}}>
{params.row.startTimestamp}
</span>
</Tooltip>
)
}
},
{ field: 'endTimestamp', headerName: 'End time (UTC)', width: 160, }, { field: 'endTimestamp', headerName: 'End time (UTC)', width: 160, },
{ {
field: 'id', field: 'id',
headerName: 'Explore', headerName: 'Explore',
width: 65, width: 65,
renderCell: (params) => ( renderCell: (params) => {
const parsedResult = params.row.result === null || params.row.result === undefined || params.row.result === "" ? null : params.row.result
const hasError = parsedResult !== null && parsedResult !== undefined && parsedResult !== "" ? parsedResult.includes("{%") && parsedResult.includes("%}") : false
return (
<Tooltip arrow placement="right" title={ <Tooltip arrow placement="right" title={
<Typography variant="body2" style={{whiteSpace: "pre-line", }}> <Typography variant="body2" style={{whiteSpace: "pre-line", }}>
{params.row.result !== null && params.row.result !== undefined && params.row.result !== "" ? {params.row.result !== null && params.row.result !== undefined && params.row.result !== "" ?
@@ -330,12 +365,15 @@ const RuntimeDebugger = (props) => {
null null
} }
</Typography> </Typography>
} > }>
<span style={{backgroundColor: !hasError ? "inherit" : "rgba(244,0,0,0.6)", }}>
<Link href={`/workflows/${params.row.workflow.id}?execution_id=${params.row.id}`} target="_blank" rel="noopener noreferrer"> <Link href={`/workflows/${params.row.workflow.id}?execution_id=${params.row.id}`} target="_blank" rel="noopener noreferrer">
<OpenInNewIcon fontSize="small" /> <OpenInNewIcon fontSize="small" />
</Link> </Link>
</span>
</Tooltip> </Tooltip>
), )
}
}, },
] ]
@@ -522,6 +560,7 @@ const RuntimeDebugger = (props) => {
minWidth: 240, minWidth: 240,
maxWidth: 240, maxWidth: 240,
}} }}
ampm={false}
label="Search from" label="Search from"
format="YYYY-MM-DD HH:mm:ss" format="YYYY-MM-DD HH:mm:ss"
value={startTime} value={startTime}
@@ -535,6 +574,7 @@ const RuntimeDebugger = (props) => {
minWidth: 240, minWidth: 240,
maxWidth: 240, maxWidth: 240,
}} }}
ampm={false}
label="Search until" label="Search until"
format="YYYY-MM-DD HH:mm:ss" format="YYYY-MM-DD HH:mm:ss"
value={endTime} value={endTime}
+28 -7
View File
@@ -550,7 +550,6 @@ const CodeEditor = (props) => {
var code_lines = localcodedata.split('\n') var code_lines = localcodedata.split('\n')
for (var i = 0; i < code_lines.length; i++){ for (var i = 0; i < code_lines.length; i++){
var current_code_line = code_lines[i] var current_code_line = code_lines[i]
console.log("Codeline: ", current_code_line)
var variable_occurence = current_code_line.match(/[\\]{0,1}[$]{1}([a-zA-Z0-9_-]+\.?){1}([a-zA-Z0-9#_-]+\.?){0,}/g) var variable_occurence = current_code_line.match(/[\\]{0,1}[$]{1}([a-zA-Z0-9_-]+\.?){1}([a-zA-Z0-9#_-]+\.?){0,}/g)
@@ -612,8 +611,6 @@ const CodeEditor = (props) => {
const fixedVariable = fixVariable(variable_occurence[occ]) const fixedVariable = fixVariable(variable_occurence[occ])
var correctVariable = availableVariables.includes(fixedVariable) var correctVariable = availableVariables.includes(fixedVariable)
if(!correctVariable) { if(!correctVariable) {
console.log("Line: ", i, "ch: ", dollar_occurence[occ])
value.markText({line:i, ch:dollar_occurence[occ]}, {line:i, ch:dollar_occurence_len[occ]+dollar_occurence[occ]}, {"css": "background-color: rgb(248, 106, 62, 0.9); padding-top: 2px; padding-bottom: 2px; color: white"}) value.markText({line:i, ch:dollar_occurence[occ]}, {line:i, ch:dollar_occurence_len[occ]+dollar_occurence[occ]}, {"css": "background-color: rgb(248, 106, 62, 0.9); padding-top: 2px; padding-bottom: 2px; color: white"})
} else { } else {
value.markText({line:i, ch:dollar_occurence[occ]}, {line:i, ch:dollar_occurence_len[occ]+dollar_occurence[occ]}, {"css": "background-color: #8b8e26; padding-top: 2px; padding-bottom: 2px; color: white"}) value.markText({line:i, ch:dollar_occurence[occ]}, {line:i, ch:dollar_occurence_len[occ]+dollar_occurence[occ]}, {"css": "background-color: #8b8e26; padding-top: 2px; padding-bottom: 2px; color: white"})
@@ -664,6 +661,23 @@ const CodeEditor = (props) => {
setlocalcodedata(updatedCode) setlocalcodedata(updatedCode)
} }
const fixStringInput = (new_input) => {
// Newline fixes
new_input = new_input.replace(/\r\n/g, "\\n")
new_input = new_input.replace(/\n/g, "\\n")
// Quote fixes
new_input = new_input.replace(/\\"/g, '"')
new_input = new_input.replace(/"/g, '\\"')
new_input = new_input.replace(/\\'/g, "'")
new_input = new_input.replace(/'/g, "\\'")
return new_input
}
const expectedOutput = (input) => { const expectedOutput = (input) => {
//const found = input.match(/[$]{1}([a-zA-Z0-9_-]+\.?){1}([a-zA-Z0-9#_-]+\.?){0,}/g) //const found = input.match(/[$]{1}([a-zA-Z0-9_-]+\.?){1}([a-zA-Z0-9#_-]+\.?){0,}/g)
@@ -687,20 +701,26 @@ const CodeEditor = (props) => {
valuefound = true valuefound = true
console.log("Here. Checking if we got an example?")
try { try {
if (typeof actionlist[j].example === "object") { if (typeof actionlist[j].example === "object") {
input = input.replace(found[i], JSON.stringify(actionlist[j].example), -1); input = input.replace(found[i], JSON.stringify(actionlist[j].example), -1);
} else if (actionlist[j].example.trim().startsWith("{") || actionlist[j].example.trim().startsWith("[")) { } else if (actionlist[j].example.trim().startsWith("{") || actionlist[j].example.trim().startsWith("[")) {
input = input.replace(found[i], JSON.stringify(actionlist[j].example), -1); input = input.replace(found[i], JSON.stringify(actionlist[j].example), -1);
} else { } else {
input = input.replace(found[i], actionlist[j].example, -1) console.log("This?")
const newExample = fixStringInput(actionlist[j].example)
input = input.replace(found[i], newExample, -1)
} }
} catch (e) { } catch (e) {
input = input.replace(found[i], actionlist[j].example, -1) input = input.replace(found[i], actionlist[j].example, -1)
} }
} }
//if (!valuefound) { //if (!valuefound) {
// console.log("Couldn't find value "+fixedVariable) // console.log("Couldn't find value "+fixedVariable)
//} //}
@@ -736,7 +756,10 @@ const CodeEditor = (props) => {
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 // Check if it contains any newlines, and replace them with raw newlines
new_input = fixStringInput(new_input)
// Replace quotes with nothing
} else { } else {
console.log("NO TYPE? ", typeof new_input) console.log("NO TYPE? ", typeof new_input)
try { try {
@@ -747,7 +770,6 @@ const CodeEditor = (props) => {
} }
} }
//console.log("FOUND2: ", fixedVariable, actionlist[j].example)
input = input.replace(fixedVariable, new_input, -1) input = input.replace(fixedVariable, new_input, -1)
input = input.replace(found[i], new_input, -1) input = input.replace(found[i], new_input, -1)
@@ -1430,7 +1452,6 @@ const CodeEditor = (props) => {
highlight_variables(value) highlight_variables(value)
}} }}
onChange={(value, viewUpdate) => { onChange={(value, viewUpdate) => {
console.log("Value: ", value, viewUpdate)
setlocalcodedata(value) setlocalcodedata(value)
expectedOutput(value) expectedOutput(value)
+2 -3
View File
@@ -4,11 +4,10 @@ const data = [
css: { css: {
label: "data(label)", label: "data(label)",
"text-valign": "center", "text-valign": "center",
"font-family": "font-family": "Segoe UI, Tahoma, Geneva, Verdana, sans-serif, sans-serif",
"Segoe UI, Tahoma, Geneva, Verdana, sans-serif, sans-serif",
"font-weight": "lighter", "font-weight": "lighter",
"margin-right": "10px",
"font-size": "18px", "font-size": "18px",
"margin-right": "10px",
width: "80px", width: "80px",
height: "80px", height: "80px",
color: "white", color: "white",
+133 -21
View File
@@ -112,6 +112,7 @@ import {
AutoFixHigh as AutoFixHighIcon, AutoFixHigh as AutoFixHighIcon,
Polyline as PolylineIcon, Polyline as PolylineIcon,
QueryStats as QueryStatsIcon, QueryStats as QueryStatsIcon,
AutoAwesome as AutoAwesomeIcon,
} from "@mui/icons-material"; } from "@mui/icons-material";
@@ -438,6 +439,7 @@ const AngularWorkflow = (defaultprops) => {
const [appAuthentication, setAppAuthentication] = React.useState(undefined); const [appAuthentication, setAppAuthentication] = React.useState(undefined);
const [variablesModalOpen, setVariablesModalOpen] = React.useState(false); const [variablesModalOpen, setVariablesModalOpen] = React.useState(false);
const [aiQueryModalOpen, setAiQueryModalOpen] = React.useState(false)
const [executionVariablesModalOpen, setExecutionVariablesModalOpen] = const [executionVariablesModalOpen, setExecutionVariablesModalOpen] =
React.useState(false); React.useState(false);
const [authenticationModalOpen, setAuthenticationModalOpen] = React.useState(false); const [authenticationModalOpen, setAuthenticationModalOpen] = React.useState(false);
@@ -592,17 +594,22 @@ const AngularWorkflow = (defaultprops) => {
const [elements, setElements] = useState([]); const [elements, setElements] = useState([]);
const [loopRunning, setLoopRunning] = useState(false) const [loopRunning, setLoopRunning] = useState(false)
var loopRunning2 = loopRunning
const stop = () => { const stop = () => {
setLoopRunning(false) setLoopRunning(false)
loopRunning2 = false
} }
const start = () => { const start = () => {
setLoopRunning(true) setLoopRunning(true)
loopRunning2 = true
} }
useEffect(() => { useEffect(() => {
//console.log("In useeffect for loopRunning: ", loopRunning) // Current variable + future state controlled
if (loopRunning) { // This is so that the loop can stop itself as well
console.log("In useeffect for loopRunning: ", loopRunning, loopRunning2)
if (loopRunning && loopRunning2) {
const intervalId = setInterval(() => { const intervalId = setInterval(() => {
if (!loopRunning) { if (!loopRunning) {
clearInterval(intervalId); clearInterval(intervalId);
@@ -983,19 +990,21 @@ const AngularWorkflow = (defaultprops) => {
return response.json(); return response.json();
}) })
.then((responseJson) => { .then((responseJson) => {
if (responseJson !== undefined && responseJson !== null && responseJson.executions !== undefined && responseJson.executions !== null && responseJson.executions.length > 0) { console.log("GOT A RESPONSE??")
if (responseJson !== undefined && responseJson !== null && responseJson.executions !== undefined && responseJson.executions !== null) {
// - means it's opposite // - means it's opposite
const newkeys = sortByKey(responseJson.executions, "-started_at"); const newkeys = sortByKey(responseJson.executions, "-started_at");
setWorkflowExecutions(newkeys); setWorkflowExecutions(newkeys);
const cursearch = typeof window === "undefined" || window.location === undefined ? "" : window.location.search; const cursearch = typeof window === "undefined" || window.location === undefined ? "" : window.location.search;
var tmpView = new URLSearchParams(cursearch).get("execution_id"); var tmpView = new URLSearchParams(cursearch).get("execution_id");
if (execution_id !== undefined && execution_id !== null && execution_id.length > 0 && (tmpView === undefined || tmpView === null || tmpView.length === 0)) { if (execution_id !== undefined && execution_id !== null && execution_id.length > 0 && (tmpView === undefined || tmpView === null || tmpView.length === 0)) {
tmpView = execution_id; tmpView = execution_id;
} }
console.log("EXECUTION ID: ", tmpView)
// Compare with currently selected item // Compare with currently selected item
if (tmpView !== undefined && tmpView !== null && tmpView.length > 0) { if (tmpView !== undefined && tmpView !== null && tmpView.length > 0) {
// Don't clean up if it's already open // Don't clean up if it's already open
@@ -1045,6 +1054,20 @@ const AngularWorkflow = (defaultprops) => {
stop() stop()
}, 5000); }, 5000);
} }
}
} else {
const cursearch = typeof window === "undefined" || window.location === undefined ? "" : window.location.search;
var tmpView = new URLSearchParams(cursearch).get("execution_id");
console.log("Alertnative execution id check: ", tmpView)
if (tmpView === undefined || tmpView === null || tmpView.length === 0) {
const execution_id = tmpView;
setExecutionModalView(1);
setExecutionRequest({
execution_id: execution_id,
});
start()
} }
} }
}) })
@@ -1067,8 +1090,14 @@ const AngularWorkflow = (defaultprops) => {
}) })
.then((response) => { .then((response) => {
if (response.status !== 200) { if (response.status !== 200) {
console.log("Status not 200 for stream results :O!");
stop(); stop();
setExecutionModalView(0);
toast("Failed loading the workflow run")
console.log("Status not 200 for stream results :O!");
//const cursearch = typeof window === "undefined" || window.location === undefined ? "" : window.location.search;
//const newitem = removeParam("execution_id", cursearch);
//navigate(curpath + newitem)
} }
return response.json(); return response.json();
@@ -1248,9 +1277,10 @@ const AngularWorkflow = (defaultprops) => {
// Style is in defaultCytoscapeStyle.js // Style is in defaultCytoscapeStyle.js
const handleUpdateResults = (responseJson, executionRequest) => { const handleUpdateResults = (responseJson, executionRequest) => {
if (responseJson === undefined || responseJson === null || responseJson.success === false) { if (responseJson === undefined || responseJson === null || responseJson.success === false) {
stop()
return return
} }
//console.log(responseJson) //console.log(responseJson)
// Loop nodes and find results // Loop nodes and find results
// Update on every interval? idk // Update on every interval? idk
@@ -1263,7 +1293,8 @@ const AngularWorkflow = (defaultprops) => {
//console.log("Updating data!") //console.log("Updating data!")
setExecutionData(responseJson) setExecutionData(responseJson)
} else { } else {
if (responseJson.status === "ABORTED" || responseJson.status === "STOPPED" || responseJson.status === "FAILURE" || responseJson.status === "WAITING") { if (responseJson.status === "ABORTED" || responseJson.status === "STOPPED" || responseJson.status === "FAILURE" || responseJson.status === "WAITING" || responseJson.status === "FINISHED") {
console.log("DONE!")
stop() stop()
} }
@@ -1321,6 +1352,7 @@ const AngularWorkflow = (defaultprops) => {
}) })
}; };
var streamDisabled2 = false
const sendStreamRequest = (body) => { const sendStreamRequest = (body) => {
//console.log("Stream not activated yet.") //console.log("Stream not activated yet.")
if (!isCloud) { if (!isCloud) {
@@ -1356,6 +1388,9 @@ const AngularWorkflow = (defaultprops) => {
.then((response) => { .then((response) => {
setSavingState(0); setSavingState(0);
if (response.status !== 200) { if (response.status !== 200) {
setStreamDisabled(true)
streamDisabled2 = true
//console.log("Status not 200 for stream :O!"); //console.log("Status not 200 for stream :O!");
} }
@@ -1367,6 +1402,7 @@ const AngularWorkflow = (defaultprops) => {
.catch((error) => { .catch((error) => {
console.log("Stream send error: ", error.toString()) console.log("Stream send error: ", error.toString())
setStreamDisabled(true) setStreamDisabled(true)
streamDisabled2 = true
}) })
} }
@@ -2537,6 +2573,17 @@ const AngularWorkflow = (defaultprops) => {
try { try {
var chunkJson = JSON.parse(chunk) var chunkJson = JSON.parse(chunk)
if (chunkJson.success === false) {
console.log("Chunk failed: ", chunkJson)
if (!streamDisabled) {
setStreamDisabled(true)
streamDisabled2 = true
}
return
}
if (chunkJson.item !== undefined && chunkJson.item !== null && chunkJson.item !== "") { if (chunkJson.item !== undefined && chunkJson.item !== null && chunkJson.item !== "") {
if (chunkJson.item === "node") { if (chunkJson.item === "node") {
if (chunkJson.type === "move") { if (chunkJson.type === "move") {
@@ -2561,6 +2608,13 @@ const AngularWorkflow = (defaultprops) => {
} }
} catch (e) { } catch (e) {
console.log("Chunk JSON error: ", e) console.log("Chunk JSON error: ", e)
if (!streamDisabled) {
setStreamDisabled(true)
streamDisabled2 = true
}
return
} }
//data.push(chunk) //data.push(chunk)
@@ -2619,7 +2673,7 @@ const AngularWorkflow = (defaultprops) => {
const streamUrl = "https://stream.shuffler.io" const streamUrl = "https://stream.shuffler.io"
const url = `${streamUrl}/api/v1/workflows/${workflowId}/stream` const url = `${streamUrl}/api/v1/workflows/${workflowId}/stream`
while (true) { while (true) {
if (streamDisabled) { if (streamDisabled === true || streamDisabled2 === true) {
break break
} }
@@ -3021,7 +3075,7 @@ const AngularWorkflow = (defaultprops) => {
sendStreamRequest({ sendStreamRequest({
"item": "node", "item": "node",
"type": "unselect", "type": "unselect",
"userid": userdata.id, "id": workflow.id,
}) })
//}, 150) //}, 150)
}; };
@@ -4071,7 +4125,6 @@ const AngularWorkflow = (defaultprops) => {
"item": "node", "item": "node",
"type": "select", "type": "select",
"id": data.id, "id": data.id,
"userid": userdata.id,
"location": { "location": {
"x": event.target.position("x"), "x": event.target.position("x"),
"y": event.target.position("y"), "y": event.target.position("y"),
@@ -5985,10 +6038,10 @@ const AngularWorkflow = (defaultprops) => {
const xParsed = destinationnodePosition.x - sourcenodePosition.x const xParsed = destinationnodePosition.x - sourcenodePosition.x
const yParsed = destinationnodePosition.y - sourcenodePosition.y const yParsed = destinationnodePosition.y - sourcenodePosition.y
const z = Math.sqrt(xParsed * xParsed + yParsed * yParsed); const z = Math.sqrt(xParsed * xParsed + yParsed * yParsed)
const costheta = xParsed / z; const costheta = xParsed / z
const alpha = 0.25; const alpha = 0.3
var controlPointDistance = [-alpha * yParsed * costheta, alpha * yParsed * costheta]; var controlPointDistance = [-alpha * yParsed * costheta, alpha * yParsed * costheta]
var controlPointWeight = [alpha, 1 - alpha] var controlPointWeight = [alpha, 1 - alpha]
//'control-point-weight': ['0.33', '0.66'], //'control-point-weight': ['0.33', '0.66'],
@@ -6151,8 +6204,18 @@ const AngularWorkflow = (defaultprops) => {
const foundtriggers = inputworkflow.triggers.map((trigger) => { const foundtriggers = inputworkflow.triggers.map((trigger) => {
const node = {}; const node = {};
node.position = trigger.position; node.position = trigger.position;
node.data = trigger;
if (trigger.large_image === undefined || trigger.large_image === null || trigger.large_image.length === 0) {
// Search triggers array for it where the name is matching and set image
var foundTrigger = triggers.find((t) => t.name === trigger.name)
if (foundTrigger !== undefined && foundTrigger !== null) {
console.log("Autofilled missing trigger image")
trigger.large_image = foundTrigger.large_image
}
}
node.data = trigger;
node.data._id = trigger["id"]; node.data._id = trigger["id"];
node.data.id = trigger["id"]; node.data.id = trigger["id"];
node.data.type = "TRIGGER"; node.data.type = "TRIGGER";
@@ -6394,13 +6457,13 @@ const AngularWorkflow = (defaultprops) => {
sendStreamRequest({ sendStreamRequest({
"item": "workflow", "item": "workflow",
"type": "enter", "type": "enter",
"userid": userdata.id, "id": workflow.id,
}) })
} }
const fetchRecommendations = (inputWorkflow) => { const fetchRecommendations = (inputWorkflow) => {
//console.log("Disabled recommendations") console.log("Disabled recommendations as they were too inaccurate")
//return return
const parsedWorkflow = JSON.parse(JSON.stringify(inputWorkflow)) const parsedWorkflow = JSON.parse(JSON.stringify(inputWorkflow))
@@ -6500,6 +6563,11 @@ const AngularWorkflow = (defaultprops) => {
return response.json(); return response.json();
}) })
.then((responseJson) => { .then((responseJson) => {
if (responseJson === null) {
console.log("No revisions found")
return
}
if (responseJson.success === false) { if (responseJson.success === false) {
console.log("Error getting workflow revisions: ", responseJson) console.log("Error getting workflow revisions: ", responseJson)
return return
@@ -6553,13 +6621,16 @@ const AngularWorkflow = (defaultprops) => {
} }
// App length necessary cus of cy initialization // App length necessary cus of cy initialization
if (elements.length === 0 && workflow.actions !== undefined && !graphSetup && Object.getOwnPropertyNames(workflow).length > 0 && workflowRecommendations !== undefined) { // Not using recommendations, so skipping this for now
//if (elements.length === 0 && workflow.actions !== undefined && !graphSetup && Object.getOwnPropertyNames(workflow).length > 0 && workflowRecommendations !== undefined) {
if (elements.length === 0 && workflow.actions !== undefined && !graphSetup && Object.getOwnPropertyNames(workflow).length > 0) {
setGraphSetup(true); setGraphSetup(true);
setupGraph(workflow); setupGraph(workflow);
console.log("In graph setup") console.log("In graph setup")
// 2nd load - configures cytoscape // 2nd load - configures cytoscape
} else if (!established && cy !== undefined && ((apps !== null && apps !== undefined && apps.length > 0) || workflow.public === true) && Object.getOwnPropertyNames(workflow).length > 0 && appAuthentication !== undefined && workflowRecommendations !== undefined) { //} else if (!established && cy !== undefined && ((apps !== null && apps !== undefined && apps.length > 0) || workflow.public === true) && Object.getOwnPropertyNames(workflow).length > 0 && appAuthentication !== undefined && workflowRecommendations !== undefined) {
} else if (!established && cy !== undefined && ((apps !== null && apps !== undefined && apps.length > 0) || workflow.public === true) && Object.getOwnPropertyNames(workflow).length > 0 && appAuthentication !== undefined) {
console.log("In POST graph setup!") console.log("In POST graph setup!")
@@ -9086,6 +9157,33 @@ const AngularWorkflow = (defaultprops) => {
backgroundColor: theme.palette.inputColor, backgroundColor: theme.palette.inputColor,
}; };
const aiQueryModal =
<Dialog
PaperComponent={PaperComponent}
disableEnforceFocus={true}
hideBackdrop={true}
disableBackdropClick={true}
style={{ pointerEvents: "none" }}
PaperComponent={PaperComponent}
aria-labelledby="draggable-dialog-title"
open={aiQueryModalOpen}
PaperProps={{
style: {
pointerEvents: "auto",
color: "white",
minWidth: isMobile ? "90%" : 800,
border: theme.palette.defaultBorder,
},
}}
onClose={() => {
}}
>
<DialogTitle id="draggable-dialog-title" style={{ cursor: "move", }}>
<span style={{ color: "white" }}>Condition</span>
</DialogTitle>
</Dialog>
const conditionsModal = ( const conditionsModal = (
<Dialog <Dialog
PaperComponent={PaperComponent} PaperComponent={PaperComponent}
@@ -11745,7 +11843,7 @@ const AngularWorkflow = (defaultprops) => {
}} }}
onChange={(event, newValue) => { onChange={(event, newValue) => {
// Workaround with event lol // Workaround with event lol
console.log(event, newValue) console.log("CHANGE: ", event, newValue)
if (newValue !== undefined && newValue !== null) { if (newValue !== undefined && newValue !== null) {
var parsedvalue = JSON.parse(JSON.stringify(newValue)) var parsedvalue = JSON.parse(JSON.stringify(newValue))
parsedvalue.actions = [] parsedvalue.actions = []
@@ -11772,6 +11870,7 @@ const AngularWorkflow = (defaultprops) => {
> >
<MenuItem <MenuItem
onClick={() => { onClick={() => {
console.log("CLICK: ", app)
const newValue = app const newValue = app
if (newValue !== undefined && newValue !== null) { if (newValue !== undefined && newValue !== null) {
@@ -13856,6 +13955,7 @@ const AngularWorkflow = (defaultprops) => {
expansionModalOpen={codeEditorModalOpen} expansionModalOpen={codeEditorModalOpen}
setExpansionModalOpen={setCodeEditorModalOpen} setExpansionModalOpen={setCodeEditorModalOpen}
setEditorData={setEditorData} setEditorData={setEditorData}
setAiQueryModalOpen={setAiQueryModalOpen}
/> />
} else if (Object.getOwnPropertyNames(selectedComment).length > 0) { } else if (Object.getOwnPropertyNames(selectedComment).length > 0) {
@@ -14403,6 +14503,13 @@ const AngularWorkflow = (defaultprops) => {
style={{ width: size, height: size }} style={{ width: size, height: size }}
/> />
); );
} else if (execution.execution_source === "ShuffleGPT") {
return (
<AutoAwesomeIcon
color="secondary"
style={{paddingTop: 8, paddingLeft: 4, height: 25, width: 25, }}
/>
);
} }
if ( if (
@@ -15484,6 +15591,7 @@ const AngularWorkflow = (defaultprops) => {
width: 30, width: 30,
}} }}
onClick={() => { onClick={() => {
if (cy !== undefined) {
const oldstartnode = cy.getElementById(data.action.id); const oldstartnode = cy.getElementById(data.action.id);
//console.log("FOUND NODe: ", oldstartnode) //console.log("FOUND NODe: ", oldstartnode)
if (oldstartnode !== undefined && oldstartnode !== null) { if (oldstartnode !== undefined && oldstartnode !== null) {
@@ -15497,6 +15605,9 @@ const AngularWorkflow = (defaultprops) => {
//data.action.label = "" //data.action.label = ""
setSelectedResult(data); setSelectedResult(data);
setCodeModalOpen(true); setCodeModalOpen(true);
} else {
toast("Please wait until the workflow is loaded and try again")
}
}} }}
> >
<Tooltip <Tooltip
@@ -17797,6 +17908,7 @@ const AngularWorkflow = (defaultprops) => {
{newView} {newView}
<VariablesModal variableInfo={variableInfo} setVariableInfo={setVariableInfo} /> <VariablesModal variableInfo={variableInfo} setVariableInfo={setVariableInfo} />
<ExecutionVariableModal variableInfo={variableInfo} setVariableInfo={setVariableInfo} /> <ExecutionVariableModal variableInfo={variableInfo} setVariableInfo={setVariableInfo} />
{aiQueryModal}
{conditionsModal} {conditionsModal}
{authenticationModal} {authenticationModal}
{codePopoutModal} {codePopoutModal}