Workflow bugfixes and form updates

This commit is contained in:
Frikky
2024-11-19 01:37:56 +01:00
parent 9d14078732
commit 2439f9d986
12 changed files with 525 additions and 329 deletions
-55
View File
@@ -1,55 +0,0 @@
name: Upload App SDK to PiPy
on:
workflow_dispatch: # Allows the workflow to be run manually from GitHub
inputs:
version:
description: 'Version of the package to publish'
required: true
release:
types: [published]
push:
tags:
- 'v*' # Triggers when a version tag is pushed (e.g., v1.0.0)
permissions:
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v3
with:
python-version: '3.x'
- name: Install dependencies
run: |
cd ./backend/app_sdk
python -m pip install --upgrade pip
pip install build
- name: Build package
run: |
cd ./backend/app_sdk
python -m build
- name: Move build artifacts
run: |
ls -alh
ls -alh ./backend/app_sdk
mv ./backend/app_sdk/dist ./dist
- name: Publish package
uses: pypa/gh-action-pypi-publish@v1.10.2
with:
verify-metadata: false
repository-url: https://upload.pypi.org/legacy/
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
env:
ACTIONS_STEP_DEBUG: true # Enables debug mode for this step
+10 -1
View File
@@ -464,8 +464,17 @@ const AppGrid = (props) => {
}}
>
<img
id={`image_${index}`}
alt={data.name}
src={data.image_url ? data.image_url : "/images/no_image.png"}
onError={(e) => {
// Replace the image with the default image
const foundImage = document.getElementById(`image_${index}`)
if (foundImage !== undefined && foundImage !== null) {
foundImage.src = theme.palette.defaultImage
data.image_url = theme.palette.defaultImage
}
}}
style={{
width: 80,
height: 80,
@@ -995,7 +1004,7 @@ const AppGrid = (props) => {
}}
autoComplete="off"
color="primary"
placeholder="Search your Activated or Self-built apps"
placeholder="Search your Activated or self-built apps"
id="shuffle_search_field"
onChange={(event) => {
setSearchQuery(event.currentTarget.value);
@@ -45,21 +45,21 @@ const AuthenticationItem = (props) => {
data.fields = [
{
key: "url",
value: "Secret. Replaced during app execution!",
value: "URL Secret. Replaced during runtime",
},
{
key: "client_id",
value: "Secret. Replaced during app execution!",
value: "ClientID Secret. Replaced during runtime.",
},
{
key: "client_secret",
value: "Secret. Replaced during app execution!",
value: "Client Secret. Replaced during runtime.",
},
{
key: "scope",
value: "Secret. Replaced during app execution!",
value: "Scope Secret. Replaced during runtime.",
},
];
]
}
const deleteAuthentication = (data) => {
@@ -330,8 +330,8 @@ const AuthenticationData = (props) => {
<Button
style={{ borderRadius: theme.palette?.borderRadius, marginTop: authFieldsOnly ? 20 : 0 }}
onClick={() => {
setAuthenticationOptions(authenticationOption);
handleSubmitCheck();
setAuthenticationOptions(authenticationOption)
handleSubmitCheck()
}}
variant={"contained"}
disabled={submitSuccessful}
+8 -6
View File
@@ -96,7 +96,7 @@ const AuthenticationOauth2 = (props) => {
autoAuth,
authButtonOnly,
isLoggedIn,
org_id,
setFinalized,
} = props;
@@ -148,7 +148,6 @@ const AuthenticationOauth2 = (props) => {
navigate(`/login?view=${window.location.pathname}&message=Log in to authenticate this app`)
}
console.log("Should automatically click the auto-auth button?: ", autoAuth)
if (autoAuth === true && selectedApp !== undefined) {
startOauth2Request()
}
@@ -452,6 +451,8 @@ const AuthenticationOauth2 = (props) => {
if (orgId !== undefined && orgId !== null && orgId.length > 0) {
console.log("Adding org_id from user side")
state += `%26org_id%3d${orgId}`;
}else{
state += `%26org_id%3d${org_id}`
}
if (oauth_url !== undefined && oauth_url !== null && oauth_url.length > 0) {
@@ -466,7 +467,7 @@ const AuthenticationOauth2 = (props) => {
state += `%26refresh_uri%3d${authentication_url}`
}
if (workflow.org_id !== undefined && workflow.org_id !== null && workflow.org_id.length > 0) {
if (workflow?.org_id !== undefined && workflow?.org_id !== null && workflow?.org_id.length > 0) {
state += `%26org_id%3d${workflow.org_id}`
}
@@ -835,13 +836,14 @@ const AuthenticationOauth2 = (props) => {
setOauthUrl(data.value);
}
const defaultValue = data.name === "url" && authenticationType.token_uri !== undefined && authenticationType.token_uri !== null && authenticationType.token_uri.length > 0 && (authenticationType.authorizationUrl === undefined || authenticationType.authorizationUrl === null || authenticationType.authorizationUrl.length === 0) && authenticationType.type === "oauth2-app" ? authenticationType.token_uri : data.value === undefined || data.value === null ? "" : data.value
const isNormalOauth = authenticationType.redirect_uri !== undefined && authenticationType.redirect_uri !== null && authenticationType.redirect_uri.length > 0
const defaultValue = !isNormalOauth && data.name === "url" && authenticationType.token_uri !== undefined && authenticationType.token_uri !== null && authenticationType.token_uri.length > 0 && (authenticationType.authorizationUrl === undefined || authenticationType.authorizationUrl === null || authenticationType.authorizationUrl.length === 0) && authenticationType.type === "oauth2-app" ? authenticationType.token_uri : data.value === undefined || data.value === null ? "" : data.value
const fieldname = data.name === "url" && authenticationType.grant_type !== undefined && authenticationType.grant_type !== null && authenticationType.grant_type.length > 0 && authenticationType.type === "oauth2-app" ? "Token URL" : data.name
const fieldname = !isNormalOauth && data.name === "url" && authenticationType.grant_type !== undefined && authenticationType.grant_type !== null && authenticationType.grant_type.length > 0 && authenticationType.type === "oauth2-app" ? "Token URL" : data.name
return (
<div key={index} style={{ marginTop: authenticationType.type === "oauth2-app" ? 10 : 0, }}>
<div key={index} style={{ marginTop: !isNormalOauth && authenticationType.type === "oauth2-app" ? 10 : 0, }}>
<LockOpenIcon style={{ marginRight: 10 }} />
<b>{fieldname}</b>
+61 -11
View File
@@ -192,13 +192,13 @@ const ParsedAction = (props) => {
const [selectedActionParameters, setSelectedActionParameters] = React.useState(selectedAction?.parameters || []);
const [selectedVariableParameter, setSelectedVariableParameter] = React.useState("");
const [paramUpdate, setParamUpdate] = React.useState("");
const [actionlist, setActionlist] = React.useState([]);
const [jsonList, setJsonList] = React.useState([]);
const [showDropdown, setShowDropdown] = React.useState(false);
const [showDropdownNumber, setShowDropdownNumber] = React.useState(0);
const [showAutocomplete, setShowAutocomplete] = React.useState(false);
const [menuPosition, setMenuPosition] = useState(null);
const [uiBox, setUiBox] = useState(null);
const [actionlist, setActionlist] = React.useState([]);
const [jsonList, setJsonList] = React.useState([]);
const [showDropdown, setShowDropdown] = React.useState(false);
const [showDropdownNumber, setShowDropdownNumber] = React.useState(0);
const [showAutocomplete, setShowAutocomplete] = React.useState(false);
const [menuPosition, setMenuPosition] = useState(null);
const [uiBox, setUiBox] = useState(null);
const isIntegration = selectedAction.app_id === "integration"
useEffect(() => {
@@ -207,6 +207,53 @@ const ParsedAction = (props) => {
}
}, [expansionModalOpen])
useEffect(() => {
// Changes the order of params to show in order:
// auth, required, optional
var changed = false
if (selectedActionParameters === undefined || selectedActionParameters === null || selectedActionParameters.length === 0) {
return
}
var auth = []
var required = []
var optional = []
var keyorder = []
for (let paramkey in selectedActionParameters) {
const param = selectedActionParameters[paramkey]
keyorder.push(param.name)
if (param.configuration) {
auth.push(param)
continue
}
if (param.required) {
required.push(param)
continue
}
optional.push(param)
}
// Check new keyorder
const newparams = auth.concat(required).concat(optional)
var newkeyorder = []
for (let paramkey in newparams) {
newkeyorder.push(newparams[paramkey].name)
}
if (keyorder.join(",") !== newkeyorder.join(",")) {
//toast("Changed order of params")
setSelectedActionParameters(newparams)
selectedAction.parameters = newparams
setSelectedAction(selectedAction)
}
}, [selectedActionParameters])
useEffect(() => {
if (selectedActionEnvironment === undefined || selectedActionEnvironment === null || Object.keys(selectedActionEnvironment).length === 0) {
@@ -582,8 +629,9 @@ const ParsedAction = (props) => {
}
let newParameters = selectedAction?.parameters?.map((param) => {
let paramvalue = param.value;
let paramvalue = param.value === undefined || param.value === null ? "" : param.value;
let errorVars = [];
if(paramvalue.includes("$")){
let actions = workflow.actions?.map((action) => {
return "$"+action.label?.toLowerCase();
@@ -1161,7 +1209,7 @@ const ParsedAction = (props) => {
var helperText = ""
if (name.includes("url")) {
if (value.includes("localhost") || value.includes("127.0.0.1")) {
helperText = "Can't use localhost. Please change to your external IP."
helperText = "Can't use localhost in Shuffle. Please change to server's IP."
}
}
@@ -1855,7 +1903,9 @@ const ParsedAction = (props) => {
<span>
<Button
color="primary"
style={{}}
style={{
textTransform: "none",
}}
fullWidth
variant="contained"
onClick={() => {
@@ -2832,7 +2882,7 @@ const ParsedAction = (props) => {
if (selectedAction.parameters === undefined || selectedAction.parameters === null || selectedAction.parameters.length !== selectedActionParameters.length) {
//selectedAction.parameters = selectedActionParameters
console.log("PARAM BUG - length change(?): ", selectedAction)
//console.log("PARAM BUG - length change(?): ", selectedAction)
}
//!selectedAction.auth_not_required &&
+5 -4
View File
@@ -874,10 +874,11 @@ const SearchData = props => {
</List>
</Grid>
<Grid style={{ textAlign: "end", width: "100%", textTransform: 'capitalize', }}>
<Button style={{ textAlign: "center", textTransform: 'capitalize' }}
onClick={() => { window.location = "/search"; }} >
See More
</Button>
<Link to="/search" style={{ textDecoration: "none", color: "#f85a3e" }}>
<Button style={{ textAlign: "center", textTransform: 'capitalize' }}>
See More
</Button>
</Link>
</Grid>
</Grid>
) : null
+24 -1
View File
@@ -13,6 +13,30 @@ const data = [
return elementname
},
"text-valign": "center",
"text-margin-x": function(element) {
// Attempt at bottom-positioning
// Required text-valign: bottom
// FIXME: Disabled for now.
return "15px"
const name = element.data("label")
console.log("Name: ", name)
if (name === null || name === undefined || name == "" || document=== undefined || document === null) {
return "0px"
}
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d')
context.font = '18px Segoe UI, Tahoma, Geneva, Verdana, sans-serif, sans-serif'
const textWidth = context.measureText(name).width
return textWidth + "px"
//return -1*(textWidth) + "px"
},
"font-family": "Segoe UI, Tahoma, Geneva, Verdana, sans-serif, sans-serif",
"font-weight": "lighter",
"font-size": "18px",
@@ -23,7 +47,6 @@ const data = [
padding: "10px",
margin: "5px",
"border-width": "1px",
"text-margin-x": "10px",
"z-index": 5001,
},
},
+4 -4
View File
@@ -6223,9 +6223,9 @@ If you're interested, please let me know a time that works for you, or set up a
--name="shuffle-orborus" \\
--pull=always \\
--volume "/var/run/docker.sock:/var/run/docker.sock" \\
-e AUTH="d85b017c-7f47-4d3a-bb20-9b00731bc397" \\
-e ENVIRONMENT_NAME="swarm testing" \\
-e ORG="9c4e7cd9-cfa4-457b-9ee5-3a9faa6e8c3c" \\
-e AUTH="${environment.auth}" \\
-e ENVIRONMENT_NAME="${environment.Name}" \\
-e ORG="${environment.org_id}" \\
-e SHUFFLE_WORKER_IMAGE="ghcr.io/shuffle/shuffle-worker:nightly" \\
-e SHUFFLE_SWARM_CONFIG=run \\
-e SHUFFLE_LOGS_DISABLED=true \\
@@ -6284,7 +6284,7 @@ curTab === 6 ? (
<div style={{ marginTop: 20, marginBottom: 20 }}>
<h2 style={{ display: "inline" }}>Locations</h2>
<span style={{ marginLeft: 25 }}>
Decides where to run your workflows and actions. Uses Shuffle's Orborus runner to handle queued jobs. Previously "Environments".
Decides where to run your workflows and actions. Uses Shuffle's Orborus runner to handle queued jobs onprem. Previously "Environments".
If you have scale problems, talk to our team: support@shuffler.io.&nbsp;
<a
+299 -213
View File
@@ -566,7 +566,7 @@ const AngularWorkflow = (defaultprops) => {
const releaseToConnectLabel = "Release to Connect"
const integrationApps = [{
"id": "integration",
"name": "Integration Framework",
"name": "Singul",
"type": "ACTION",
"app_version": "1.0.0",
"loop_versions": ["1.0.0"],
@@ -737,8 +737,64 @@ const releaseToConnectLabel = "Release to Connect"
}
}
if (cy !== undefined && cy !== null) {
// Check if any apps in the workflow has
cy.nodes().forEach((node) => {
const data = node.data()
if (data.app_id === foundapp.id) {
if (data.name === "tmp" && data.parameters !== undefined && data.parameters !== null && data.parameters.length === 1 && data.parameters[0].name === "tmp" && foundapp.actions !== undefined && foundapp.actions !== null && foundapp.actions.length > 0) {
const startIndex = foundapp.actions.findIndex((action) => action.category_label !== undefined && action.category_label !== null && action.category_label.length > 0)
const actionIndex = startIndex < 0 ? 0 : startIndex
node.data("name", foundapp.actions[actionIndex].name)
node.data("large_image", foundapp.large_image)
node.data("parameters", foundapp.actions[actionIndex].parameters)
node.data("finished", true)
node.data("category", foundapp.categories !== null && foundapp.categories !== undefined && foundapp.categories.length > 0 ? foundapp.categories[0] : "")
/*
name: app.actions[actionIndex].name,
label: actionLabel,
app_name: app.name,
app_version: app.app_version,
app_id: app.id,
sharing: app.sharing,
private_id: app.private_id,
description: description,
environment: parsedEnvironments,
errors: [],
finished: false,
id_: newNodeId,
_id_: newNodeId,
id: newNodeId,
is_valid: true,
type: actionType,
parameters: parameters,
isStartNode: false,
large_image: app.large_image,
run_magic_output: false,
authentication: [],
execution_variable: undefined,
example: example,
required_body_fields: app.actions[actionIndex].required_body_fields,
authentication_id: authId,
finished: false,
template: app.template === true ? true : false,
*/
toast("REPLACING ACTIONS")
}
}
})
//if (action.app_id === same && app.actions.length === 1 && app.actions[0].parameters.length === 1 && app.actions[0].parameters[0].name === "tmp") {
}
// FIXME: Add it to the existing list AND update the selected app
}
})
.catch((error) => {
console.log(`Failed side-loading app ${appId}: ${error}`)
@@ -974,7 +1030,6 @@ const releaseToConnectLabel = "Release to Connect"
if (responseJson.reason !== undefined && responseJson.reason !== undefined && responseJson.reason.length > 0) {
if (!responseJson.reason.includes("404: Not Found") && responseJson.reason.length > 25) {
// Translate <img> into markdown ![]()
const imgRegex = /<img.*?src="(.*?)"/g;
const newdata = responseJson.reason.replace(imgRegex, '![]($1)');
@@ -993,7 +1048,6 @@ const releaseToConnectLabel = "Release to Connect"
useEffect(() => {
if (authenticationModalOpen === true && selectedAction.app_name !== undefined) {
console.log(`Should get app docs for: ${selectedAction.app_name}`)
//console.log(selectedAction)
//console.log("APP: ", selectedApp)
@@ -2607,7 +2661,7 @@ const releaseToConnectLabel = "Release to Connect"
return
}
console.log("Apps loaded. JSON decoding next")
//console.log("Apps loaded. JSON decoding next")
return response.json()
})
@@ -3816,7 +3870,6 @@ const releaseToConnectLabel = "Release to Connect"
left: 0,
selected: "",
});
//console.timeEnd("UNSELECT");
})
sendStreamRequest({
@@ -4020,6 +4073,7 @@ const releaseToConnectLabel = "Release to Connect"
nodedata.app_name !== "Testing" &&
nodedata.app_name !== "Shuffle Workflow" &&
nodedata.app_name !== "Integration Framework" &&
nodedata.app_name !== "Singul" &&
nodedata.app_name !== "User Input") ||
nodedata.isStartNode)
) {
@@ -4280,13 +4334,30 @@ const releaseToConnectLabel = "Release to Connect"
}
}
}
/*
// FIXME: This is the start of a highlighter for the node
// to better match it up with other elements
// 1. Get current node's position in X/Y on the screen
// 2. Draw a red line on the X and Y axis for positioning
// Draw a red div line in the HTML
const position = event.target.position()
const redline = document.getElementById("redline")
if (redline !== null && redline !== undefined) {
redline.style.display = "block"
redline.style.position = "absolute"
redline.style.left = position.x + "px"
redline.style.top = position.y + "px"
redline.style.height = "10000px"
redline.style.width = 1
console.log("REDLINE!")
}
*/
}
if (
originalLocation.x === 0 &&
originalLocation.y === 0 &&
nodedata.position !== undefined
) {
if (originalLocation.x === 0 && originalLocation.y === 0 && nodedata.position !== undefined) {
originalLocation.x = nodedata.position.x;
originalLocation.y = nodedata.position.y;
}
@@ -5340,37 +5411,61 @@ const releaseToConnectLabel = "Release to Connect"
}
}
} else {
console.log("Should check APP if it has the same params as ACTION")
for (let actionKey in curapp.actions) {
const tmpaction = curapp.actions[actionKey]
if (tmpaction.name === curaction.name) {
console.log("Found action - needs change?", tmpaction)
if (tmpaction.parameters !== undefined && tmpaction.parameters !== null && tmpaction.parameters.length > 0) {
curaction.parameters = JSON.parse(JSON.stringify(tmpaction.parameters))
}
break
}
console.log("Should check APP if it has the same params as ACTION")
for (let actionKey in curapp.actions) {
const tmpaction = curapp.actions[actionKey]
if (tmpaction.name === curaction.name) {
console.log("Found action - needs change?", tmpaction)
if (tmpaction.parameters !== undefined && tmpaction.parameters !== null && tmpaction.parameters.length > 0) {
curaction.parameters = JSON.parse(JSON.stringify(tmpaction.parameters))
}
break
}
}
}
// Fix authentication fields that may be missing in the UI
if (curapp.authentication.required && !curapp?.authentication?.type?.includes("oauth")) {
if (curapp.authentication.parameters !== undefined && curapp.authentication.parameters !== null) {
var actionChanged = false
for (let paramKey in curapp.authentication.parameters) {
var param = curapp.authentication.parameters[paramKey]
if (curaction.parameters === undefined || curaction.parameters === null) {
curaction.parameters = []
}
var found = false
for (let actionParamKey in curaction.parameters) {
if (curaction.parameters[actionParamKey].name === param.name) {
found = true
break
}
}
//curaction["authentication"] = []
//curaction["authentication_id"] = ""
// Fix parameters that are... Not ideal
//var paramnames = []
//var newparams = []
//for (let paramKey in curaction.parameters) {
// console.log("Name: ", curaction.parameters[paramKey].name)
// if (paramnames.includes(curaction.parameters[paramKey].name)) {
// continue
// }
if (!found) {
param.configuration = true
curaction.parameters.push(param)
actionChanged = true
}
}
// paramnames.push(curaction.parameters[paramKey].name)
// newparams.push(curaction.parameters[paramKey])
//}
if (actionChanged && workflow.actions !== undefined && workflow.actions !== null) {
// Find it in the workflow and set it
for (let wfActionKey in workflow.actions) {
if (workflow.actions[wfActionKey].id === curaction.id) {
workflow.actions[wfActionKey] = curaction
}
}
//curaction.parameters = newparams
setWorkflow(workflow)
}
}
}
setSelectedApp(curapp);
setSelectedApp(curapp)
setSelectedAction(curaction);
cy.removeListener("drag");
@@ -5537,7 +5632,7 @@ const releaseToConnectLabel = "Release to Connect"
setSelectedTriggerIndex(trigger_index)
setSelectedTrigger(data)
setSelectedActionEnvironment(data.env)
//setSelectedActionEnvironment(data.env)
}, 25)
} else if (data.type === "COMMENT") {
setSelectedComment(data);
@@ -5889,7 +5984,7 @@ const releaseToConnectLabel = "Release to Connect"
const edge = event.target.data();
if (edge.source === undefined && edge.target === undefined) {
console.log("Edge added without source or target")
//console.log("Edge added without source or target")
return
}
@@ -6020,7 +6115,7 @@ const releaseToConnectLabel = "Release to Connect"
found = true
break
} else {
console.log("Old branch didn't exist afterall. Remove.")
//console.log("Old branch didn't exist afterall. Remove.")
}
}
@@ -6115,28 +6210,13 @@ const releaseToConnectLabel = "Release to Connect"
const node = event.target;
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.app_id === undefined) {
//console.log("Returning because node is not valid: ", nodedata)
return;
}
// Check for recommendations when a new action is added
// if (isLoaded === true && firstrequest === false) {
// fetchRecommendations(workflow)
// }
// DONT MOVE THIS LINE RIGHT HERE v
setLastSaved(false)
// Dont move the line above. May break stuff.
if (node.isNode() && cy.nodes().size() === 1) {
workflow.start = node.data("id");
nodedata.isStartNode = true;
@@ -6169,15 +6249,8 @@ const releaseToConnectLabel = "Release to Connect"
}
if (nodedata.type === "ACTION") {
// Should get recommendations to load in for all nodesma
// Should get recommendations to load in for all nodesma
/*
var curaction = workflow.actions.find((a) => a.id === nodedata.id);
if (curaction === null || curaction === undefined) {
toast("Node not found. Please remake it.")
event.target.remove();
}
*/
if (workflow.actions.length === 1 && workflow.actions[0].id === workflow.start) {
const newEdgeUuid = uuidv4();
const newcybranch = {
@@ -6216,11 +6289,7 @@ const releaseToConnectLabel = "Release to Connect"
}
if (
nodedata.parameters !== undefined &&
nodedata.parameters !== null &&
!nodedata.label.endsWith("_copy")
) {
if (nodedata.parameters !== undefined && nodedata.parameters !== null && !nodedata.label.endsWith("_copy")) {
var newparameters = [];
for (let [subkey,subkeyval] in Object.entries(nodedata.parameters)) {
@@ -6679,42 +6748,58 @@ const releaseToConnectLabel = "Release to Connect"
return response.json();
})
.then((responseJson) => {
var found = false;
var showEnvCnt = 0;
var found = false
var showEnvCnt = 0
for (let jsonkey in responseJson) {
if (responseJson[jsonkey].default && !found) {
setDefaultEnvironmentIndex(jsonkey);
found = true;
setDefaultEnvironmentIndex(jsonkey)
found = true
}
if (responseJson[jsonkey].archived === false) {
showEnvCnt += 1;
showEnvCnt += 1
}
}
if (showEnvCnt > 1) {
setShowEnvironment(true);
setShowEnvironment(true)
}
if (!found) {
for (let jsonkey in responseJson) {
if (!responseJson[jsonkey].archived) {
setDefaultEnvironmentIndex(jsonkey);
setDefaultEnvironmentIndex(jsonkey)
break;
}
}
}
// FIXME: Don't allow multiple in cloud yet. Cloud -> Onprem isn't stable.
if (isCloud) {
if (responseJson !== undefined && responseJson !== null && responseJson.length > 0) {
setEnvironments(responseJson);
setEnvironments(responseJson)
} else {
setEnvironments([{ Name: "Cloud", Type: "cloud" }]);
setEnvironments([{ Name: "Cloud", Type: "cloud" }])
}
} else {
setEnvironments(responseJson);
setEnvironments(responseJson)
}
/*
setTimeout(() => {
console.log("ACTIONS: ", workflow.actions)
if (workflow.actions !== undefined && workflow.actions !== null && workflow.actions.length > 0) {
for (var actionkey in workflow.actions) {
if (workflow.actions[actionkey].environment !== undefined && workflow.actions[actionkey].environment !== null && workflow.actions[actionkey].environment.length > 0) {
const env = environments.findIndex((data) => data.Name === workflow.actions[actionkey].environment)
if (env !== -1) {
setSelectedActionEnvironment(environments[env])
}
}
}
}
}, 2500)
*/
})
.catch((error) => {
//toast(error.toString());
@@ -7446,7 +7531,6 @@ const releaseToConnectLabel = "Release to Connect"
console.log("NODE UNFINISHED (hover in): ", nodedata)
// Should just be 1, so this should be fast enough :3
/*
const incomingEdges = event.target.incomers("edge").jsons()
if (incomingEdges !== undefined && incomingEdges !== null) {
for (var i = 0; i < incomingEdges.length; i++) {
@@ -7465,7 +7549,6 @@ const releaseToConnectLabel = "Release to Connect"
}
return
*/
}
@@ -7603,28 +7686,6 @@ const releaseToConnectLabel = "Release to Connect"
if (nodedata.type !== "COMMENT") {
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) {
@@ -7884,7 +7945,7 @@ const releaseToConnectLabel = "Release to Connect"
} else {
action.iconBackground = iconInfo.iconBackgroundColor;
}
} else if (action.app_name === "Integration Framework") {
} else if (action.app_name === "Integration Framework" || action.app_name === "Singul") {
const iconInfo = GetIconInfo(action)
if (iconInfo !== undefined && iconInfo !== null) {
action.fillGradient = iconInfo.fillGradient
@@ -7921,13 +7982,17 @@ const releaseToConnectLabel = "Release to Connect"
})
// What are these again? Where are they used?
const decoratorNodes = []
/*
// Removed for now as it wasn't really that helpful
const decoratorNodes = inputworkflow.actions.map((action) => {
if (!action.isStartNode) {
if (action.app_name === "Testing") {
return null
} else if (action.app_name === "Shuffle Tools") {
return null
} else if (action.app_name === "Integration Framework") {
} else if (action.app_name === "Integration Framework" || action.app_name === "Singul") {
return null
}
}
@@ -7964,6 +8029,7 @@ const releaseToConnectLabel = "Release to Connect"
}
return decoratorNode
})
*/
const foundtriggers = inputworkflow.triggers.map((trigger) => {
@@ -9509,8 +9575,22 @@ const releaseToConnectLabel = "Release to Connect"
const handleAppDrag = (e, app) => {
const cycontainer = cy.container();
console.log("APPDRAG!")
// Handling drag of public apps
if (app.objectID !== undefined && app.objectID !== null && app.objectID.length > 0) {
// FIXME: This is still buggy for now. Not allowed
return
loadAppConfig(app.objectID, undefined)
// Some arbitrary check
app.id = app.objectID
app.actions = [{
"name": "tmp",
"parameters": [{
"name": "tmp",
}]
}]
}
if (app.type === "TRIGGER") {
handleTriggerDrag(e, app)
@@ -9520,13 +9600,8 @@ const releaseToConnectLabel = "Release to Connect"
//console.log("e: ", e)
//console.log("Offset: ", cycontainer)
// Chrome lol
if (
e.pageX > cycontainer.offsetLeft &&
e.pageX < cycontainer.offsetLeft + cycontainer.offsetWidth &&
e.pageY > cycontainer.offsetTop &&
e.pageY < cycontainer.offsetTop + cycontainer.offsetHeight
) {
// HTML -> Canvas overlap check
if (e.pageX > cycontainer.offsetLeft && e.pageX < cycontainer.offsetLeft + cycontainer.offsetWidth && e.pageY > cycontainer.offsetTop && e.pageY < cycontainer.offsetTop + cycontainer.offsetHeight) {
if (newNodeId.length > 0) {
var currentnode = cy.getElementById(newNodeId);
if (
@@ -9902,8 +9977,19 @@ const releaseToConnectLabel = "Release to Connect"
>
<Grid item>
<img
alt={newAppname}
id={`image_${props?.index}`}
src={image}
onError={(e) => {
if (props.index !== undefined && props.index !== null) {
// Replace the image with the default image
const foundImage = document.getElementById(`image_${props.index}`)
if (foundImage !== undefined && foundImage !== null) {
foundImage.src = theme.palette.defaultImage
app.large_image = theme.palette.defaultImage
}
}
}}
style={{
pointerEvents: "none",
userDrag: "none",
@@ -10063,7 +10149,7 @@ const releaseToConnectLabel = "Release to Connect"
const clickedApp = (hit) => {
toast.success(`Activating App. Please wait a moment.`)
toast.success(`Activating App. Please wait a moment, and it will show up highlighted in your apps.`)
const queryID = hit.__queryID
@@ -10174,6 +10260,7 @@ const releaseToConnectLabel = "Release to Connect"
e.preventDefault()
e.stopPropagation()
handleAppDrag(e, hit)
if (!appdragged) {
clickedApp(hit)
}
@@ -10184,8 +10271,8 @@ const releaseToConnectLabel = "Release to Connect"
}}
dragging={false}
position={{
x: 0,
y: 0,
x: 0,
y: 0,
}}
>
<div style={{ textDecoration: "none", color: "white", }} onClick={(event) => {
@@ -10297,14 +10384,14 @@ const releaseToConnectLabel = "Release to Connect"
<span>
{/*<Zoom key={index} in={true} style={{ transitionDelay: `${delay}ms` }}>*/}
<div>
<ParsedAppPaper key={index} app={app} />
<ParsedAppPaper key={index} index={index} app={app} />
</div>
{/*</Zoom>*/}
</span>
:
<div key={index}>
{extraMessage}
<ParsedAppPaper key={index} app={app} />
<ParsedAppPaper key={index} index={index} app={app} />
</div>
)
})}
@@ -12728,7 +12815,7 @@ const releaseToConnectLabel = "Release to Connect"
type: "action",
id: item.id,
name: item.label,
autocomplete: `${item.label.split(" ").join("_")}`,
autocomplete: `${item?.label?.split(" ")?.join("_")}`,
example: exampledata,
}
actionlist.push(actionvalue);
@@ -14843,7 +14930,7 @@ const releaseToConnectLabel = "Release to Connect"
<div style={{ flex: "10" }}>
<b>Information</b>
<Typography variant="body2" color="textSecondary">
The information you want to show the user. Supports variables.
The information you want to show the user. Supports variables. Supports Markdown & HTML.
</Typography>
</div>
</div>
@@ -15058,7 +15145,7 @@ const releaseToConnectLabel = "Release to Connect"
style={{
backgroundColor: theme.palette.inputColor,
borderRadius: theme.palette?.borderRadius,
marginTop: 10,
marginTop: 10,
}}
InputProps={{
style: {
@@ -15092,7 +15179,7 @@ const releaseToConnectLabel = "Release to Connect"
style={{
backgroundColor: theme.palette.inputColor,
borderRadius: theme.palette?.borderRadius,
marginTop: 10,
marginTop: 10,
}}
InputProps={{
style: {
@@ -15114,9 +15201,8 @@ const releaseToConnectLabel = "Release to Connect"
/>
) : null}
</div>
<div style={{marginTop: 0, }} />
<div style={{marginTop: 50, }} />
<b>Required Input-Questions</b>
{workflow.input_questions !== undefined && workflow.input_questions !== null && workflow.input_questions.length > 0 ?
<div>
@@ -15174,6 +15260,7 @@ const releaseToConnectLabel = "Release to Connect"
<Typography variant="body2">No Input-Questions found. Click to add them!</Typography>
</div>
}
</div>
</div>
const defaultEnvironment = environments.find(
@@ -15876,71 +15963,77 @@ const releaseToConnectLabel = "Release to Connect"
getFiles(e.target.value)
listOrgCache(e.target.value)
if (e.target.value === originalWorkflow.org_id) {
console.log("Original org selected. No change.")
updateCurrentWorkflow(originalWorkflow)
return
} else {
// Load environments, auth, auth groups
//toast("Loading correct info for suborg")
}
// FIXME: There is a timing problem here.
// For events to have the data they need, they
// need to be registered with setupGraph()
// AFTER all the APIs are done
// Should look through childorg workflow
console.log("Original: ", originalWorkflow)
if (originalWorkflow.childorg_workflow_ids === undefined || originalWorkflow.childorg_workflow_ids === null || originalWorkflow.childorg_workflow_ids.length === 0) {
console.log("In childorg doesn't exist. Suborgworkflows: ", suborgWorkflows)
setTimeout(() => {
if (e.target.value === originalWorkflow.org_id) {
console.log("Original org selected. No change.")
if (suborgWorkflows !== undefined && suborgWorkflows !== null && suborgWorkflows.length > 0) {
var found = false
for (var suborgkey in suborgWorkflows) {
const suborgWorkflow = suborgWorkflows[suborgkey]
if (suborgWorkflow.org_id === e.target.value) {
found = true
updateCurrentWorkflow(suborgWorkflow)
break
updateCurrentWorkflow(originalWorkflow)
return
} else {
// Load environments, auth, auth groups
//toast("Loading correct info for suborg")
}
console.log("Original: ", originalWorkflow)
if (originalWorkflow.childorg_workflow_ids === undefined || originalWorkflow.childorg_workflow_ids === null || originalWorkflow.childorg_workflow_ids.length === 0) {
console.log("In childorg doesn't exist. Suborgworkflows: ", suborgWorkflows)
if (suborgWorkflows !== undefined && suborgWorkflows !== null && suborgWorkflows.length > 0) {
var found = false
for (var suborgkey in suborgWorkflows) {
const suborgWorkflow = suborgWorkflows[suborgkey]
if (suborgWorkflow.org_id === e.target.value) {
found = true
updateCurrentWorkflow(suborgWorkflow)
break
}
}
}
if (!found) {
toast("(3) Creating new workflow for this org. Please wait a second while we duplicate.")
//console.log("No workflow found out of suborg workflows.")
//saveWorkflow(originalWorkflow, undefined, undefined, e.target.value)
if (!found) {
toast("(3) Creating new workflow for this org. Please wait a second while we duplicate.")
//console.log("No workflow found out of suborg workflows.")
//saveWorkflow(originalWorkflow, undefined, undefined, e.target.value)
}
} else {
console.log("Suborgworkflows: ", suborgWorkflows)
toast("(1) Loading NEW workflow for this org (?). Please wait a second.")
saveWorkflow(originalWorkflow, undefined, undefined, e.target.value)
}
} else {
console.log("Suborgworkflows: ", suborgWorkflows)
toast("(1) Loading NEW workflow for this org (?). Please wait a second.")
saveWorkflow(originalWorkflow, undefined, undefined, e.target.value)
}
} else {
console.log("In childorg EXIST!")
console.log("In childorg EXIST!")
var workflowFound = false
for (var childorgidkey in originalWorkflow.childorg_workflow_ids) {
const childworkflowid = originalWorkflow.childorg_workflow_ids[childorgidkey]
for (var suborgWorkflowKey in suborgWorkflows) {
const suborgWorkflow = suborgWorkflows[suborgWorkflowKey]
if (suborgWorkflow.org_id === e.target.value) {
workflowFound = true
var workflowFound = false
for (var childorgidkey in originalWorkflow.childorg_workflow_ids) {
const childworkflowid = originalWorkflow.childorg_workflow_ids[childorgidkey]
for (var suborgWorkflowKey in suborgWorkflows) {
const suborgWorkflow = suborgWorkflows[suborgWorkflowKey]
if (suborgWorkflow.org_id === e.target.value) {
workflowFound = true
updateCurrentWorkflow(suborgWorkflow)
updateCurrentWorkflow(suborgWorkflow)
break
}
}
if (workflowFound) {
break
}
}
if (workflowFound) {
break
if (!workflowFound) {
console.log("No workflow found.")
toast("(2) Creating new workflow for this org. Please wait a few seconds while we prepare it for you.")
//saveWorkflow(originalWorkflow, undefined, undefined, e.target.value)
}
}
if (!workflowFound) {
console.log("No workflow found.")
toast("(2) Creating new workflow for this org. Please wait a few seconds while we prepare it for you.")
//saveWorkflow(originalWorkflow, undefined, undefined, e.target.value)
}
}
}, 500)
})
}}
label="Suborg Distribution"
@@ -16048,7 +16141,7 @@ const releaseToConnectLabel = "Release to Connect"
})}
</div>
{showEnvironment === true && environments.length > 1 ?
{showEnvironment === true && environments.length > 1 && selectedActionEnvironment !== undefined && selectedActionEnvironment !== null && selectedActionEnvironment.Name !== undefined && selectedActionEnvironment.Name !== null ?
<FormControl fullWidth style={{marginTop: 15, marginleft: 10, pointerEvents: "auto", }}>
<InputLabel
@@ -16069,10 +16162,11 @@ const releaseToConnectLabel = "Release to Connect"
},
}}
onChange={(e) => {
setLastSaved(false)
const env = environments.find((a) => a.Name === e.target.value);
setSelectedActionEnvironment(env);
selectedAction.environment = env.Name;
setSelectedAction(selectedAction);
setSelectedActionEnvironment(env)
selectedAction.environment = env.Name
setSelectedAction(selectedAction)
for (let actionkey in workflow.actions) {
workflow.actions[actionkey].environment = env.Name
@@ -16110,7 +16204,7 @@ const releaseToConnectLabel = "Release to Connect"
{data.Name === "cloud" || data.Name === "Cloud" ? null : !isRunning ?
<a href={`/admin?tab=locations&env=${data.Name}`} target="_blank" style={{textDecoration: "none",}}>
<Tooltip title={"Click to configure the environment"} placement="top">
<Tooltip title={"Click to configure this location"} placement="top">
<Chip
style={{marginLeft: 0, padding: 0, marginRight: 10, cursor: "pointer", backgroundColor: red, }}
label={"Stopped"}
@@ -19684,8 +19778,7 @@ const releaseToConnectLabel = "Release to Connect"
maxHeight: 550,
overflowY: "auto",
overflowX: "hidden",
// zIndex: 10012,
border: theme.palette.defaultBorder,
border: theme.palette.defaultBorder,
},
}}
>
@@ -19866,7 +19959,7 @@ const releaseToConnectLabel = "Release to Connect"
</span>
<div style={{ marginBottom: 40, }}>
<div style={{ display: "flex", marginBottom: 15, position: "sticky", top: -31, zIndex: 10000, backgroundColor: "rgba(56,56,56, 1)", }}>
<div style={{ display: "flex", marginBottom: 15, position: "sticky", top: -31, zIndex: 10000, }}>
{curapp === null ? null : (
<img
alt={selectedResult.action.app_name}
@@ -20631,7 +20724,7 @@ const releaseToConnectLabel = "Release to Connect"
toast(
"Field " +
selectedApp.authentication.parameters[paramkey].name +
" can't be empty"
" can't be empty. If you want it empty, put space."
);
return;
}
@@ -20660,7 +20753,6 @@ const releaseToConnectLabel = "Release to Connect"
var newAuthOption = JSON.parse(JSON.stringify(authenticationOption));
var newFields = [];
console.log("Fields: ", newAuthOption.fields)
for (let authkey in newAuthOption.fields) {
const value = newAuthOption.fields[authkey];
newFields.push({
@@ -20673,7 +20765,7 @@ const releaseToConnectLabel = "Release to Connect"
setNewAppAuth(newAuthOption)
if (configureWorkflowModalOpen) {
setSelectedAction({})
//setSelectedAction({})
}
setUpdate(authenticationOption.id)
@@ -20750,8 +20842,14 @@ const releaseToConnectLabel = "Release to Connect"
return (
<div key={index} style={{ marginTop: 10 }}>
<LockOpenIcon style={{ marginRight: 10 }} />
<b>{data.name}</b>
<div style={{display: "flex", }}>
<LockOpenIcon style={{
marginRight: 10
}} />
<Typography variant="body1">
{data?.name?.endsWith("_basic") ? data?.name?.replace("_basic", "") : data?.name}
</Typography>
</div>
{data.schema !== undefined &&
data.schema !== null &&
@@ -20815,7 +20913,7 @@ const releaseToConnectLabel = "Release to Connect"
}
color="primary"
defaultValue={
data.value !== undefined && data.value !== null
data.value !== undefined && data.value !== null && !data.value.includes("Secret. Replace")
? data.value
: ""
}
@@ -20824,6 +20922,7 @@ const releaseToConnectLabel = "Release to Connect"
authenticationOption.fields[data.name] =
event.target.value;
}}
id={`${data.name}_auth`}
/>
)}
</div>
@@ -20832,19 +20931,11 @@ const releaseToConnectLabel = "Release to Connect"
</DialogContent>
<DialogActions>
<Button
style={{}}
onClick={() => {
setAuthenticationModalOpen(false);
}}
color="secondary"
>
Cancel
</Button>
<Button
style={{}}
style={{width: 150, margin: "auto", }}
disabled={false}
variant="outlined"
onClick={() => {
setAuthenticationOptions(authenticationOption);
setAuthenticationOptions(authenticationOption)
handleSubmitCheck()
}}
color="primary"
@@ -20856,7 +20947,8 @@ const releaseToConnectLabel = "Release to Connect"
);
};
const configureWorkflowModal =
// FIXME: Re-enable?
const configureWorkflowModal = true ? null :
configureWorkflowModalOpen && apps.length !== 0 ? (
<Dialog
open={configureWorkflowModalOpen}
@@ -20919,10 +21011,6 @@ const releaseToConnectLabel = "Release to Connect"
style={{ pointerEvents: "none" }}
open={authenticationModalOpen}
onClose={() => {
//if (configureWorkflowModalOpen) {
// setSelectedAction({});
//}
//
setSelectedMeta(undefined)
}}
PaperProps={{
@@ -21031,7 +21119,7 @@ const releaseToConnectLabel = "Release to Connect"
onClick={() => {
setAuthenticationModalOpen(false);
if (configureWorkflowModalOpen) {
setSelectedAction({});
//setSelectedAction({});
}
}}
>
@@ -21360,15 +21448,6 @@ const releaseToConnectLabel = "Release to Connect"
</DialogContent>
<DialogActions>
<Button
style={{ borderRadius: "0px" }}
onClick={() => {
setTenzirConfigModalOpen(false);
}}
color="secondary"
>
Cancel
</Button>
<Button
style={{ borderRadius: "0px" }}
variant="contained"
@@ -22050,6 +22129,13 @@ const releaseToConnectLabel = "Release to Connect"
</div>
: null*/}
<div
id="redline"
style={{
display: "none",
}}
/>
{showVideo !== undefined && showVideo.length > 0 ?
<div style={{ borderRadius: theme.palette?.borderRadius, zIndex: 12501, position: "fixed", left: 40, bottom: 150, width: 300, }}>
<IconButton
+107 -26
View File
@@ -75,6 +75,7 @@ const RunWorkflow = (defaultprops) => {
const [realtimeMarkdown, setRealtimeMarkdown] = React.useState("")
const [forms, setForms] = React.useState([])
const [boxWidth, setBoxWidth] = React.useState(500)
const [inputQuestions, setInputQuestions] = React.useState([])
const IframeWrapper = (props) => {
var propsCopy = JSON.parse(JSON.stringify(props))
@@ -141,6 +142,18 @@ const RunWorkflow = (defaultprops) => {
return true
}
// Check if it's an object or not
if (typeof executionArgument === "string") {
// Make it an object
try {
executionArgument = JSON.parse(executionArgument)
} catch (e) {
console.log("Error parsing execution argument: ", e)
executionArgument = {}
}
}
console.log("EXEC: ", executionArgument)
for (var key in executionArgument) {
if (executionArgument[key] === undefined || executionArgument[key] === null || executionArgument[key] === "") {
return false
@@ -262,9 +275,12 @@ const RunWorkflow = (defaultprops) => {
return (
<div style={{marginTop: executionMargin, }}>
<Divider style={{marginTop: 20, marginBottom: 20, }}/>
{workflowQuestion !== "" ? null :
<Divider style={{marginTop: 20, marginBottom: 20, }}/>
}
{validate.valid === false ?
{workflowQuestion !== "" ? null :
validate.valid === false ?
<div style={{marginTop: 20, }}>
<Divider />
<Markdown
@@ -533,6 +549,12 @@ const RunWorkflow = (defaultprops) => {
})
}
const searchParams = new URLSearchParams(window.location.search)
const answer = searchParams.get("answer")
const execution_id = searchParams.get("reference_execution")
const authorization = searchParams.get("authorization")
const sourceNode = searchParams.get("source_node")
const getWorkflow = (workflow_id, selectedNode) => {
setRealtimeMarkdown("")
@@ -588,6 +610,56 @@ const RunWorkflow = (defaultprops) => {
}
}
// Override with just relevant fields
if (sourceNode !== undefined && sourceNode !== null && sourceNode.length > 0) {
for (var triggerkey in responseJson.triggers) {
const trig = responseJson.triggers[triggerkey]
if (trig.id !== sourceNode) {
continue
}
console.log("TRIG: ", trig)
if (trig.parameters === undefined || trig.parameters === null) {
trig.parameters = []
}
for (var paramkey in trig.parameters) {
const param = trig.parameters[paramkey]
if (param.name !== "input_questions") {
continue
}
// Parse as json
var keepfields = []
try {
const parsed = JSON.parse(param.value)
// Find this in the workflow.input_questions
for (var questionkey in responseJson.input_questions) {
var question = JSON.parse(JSON.stringify(responseJson.input_questions[questionkey]))
question.value = question.value.split(";")[0]
if (parsed.includes(question.name)) {
keepfields.push(question.value)
}
}
//newexec = {}
} catch (e) {
console.log("Error parsing input questions: ", e)
}
// Remapping it to exec
if (keepfields.length > 0) {
newexec = {}
for (var key in keepfields) {
newexec[keepfields[key]] = ""
}
}
}
}
}
setExecutionArgument(newexec)
}
@@ -624,7 +696,8 @@ const RunWorkflow = (defaultprops) => {
}
}
responseJson.input_questions = relevantquestions
setInputQuestions(relevantquestions)
//responseJson.input_questions = relevantquestions
}
}
}
@@ -899,11 +972,6 @@ const RunWorkflow = (defaultprops) => {
});
};
const searchParams = new URLSearchParams(window.location.search)
const answer = searchParams.get("answer")
const execution_id = searchParams.get("reference_execution")
const authorization = searchParams.get("authorization")
const sourceNode = searchParams.get("source_node")
useEffect(() => {
if (!isLoaded) {
@@ -963,9 +1031,14 @@ const RunWorkflow = (defaultprops) => {
}
if (result.status !== "WAITING") {
if (parsedresult.information !== undefined && parsedresult.information !== null && parsedresult.information.length > 0) {
setWorkflowQuestion(parsedresult.information)
}
if (parsedresult.click_info !== undefined && parsedresult.click_info !== null) {
if (parsedresult.click_info.user !== undefined && parsedresult.click_info.user !== null && parsedresult.click_info.user.length > 0) {
setMessage("Already answered by " + parsedresult.click_info.user)
}
} else {
setMessage("Answered.")
@@ -981,8 +1054,12 @@ const RunWorkflow = (defaultprops) => {
const buttonBackground = "linear-gradient(to right, #f86a3e, #f34079)"
const buttonStyle = {borderRadius: 25, height: 50, fontSize: 18, backgroundImage: handleValidateForm(executionArgument) || executionLoading ? buttonBackground : "grey", color: "white"}
//const disabledButtons = message.length > 0 || executionData.status === "FINISHED" || executionData.status === "ABORTED"
const disabledButtons = executionLoading || executionRunning
// Check if all fields are filled in?
var disabledButtons = executionLoading || executionRunning || message.length > 0
if (disabledButtons === false && workflow.input_questions !== undefined && workflow.input_questions !== null && workflow.input_questions.length > 0) {
// Check field values
//disabledButtons = handleValidateForm(executionArgument)
}
const organization = selectedOrganization !== undefined && selectedOrganization !== null ? selectedOrganization.name : "Unknown"
const contact = selectedOrganization !== undefined && selectedOrganization !== null && selectedOrganization.org !== undefined && selectedOrganization.org !== null? selectedOrganization.org : "support@shuffler.io"
@@ -1073,7 +1150,7 @@ const RunWorkflow = (defaultprops) => {
</div>
:
<div>
{workflow.form_control.input_markdown !== undefined && workflow.form_control.input_markdown !== null && workflow.form_control.input_markdown.length > 0 ?
{workflowQuestion !== "" || (workflow.form_control.input_markdown !== undefined && workflow.form_control.input_markdown !== null && workflow.form_control.input_markdown.length > 0) ?
<div style={{marginBottom: 20, }}>
<Markdown
components={{
@@ -1089,13 +1166,13 @@ const RunWorkflow = (defaultprops) => {
}}
rehypePlugins={[rehypeRaw]}
>
{realtimeMarkdown !== undefined && realtimeMarkdown !== null && realtimeMarkdown.length > 0 ? realtimeMarkdown : workflow.form_control.input_markdown}
{workflowQuestion !== "" ? workflowQuestion : realtimeMarkdown !== undefined && realtimeMarkdown !== null && realtimeMarkdown.length > 0 ? realtimeMarkdown : workflow.form_control.input_markdown}
</Markdown>
</div>
: null}
<form onSubmit={(e) => {onSubmit(e)}} style={{margin: "25px 0px 15px 0px",}}>
{workflow.form_control.input_markdown !== undefined && workflow.form_control.input_markdown !== null && workflow.form_control.input_markdown.length > 0 ? null :
{workflowQuestion !== "" || (workflow.form_control.input_markdown !== undefined && workflow.form_control.input_markdown !== null && workflow.form_control.input_markdown.length > 0) ? null :
<div>
<img
alt={workflow.name}
@@ -1146,7 +1223,7 @@ const RunWorkflow = (defaultprops) => {
{workflow.input_questions !== undefined && workflow.input_questions !== null && workflow.input_questions.length > 0 ?
<div style={{marginBottom: 5, }}>
{workflow.input_questions.map((question, index) => {
{inputQuestions.map((question, index) => {
// Multiple choice checks for semicolon-splits
var multiChoiceOptions = question.value !== undefined && question.value !== null && question.value.length > 0 && question.value.includes(";") ? question.value.split(";") : []
@@ -1280,25 +1357,26 @@ const RunWorkflow = (defaultprops) => {
What do you want to do?
</Typography>
}
<div fullWidth style={{width: "100%", marginTop: 10, marginBottom: 10, display: "flex", }}>
<Button fullWidth id="continue_execution" variant="contained" disabled={disabledButtons} color="primary" style={{flex: 1,}} onClick={() => {
onSubmit(null, execution_id, authorization, true)
<div fullWidth style={{width: "100%", marginTop: 10, marginBottom: 10, display: "flex", }}>
<Button fullWidth id="continue_execution" variant="contained" disabled={!handleValidateForm(executionArgument) || disabledButtons} color="primary" style={{flex: 1,}} onClick={() => {
setButtonClicked("FINISHED")
setExecutionData({
status: "FINISHED",
})
onSubmit(null, execution_id, authorization, true)
}}>Continue</Button>
<Typography variant="body1" style={{marginLeft: 3, marginRight: 3, marginTop: 3, }}>
&nbsp;or&nbsp;
</Typography>
<Button fullWidth id="abort_execution" variant="contained" color="primary" disabled={disabledButtons} style={{ flex: 1, }} onClick={() => {
onSubmit(null, execution_id, authorization, false)
<Button fullWidth id="abort_execution" variant="contained" disabled={!handleValidateForm(executionArgument) || disabledButtons} color="primary" style={{ flex: 1, }} onClick={() => {
setButtonClicked("ABORTED")
setExecutionData({
status: "ABORTED",
})
onSubmit(null, execution_id, authorization, false)
}}>Stop</Button>
</div>
</span>
@@ -1393,15 +1471,18 @@ const RunWorkflow = (defaultprops) => {
</div>
}
</Paper>
<Typography variant="body2" color="textSecondary" align="center" style={{marginTop: 10, }} >
Forms are in Beta. Form submission data includes your Organization's unique ID while logged in, or a unique identifier for your browser otherwise. Your input will be automatically sanitized.
</Typography>
{workflowQuestion !== "" ? null :
<Typography variant="body2" color="textSecondary" align="center" style={{marginTop: 10, }} >
Forms are in late Beta. Form submission data includes your Organization's unique ID while logged in, or a unique identifier for your browser otherwise. Your input will be automatically sanitized.
</Typography>
}
</div>
// const isCorrectOrg = userdata.active_org.id === undefined || userdata.active_org.id === null || workflow.org_id === null || workflow.org_id === undefined || workflow.org_id.length === 0 || userdata.active_org.id === workflow.org_id
const loadedCheck = isLoaded ?
<div>
<div style={{marginTop: 30, }}>
{editWorkflowModalOpen === true ?
<EditWorkflow
saveWorkflow={saveWorkflow}
@@ -1474,7 +1555,7 @@ const RunWorkflow = (defaultprops) => {
>
Organization only
</MenuItem>
<Divider />
<Divider />
<MenuItem
value={"form"}
>
@@ -1485,7 +1566,7 @@ const RunWorkflow = (defaultprops) => {
</DialogContent>
</Dialog>
{isLoggedIn && userdata?.active_org?.id === workflow?.org_id ?
{isLoggedIn && userdata?.active_org?.id === workflow?.org_id || userdata?.support === true ?
<div style={{position: "fixed", top: 10, right: 20, }}>
<Button
-1
View File
@@ -782,7 +782,6 @@ func deployApp(cli *dockerclient.Client, image string, identifier string, env []
// image on every Orborus/new worker restart.
// Running as coroutine for eventual completeness
//go shuffle.DownloadDockerImageBackend(&http.Client{}, image)
// FIXME: With goroutines it got too much trouble of deploying with an older version
// Allowing slow startups, as long as it's eventually fast, and uses the same registry as on host.
shuffle.DownloadDockerImageBackend(&http.Client{Timeout: imagedownloadTimeout}, image)