Added realtime Workflow stream testing for workflow collab

This commit is contained in:
frikky
2022-11-11 14:42:05 +01:00
parent 3c36da958b
commit d0ea0b9d84
+455 -134
View File
@@ -17,6 +17,10 @@ import { isMobile } from "react-device-detect"
import aa from 'search-insights' import aa from 'search-insights'
import Drift from "react-driftjs"; import Drift from "react-driftjs";
//import { Cron } from 'react-js-cron';
//import 'react-js-cron/dist/styles.css'
import { InstantSearch, Configure, connectSearchBox, connectHits, Index } from 'react-instantsearch-dom'; import { InstantSearch, Configure, connectSearchBox, connectHits, Index } from 'react-instantsearch-dom';
import algoliasearch from 'algoliasearch/lite'; import algoliasearch from 'algoliasearch/lite';
@@ -108,11 +112,13 @@ import {
} from '@mui/icons-material'; } from '@mui/icons-material';
import Autocomplete from "@material-ui/lab/Autocomplete"; import Autocomplete from "@material-ui/lab/Autocomplete";
import * as cytoscape from "cytoscape"; import * as cytoscape from "cytoscape";
import * as edgehandles from "cytoscape-edgehandles"; import * as edgehandles from "cytoscape-edgehandles";
import * as clipboard from "cytoscape-clipboard"; import * as clipboard from "cytoscape-clipboard";
import CytoscapeComponent from "react-cytoscapejs"; import CytoscapeComponent from "react-cytoscapejs";
import undoRedo from "cytoscape-undo-redo"; import undoRedo from "cytoscape-undo-redo";
import Draggable from "react-draggable"; import Draggable from "react-draggable";
import cytoscapestyle from "../defaultCytoscapeStyle"; import cytoscapestyle from "../defaultCytoscapeStyle";
@@ -276,6 +282,7 @@ const AngularWorkflow = (defaultprops) => {
const [leftViewOpen, setLeftViewOpen] = React.useState(isMobile ? false : true); const [leftViewOpen, setLeftViewOpen] = React.useState(isMobile ? false : true);
const [leftBarSize, setLeftBarSize] = React.useState(isMobile ? 0 : 350); const [leftBarSize, setLeftBarSize] = React.useState(isMobile ? 0 : 350);
const [creatorProfile, setCreatorProfile] = React.useState({}); const [creatorProfile, setCreatorProfile] = React.useState({});
const [usecases, setUsecases] = React.useState([]);
const [files, setFiles] = React.useState({ const [files, setFiles] = React.useState({
"namespaces": [ "namespaces": [
"default", "default",
@@ -354,6 +361,7 @@ const AngularWorkflow = (defaultprops) => {
const [environments, setEnvironments] = React.useState([]); const [environments, setEnvironments] = React.useState([]);
const [established, setEstablished] = React.useState(false); const [established, setEstablished] = React.useState(false);
const [setupSent, setSetupSent] = React.useState(false);
const [graphSetup, setGraphSetup] = React.useState(false); const [graphSetup, setGraphSetup] = React.useState(false);
@@ -855,7 +863,7 @@ const AngularWorkflow = (defaultprops) => {
) { ) {
setExecutionData(responseJson); setExecutionData(responseJson);
} else { } else {
console.log("NOT updating state."); //console.log("NOT updating state.");
} }
} }
} }
@@ -1039,6 +1047,7 @@ const AngularWorkflow = (defaultprops) => {
const sendStreamRequest = (body) => { const sendStreamRequest = (body) => {
console.log("Stream not activated yet.") console.log("Stream not activated yet.")
return return
// Session may be important here huh // Session may be important here huh
body.user_id = userdata.id body.user_id = userdata.id
@@ -1063,10 +1072,9 @@ const AngularWorkflow = (defaultprops) => {
console.log("RESP: ", responseJson) console.log("RESP: ", responseJson)
}) })
.catch((error) => { .catch((error) => {
console.log("Stream error: ", error.toString()) console.log("Stream send error: ", error.toString())
//alert.error(error.toString()); //alert.error(error.toString());
}) })
} }
const saveWorkflow = (curworkflow, executionArgument, startNode) => { const saveWorkflow = (curworkflow, executionArgument, startNode) => {
@@ -1302,6 +1310,13 @@ const AngularWorkflow = (defaultprops) => {
alert.error("Failed to save. Please contact your support@shuffler.io or your local 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 {
sendStreamRequest({
"item": "workflow",
"type": "save",
"id": workflow.id,
})
if ( if (
responseJson.new_id !== undefined && responseJson.new_id !== undefined &&
responseJson.new_id !== null responseJson.new_id !== null
@@ -1568,13 +1583,17 @@ const AngularWorkflow = (defaultprops) => {
} }
if (appUpdates === true) { if (appUpdates === true) {
console.log("Closing auth modal: Success")
setAuthenticationModalOpen(false); setAuthenticationModalOpen(false);
setSelectedAction(selectedAction); setSelectedAction(selectedAction);
setWorkflow(workflow); setWorkflow(workflow);
saveWorkflow(workflow); saveWorkflow(workflow);
alert.info("Added and updated authentication!"); alert.info("Added and updated authentication!");
} else { } else {
alert.error("Failed to find new authentication - did it work?"); console.log("Closing auth modal? FAIL")
alert.error("Failed to find new authentication. See details in Oauth2 popup window where auth was attempted.");
} }
} else { } else {
alert.info("No authentication to update"); alert.info("No authentication to update");
@@ -2101,6 +2120,12 @@ const AngularWorkflow = (defaultprops) => {
}); });
//console.timeEnd("UNSELECT"); //console.timeEnd("UNSELECT");
}) })
sendStreamRequest({
"item": "node",
"type": "unselect",
"userid": userdata.id,
})
//}, 150) //}, 150)
}; };
@@ -2345,6 +2370,7 @@ const AngularWorkflow = (defaultprops) => {
console.log("Node already exists - don't add descriptor node"); console.log("Node already exists - don't add descriptor node");
} }
} }
originalLocation = { originalLocation = {
x: 0, x: 0,
y: 0, y: 0,
@@ -2354,7 +2380,10 @@ const AngularWorkflow = (defaultprops) => {
"item": "node", "item": "node",
"type": "move", "type": "move",
"id": nodedata.id, "id": nodedata.id,
"location": {"x": event.target.position("x"), "y": event.target.position("y")} "location": {
"x": event.target.position("x"),
"y": event.target.position("y"),
}
}) })
}; };
@@ -2386,6 +2415,16 @@ const AngularWorkflow = (defaultprops) => {
//console.log("No appid? ", nodedata) //console.log("No appid? ", nodedata)
} }
if (nodedata.buttonType === "edgehandler") {
console.log("Enable edgehandler!")
console.log("Find parent: ", nodedata.attachedTo)
const parentNode = cy.getElementById(nodedata.attachedTo);
if (parentNode !== null && parentNode !== undefined) {
console.log("Start parentnode tracking!")
//cy.edgehandles().start(parentNode)
}
}
if (nodedata.id === selectedAction.id) { if (nodedata.id === selectedAction.id) {
return; return;
} }
@@ -2524,6 +2563,7 @@ const AngularWorkflow = (defaultprops) => {
//event.target.unselect(); //event.target.unselect();
setRightSideBarOpen(true); setRightSideBarOpen(true);
return return
} else if (data.buttonType === "copy") { } else if (data.buttonType === "copy") {
console.log("COPY!"); console.log("COPY!");
@@ -2725,7 +2765,6 @@ const AngularWorkflow = (defaultprops) => {
// curaction.app_id = curapp.id // curaction.app_id = curapp.id
// //.valueOf() // //.valueOf()
//} //}
console.log("CURAPP: ", curapp)
curaction.app_id = curapp.id curaction.app_id = curapp.id
setAuthenticationType( setAuthenticationType(
@@ -2904,6 +2943,18 @@ const AngularWorkflow = (defaultprops) => {
}); });
console.log("DOne in the node update") console.log("DOne in the node update")
sendStreamRequest({
"item": "node",
"type": "select",
"id": data.id,
"userid": userdata.id,
"location": {
"x": event.target.position("x"),
"y": event.target.position("y"),
}
})
}) })
} }
@@ -3216,7 +3267,7 @@ const AngularWorkflow = (defaultprops) => {
setLastSaved(false); setLastSaved(false);
const edge = event.target.data(); const edge = event.target.data();
console.log("edge: ", edge) console.log("edge added: ", edge)
if (edge.source === undefined && edge.target === undefined) { if (edge.source === undefined && edge.target === undefined) {
return return
} }
@@ -3232,7 +3283,7 @@ const AngularWorkflow = (defaultprops) => {
const destinationnode = cy.getElementById(edge.target) const destinationnode = cy.getElementById(edge.target)
if (sourcenode === undefined || sourcenode === null || destinationnode === undefined || destinationnode === null) { if (sourcenode === undefined || sourcenode === null || destinationnode === undefined || destinationnode === null) {
} else { } else {
console.log("Is it a trigger? If so, check if it already has a branch and remove it: ", sourcenode.data()) console.log("Edge added: Is it a trigger? If so, check if it already has a branch and remove it: ", sourcenode.data())
if (sourcenode.data("type") === "TRIGGER") { if (sourcenode.data("type") === "TRIGGER") {
if (sourcenode.data("app_name") !== "Shuffle Workflow" && sourcenode.data("app_name") !== "User Input") { if (sourcenode.data("app_name") !== "Shuffle Workflow" && sourcenode.data("app_name") !== "User Input") {
setTimeout(() => { setTimeout(() => {
@@ -3286,9 +3337,8 @@ const AngularWorkflow = (defaultprops) => {
} }
const eventTarget = event.target.target() const eventTarget = event.target.target()
console.log("BUTTON! Find parent from: ", eventTarget) console.log("BUTTON ADDED! Find parent from: ", eventTarget)
if (eventTarget.data("isButton") === true) { if (eventTarget.data("isButton") === true) {
console.log("ACTUALLY A BUTTON!")
const parentNode = cy.getElementById(eventTarget.data("attachedTo")) const parentNode = cy.getElementById(eventTarget.data("attachedTo"))
event.target.remove() event.target.remove()
console.log("Setting it to parentnode: ", parentNode.data()) console.log("Setting it to parentnode: ", parentNode.data())
@@ -3437,6 +3487,10 @@ const AngularWorkflow = (defaultprops) => {
const node = event.target; const node = event.target;
const nodedata = event.target.data(); const nodedata = event.target.data();
if (Object.keys(nodedata).length === 1) {
console.log("Check if another node actually exists before adding")
}
if (nodedata.finished === false || (nodedata.id !== undefined && nodedata.is_valid === undefined) if (nodedata.finished === false || (nodedata.id !== undefined && nodedata.is_valid === undefined)
) { ) {
//if (nodedata.app_id === undefined) { //if (nodedata.app_id === undefined) {
@@ -4335,6 +4389,28 @@ const AngularWorkflow = (defaultprops) => {
if (nodedata.type !== "COMMENT") { if (nodedata.type !== "COMMENT") {
parsedStyle.color = "white"; parsedStyle.color = "white";
//if (!event.target.data("isButton") && !event.target.data("buttonId")) {
// const px = event.target.position("x") - 0;
// const py = event.target.position("y") - 50;
// const circleId = (newNodeId = uuidv4());
// console.log("Got px, py: ", px, py)
//
// cy.add({
// group: "nodes",
// data: {
// weight: 30,
// id: circleId,
// isButton: true,
// attachedTo: event.target.data("id"),
// buttonType: "edgehandler",
// is_valid: true,
// },
// position: { x: px, y: py },
// locked: true,
// })
//}
} }
if (event.target !== undefined && event.target !== null) { if (event.target !== undefined && event.target !== null) {
@@ -4370,6 +4446,11 @@ const AngularWorkflow = (defaultprops) => {
return; return;
} }
const cytoscapeElement = document.getElementById("cytoscape_view")
if (cytoscapeElement !== undefined && cytoscapeElement !== null) {
cytoscapeElement.style.cursor = "default"
}
//event.target.removeStyle(); //event.target.removeStyle();
}; };
@@ -4384,51 +4465,81 @@ const AngularWorkflow = (defaultprops) => {
return; return;
} }
const sourcecolor = cy const cytoscapeElement = document.getElementById("cytoscape_view")
.getElementById(event.target.data("source")) if (cytoscapeElement !== undefined && cytoscapeElement !== null) {
.style("border-color"); cytoscapeElement.style.cursor = "pointer"
const targetcolor = cy }
.getElementById(event.target.data("target"))
.style("border-color");
//console.log(sourcecolor, targetcolor) //const sourcecolor = cy
if ( // .getElementById(event.target.data("source"))
sourcecolor !== null && // .style("border-color");
sourcecolor !== undefined && //const targetcolor = cy
targetcolor !== null && // .getElementById(event.target.data("target"))
targetcolor !== undefined && // .style("border-color");
!sourcecolor.includes("rgb") &&
!targetcolor.includes("rgb")
) {
console.log(sourcecolor)
console.log(targetcolor)
if (event.target !== null && event.target.value !== null) { ////console.log(sourcecolor, targetcolor)
event.target.animate({ //if (
style: { // sourcecolor !== null &&
"target-arrow-color": targetcolor, // sourcecolor !== undefined &&
"line-fill": "linear-gradient", // targetcolor !== null &&
"line-gradient-stop-colors": [sourcecolor, targetcolor], // targetcolor !== undefined &&
"line-gradient-stop-positions": [0, 1], // !sourcecolor.includes("rgb") &&
}, // !targetcolor.includes("rgb")
duration: animationDuration, //) {
}) // console.log(sourcecolor)
} else { // console.log(targetcolor)
event.target.animate({
style: {
"target-arrow-color": targetcolor,
"line-fill": "linear-gradient",
"line-gradient-stop-colors": ["#41dcab", "#41dcab"],
"line-gradient-stop-positions": [0, 1],
},
duration: animationDuration,
})
} // if (event.target !== null && event.target.value !== null) {
} // event.target.animate({
// style: {
// "target-arrow-color": targetcolor,
// "line-fill": "linear-gradient",
// "line-gradient-stop-colors": [sourcecolor, targetcolor],
// "line-gradient-stop-positions": [0, 1],
// },
// duration: animationDuration,
// })
// } else {
// event.target.animate({
// style: {
// "target-arrow-color": targetcolor,
// "line-fill": "linear-gradient",
// "line-gradient-stop-colors": ["#41dcab", "#41dcab"],
// "line-gradient-stop-positions": [0, 1],
// },
// duration: animationDuration,
// })
// }
//}
if (event.target !== undefined && event.target !== null) {
//const targetcolor = "#66a8b1"
//const parsedStyle = {
// "width": "10px",
// "font-size": "18px",
// "target-arrow-color": "#66a8b1",
// "color": "#66a8b1",
//}
//event.target.addClass("shuffle-hover-highlight");
//console.log("Style1: ", event.target)
//console.log("Style: ", event.target.style())
//event.target.animate(
// {
// style: parsedStyle,
// },
// {
// duration: animationDuration,
// }
//)
}
} }
// Thanks :) // Calculates how a trigger should curve
// Thanks to:
// https://codepen.io/guillaumethomas/pen/xxbbBKO // https://codepen.io/guillaumethomas/pen/xxbbBKO
const calculateEdgeCurve = (sourcenodePosition, destinationnodePosition) => { const calculateEdgeCurve = (sourcenodePosition, destinationnodePosition) => {
const xParsed = destinationnodePosition.x - sourcenodePosition.x const xParsed = destinationnodePosition.x - sourcenodePosition.x
@@ -4498,6 +4609,7 @@ const AngularWorkflow = (defaultprops) => {
node.position = action.position; node.position = action.position;
node.data = action; node.data = action;
node.data.id = action["id"];
node.data._id = action["id"]; node.data._id = action["id"];
node.data.type = "ACTION"; node.data.type = "ACTION";
node.isStartNode = action["id"] === workflow.start; node.isStartNode = action["id"] === workflow.start;
@@ -4560,6 +4672,7 @@ const AngularWorkflow = (defaultprops) => {
node.data = trigger; node.data = trigger;
node.data._id = trigger["id"]; node.data._id = trigger["id"];
node.data.id = trigger["id"];
node.data.type = "TRIGGER"; node.data.type = "TRIGGER";
return node; return node;
@@ -4615,13 +4728,18 @@ const AngularWorkflow = (defaultprops) => {
// This is an attempt at prettier edges. The numbers are weird to work with. // This is an attempt at prettier edges. The numbers are weird to work with.
// Bezier curves // Bezier curves
//http://manual.graphspace.org/projects/graphspace-python/en/latest/demos/edge-types.html //http://manual.graphspace.org/projects/graphspace-python/en/latest/demos/edge-types.html
const sourcenode = actions.find(node => node.data._id === branch.source_id) var sourcenode = actions.find(node => node.data._id === branch.source_id || node.data.id === branch.source_id)
const destinationnode = actions.find(node => node.data._id === branch.destination_id) var destinationnode = actions.find(node => node.data._id === branch.destination_id || node.data.id === branch.destination_id)
if (sourcenode !== undefined && destinationnode !== undefined && branch.source_id !== branch.destination_id) {
//node.data._id = action["id"]
//console.log("SOURCE: ", sourcenode.position)
//console.log("DESTINATIONNODE: ", destinationnode.position)
if (sourcenode === undefined) {
sourcenode = triggers.find(node => node.data._id === branch.source_id || node.data.id === branch.source_id)
}
if (destinationnode === undefined) {
destinationnode = triggers.find(node => node.data._id === branch.destination_id || node.data.id === branch.destination_id)
}
if (sourcenode !== undefined && destinationnode !== undefined && branch.source_id !== branch.destination_id) {
const edgeCurve = calculateEdgeCurve(sourcenode.position, destinationnode.position) const edgeCurve = calculateEdgeCurve(sourcenode.position, destinationnode.position)
edge.style = { edge.style = {
'control-point-distance': edgeCurve.distance, 'control-point-distance': edgeCurve.distance,
@@ -4753,12 +4871,53 @@ const AngularWorkflow = (defaultprops) => {
*/ */
}; };
if (isLoaded && setupSent === false) {
setSetupSent(true)
sendStreamRequest({
"item": "workflow",
"type": "enter",
"userid": userdata.id,
})
}
const fetchUsecases = () => {
fetch(globalUrl + "/api/v1/workflows/usecases", {
method: "GET",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
credentials: "include",
})
.then((response) => {
if (response.status !== 200) {
console.log("Status not 200 for usecases");
}
return response.json();
})
.then((responseJson) => {
if (responseJson.success !== false) {
console.log("Usecases: ", usecases)
setUsecases(responseJson)
} else {
}
})
.catch((error) => {
//alert.error("ERROR: " + error.toString());
console.log("ERROR getting usecases: " + error.toString());
})
}
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
//useEffect(() => { //useEffect(() => {
if (firstrequest) { if (firstrequest) {
setFirstrequest(false); setFirstrequest(false);
getWorkflow(props.match.params.key, {}); getWorkflow(props.match.params.key, {});
getApps(); getApps();
fetchUsecases()
const cursearch = const cursearch =
typeof window === "undefined" || window.location === undefined typeof window === "undefined" || window.location === undefined
@@ -4806,36 +4965,76 @@ const AngularWorkflow = (defaultprops) => {
setGraphSetup(true); setGraphSetup(true);
setupGraph(); setupGraph();
console.log("In graph setup") console.log("In graph setup")
} else if (
// 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 && authLoaded) {
!established && cy !== undefined &&
((apps !== null && apps !== undefined && apps.length > 0) || workflow.public === true) && Object.getOwnPropertyNames(workflow).length > 0 && authLoaded) {
console.log("In POST graph setup!") console.log("In POST graph setup!")
//This part has to load LAST, as it's kind of not async. //This part has to load LAST, as it's kind of not async.
//This means we need everything else to happen first. //This means we need everything else to happen first.
setEstablished(true); setEstablished(true);
// Validate if the node is just a node lol // Validate if the node is just a node lol
cy.edgehandles({
handleNodes: (el) => {
if (el.isNode() &&
!el.data("isButton") &&
!el.data("isDescriptor") &&
!el.data("isSuggestion") &&
el.data("type") !== "COMMENT") {
return true
}
return false console.log("CY grid: ", cy.gridGuide)
},
preview: false, // https://www.npmjs.com/package/cytoscape-grid-guide
toggleOffOnLeave: true, //
loopAllowed: function (node) { if (cy.gridGuide !== undefined) {
return false; cy.gridGuide({
}, gridSpacing: 30,
}); guidelinesStyle: {
strokeStyle: "#8b7d6b", // color of geometric guidelines
geometricGuidelineRange: 400, // range of geometric guidelines
range: 100, // max range of distribution guidelines
minDistRange: 10, // min range for distribution guidelines
distGuidelineOffset: 10, // shift amount of distribution guidelines
horizontalDistColor: "#ff0000", // color of horizontal distribution alignment
verticalDistColor: "#00ff00", // color of vertical distribution alignment
initPosAlignmentColor: "#0000ff", // color of alignment to initial mouse location
lineDash: [0, 0], // line style of geometric guidelines
horizontalDistLine: [0, 0], // line style of horizontal distribution guidelines
verticalDistLine: [0, 0], // line style of vertical distribution guidelines
initPosAlignmentLine: [0, 0], // line style of alignment to initial mouse position
}
})
} else {
console.log("ERROR: Failed to render grid as it's unitialized")
}
if (cy.edgehandles !== undefined) {
console.log("Inside edgehandles")
cy.edgehandles({
handleNodes: (el) => {
console.log("in handlenodes")
if (el.isNode() &&
!el.data("isButton") &&
!el.data("isDescriptor") &&
!el.data("isSuggestion") &&
el.data("type") !== "COMMENT") {
return true
}
return false
},
preview: false,
toggleOffOnLeave: true,
loopAllowed: function (node) {
return false;
},
});
//cy.edgehandles({
// preview: false,
//})
//cy.edgehandles().enable()
} else {
console.log("ERROR: Failed to initialize edgehandler")
}
// preview: true, // preview: true,
cy.fit(null, 200); cy.fit(null, 200);
@@ -6916,6 +7115,7 @@ const AngularWorkflow = (defaultprops) => {
}; };
const setTriggerCronWrapper = (value) => { const setTriggerCronWrapper = (value) => {
console.log("Cron Value: ", value)
if (selectedTrigger.parameters === null) { if (selectedTrigger.parameters === null) {
selectedTrigger.parameters = []; selectedTrigger.parameters = [];
} }
@@ -9288,7 +9488,7 @@ const AngularWorkflow = (defaultprops) => {
</Tooltip> </Tooltip>
) )
}} }}
renderInput={(params) => { renderInput={(params) => {
return ( return (
<TextField <TextField
style={{ style={{
@@ -9830,63 +10030,171 @@ const AngularWorkflow = (defaultprops) => {
placeholder={selectedTrigger.label} placeholder={selectedTrigger.label}
onChange={selectedTriggerChange} onChange={selectedTriggerChange}
/> />
<div style={{ marginTop: "20px" }}> {apps !== undefined && apps !== null && apps.length > 0 ?
<Typography>Environment</Typography> <div style={{ marginTop: 35, }}>
<Select <Autocomplete
MenuProps={{ id="action_search"
disableScrollLock: true, autoHighlight
value={selectedTrigger.app_association}
classes={{ inputRoot: classes.inputRoot }}
ListboxProps={{
style: {
backgroundColor: theme.palette.inputColor,
color: "white",
},
}}
filterOptions={(options, { inputValue }) => {
//console.log("Option contains?: ", inputValue, options)
const lowercaseValue = inputValue.toLowerCase()
options = options.filter(x => x.name.replaceAll("_", " ").toLowerCase().includes(lowercaseValue) || x.description.toLowerCase().includes(lowercaseValue))
return options
}} }}
value={selectedTrigger.environment} getOptionLabel={(option) => {
disabled={selectedTrigger.status === "running"} if (
SelectDisplayProps={{ option === undefined ||
style: { option === null ||
marginLeft: 10, option.name === undefined ||
}, option.name === null
}} ) {
fullWidth return null;
onChange={(e) => { }
selectedTrigger.environment = e.target.value;
if (e.target.value === "cloud") {
const tmpvalue = workflow.triggers[selectedTriggerIndex].parameters[0].value.split("/");
const urlpath = tmpvalue.slice(3, tmpvalue.length);
const newurl = "https://shuffler.io/" + urlpath.join("/");
workflow.triggers[selectedTriggerIndex].parameters[0].value = newurl;
} else {
const tmpvalue = workflow.triggers[selectedTriggerIndex].parameters[0].value.split("/");
const urlpath = tmpvalue.slice(3, tmpvalue.length);
const newurl = window.location.origin + "/" + urlpath.join("/");
workflow.triggers[selectedTriggerIndex].parameters[0].value = newurl;
}
console.log("New value: ", workflow.triggers[selectedTriggerIndex].parameters[0]) const newname = (
selectedTrigger.parameters[0] = workflow.triggers[selectedTriggerIndex].parameters[0] option.name.charAt(0).toUpperCase() + option.name.substring(1)
setSelectedTrigger(selectedTrigger); ).replaceAll("_", " ");
setWorkflow(workflow);
setUpdate(Math.random());
}}
style={{
backgroundColor: inputColor,
color: "white",
height: 50,
}}
>
{triggerEnvironments.map((data) => {
if (data.archived) {
return null;
}
return ( return newname;
<MenuItem }}
key={data} options={sortByKey(apps, "name")}
style={{ backgroundColor: inputColor, color: "white" }} fullWidth
value={data} style={{
> backgroundColor: theme.palette.inputColor,
{data} height: 50,
</MenuItem> borderRadius: theme.palette.borderRadius,
); }}
})} onChange={(event, newValue) => {
</Select> // Workaround with event lol
</div> console.log(event, newValue)
if (newValue !== undefined && newValue !== null) {
var parsedvalue = JSON.parse(JSON.stringify(newValue))
parsedvalue.actions = []
parsedvalue.authentication = {}
selectedTrigger.app_association = parsedvalue
setUpdate(Math.random());
}
// setNewSelectedAction({
// target: {
// value: newValue.name
// }
// });
//}
}}
renderOption={(app) => {
var appname = app.name.replaceAll("_", " ")
appname = appname.charAt(0).toUpperCase() + appname.substring(1)
return (
<Tooltip
color="secondary"
title={appname}
placement="left"
>
<div>
<div style={{ display: "flex", marginBottom: 0,}}>
<Avatar variant="rounded">
<img
alt={appname}
src={app.large_image}
style={{ width: 50, height: 50, }}
/>
</Avatar>
<Typography variant="body1" style={{marginLeft: 15, }}>
{appname}
</Typography>
</div>
</div>
</Tooltip>
)
}}
renderInput={(params) => {
return (
<TextField
color="primary"
variant="body1"
style={{
backgroundColor: theme.palette.inputColor,
borderRadius: theme.palette.borderRadius,
}}
{...params}
label="Find Associated App (optional)"
variant="outlined"
/>
);
}}
/>
</div>
: null}
{selectedTrigger.status === "running" ? null :
<div style={{ marginTop: "20px" }}>
<Typography>Environment</Typography>
<Select
MenuProps={{
disableScrollLock: true,
}}
value={selectedTrigger.environment}
disabled={selectedTrigger.status === "running"}
SelectDisplayProps={{
style: {
marginLeft: 10,
},
}}
fullWidth
onChange={(e) => {
selectedTrigger.environment = e.target.value;
if (e.target.value === "cloud") {
const tmpvalue = workflow.triggers[selectedTriggerIndex].parameters[0].value.split("/");
const urlpath = tmpvalue.slice(3, tmpvalue.length);
const newurl = "https://shuffler.io/" + urlpath.join("/");
workflow.triggers[selectedTriggerIndex].parameters[0].value = newurl;
} else {
const tmpvalue = workflow.triggers[selectedTriggerIndex].parameters[0].value.split("/");
const urlpath = tmpvalue.slice(3, tmpvalue.length);
const newurl = window.location.origin + "/" + urlpath.join("/");
workflow.triggers[selectedTriggerIndex].parameters[0].value = newurl;
}
console.log("New value: ", workflow.triggers[selectedTriggerIndex].parameters[0])
selectedTrigger.parameters[0] = workflow.triggers[selectedTriggerIndex].parameters[0]
setSelectedTrigger(selectedTrigger);
setWorkflow(workflow);
setUpdate(Math.random());
}}
style={{
backgroundColor: inputColor,
color: "white",
height: 50,
}}
>
{triggerEnvironments.map((data) => {
if (data.archived) {
return null;
}
return (
<MenuItem
key={data}
style={{ backgroundColor: inputColor, color: "white" }}
value={data}
>
{data}
</MenuItem>
);
})}
</Select>
</div>
}
<Divider <Divider
style={{ style={{
marginTop: "20px", marginTop: "20px",
@@ -10938,6 +11246,14 @@ const AngularWorkflow = (defaultprops) => {
setTriggerCronWrapper(e.target.value); setTriggerCronWrapper(e.target.value);
}} }}
/> />
{/*selectedTrigger.environment === "cloud" ?
<Cron
value={workflow.triggers[selectedTriggerIndex].parameters[0].value}
setValue={setTriggerCronWrapper}
/>
:
null
*/}
<div <div
style={{ style={{
marginTop: "20px", marginTop: "20px",
@@ -11175,6 +11491,7 @@ const AngularWorkflow = (defaultprops) => {
/> />
</div> </div>
</Menu> </Menu>
{/*
<Tooltip <Tooltip
color="secondary" color="secondary"
title="Workflow settings" title="Workflow settings"
@@ -11195,6 +11512,7 @@ const AngularWorkflow = (defaultprops) => {
</Button> </Button>
</span> </span>
</Tooltip> </Tooltip>
*/}
{isMobile ? {isMobile ?
<Tooltip <Tooltip
color="secondary" color="secondary"
@@ -14441,7 +14759,7 @@ const AngularWorkflow = (defaultprops) => {
style: { style: {
backgroundColor: surfaceColor, backgroundColor: surfaceColor,
color: "white", color: "white",
minWidth: 600, minWidth: 650,
border: theme.palette.defaultBorder, border: theme.palette.defaultBorder,
}, },
}} }}
@@ -14477,6 +14795,8 @@ const AngularWorkflow = (defaultprops) => {
newWebhook={newWebhook} newWebhook={newWebhook}
submitSchedule={submitSchedule} submitSchedule={submitSchedule}
referenceUrl={referenceUrl} referenceUrl={referenceUrl}
workflowExecutions={workflowExecutions}
getWorkflowExecution={getWorkflowExecution}
isCloud={isCloud} isCloud={isCloud}
/> />
</Dialog> </Dialog>
@@ -14735,6 +15055,7 @@ const AngularWorkflow = (defaultprops) => {
setModalOpen={setEditWorkflowModalOpen} setModalOpen={setEditWorkflowModalOpen}
isEditing={true} isEditing={true}
userdata={userdata} userdata={userdata}
usecases={usecases}
/> />
: null} : null}