Workflow fixes
This commit is contained in:
@@ -72,6 +72,7 @@ const EditWorkflow = (props) => {
|
||||
|
||||
const [submitLoading, setSubmitLoading] = React.useState(false);
|
||||
const [showMoreClicked, setShowMoreClicked] = React.useState(expanded === true ? true : false);
|
||||
|
||||
const [innerWorkflow, setInnerWorkflow] = React.useState(workflow)
|
||||
|
||||
const [newWorkflowTags, setNewWorkflowTags] = React.useState(workflow.tags !== undefined && workflow.tags !== null ? JSON.parse(JSON.stringify(workflow.tags)) : [])
|
||||
@@ -80,7 +81,8 @@ const EditWorkflow = (props) => {
|
||||
const [selectedUsecases, setSelectedUsecases] = React.useState(workflow.usecase_ids !== undefined && workflow.usecase_ids !== null ? JSON.parse(JSON.stringify(workflow.usecase_ids)) : []);
|
||||
const [foundWorkflowId, setFoundWorkflowId] = React.useState("")
|
||||
const [name, setName] = React.useState(workflow.name !== undefined ? workflow.name : "")
|
||||
const [dueDate, setDueDate] = React.useState(workflow.due_date !== undefined && workflow.due_date !== null && workflow.due_date !== 0 ? dayjs(workflow.due_date*1000) : dayjs().subtract(1, 'day'))
|
||||
const [workflowAsCode, setWorkflowAsCode] = React.useState(false)
|
||||
const [dueDate, setDueDate] = React.useState(workflow.due_date !== undefined && workflow.due_date !== null && workflow.due_date !== 0 ? dayjs(workflow.due_date * 1000) : dayjs().subtract(1, 'day'))
|
||||
|
||||
const [inputQuestions, setInputQuestions] = React.useState(workflow.input_questions !== undefined && workflow.input_questions !== null ? JSON.parse(JSON.stringify(workflow.input_questions)) : [])
|
||||
const [inputMarkdown, setInputMarkdown] = React.useState(workflow?.form_control?.input_markdown !== undefined && workflow?.form_control?.input_markdown !== null ? workflow?.form_control?.input_markdown : "")
|
||||
@@ -206,11 +208,11 @@ const EditWorkflow = (props) => {
|
||||
},
|
||||
}}
|
||||
>
|
||||
<DialogTitle style={{padding: 30, paddingBottom: 0, zIndex: 1000,}}>
|
||||
<div style={{display: "flex"}}>
|
||||
<div style={{flex: 1, color: "rgba(255,255,255,0.9)" }}>
|
||||
<div style={{display: "flex"}}>
|
||||
<Typography variant="h4" style={{flex: 9, }}>
|
||||
<DialogTitle style={{ padding: 30, paddingBottom: 0, zIndex: 1000, }}>
|
||||
<div style={{ display: "flex" }}>
|
||||
<div style={{ flex: 1, color: "rgba(255,255,255,0.9)" }}>
|
||||
<div style={{ display: "flex" }}>
|
||||
<Typography variant="h4" style={{ flex: 9, }}>
|
||||
{newWorkflow ? "New" : "Editing"} workflow
|
||||
</Typography>
|
||||
|
||||
@@ -236,7 +238,7 @@ const EditWorkflow = (props) => {
|
||||
}
|
||||
|
||||
</div>
|
||||
<Typography variant="body2" color="textSecondary" style={{marginTop: 20, maxWidth: 440,}}>
|
||||
<Typography variant="body2" color="textSecondary" style={{ marginTop: 20, maxWidth: 440, }}>
|
||||
Workflows can be built from scratch, or from templates. <a href="/usecases2" rel="noopener noreferrer" target="_blank" style={{ textDecoration: "none", color: "#f86a3e" }}>Usecases</a> can help you discover next steps, and you can <a href="/search?tab=workflows" rel="noopener noreferrer" target="_blank" style={{ textDecoration: "none", color: "#f86a3e" }}>search</a> for them directly. <a href="/docs/workflows" rel="noopener noreferrer" target="_blank" style={{ textDecoration: "none", color: "#f86a3e" }}>Learn more</a>
|
||||
</Typography>
|
||||
|
||||
@@ -278,7 +280,7 @@ const EditWorkflow = (props) => {
|
||||
</div>
|
||||
</DialogTitle>
|
||||
<FormControl>
|
||||
<div style={{borderTop: "1px solid rgba(255,255,255,0.5)", width: 600, position: "fixed", right: 20, bottom: 0, zIndex: 1002, backgroundColor: "rgba(53,53,53,1)", height: 75, paddingTop: 20, paddingLeft: 75, }}>
|
||||
<div style={{ borderTop: "1px solid rgba(255,255,255,0.5)", width: 600, position: "fixed", right: 20, bottom: 0, zIndex: 1002, backgroundColor: "rgba(53,53,53,1)", height: 75, paddingTop: 20, paddingLeft: 75, }}>
|
||||
{/*
|
||||
<Button
|
||||
style={{}}
|
||||
@@ -336,7 +338,7 @@ const EditWorkflow = (props) => {
|
||||
}
|
||||
|
||||
if (dueDate > 0) {
|
||||
innerWorkflow.due_date = new Date(`${dueDate["$y"]}-${dueDate["$M"]+1}-${dueDate["$D"]}`).getTime()/1000
|
||||
innerWorkflow.due_date = new Date(`${dueDate["$y"]}-${dueDate["$M"] + 1}-${dueDate["$D"]}`).getTime() / 1000
|
||||
}
|
||||
|
||||
if (saveWorkflow !== undefined) {
|
||||
@@ -356,6 +358,7 @@ const EditWorkflow = (props) => {
|
||||
innerWorkflow.usecase_ids,
|
||||
innerWorkflow.blogpost,
|
||||
innerWorkflow.status,
|
||||
workflowAsCode
|
||||
)
|
||||
setWorkflow({})
|
||||
} else {
|
||||
@@ -376,8 +379,8 @@ const EditWorkflow = (props) => {
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<DialogContent style={{paddingTop: 10, display: "flex", minHeight: 300, zIndex: 1001, paddingBottom: 200, }}>
|
||||
<div style={{minWidth: newWorkflow ? 500 : 550, maxWidth: newWorkflow ? 450 : 500, }}>
|
||||
<DialogContent style={{ paddingTop: 10, display: "flex", minHeight: 300, zIndex: 1001, paddingBottom: 200, }}>
|
||||
<div style={{ minWidth: newWorkflow ? 500 : 550, maxWidth: newWorkflow ? 450 : 500, }}>
|
||||
<TextField
|
||||
onChange={(event) => {
|
||||
setName(event.target.value)
|
||||
@@ -396,9 +399,10 @@ const EditWorkflow = (props) => {
|
||||
autoFocus
|
||||
fullWidth
|
||||
/>
|
||||
<div style={{display: "flex", marginTop: 10, }}>
|
||||
|
||||
<div style={{ display: "flex", marginTop: 10, }}>
|
||||
{usecases !== null && usecases !== undefined && usecases.length > 0 ?
|
||||
<FormControl style={{flex: 1, marginRight: 5,}}>
|
||||
<FormControl style={{ flex: 1, marginRight: 5, }}>
|
||||
<InputLabel htmlFor="grouped-select-usecase">Usecases</InputLabel>
|
||||
<Select
|
||||
defaultValue=""
|
||||
@@ -419,7 +423,7 @@ const EditWorkflow = (props) => {
|
||||
return (
|
||||
<span key={index}>
|
||||
<ListSubheader
|
||||
style={{color: usecase.color}}
|
||||
style={{ color: usecase.color }}
|
||||
>
|
||||
{usecase.name}
|
||||
</ListSubheader>
|
||||
@@ -440,7 +444,7 @@ const EditWorkflow = (props) => {
|
||||
setUpdate(Math.random());
|
||||
setSelectedUsecases(selectedUsecases)
|
||||
}}>
|
||||
<Checkbox style={{color: selectedUsecases.includes(subcase.name) ? usecase.color : theme.palette.inputColor}} checked={selectedUsecases.includes(subcase.name)} />
|
||||
<Checkbox style={{ color: selectedUsecases.includes(subcase.name) ? usecase.color : theme.palette.inputColor }} checked={selectedUsecases.includes(subcase.name)} />
|
||||
<ListItemText primary={subcase.name} />
|
||||
</MenuItem>
|
||||
)
|
||||
@@ -452,7 +456,7 @@ const EditWorkflow = (props) => {
|
||||
</FormControl>
|
||||
: null}
|
||||
<MuiChipsInput
|
||||
style={{ flex: 1, maxHeight: 120, overflow: "auto",}}
|
||||
style={{ flex: 1, maxHeight: 120, overflow: "auto", }}
|
||||
InputProps={{
|
||||
style: {
|
||||
color: "white",
|
||||
@@ -493,7 +497,7 @@ const EditWorkflow = (props) => {
|
||||
</div>
|
||||
|
||||
{showMoreClicked === true ?
|
||||
<div style={{marginTop: 50, }}>
|
||||
<div style={{ marginTop: 50, }}>
|
||||
<TextField
|
||||
onBlur={(event) => {
|
||||
setDescription(event.target.value)
|
||||
@@ -514,8 +518,8 @@ const EditWorkflow = (props) => {
|
||||
fullWidth
|
||||
/>
|
||||
|
||||
<div style={{display: "flex"}}>
|
||||
<FormControl style={{marginTop: 15, }}>
|
||||
<div style={{ display: "flex" }}>
|
||||
<FormControl style={{ marginTop: 15, }}>
|
||||
<FormLabel id="demo-row-radio-buttons-group-label">Status</FormLabel>
|
||||
<RadioGroup
|
||||
row
|
||||
@@ -552,7 +556,7 @@ const EditWorkflow = (props) => {
|
||||
</div>
|
||||
<div />
|
||||
|
||||
<FormControl style={{marginTop: 15, }}>
|
||||
<FormControl style={{ marginTop: 15, }}>
|
||||
<FormLabel id="demo-row-radio-buttons-group-label">Type</FormLabel>
|
||||
<RadioGroup
|
||||
row
|
||||
@@ -631,25 +635,25 @@ const EditWorkflow = (props) => {
|
||||
fullWidth
|
||||
/>
|
||||
|
||||
<Divider style={{marginTop: 20, marginBottom: 20, }} />
|
||||
<Divider style={{ marginTop: 20, marginBottom: 20, }} />
|
||||
|
||||
<Typography variant="h4" style={{marginTop: 50, }}>
|
||||
<Typography variant="h4" style={{ marginTop: 50, }}>
|
||||
MSSP controls
|
||||
</Typography>
|
||||
|
||||
|
||||
<Typography variant="body1" style={{marginTop: 50, }}>
|
||||
<Typography variant="body1" style={{ marginTop: 50, }}>
|
||||
MSSP Suborg Distribution (<b>beta</b> - contact support@shuffler.io for more info)
|
||||
</Typography>
|
||||
{userdata !== undefined && userdata !== null && userdata.orgs !== undefined && userdata.orgs !== null && userdata.orgs.length > 0 ?
|
||||
userdata.orgs.filter(org => org.creator_org === userdata.active_org.id).length === 0 ?
|
||||
userdata.active_org.creator_org === undefined || userdata.active_org.creator_org === null || userdata.active_org.creator_org === "" ?
|
||||
<Typography variant="body2" style={{marginTop: 10, color: "rgba(255,255,255,0.7)"}}>
|
||||
Your organization does not have any suborgs yet OR your user may not have access to available suborgs. Please <a href="/admin?tab=suborgs" style={{textDecoration: "none", color: "#f86a3e"}} target="_blank">make one</a> or get access to suborgs by another admin, then try again.
|
||||
<Typography variant="body2" style={{ marginTop: 10, color: "rgba(255,255,255,0.7)" }}>
|
||||
Your organization does not have any suborgs yet OR your user may not have access to available suborgs. Please <a href="/admin?tab=suborgs" style={{ textDecoration: "none", color: "#f86a3e" }} target="_blank">make one</a> or get access to suborgs by another admin, then try again.
|
||||
</Typography>
|
||||
:
|
||||
<Typography variant="body2" style={{marginTop: 10, color: "rgba(255,255,255,0.7)"}}>
|
||||
{innerWorkflow.parentorg_workflow !== undefined && innerWorkflow.parentorg_workflow !== null && innerWorkflow.parentorg_workflow.length > 0 ? <span>This workflow is distributed from <a href={`/workflows/${innerWorkflow.parentorg_workflow}`} style={{textDecoration: "none", color: "#f86a3e"}} target="_blank">your parent workflow</a> (you may not have access).</span> : null}
|
||||
<Typography variant="body2" style={{ marginTop: 10, color: "rgba(255,255,255,0.7)" }}>
|
||||
{innerWorkflow.parentorg_workflow !== undefined && innerWorkflow.parentorg_workflow !== null && innerWorkflow.parentorg_workflow.length > 0 ? <span>This workflow is distributed from <a href={`/workflows/${innerWorkflow.parentorg_workflow}`} style={{ textDecoration: "none", color: "#f86a3e" }} target="_blank">your parent workflow</a> (you may not have access).</span> : null}
|
||||
<br />
|
||||
<br />
|
||||
You can only distribute to suborgs from a parent org.
|
||||
@@ -657,7 +661,7 @@ const EditWorkflow = (props) => {
|
||||
:
|
||||
<Select
|
||||
multiple
|
||||
style={{marginTop: 10, }}
|
||||
style={{ marginTop: 10, }}
|
||||
value={innerWorkflow.suborg_distribution === undefined || innerWorkflow.suborg_distribution === null ? ["none"] : innerWorkflow.suborg_distribution}
|
||||
onChange={(e) => {
|
||||
var newvalue = e.target.value
|
||||
@@ -736,8 +740,8 @@ const EditWorkflow = (props) => {
|
||||
})}
|
||||
</Select>
|
||||
:
|
||||
<Link to={"/admin?tab=suborgs"} style={{textDecoration: "none", color: "#f86a3e"}} target="_blank">
|
||||
<Typography variant="body2" style={{marginTop: 10, }}>
|
||||
<Link to={"/admin?tab=suborgs"} style={{ textDecoration: "none", color: "#f86a3e" }} target="_blank">
|
||||
<Typography variant="body2" style={{ marginTop: 10, }}>
|
||||
Create a sub-org to distribute workflows to suborgs.
|
||||
</Typography>
|
||||
</Link>
|
||||
@@ -747,11 +751,11 @@ const EditWorkflow = (props) => {
|
||||
|
||||
|
||||
|
||||
<Typography variant="body1" style={{marginTop: 100, }}>
|
||||
<Typography variant="body1" style={{ marginTop: 100, }}>
|
||||
Git Backup Repository
|
||||
</Typography>
|
||||
<Typography variant="body2" style={{ textAlign: "left", marginTop: 5, }} color="textSecondary">
|
||||
Decide where this workflow is backed up in a Git repository. Will create logs and notifications if upload fails. <b>The repository and branch must already have been initialized</b>. Files will show up in the root folder in the format 'orgid/workflow status/workflow id.json' without images. Overrides your <a href="/admin?admin_tab=organization" style={{textDecoration: "none", color: "#f86a3e"}} target="_blank">default backup repository</a>. <a href="/docs/configuration#environment-variables" style={{textDecoration: "none", color: "#f86a3e"}} target="_blank">Credentials are encrypted.</a> Creates <a href="/admin?admin_tab=priorities" style={{textDecoration: "none", color: "#f86a3e"}} target="_blank">notifications</a> if it fails.
|
||||
Decide where this workflow is backed up in a Git repository. Will create logs and notifications if upload fails. <b>The repository and branch must already have been initialized</b>. Files will show up in the root folder in the format 'orgid/workflow status/workflow id.json' without images. Overrides your <a href="/admin?admin_tab=organization" style={{ textDecoration: "none", color: "#f86a3e" }} target="_blank">default backup repository</a>. <a href="/docs/configuration#environment-variables" style={{ textDecoration: "none", color: "#f86a3e" }} target="_blank">Credentials are encrypted.</a> Creates <a href="/admin?admin_tab=priorities" style={{ textDecoration: "none", color: "#f86a3e" }} target="_blank">notifications</a> if it fails.
|
||||
</Typography>
|
||||
<Grid container style={{ marginTop: 10, }} spacing={2}>
|
||||
<Grid item xs={6} style={{}}>
|
||||
@@ -823,7 +827,7 @@ const EditWorkflow = (props) => {
|
||||
</span>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container style={{ }} spacing={2}>
|
||||
<Grid container style={{}} spacing={2}>
|
||||
<Grid item xs={6} style={{}}>
|
||||
<span>
|
||||
<Typography>Username</Typography>
|
||||
@@ -893,23 +897,23 @@ const EditWorkflow = (props) => {
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<Divider style={{marginTop: 20, marginBottom: 20, }} />
|
||||
<Divider style={{ marginTop: 20, marginBottom: 20, }} />
|
||||
|
||||
|
||||
<div id="form_fill" style={{position: "relative", }}>
|
||||
<Typography variant="h4" style={{marginTop: 100, }}>
|
||||
<div id="form_fill" style={{ position: "relative", }}>
|
||||
<Typography variant="h4" style={{ marginTop: 100, }}>
|
||||
Form Control
|
||||
</Typography>
|
||||
<Typography variant="body1" color="textSecondary" style={{marginTop: 10, }}>
|
||||
<Typography variant="body1" color="textSecondary" style={{ marginTop: 10, }}>
|
||||
Form Control is used to control how the Form for the workflow is shown to users. You can add input fields, markdown, and more. This is the first step in the workflow, and is required for all workflows.
|
||||
</Typography>
|
||||
|
||||
<Typography variant="h6" style={{marginTop: 50, }}>
|
||||
<Typography variant="h6" style={{ marginTop: 50, }}>
|
||||
Input fields
|
||||
</Typography>
|
||||
|
||||
<Tooltip title="Go to Public Form page">
|
||||
<IconButton style={{position: "absolute", top: 0, right: 10, }}>
|
||||
<IconButton style={{ position: "absolute", top: 0, right: 10, }}>
|
||||
<a
|
||||
rel="noopener noreferrer"
|
||||
href={`/forms/${workflow.id}`}
|
||||
@@ -927,7 +931,7 @@ const EditWorkflow = (props) => {
|
||||
|
||||
</div>
|
||||
|
||||
<Typography variant="body2" color="textSecondary" style={{marginBottom: 20, }}>
|
||||
<Typography variant="body2" color="textSecondary" style={{ marginBottom: 20, }}>
|
||||
Input fields are fields that will be used during the startup of the workflow. These will be formatted in JSON and is most commonly used from the <a href={`/forms/${workflow.id}`} rel="noopener noreferrer" target="_blank" style={{ textDecoration: "none", color: "#f86a3e" }}>Form page</a> for this workflow. If chosen in the User Input node, these will be required fields. Use Semi-Colon ";" to create dropdown options. The first key will be the name shown, and subsequent keys will be the available values.
|
||||
</Typography>
|
||||
|
||||
@@ -941,7 +945,7 @@ const EditWorkflow = (props) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{display: "flex", }}>
|
||||
<div style={{ display: "flex", }}>
|
||||
<TextField
|
||||
disabled={data.deleted === true}
|
||||
style={{
|
||||
@@ -1037,10 +1041,10 @@ const EditWorkflow = (props) => {
|
||||
</Button>
|
||||
|
||||
<div id="input_markdown">
|
||||
<Typography variant="h6" style={{marginTop: 50, }}>
|
||||
<Typography variant="h6" style={{ marginTop: 50, }}>
|
||||
Input Markdown
|
||||
</Typography>
|
||||
<Typography variant="body2" color="textSecondary" style={{marginBottom: 20, }}>
|
||||
<Typography variant="body2" color="textSecondary" style={{ marginBottom: 20, }}>
|
||||
Markdown will be shown on the <a href={`/forms/${workflow.id}`} rel="noopener noreferrer" target="_blank" style={{ textDecoration: "none", color: "#f86a3e" }}>Form page</a>. The first image added will be used in your Form Toolbox list. Output for a Workflow is shown in Markdown, and is controlled by the LAST action that runs. Supports HTML.
|
||||
</Typography>
|
||||
<TextField
|
||||
@@ -1070,10 +1074,10 @@ const EditWorkflow = (props) => {
|
||||
</div>
|
||||
|
||||
<div id="form_size">
|
||||
<Typography variant="h6" style={{marginTop: 50, }}>
|
||||
<Typography variant="h6" style={{ marginTop: 50, }}>
|
||||
Form Size
|
||||
</Typography>
|
||||
<Typography variant="body2" color="textSecondary" style={{marginBottom: 20, }}>
|
||||
<Typography variant="body2" color="textSecondary" style={{ marginBottom: 20, }}>
|
||||
Control the width of the form. It will grow vertically as needed.
|
||||
</Typography>
|
||||
<Slider
|
||||
@@ -1091,22 +1095,22 @@ const EditWorkflow = (props) => {
|
||||
</div>
|
||||
|
||||
<div id="output_control">
|
||||
<Typography variant="h6" style={{marginTop: 50, }}>
|
||||
<Typography variant="h6" style={{ marginTop: 50, }}>
|
||||
Output Control ({selectedYieldActions.length === 0 ? "No Returns" : selectedYieldActions.length === 1 ? "Returning 1 node" : `Returning ${selectedYieldActions.length} nodes`})
|
||||
</Typography>
|
||||
|
||||
<Typography variant="body2" color="textSecondary" style={{marginBottom: 20, }}>
|
||||
<Typography variant="body2" color="textSecondary" style={{ marginBottom: 20, }}>
|
||||
When running this workflow, the output will be shown as a Markdown object by default, with JSON objects being rendered. By adding nodes below, they will be shown while the workflow is running as soon as they get a result. Failing/Skipped nodes are not shown. This makes it possible to track progress for more complex usecases.
|
||||
</Typography>
|
||||
|
||||
<FormControl style={{marginTop: 15, }}>
|
||||
<FormControl style={{ marginTop: 15, }}>
|
||||
<Select
|
||||
defaultValue=""
|
||||
id="output-yield-control"
|
||||
label="Yielding nodes"
|
||||
multiple
|
||||
fullWidth
|
||||
style={{width: 500, }}
|
||||
style={{ width: 500, }}
|
||||
value={selectedYieldActions === [] ? ["none"] : selectedYieldActions}
|
||||
renderValue={(selected) => selected.join(', ')}
|
||||
onChange={(event) => {
|
||||
@@ -1135,7 +1139,7 @@ const EditWorkflow = (props) => {
|
||||
value={action.id}
|
||||
>
|
||||
<Tooltip title={action.app_name} key={actionIndex}>
|
||||
<img src={action.large_image !== undefined && action.large_image !== null && action.large_image.length > 0 ? action.large_image : theme.palette.defaultImage} style={{width: 20, height: 20, marginRight: 10, }} />
|
||||
<img src={action.large_image !== undefined && action.large_image !== null && action.large_image.length > 0 ? action.large_image : theme.palette.defaultImage} style={{ width: 20, height: 20, marginRight: 10, }} />
|
||||
</Tooltip>
|
||||
{action.label}
|
||||
</MenuItem>
|
||||
@@ -1147,11 +1151,26 @@ const EditWorkflow = (props) => {
|
||||
</div>
|
||||
: null}
|
||||
|
||||
{/*!isEditing ? <>
|
||||
<div style={{ marginTop: 20, }}>
|
||||
<FormControlLabel
|
||||
control={<Checkbox />}
|
||||
label="Create workflow as code"
|
||||
style={{ marginTop: '12px' }}
|
||||
onChange={(e) => {
|
||||
setWorkflowAsCode(e.target.checked)
|
||||
workflow.workflow_as_code = e.target.checked
|
||||
setWorkflow(workflow)
|
||||
setInnerWorkflow(workflow)
|
||||
}}
|
||||
/>
|
||||
|
||||
</div>
|
||||
</> : null*/}
|
||||
|
||||
<Tooltip color="primary" title={"Add more details"} placement="top">
|
||||
<Button
|
||||
style={{ margin: "auto", marginTop: 50, marginBottom: 100, textAlign: "center", textTransform: "none", }}
|
||||
style={{ margin: "auto", marginTop: 50, marginBottom: 10, textAlign: "center", textTransform: "none", }}
|
||||
variant="outlined"
|
||||
disabled={newWorkflow === true}
|
||||
color="secondary"
|
||||
@@ -1159,24 +1178,25 @@ const EditWorkflow = (props) => {
|
||||
setShowMoreClicked(!showMoreClicked);
|
||||
}}
|
||||
>
|
||||
{showMoreClicked ? <ExpandLessIcon style={{marginRight: 10, }}/> : <ExpandMoreIcon style={{marginRight: 10, }}/>}
|
||||
{showMoreClicked ? "Less Options": "More Options"}
|
||||
{showMoreClicked ? <ExpandLessIcon style={{ marginRight: 10, }} /> : <ExpandMoreIcon style={{ marginRight: 10, }} />}
|
||||
{showMoreClicked ? "Less Options" : "More Options"}
|
||||
|
||||
</Button>
|
||||
</Tooltip>
|
||||
|
||||
</div>
|
||||
|
||||
</DialogContent>
|
||||
|
||||
|
||||
{newWorkflow === true ?
|
||||
<span style={{marginTop: 30, }}>
|
||||
<Typography variant="h6" style={{marginLeft: 30, paddingBottom: 0, }}>
|
||||
<span style={{ marginTop: 30, }}>
|
||||
<Typography variant="h6" style={{ marginLeft: 30, paddingBottom: 0, }}>
|
||||
Relevant Workflows
|
||||
</Typography>
|
||||
|
||||
{priority === null || priority === undefined ? null :
|
||||
<div style={{marginLeft: 30, }}>
|
||||
<div style={{ marginLeft: 30, }}>
|
||||
<WorkflowTemplatePopup
|
||||
userdata={userdata}
|
||||
globalUrl={globalUrl}
|
||||
@@ -1214,7 +1234,7 @@ const EditWorkflow = (props) => {
|
||||
</div>
|
||||
: null*/}
|
||||
</FormControl>
|
||||
</Drawer>
|
||||
</Drawer >
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -114,6 +114,7 @@ const CodeEditor = (props) => {
|
||||
editorData,
|
||||
|
||||
setAiQueryModalOpen,
|
||||
fullScreenMode
|
||||
} = props
|
||||
|
||||
const [localcodedata, setlocalcodedata] = React.useState(codedata === undefined || codedata === null || codedata.length === 0 ? "" : codedata);
|
||||
@@ -999,6 +1000,55 @@ const CodeEditor = (props) => {
|
||||
}
|
||||
}
|
||||
|
||||
if (fullScreenMode) {
|
||||
return (
|
||||
<AceEditor
|
||||
mode="python"
|
||||
theme="gruvbox"
|
||||
value={localcodedata}
|
||||
onChange={(value, editor) => {
|
||||
// setlocalcodedata(value)
|
||||
// expectedOutput(value)
|
||||
// highlight_variables(value,editor)
|
||||
setlocalcodedata(value)
|
||||
setcodedata(value)
|
||||
}}
|
||||
name="python-editor"
|
||||
fontSize={14}
|
||||
width="100%"
|
||||
height="100%"
|
||||
showPrintMargin={false}
|
||||
showGutter={true}
|
||||
markers={markers}
|
||||
highlightActiveLine={false}
|
||||
|
||||
enableBasicAutocompletion={true}
|
||||
completers={[customCompleter]}
|
||||
|
||||
style={{
|
||||
wordBreak: "break-word",
|
||||
marginTop: 0,
|
||||
paddingBottom: 10,
|
||||
overflowY: "auto",
|
||||
whiteSpace: "pre-wrap",
|
||||
wordWrap: "break-word",
|
||||
backgroundColor: "rgba(40,40,40,1)",
|
||||
zIndex: activeDialog === "codeeditor" ? 1200 : 1100,
|
||||
}}
|
||||
|
||||
setOptions={{
|
||||
enableBasicAutocompletion: true,
|
||||
enableLiveAutocompletion: true,
|
||||
enableSnippets: true,
|
||||
showLineNumbers: true,
|
||||
tabSize: 4,
|
||||
fontFamily: "'JetBrains Mono', Consolas, monospace",
|
||||
useSoftTabs: true
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
aria-labelledby="draggable-dialog-title"
|
||||
@@ -1130,7 +1180,7 @@ const CodeEditor = (props) => {
|
||||
*/}
|
||||
{ isFileEditor ? null :
|
||||
<div style={{display: "flex", maxHeight: 40, }}>
|
||||
{selectedAction.name === "execute_python" ?
|
||||
{selectedAction?.name === "execute_python" ?
|
||||
<Typography variant="body1" style={{marginTop: 5, }}>
|
||||
Run Python Code
|
||||
</Typography>
|
||||
@@ -1300,7 +1350,7 @@ const CodeEditor = (props) => {
|
||||
maxHeight: 650,
|
||||
}}
|
||||
>
|
||||
{actionlist.map((innerdata) => {
|
||||
{actionlist?.map((innerdata) => {
|
||||
const icon =
|
||||
innerdata.type === "action" ? (
|
||||
<AppsIcon style={{ marginRight: 10 }} />
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* eslint-disable react/no-multi-comp */
|
||||
import React, { useState, useEffect, useLayoutEffect, memo, useMemo, useRef } from "react";
|
||||
import React, { useState, useEffect, useLayoutEffect, memo, useMemo, useRef, useContext } from "react";
|
||||
import ReactDOM from "react-dom"
|
||||
|
||||
import theme from "../theme.jsx";
|
||||
@@ -72,6 +72,8 @@ import {
|
||||
ButtonGroup,
|
||||
} from "@mui/material";
|
||||
|
||||
import CodeIcon from '@mui/icons-material/Code';
|
||||
|
||||
import {
|
||||
Folder as FolderIcon,
|
||||
VerifiedUser as VerifiedUserIcon,
|
||||
@@ -151,6 +153,8 @@ import PaperComponent from "../components/PaperComponent.jsx"
|
||||
import ExtraApps from "../components/ExtraApps.jsx"
|
||||
import EditWorkflow from "../components/EditWorkflow.jsx"
|
||||
import { act } from "react";
|
||||
import { Context } from "../context/ContextApi.jsx";
|
||||
import transitions from "@material-ui/core/styles/transitions.js";
|
||||
// import AppStats from "../components/AppStats.jsx";
|
||||
const noImage = "/public/no_image.png";
|
||||
|
||||
@@ -396,6 +400,9 @@ const AngularWorkflow = (defaultprops) => {
|
||||
props.match = {}
|
||||
props.match.params = params
|
||||
|
||||
const { leftSideBarOpenByClick, windowWidth } = useContext(Context)
|
||||
const [workflowAsCode, setWorkflowAsCode] = useState(false);
|
||||
|
||||
var to_be_copied = "";
|
||||
const [firstrequest, setFirstrequest] = React.useState(true);
|
||||
const [cystyle] = useState(cytoscapestyle);
|
||||
@@ -801,6 +808,15 @@ const releaseToConnectLabel = "Release to Connect"
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
console.log("Loaded workflow: ", workflow)
|
||||
if (workflow.actions?.length == 1) {
|
||||
if (workflow.actions[0].app_id == "3e320a20966d33c9b7e6790b2705f0bf") {
|
||||
setWorkflowAsCode(true);
|
||||
}
|
||||
}
|
||||
}, [workflow]);
|
||||
|
||||
// Event for making sure app is correct
|
||||
useEffect(() => {
|
||||
if (selectedApp === undefined || selectedApp === null && selectedApp.app_name === undefined) {
|
||||
@@ -3227,6 +3243,10 @@ const releaseToConnectLabel = "Release to Connect"
|
||||
|
||||
cy.add(nodeData)
|
||||
|
||||
if (workflowAsCode) {
|
||||
setWorkflowAsCode(false)
|
||||
}
|
||||
|
||||
// Wait 100ms then add a style for it
|
||||
setTimeout(() => {
|
||||
const node = cy.getElementById(chunkJson.id)
|
||||
@@ -6318,6 +6338,10 @@ const releaseToConnectLabel = "Release to Connect"
|
||||
}
|
||||
}
|
||||
|
||||
if (nodedata.app_id == "3e320a20966d33c9b7e6790b2705f0bf") {
|
||||
setWorkflowAsCode(true);
|
||||
}
|
||||
|
||||
if (nodedata.decorator !== true && nodedata.attachedTo === undefined) {
|
||||
var newdata = JSON.parse(JSON.stringify(nodedata))
|
||||
newdata.large_image = ""
|
||||
@@ -9002,7 +9026,7 @@ const releaseToConnectLabel = "Release to Connect"
|
||||
});
|
||||
};
|
||||
|
||||
const parsedHeight = isMobile ? bodyHeight - appBarSize * 4 : bodyHeight - appBarSize - 50
|
||||
const parsedHeight = isMobile ? bodyHeight - appBarSize * 4 : userdata?.support ? bodyHeight - 80 : bodyHeight - appBarSize - 50
|
||||
const appViewStyle = {
|
||||
marginLeft: 5,
|
||||
marginRight: 5,
|
||||
@@ -9342,6 +9366,7 @@ const releaseToConnectLabel = "Release to Connect"
|
||||
minHeight: parsedHeight,
|
||||
maxHeight: parsedHeight,
|
||||
overflow: "hidden",
|
||||
paddingTop: userdata?.support ? 10 : 0,
|
||||
}}
|
||||
>
|
||||
{thisview}
|
||||
@@ -11016,11 +11041,14 @@ const releaseToConnectLabel = "Release to Connect"
|
||||
iterations += 1;
|
||||
}
|
||||
|
||||
|
||||
// Remove on the end as we don't want to remove everything
|
||||
results = results.filter((data) => data.id !== action.id)
|
||||
results = results.filter((data) => data.type === "ACTION" || data.app_name === "Shuffle Workflow" || data.app_name === "User Input")
|
||||
results.push({ label: "Execution Argument", type: "INTERNAL" })
|
||||
|
||||
console.log(results)
|
||||
|
||||
return results
|
||||
}
|
||||
|
||||
@@ -11050,9 +11078,9 @@ const releaseToConnectLabel = "Release to Connect"
|
||||
const minSize = 370
|
||||
var rightsidebarStyle = {
|
||||
position: "fixed",
|
||||
top: appBarSize + 25,
|
||||
top: userdata?.support ? appBarSize - 35 : appBarSize + 25,
|
||||
right: 25,
|
||||
height: "80vh",
|
||||
height: userdata?.support ? "90vh": "80vh",
|
||||
width: isMobile ? "100%" : minSize,
|
||||
minWidth: minSize,
|
||||
maxWidth: 600,
|
||||
@@ -15961,24 +15989,33 @@ const releaseToConnectLabel = "Release to Connect"
|
||||
const cytoscapeViewWidths = isMobile ? 50 : 950;
|
||||
const bottomBarStyle = {
|
||||
position: "fixed",
|
||||
right: isMobile ? 20 : 20,
|
||||
bottom: isMobile ? undefined : 0,
|
||||
top: isMobile ? appBarSize + 55 : undefined,
|
||||
left: isMobile ? undefined : leftBarSize,
|
||||
minWidth: cytoscapeViewWidths,
|
||||
maxWidth: cytoscapeViewWidths,
|
||||
transition: "all 0.3s ease",
|
||||
minWidth: userdata?.support && windowWidth < 1600 && leftSideBarOpenByClick ? 800 : cytoscapeViewWidths,
|
||||
maxWidth: userdata?.support && windowWidth < 1600 && leftSideBarOpenByClick ? 800 : cytoscapeViewWidths,
|
||||
marginLeft: 20,
|
||||
marginBottom: 20,
|
||||
marginBottom: 30,
|
||||
zIndex: 10,
|
||||
};
|
||||
transform: isMobile
|
||||
? `translateX(20px)`
|
||||
: `translateX(${userdata?.support
|
||||
? leftSideBarOpenByClick ? 340 : 330
|
||||
: leftBarSize}px)`,
|
||||
top: isMobile ? appBarSize + 55 : undefined,
|
||||
bottom: isMobile ? undefined : 0,
|
||||
};
|
||||
|
||||
const topBarStyle = {
|
||||
position: "fixed",
|
||||
right: 0,
|
||||
left: isMobile ? 20 : leftBarSize + 20,
|
||||
top: isMobile ? 30 : appBarSize + 20,
|
||||
top: isMobile ? 30 : userdata?.support ? appBarSize - 20 : appBarSize + 20,
|
||||
pointerEvents: "none",
|
||||
}
|
||||
transition: "transform 0.3s ease",
|
||||
transform: isMobile
|
||||
? `translateX(20px)`
|
||||
: userdata?.support
|
||||
? `translateX(${leftSideBarOpenByClick ? 340 : 330}px)`
|
||||
: `translateX(${leftBarSize + 20}px)`,
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -16028,6 +16065,26 @@ const releaseToConnectLabel = "Release to Connect"
|
||||
pointerEvents: "none",
|
||||
}}>{workflow.name}</h2>
|
||||
</Breadcrumbs>
|
||||
{workflowAsCode && (
|
||||
<Tooltip title="Switch to Code View">
|
||||
<Button
|
||||
startIcon={<CodeIcon />}
|
||||
variant="outlined"
|
||||
color="secondary"
|
||||
onClick={() => {
|
||||
window.location.href = `/workflows/${workflow.id}/code`
|
||||
}}
|
||||
style={{
|
||||
marginTop: 10,
|
||||
marginLeft: 5,
|
||||
height: 40,
|
||||
pointerEvents: "auto",
|
||||
}}
|
||||
>
|
||||
Build this workflow as code
|
||||
</Button>
|
||||
</Tooltip>
|
||||
)}
|
||||
|
||||
{!distributedFromParent ?
|
||||
isCorrectOrg ? null :
|
||||
@@ -16706,11 +16763,12 @@ const releaseToConnectLabel = "Release to Connect"
|
||||
style={{
|
||||
border: "1px solid rgba(255,255,255,0.1)",
|
||||
position: "absolute",
|
||||
bottom: 130,
|
||||
left: leftBarSize+20,
|
||||
bottom: 140,
|
||||
left: userdata?.support ? leftSideBarOpenByClick ? 620 : 435 : leftBarSize + 20,
|
||||
color: "white",
|
||||
padding: 10,
|
||||
borderRadius: theme.palette?.borderRadius,
|
||||
transition: "left 0.3s ease, top 0.3s ease",
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -20293,7 +20351,7 @@ const releaseToConnectLabel = "Release to Connect"
|
||||
);
|
||||
|
||||
const newView = (
|
||||
<div style={{ color: "white" }}>
|
||||
<div style={{ color: "white", marginLeft: userdata?.support ? leftSideBarOpenByClick ? 280 : 100 : 0, transition: "margin-left 0.3s ease", }}>
|
||||
<div
|
||||
style={{ display: "flex", borderTop: "1px solid rgba(91, 96, 100, 1)" }}
|
||||
>
|
||||
@@ -20330,7 +20388,7 @@ const releaseToConnectLabel = "Release to Connect"
|
||||
wheelSensitivity={0.25}
|
||||
style={{
|
||||
width: cytoscapeWidth,
|
||||
height: bodyHeight - appBarSize - 5,
|
||||
height: userdata?.support ? bodyHeight - 20 : bodyHeight - appBarSize - 5,
|
||||
backgroundColor: theme.palette.surfaceColor,
|
||||
}}
|
||||
stylesheet={cystyle}
|
||||
@@ -22225,7 +22283,7 @@ const releaseToConnectLabel = "Release to Connect"
|
||||
|
||||
const loadedCheck =
|
||||
isLoaded && workflowDone ? (
|
||||
<div>
|
||||
<div style={{overflow:'hidden'}}>
|
||||
{newView}
|
||||
<VariablesModal variableInfo={variableInfo} setVariableInfo={setVariableInfo} />
|
||||
<ExecutionVariableModal variableInfo={variableInfo} setVariableInfo={setVariableInfo} />
|
||||
@@ -22359,7 +22417,7 @@ const releaseToConnectLabel = "Release to Connect"
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div style={{width: 200, margin: "auto", marginTop: 300, textAlign: "center", }}>
|
||||
<div style={{width: 200, margin: "auto", paddingTop: 300, textAlign: "center", }}>
|
||||
<CircularProgress style={{}} />
|
||||
<Typography variant="body2" color="textSecondary" style={{marginTop: 10, }}>
|
||||
Loading Workflow & Apps...
|
||||
|
||||
@@ -302,7 +302,7 @@ const SetAuthentication = (props) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{ padding: 50, border: failed === true ? `1px solid ${red}` : "1px solid rgba(255,255,255,0.6)", borderRadius: theme.palette?.borderRadius, width: 500, margin: "auto", marginTop: 50, itemAlign: "center", textAlign: "center",}}>
|
||||
<div style={{ padding: 50, border: failed === true ? `1px solid ${red}` : "1px solid rgba(255,255,255,0.6)", borderRadius: theme.palette?.borderRadius, width: 500, margin: "auto", paddingTop: 50, itemAlign: "center", textAlign: "center",}}>
|
||||
<Typography
|
||||
variant="h4"
|
||||
style={{ marginLeft: "auto", marginRight: "auto", marginTop: 50}}
|
||||
|
||||
@@ -105,13 +105,11 @@ const useStyles = makeStyles(() => {
|
||||
display: "none",
|
||||
},
|
||||
"& .MuiDataGrid-colCell, .MuiDataGrid-cell": {
|
||||
borderRight: `1px solid ${
|
||||
theme?.palette?.type === "light" ? "white" : "#303030"
|
||||
borderRight: `1px solid ${theme?.palette?.type === "light" ? "white" : "#303030"
|
||||
}`,
|
||||
},
|
||||
"& .MuiDataGrid-columnsContainer, .MuiDataGrid-cell": {
|
||||
borderBottom: `1px solid ${
|
||||
theme?.palette?.type === "light" ? "#f0f0f0" : "#303030"
|
||||
borderBottom: `1px solid ${theme?.palette?.type === "light" ? "#f0f0f0" : "#303030"
|
||||
}`,
|
||||
},
|
||||
"& .MuiDataGrid-cell": {
|
||||
@@ -157,7 +155,7 @@ export const GetIconInfo = (action) => {
|
||||
"preview",
|
||||
],
|
||||
},
|
||||
{ key: "add", values: ["add", "accept", ] },
|
||||
{ key: "add", values: ["add", "accept",] },
|
||||
{ key: "delete", values: ["delete", "remove", "clear", "clean", "dismiss",] },
|
||||
{
|
||||
key: "send",
|
||||
@@ -175,7 +173,7 @@ export const GetIconInfo = (action) => {
|
||||
},
|
||||
{
|
||||
key: "repeat",
|
||||
values: ["repeat", "retry", "pause", "skip", "copy", "replicat", "demo", ],
|
||||
values: ["repeat", "retry", "pause", "skip", "copy", "replicat", "demo",],
|
||||
},
|
||||
{ key: "execute", values: ["execute", "run", "play", "raise"] },
|
||||
{ key: "extract", values: ["extract", "unpack", "decompress", "open"] },
|
||||
@@ -209,7 +207,7 @@ export const GetIconInfo = (action) => {
|
||||
var selectedKey = ""
|
||||
if (action.app_name == "Integration Framework") {
|
||||
selectedKey = "magic"
|
||||
}else if (action.name === undefined || action.name === null) {
|
||||
} else if (action.name === undefined || action.name === null) {
|
||||
} else {
|
||||
const actionname = action.name.toLowerCase()
|
||||
for (var key in iconList) {
|
||||
@@ -498,7 +496,7 @@ export const validateJson = (showResult) => {
|
||||
|
||||
var result = showResult;
|
||||
try {
|
||||
result = jsonvalid ? JSON.parse(showResult, {"storeAsString": true}) : showResult;
|
||||
result = jsonvalid ? JSON.parse(showResult, { "storeAsString": true }) : showResult;
|
||||
} catch (e) {
|
||||
////console.log("Failed parsing JSON even though its valid: ", e)
|
||||
jsonvalid = false;
|
||||
@@ -665,7 +663,7 @@ const Workflows = (props) => {
|
||||
const [view, setView] = React.useState("grid");
|
||||
const [filters, setFilters] = React.useState([]);
|
||||
const [submitLoading, setSubmitLoading] = React.useState(false);
|
||||
const [actionImageList, setActionImageList] = React.useState([{"large_image": ""}])
|
||||
const [actionImageList, setActionImageList] = React.useState([{ "large_image": "" }])
|
||||
|
||||
const [firstLoad, setFirstLoad] = React.useState(true);
|
||||
const [showMoreClicked, setShowMoreClicked] = React.useState(false);
|
||||
@@ -841,7 +839,7 @@ const Workflows = (props) => {
|
||||
setApps(responseJson);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log("App loading error: "+error.toString());
|
||||
console.log("App loading error: " + error.toString());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1038,7 +1036,7 @@ const Workflows = (props) => {
|
||||
// Do backwards so it doesn't change
|
||||
toast("Starting deletion of workflows. This might take a while.")
|
||||
for (var i = selectedWorkflowIndexes.length - 1; i >= 0; i--) {
|
||||
const workflow = filteredWorkflows[selectedWorkflowIndexes[i]-1]
|
||||
const workflow = filteredWorkflows[selectedWorkflowIndexes[i] - 1]
|
||||
if (workflow !== undefined && workflow !== null && workflow.id !== undefined && workflow.id !== null) {
|
||||
deleteWorkflow(workflow.id, true)
|
||||
}
|
||||
@@ -1432,7 +1430,7 @@ const Workflows = (props) => {
|
||||
display: "flex",
|
||||
minWidth: isMobile ? "100%" : 1024,
|
||||
maxWidth: isMobile ? "100%" : 1024,
|
||||
margin: drawerWidth === 0 ? "auto" : `auto ${drawerWidth+100} auto auto`,
|
||||
margin: drawerWidth === 0 ? "auto" : `auto ${drawerWidth + 100} auto auto`,
|
||||
paddingBottom: 200,
|
||||
};
|
||||
|
||||
@@ -2021,7 +2019,7 @@ const Workflows = (props) => {
|
||||
continue
|
||||
}
|
||||
|
||||
if (appsFound.findIndex(data => data.app_name === parsedAction.app_name) < 0){
|
||||
if (appsFound.findIndex(data => data.app_name === parsedAction.app_name) < 0) {
|
||||
appsFound.push(parsedAction)
|
||||
}
|
||||
}
|
||||
@@ -2216,7 +2214,7 @@ const Workflows = (props) => {
|
||||
alt={foundOrg.name}
|
||||
src={foundOrg.image}
|
||||
style={imageStyle}
|
||||
onClick={() => {}}
|
||||
onClick={() => { }}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -2258,7 +2256,7 @@ const Workflows = (props) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{width: "100%", minWidth: 320, position: "relative", border: highlightIds.includes(data.id) ? "2px solid #f85a3e" : isDistributed || hasSuborgs ? "1px solid #40E0D0" : "inherit", borderRadius: theme.palette?.borderRadius, }}>
|
||||
<div style={{ width: "100%", minWidth: 320, position: "relative", border: highlightIds.includes(data.id) ? "2px solid #f85a3e" : isDistributed || hasSuborgs ? "1px solid #40E0D0" : "inherit", borderRadius: theme.palette?.borderRadius, }}>
|
||||
<Paper square style={paperAppStyle}>
|
||||
{selectedCategory !== "" ?
|
||||
<Tooltip title={`Usecase Category: ${selectedCategory}`} placement="bottom">
|
||||
@@ -2304,9 +2302,9 @@ const Workflows = (props) => {
|
||||
*/
|
||||
}}
|
||||
title={
|
||||
<div style={{width: "100%", minWidth: 250, maxWidth: 310, }}>
|
||||
<div style={{ width: "100%", minWidth: 250, maxWidth: 310, }}>
|
||||
{data.image !== undefined && data.image !== null && data.image.length > 0 ?
|
||||
<img src={data.image} alt={data.name} style={{backgroundColor: theme.palette.surfaceColor, maxWidth: 300, minWidth: 250, borderRadius: theme.palette?.borderRadius, }} />
|
||||
<img src={data.image} alt={data.name} style={{ backgroundColor: theme.palette.surfaceColor, maxWidth: 300, minWidth: 250, borderRadius: theme.palette?.borderRadius, }} />
|
||||
: null}
|
||||
<Typography>
|
||||
Edit '{data.name}'
|
||||
@@ -2332,7 +2330,7 @@ const Workflows = (props) => {
|
||||
}}
|
||||
>
|
||||
<Link
|
||||
to={"/workflows/" + data.id}
|
||||
to={data.workflow_as_code ? `/workflows/${data.id}/code` : `/workflows/${data.id}`}
|
||||
style={{ textDecoration: "none", color: "inherit" }}
|
||||
>
|
||||
{parsedName}
|
||||
@@ -2342,8 +2340,8 @@ const Workflows = (props) => {
|
||||
</Grid>
|
||||
<Grid item style={workflowActionStyle}>
|
||||
{appGroup.length > 0 ?
|
||||
<div style={{display: "flex", marginTop: 8, }}>
|
||||
<AvatarGroup max={4} style={{marginLeft: 5, maxHeight: 24,}}>
|
||||
<div style={{ display: "flex", marginTop: 8, }}>
|
||||
<AvatarGroup max={4} style={{ marginLeft: 5, maxHeight: 24, }}>
|
||||
{appGroup.map((data, index) => {
|
||||
return (
|
||||
<div
|
||||
@@ -2359,7 +2357,7 @@ const Workflows = (props) => {
|
||||
}}
|
||||
>
|
||||
<Tooltip color="primary" title={data.app_name} placement="bottom">
|
||||
<Avatar alt={data.app_name} src={data.large_image} style={{width: 24, height: 24}}/>
|
||||
<Avatar alt={data.app_name} src={data.large_image} style={{ width: 24, height: 24 }} />
|
||||
</Tooltip>
|
||||
</div>
|
||||
)
|
||||
@@ -2509,7 +2507,7 @@ const Workflows = (props) => {
|
||||
: null}
|
||||
</Grid>
|
||||
{data.actions !== undefined && data.actions !== null ? (
|
||||
<div style={{position: "absolute", top: 10, right: 10, }}>
|
||||
<div style={{ position: "absolute", top: 10, right: 10, }}>
|
||||
<IconButton
|
||||
aria-label="more"
|
||||
aria-controls="long-menu"
|
||||
@@ -2524,7 +2522,7 @@ const Workflows = (props) => {
|
||||
) : null}
|
||||
{(data.sharing !== undefined && data.sharing !== null && data.sharing === "form") || (data?.form_control?.input_markdown !== undefined && data?.form_control?.input_markdown !== null && data?.form_control?.input_markdown !== "") ?
|
||||
<Tooltip title="Edit Form" placement="top">
|
||||
<div style={{position: "absolute", top: 45, right: 8, }}>
|
||||
<div style={{ position: "absolute", top: 45, right: 8, }}>
|
||||
<IconButton
|
||||
aria-label="more"
|
||||
aria-controls="long-menu"
|
||||
@@ -2557,6 +2555,7 @@ const Workflows = (props) => {
|
||||
currentUsecases,
|
||||
inputblogpost,
|
||||
inputstatus,
|
||||
workflow_as_code,
|
||||
) => {
|
||||
|
||||
var method = "POST";
|
||||
@@ -2578,6 +2577,10 @@ const Workflows = (props) => {
|
||||
// FIXME: Loop triggers and turn them off?
|
||||
}
|
||||
|
||||
if (workflow_as_code !== undefined && workflow_as_code !== null && workflow_as_code !== "") {
|
||||
workflowdata["workflow_as_code"] = workflow_as_code
|
||||
}
|
||||
|
||||
workflowdata["name"] = name;
|
||||
workflowdata["description"] = description;
|
||||
if (tags !== undefined) {
|
||||
@@ -2587,6 +2590,7 @@ const Workflows = (props) => {
|
||||
workflowdata["blogpost"] = inputblogpost
|
||||
workflowdata["status"] = inputstatus
|
||||
|
||||
|
||||
if (defaultReturnValue !== undefined) {
|
||||
workflowdata["default_return_value"] = defaultReturnValue;
|
||||
}
|
||||
@@ -2629,7 +2633,11 @@ const Workflows = (props) => {
|
||||
|
||||
if (redirect) {
|
||||
//window.location.pathname = "/workflows/" + responseJson["id"];
|
||||
navigate("/workflows/" + responseJson["id"])
|
||||
|
||||
// navigate("/workflows/" + responseJson["id"])
|
||||
navigate(`/workflows/${responseJson["id"]}` + (workflow_as_code ? "/code" : ""))
|
||||
|
||||
// {data.workflow_as_code ? `/workflows/${data.id}/code` : `/workflows/${data.id}`}
|
||||
//setModalOpen(false);
|
||||
} else if (!redirect) {
|
||||
// Update :)
|
||||
@@ -2872,8 +2880,8 @@ const Workflows = (props) => {
|
||||
<Grid item>
|
||||
<div style={{ display: "flex" }}>
|
||||
{appGroup.length > 0 ?
|
||||
<div style={{display: "flex", marginTop: 3, }}>
|
||||
<AvatarGroup max={4} style={{marginLeft: 5, maxHeight: 24,}}>
|
||||
<div style={{ display: "flex", marginTop: 3, }}>
|
||||
<AvatarGroup max={4} style={{ marginLeft: 5, maxHeight: 24, }}>
|
||||
{appGroup.map((data, index) => {
|
||||
return (
|
||||
<div
|
||||
@@ -2889,7 +2897,7 @@ const Workflows = (props) => {
|
||||
}}
|
||||
>
|
||||
<Tooltip color="primary" title={data.app_name} placement="bottom">
|
||||
<Avatar alt={data.app_name} src={data.large_image} style={{width: 24, height: 24}}/>
|
||||
<Avatar alt={data.app_name} src={data.large_image} style={{ width: 24, height: 24 }} />
|
||||
</Tooltip>
|
||||
</div>
|
||||
)
|
||||
@@ -3064,7 +3072,7 @@ const Workflows = (props) => {
|
||||
width: 100,
|
||||
sortable: false,
|
||||
disableClickEventBubbling: true,
|
||||
renderCell: (params) => {},
|
||||
renderCell: (params) => { },
|
||||
},
|
||||
];
|
||||
|
||||
@@ -3103,7 +3111,7 @@ const Workflows = (props) => {
|
||||
<div style={gridContainer}>
|
||||
<Tooltip title={`New Workflow`} placement="bottom">
|
||||
<IconButton
|
||||
style={{position: "absolute", top: 10, right: 50, zIndex: 1000}}
|
||||
style={{ position: "absolute", top: 10, right: 50, zIndex: 1000 }}
|
||||
onClick={() => {
|
||||
setModalOpen(true)
|
||||
setIsEditing(false)
|
||||
@@ -3114,7 +3122,7 @@ const Workflows = (props) => {
|
||||
</Tooltip>
|
||||
{filteredWorkflows.length === 0 ? null :
|
||||
<IconButton
|
||||
style={{position: "absolute", top: 10, right: 10, zIndex: 1000}}
|
||||
style={{ position: "absolute", top: 10, right: 10, zIndex: 1000 }}
|
||||
disabled={selectedWorkflowIndexes.length === 0}
|
||||
onClick={() => {
|
||||
setDeleteModalOpen(true)
|
||||
@@ -3197,9 +3205,9 @@ const Workflows = (props) => {
|
||||
margin="dense"
|
||||
fullWidth
|
||||
/>
|
||||
<div style={{display: "flex", marginTop: 10, }}>
|
||||
<div style={{ display: "flex", marginTop: 10, }}>
|
||||
<MuiChipsInput
|
||||
style={{ flex: 1}}
|
||||
style={{ flex: 1 }}
|
||||
InputProps={{
|
||||
style: {
|
||||
color: "white",
|
||||
@@ -3219,7 +3227,7 @@ const Workflows = (props) => {
|
||||
}}
|
||||
/>
|
||||
{usecases !== null && usecases !== undefined && usecases.length > 0 ?
|
||||
<FormControl style={{flex: 1, marginLeft: 5, }}>
|
||||
<FormControl style={{ flex: 1, marginLeft: 5, }}>
|
||||
<InputLabel htmlFor="grouped-select-usecase">Usecases</InputLabel>
|
||||
<Select
|
||||
defaultValue=""
|
||||
@@ -3262,7 +3270,7 @@ const Workflows = (props) => {
|
||||
setUpdate(Math.random());
|
||||
setSelectedUsecases(selectedUsecases)
|
||||
}}>
|
||||
<Checkbox style={{color: selectedUsecases.includes(subcase.name) ? usecase.color : theme.palette.inputColor}} checked={selectedUsecases.includes(subcase.name)} />
|
||||
<Checkbox style={{ color: selectedUsecases.includes(subcase.name) ? usecase.color : theme.palette.inputColor }} checked={selectedUsecases.includes(subcase.name)} />
|
||||
<ListItemText primary={subcase.name} />
|
||||
</MenuItem>
|
||||
)
|
||||
@@ -3276,7 +3284,7 @@ const Workflows = (props) => {
|
||||
</div>
|
||||
|
||||
{showMoreClicked ?
|
||||
<span style={{marginTop: 25, }}>
|
||||
<span style={{ marginTop: 25, }}>
|
||||
<TextField
|
||||
onBlur={(event) => {
|
||||
if (event.target.value.toLowerCase() === "test") {
|
||||
@@ -3330,7 +3338,7 @@ const Workflows = (props) => {
|
||||
: null}
|
||||
<Tooltip color="primary" title={"Add more details"} placement="top">
|
||||
<IconButton
|
||||
style={{ color: "white", margin: "auto", marginTop: 10, textAlign: "center", width: 50,}}
|
||||
style={{ color: "white", margin: "auto", marginTop: 10, textAlign: "center", width: 50, }}
|
||||
onClick={() => {
|
||||
setShowMoreClicked(!showMoreClicked);
|
||||
}}
|
||||
@@ -3624,7 +3632,7 @@ const Workflows = (props) => {
|
||||
<div style={workflowViewStyle}>
|
||||
<div style={{ display: "flex", marginTop: 25, }}>
|
||||
<div style={{ flex: 1 }}>
|
||||
<Typography variant="h1" style={{fontSize: 30}}>
|
||||
<Typography variant="h1" style={{ fontSize: 30 }}>
|
||||
Workflows
|
||||
</Typography>
|
||||
</div>
|
||||
@@ -3681,7 +3689,7 @@ const Workflows = (props) => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{width: "100%", minHeight: isMobile ? 0 : hasWorkflows ? 0 : 51, maxHeight: isMobile ? 0 : 51, marginTop: 10, }}>
|
||||
<div style={{ width: "100%", minHeight: isMobile ? 0 : hasWorkflows ? 0 : 51, maxHeight: isMobile ? 0 : 51, marginTop: 10, }}>
|
||||
{!isMobile && !hasWorkflows && usecases !== null && usecases !== undefined && usecases.length > 0 ?
|
||||
<div style={{ display: "flex", }}>
|
||||
{usecases.map((usecase, index) => {
|
||||
@@ -3689,7 +3697,7 @@ const Workflows = (props) => {
|
||||
return null
|
||||
}
|
||||
|
||||
const percentDone = usecase.matches.length > 0 ? parseInt(usecase.matches.length/usecase.list.length*100) : 0
|
||||
const percentDone = usecase.matches.length > 0 ? parseInt(usecase.matches.length / usecase.list.length * 100) : 0
|
||||
if (percentDone === 0) {
|
||||
usecase = findMatches(usecase, workflows)
|
||||
}
|
||||
@@ -3702,7 +3710,7 @@ const Workflows = (props) => {
|
||||
backgroundImage: `linear-gradient(to right, ${usecase.color}, ${usecase.color} ${percentDone}%, transparent ${percentDone}%, transparent 100%)`,
|
||||
backgroundColor: filters.includes(usecase.name.toLowerCase()) ? null : theme.palette.surfaceColor,
|
||||
borderRadius: theme.palette?.borderRadius,
|
||||
marginRight: index === usecases.length-1 ? 0 : 10,
|
||||
marginRight: index === usecases.length - 1 ? 0 : 10,
|
||||
cursor: "pointer",
|
||||
border: `2px solid ${usecase.color}`,
|
||||
overflow: "hidden",
|
||||
@@ -3719,10 +3727,10 @@ const Workflows = (props) => {
|
||||
}}
|
||||
>
|
||||
<span style={{ textDecoration: "none", display: "flex", }}>
|
||||
<Typography variant="body1" color="textPrimary" style={{flex: 4, }}>
|
||||
<Typography variant="body1" color="textPrimary" style={{ flex: 4, }}>
|
||||
{usecase.name}
|
||||
</Typography>
|
||||
<Typography variant="body2" color="textSecondary" style={{flex: 1, marginTop: 0,}}>
|
||||
<Typography variant="body2" color="textSecondary" style={{ flex: 1, marginTop: 0, }}>
|
||||
{usecase.matches.length}/{usecase.list.length}
|
||||
</Typography>
|
||||
</span>
|
||||
@@ -3805,8 +3813,8 @@ const Workflows = (props) => {
|
||||
>
|
||||
<img
|
||||
style={{
|
||||
height: isCloud ? imgSize : imgSize+4,
|
||||
width: isCloud ? imgSize : imgSize+4,
|
||||
height: isCloud ? imgSize : imgSize + 4,
|
||||
width: isCloud ? imgSize : imgSize + 4,
|
||||
position: "absolute",
|
||||
top: -2,
|
||||
left: -2,
|
||||
@@ -3842,24 +3850,26 @@ const Workflows = (props) => {
|
||||
) : null}
|
||||
|
||||
{userdata.priorities !== undefined && userdata.priorities !== null && userdata.priorities.length > 0 && userdata.priorities[0].name.includes("CPU") && userdata.priorities[0].active === true ?
|
||||
<div style={{border: "1px solid rgba(255,255,255,0.1)" , borderRadius: theme.palette?.borderRadius, marginTop: 10,
|
||||
marginBottom: 10, padding: 15, textAlign: "center" , height: 70, textAlign: "left" , backgroundColor:
|
||||
theme.palette.surfaceColor, display: "flex" , maxHeight: "105px", minHeight: "110px"}}
|
||||
<div style={{
|
||||
border: "1px solid rgba(255,255,255,0.1)", borderRadius: theme.palette?.borderRadius, marginTop: 10,
|
||||
marginBottom: 10, padding: 15, textAlign: "center", height: 70, textAlign: "left", backgroundColor:
|
||||
theme.palette.surfaceColor, display: "flex", maxHeight: "105px", minHeight: "110px"
|
||||
}}
|
||||
>
|
||||
<div style={{flex: 2, overflow: "hidden",}}>
|
||||
<div style={{ flex: 2, overflow: "hidden", }}>
|
||||
<Typography variant="body1" >
|
||||
{userdata.priorities[0].name}
|
||||
</Typography>
|
||||
<div style={{flex: "2 1 0%", overflow: "hidden"}}>
|
||||
<span style={{display: "flex", marginTop: "10px"}}>
|
||||
<Typography variant="body2" color="textSecondary" style={{marginTop: "3px"}}>
|
||||
<div style={{ flex: "2 1 0%", overflow: "hidden" }}>
|
||||
<span style={{ display: "flex", marginTop: "10px" }}>
|
||||
<Typography variant="body2" color="textSecondary" style={{ marginTop: "3px" }}>
|
||||
{userdata.priorities[0].description}
|
||||
</Typography>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{flex: 1, display: "flex", marginLeft: 30, }}>
|
||||
<Button style={{height: 50, borderRadius: 25, marginTop: 8, width: 175, backgroundColor: "rgba(255,255,255,0.8)"}} variant="contained" color="secondary" onClick={() => {navigate(userdata.priorities[0].url)}}>
|
||||
<div style={{ flex: 1, display: "flex", marginLeft: 30, }}>
|
||||
<Button style={{ height: 50, borderRadius: 25, marginTop: 8, width: 175, backgroundColor: "rgba(255,255,255,0.8)" }} variant="contained" color="secondary" onClick={() => { navigate(userdata.priorities[0].url) }}>
|
||||
explore
|
||||
</Button>
|
||||
{/*
|
||||
@@ -3922,7 +3932,7 @@ const Workflows = (props) => {
|
||||
|
||||
{foundPriority != null && filteredWorkflows.length > 6 ?
|
||||
<Priority
|
||||
style={{marginTop: 15, }}
|
||||
style={{ marginTop: 15, }}
|
||||
globalUrl={globalUrl}
|
||||
priority={foundPriority}
|
||||
checkLogin={checkLogin}
|
||||
@@ -3994,7 +4004,7 @@ const Workflows = (props) => {
|
||||
const workflowDownloadModalOpen = loadWorkflowsModalOpen ? (
|
||||
<Dialog
|
||||
open={loadWorkflowsModalOpen}
|
||||
onClose={() => {}}
|
||||
onClose={() => { }}
|
||||
PaperProps={{
|
||||
style: {
|
||||
backgroundColor: theme.palette.surfaceColor,
|
||||
@@ -4125,25 +4135,25 @@ const Workflows = (props) => {
|
||||
//const [percentDone, setPercentDone] = React.useState(0)
|
||||
const percentDone = gettingStartedItems.filter((item) => item.done).length / gettingStartedItems.length * 100
|
||||
|
||||
const GettingStartedItem = ({item, index}) => {
|
||||
const GettingStartedItem = ({ item, index }) => {
|
||||
const [clicked, setClicked] = React.useState(false)
|
||||
const doneIcon = item.done ? <CheckCircleIcon style={{color: "#4caf50", marginRight: 10, }} /> : <RadioButtonUncheckedIcon disabled style={{color: "#bdbdbd", marginRight: 10, }} />
|
||||
const doneIcon = item.done ? <CheckCircleIcon style={{ color: "#4caf50", marginRight: 10, }} /> : <RadioButtonUncheckedIcon disabled style={{ color: "#bdbdbd", marginRight: 10, }} />
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{cursor: "pointer", padding: 20, borderBottom: "1px solid rgba(255,255,255,0.3", backgroundColor: !clicked ? "#1f2023" : theme.palette.inputColor, }}
|
||||
style={{ cursor: "pointer", padding: 20, borderBottom: "1px solid rgba(255,255,255,0.3", backgroundColor: !clicked ? "#1f2023" : theme.palette.inputColor, }}
|
||||
onClick={() => setClicked(true)}
|
||||
>
|
||||
<Typography variant="body2" style={{display: "flex", textDecoration: item.done ? "line-through" : "none", }}>
|
||||
<Typography variant="body2" style={{ display: "flex", textDecoration: item.done ? "line-through" : "none", }}>
|
||||
{doneIcon} {index + 1}. {item.name}
|
||||
</Typography>
|
||||
{clicked ?
|
||||
<span>
|
||||
<Typography variant="body2" style={{marginLeft: 30, }}>
|
||||
<Typography variant="body2" style={{ marginLeft: 30, }}>
|
||||
{item.description}
|
||||
</Typography>
|
||||
<Link to={item.link} style={{color: "inherit", textDecoration: "none", }}>
|
||||
<Button variant={item.done ? "outlined" : "contained"} color="primary" style={{marginLeft: 30, marginTop: 5, }}>
|
||||
<Link to={item.link} style={{ color: "inherit", textDecoration: "none", }}>
|
||||
<Button variant={item.done ? "outlined" : "contained"} color="primary" style={{ marginLeft: 30, marginTop: 5, }}>
|
||||
Configure
|
||||
</Button>
|
||||
</Link>
|
||||
@@ -4176,8 +4186,8 @@ const Workflows = (props) => {
|
||||
},
|
||||
}}
|
||||
>
|
||||
<div style={{backgroundColor: "#f86a3e", display: "flex", }}>
|
||||
<Typography variant="h6" style={{flex: 5, marginTop: 20, marginLeft: 20, marginBottom: 20, }}>
|
||||
<div style={{ backgroundColor: "#f86a3e", display: "flex", }}>
|
||||
<Typography variant="h6" style={{ flex: 5, marginTop: 20, marginLeft: 20, marginBottom: 20, }}>
|
||||
Getting Started
|
||||
</Typography>
|
||||
<Tooltip
|
||||
@@ -4193,28 +4203,28 @@ const Workflows = (props) => {
|
||||
localStorage.setItem(sidebarKey, "closed");
|
||||
}}
|
||||
>
|
||||
<ArrowRightIcon style={{color: "white"}} />
|
||||
<ArrowRightIcon style={{ color: "white" }} />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div style={{padding: 20, }}>
|
||||
<div style={{ padding: 20, }}>
|
||||
<Typography variant="body2">
|
||||
Setup progress: <b>{isNaN(percentDone) ? 0 : percentDone}%</b>
|
||||
</Typography>
|
||||
|
||||
<LinearProgress color="primary" variant="determinate" value={percentDone} style={{marginTop: 5, height: 7, borderRadius: theme.palette?.borderRadius, }} />
|
||||
<LinearProgress color="primary" variant="determinate" value={percentDone} style={{ marginTop: 5, height: 7, borderRadius: theme.palette?.borderRadius, }} />
|
||||
|
||||
<Typography variant="body2" style={{marginTop: 20, }}>
|
||||
<Typography variant="body2" style={{ marginTop: 20, }}>
|
||||
Follow these steps to get you up and running!
|
||||
</Typography>
|
||||
<Divider style={{marginTop: 20, }} />
|
||||
<Typography variant="body2" style={{color: "#f86a3e", marginTop: 20, cursor: "pointer", }} onClick={() => {
|
||||
<Divider style={{ marginTop: 20, }} />
|
||||
<Typography variant="body2" style={{ color: "#f86a3e", marginTop: 20, cursor: "pointer", }} onClick={() => {
|
||||
setVideoViewOpen(true)
|
||||
}}>
|
||||
<b>Watch 2-min introduction video</b>
|
||||
</Typography>
|
||||
</div>
|
||||
<div style={{borderTop: "1px solid rgba(255,255,255,0.3)", }}>
|
||||
<div style={{ borderTop: "1px solid rgba(255,255,255,0.3)", }}>
|
||||
{gettingStartedItems.map((item, index) => {
|
||||
return (
|
||||
<GettingStartedItem key={index} item={item} index={index} />
|
||||
@@ -4262,7 +4272,7 @@ const Workflows = (props) => {
|
||||
<iframe
|
||||
width="560"
|
||||
height="315"
|
||||
style={{margin: "0px auto 0px auto", width: 560, height: 315,}}
|
||||
style={{ margin: "0px auto 0px auto", width: 560, height: 315, }}
|
||||
src="https://www.youtube-nocookie.com/embed/rO7k9q3OgC0"
|
||||
title="Introduction video"
|
||||
frameborder="0"
|
||||
@@ -4280,7 +4290,7 @@ const Workflows = (props) => {
|
||||
<TourButton />
|
||||
</ShepherdTour>
|
||||
*/}
|
||||
<DropzoneWrapper onDrop={uploadFile} WorkflowView={WorkflowView}/>
|
||||
<DropzoneWrapper onDrop={uploadFile} WorkflowView={WorkflowView} />
|
||||
{/*modalView*/}
|
||||
{deleteModal}
|
||||
{exportVerifyModal}
|
||||
|
||||
Reference in New Issue
Block a user