Merge branch 'launch' into master
This commit is contained in:
@@ -17,6 +17,7 @@ COPY ./src /usr/src/app/src/
|
||||
COPY ./*.sh /usr/src/app/
|
||||
COPY ./*.json /usr/src/app/
|
||||
|
||||
RUN rm -rf /usr/src/app/node_modules/webpack
|
||||
RUN yarn build
|
||||
|
||||
# Production environment
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
{
|
||||
"name": "shuffler",
|
||||
"homepage": "https://shuffler.io",
|
||||
"version": "0.9.24",
|
||||
"version": "0.9.25",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.15.8",
|
||||
"@material-ui/core": "^4.5.2",
|
||||
"@material-ui/data-grid": "^4.0.0-alpha.22",
|
||||
"@material-ui/icons": "^4.11.2",
|
||||
@@ -13,8 +14,8 @@
|
||||
"@uiw/react-codemirror": "^3.2.1",
|
||||
"@use-it/interval": "^1.0.0",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"class-transformer": "^0.3.1",
|
||||
"create-react-app": "^2.0.3",
|
||||
"class-transformer": "^0.4.0",
|
||||
"create-react-app": "^4.0.3",
|
||||
"cytoscape": "^3.11.0",
|
||||
"cytoscape-clipboard": "^2.2.1",
|
||||
"cytoscape-cxtmenu": "^3.1.1",
|
||||
@@ -62,7 +63,7 @@
|
||||
"shellwords": "^0.1.1",
|
||||
"simplebar": "^4.2.3",
|
||||
"styled-components": "^4.4.0",
|
||||
"webpack": "4.44.2",
|
||||
"webpack": "^4.44.2",
|
||||
"websocket": "^1.0.30",
|
||||
"yaml": "^1.7.2",
|
||||
"yamljs": "^0.3.0",
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="46px" height="46px" viewBox="0 0 46 46" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
|
||||
<!-- Generator: Sketch 3.3.3 (12081) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>btn_google_light_focus_ios</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs>
|
||||
<filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="filter-1">
|
||||
<feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="0.5" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.168 0" in="shadowBlurOuter1" type="matrix" result="shadowMatrixOuter1"></feColorMatrix>
|
||||
<feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetOuter2"></feOffset>
|
||||
<feGaussianBlur stdDeviation="0.5" in="shadowOffsetOuter2" result="shadowBlurOuter2"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.084 0" in="shadowBlurOuter2" type="matrix" result="shadowMatrixOuter2"></feColorMatrix>
|
||||
<feMerge>
|
||||
<feMergeNode in="shadowMatrixOuter1"></feMergeNode>
|
||||
<feMergeNode in="shadowMatrixOuter2"></feMergeNode>
|
||||
<feMergeNode in="SourceGraphic"></feMergeNode>
|
||||
</feMerge>
|
||||
</filter>
|
||||
<rect id="path-2" x="0" y="0" width="40" height="40" rx="2"></rect>
|
||||
</defs>
|
||||
<g id="Google-Button" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
|
||||
<g id="9-PATCH" sketch:type="MSArtboardGroup" transform="translate(-668.000000, -160.000000)"></g>
|
||||
<g id="btn_google_light_focus" sketch:type="MSArtboardGroup" transform="translate(-1.000000, -1.000000)">
|
||||
<rect id="Rectangle-14" fill-opacity="0.3" fill="#4285F4" sketch:type="MSShapeGroup" x="1" y="1" width="46" height="46"></rect>
|
||||
<g id="button" sketch:type="MSLayerGroup" transform="translate(4.000000, 4.000000)" filter="url(#filter-1)">
|
||||
<g id="button-bg">
|
||||
<use fill="#FFFFFF" fill-rule="evenodd" sketch:type="MSShapeGroup" xlink:href="#path-2"></use>
|
||||
<use fill="none" xlink:href="#path-2"></use>
|
||||
<use fill="none" xlink:href="#path-2"></use>
|
||||
<use fill="none" xlink:href="#path-2"></use>
|
||||
</g>
|
||||
</g>
|
||||
<g id="logo_googleg_48dp" sketch:type="MSLayerGroup" transform="translate(15.000000, 15.000000)">
|
||||
<path d="M17.64,9.20454545 C17.64,8.56636364 17.5827273,7.95272727 17.4763636,7.36363636 L9,7.36363636 L9,10.845 L13.8436364,10.845 C13.635,11.97 13.0009091,12.9231818 12.0477273,13.5613636 L12.0477273,15.8195455 L14.9563636,15.8195455 C16.6581818,14.2527273 17.64,11.9454545 17.64,9.20454545 L17.64,9.20454545 Z" id="Shape" fill="#4285F4" sketch:type="MSShapeGroup"></path>
|
||||
<path d="M9,18 C11.43,18 13.4672727,17.1940909 14.9563636,15.8195455 L12.0477273,13.5613636 C11.2418182,14.1013636 10.2109091,14.4204545 9,14.4204545 C6.65590909,14.4204545 4.67181818,12.8372727 3.96409091,10.71 L0.957272727,10.71 L0.957272727,13.0418182 C2.43818182,15.9831818 5.48181818,18 9,18 L9,18 Z" id="Shape" fill="#34A853" sketch:type="MSShapeGroup"></path>
|
||||
<path d="M3.96409091,10.71 C3.78409091,10.17 3.68181818,9.59318182 3.68181818,9 C3.68181818,8.40681818 3.78409091,7.83 3.96409091,7.29 L3.96409091,4.95818182 L0.957272727,4.95818182 C0.347727273,6.17318182 0,7.54772727 0,9 C0,10.4522727 0.347727273,11.8268182 0.957272727,13.0418182 L3.96409091,10.71 L3.96409091,10.71 Z" id="Shape" fill="#FBBC05" sketch:type="MSShapeGroup"></path>
|
||||
<path d="M9,3.57954545 C10.3213636,3.57954545 11.5077273,4.03363636 12.4404545,4.92545455 L15.0218182,2.34409091 C13.4631818,0.891818182 11.4259091,0 9,0 C5.48181818,0 2.43818182,2.01681818 0.957272727,4.95818182 L3.96409091,7.29 C4.67181818,5.16272727 6.65590909,3.57954545 9,3.57954545 L9,3.57954545 Z" id="Shape" fill="#EA4335" sketch:type="MSShapeGroup"></path>
|
||||
<path d="M0,0 L18,0 L18,18 L0,18 L0,0 Z" id="Shape" sketch:type="MSShapeGroup"></path>
|
||||
</g>
|
||||
<g id="handles_square" sketch:type="MSLayerGroup"></g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.4 KiB |
@@ -276,7 +276,7 @@ const Header = props => {
|
||||
setAnchorEl(event.currentTarget);
|
||||
}}>
|
||||
<Badge badgeContent={notifications.length} color="primary">
|
||||
<NotificationsIcon color="secondary" style={{height: 35, width: 35,}} alt="Your username here" src="" />
|
||||
<NotificationsIcon color="secondary" style={{height: 30, width: 30,}} alt="Your username here" src="" />
|
||||
</Badge>
|
||||
</IconButton>
|
||||
<Menu
|
||||
@@ -325,7 +325,7 @@ const Header = props => {
|
||||
<IconButton color="primary" style={{zIndex: 10001, marginRight: 15, }} aria-controls="simple-menu" aria-haspopup="true" onClick={(event) => {
|
||||
setAnchorElAvatar(event.currentTarget);
|
||||
}}>
|
||||
<Avatar style={{height: 35, width: 35,}} alt="Your username here" src="" />
|
||||
<Avatar style={{height: 30, width: 30,}} alt="Your username here" src="" />
|
||||
</IconButton>
|
||||
<Menu
|
||||
id="simple-menu"
|
||||
@@ -439,7 +439,7 @@ const Header = props => {
|
||||
{notificationMenu}
|
||||
{userdata === undefined || userdata.admin === undefined || userdata.admin === null || !userdata.admin ? null :
|
||||
<Link to="/admin" style={hrefStyle}>
|
||||
<Button color="primary" variant="contained" style={{marginRight: 15, marginTop: 12}}>
|
||||
<Button color="primary" variant="outlined" style={{marginRight: 15, marginTop: 12}}>
|
||||
Admin
|
||||
</Button>
|
||||
</Link>
|
||||
|
||||
@@ -53,23 +53,31 @@ const AuthenticationOauth2 = (props) => {
|
||||
|
||||
var resources = ""
|
||||
if (scopes !== undefined && scopes !== null & scopes.length > 0) {
|
||||
//scopes.push("offline_access")
|
||||
resources = scopes.join(",")
|
||||
}
|
||||
|
||||
const authentication_url = authenticationType.token_uri
|
||||
|
||||
console.log("SCOPES2: ", resources)
|
||||
//console.log("AUTH: ", authenticationType)
|
||||
//console.log("SCOPES2: ", resources)
|
||||
const redirectUri = `${window.location.protocol}//${window.location.host}/set_authentication`
|
||||
var state = `workflow_id%3D${workflow.id}%26reference_action_id%3d${selectedAction.app_id}%26app_name%3d${selectedAction.app_name}%26app_id%3d${selectedAction.app_id}%26app_version%3d${selectedAction.app_version}%26authentication_url%3d${authentication_url}%26scope%3d${resources}%26client_id%3d${client_id}%26client_secret%3d${client_secret}`
|
||||
if (oauth_url !== undefined && oauth_url !== null && oauth_url.length > 0) {
|
||||
state += `%26oauth_url%3d${oauth_url}`
|
||||
console.log("ADDING OAUTH2 URL: ", state)
|
||||
}
|
||||
const url = `${authenticationType.redirect_uri}?client_id=${client_id}&redirect_uri=${redirectUri}&response_type=code&scope=${resources}&prompt=consent&state=${state}`
|
||||
|
||||
if (authenticationType.refresh_uri !== undefined && authenticationType.refresh_uri !== null && authenticationType.refresh_uri.length > 0) {
|
||||
state += `%26refresh_uri%3d${authenticationType.refresh_uri}`
|
||||
} else {
|
||||
state += `%26refresh_uri%3d${authentication_url}`
|
||||
}
|
||||
|
||||
const url = `${authenticationType.redirect_uri}?client_id=${client_id}&redirect_uri=${redirectUri}&response_type=code&scope=${resources}&prompt=consent&state=${state}&access_type=offline`
|
||||
|
||||
//const url = `https://accounts.zoho.com/oauth/v2/auth?response_type=code&client_id=${client_id}&scope=AaaServer.profile.Read&redirect_uri=${redirectUri}&prompt=consent`
|
||||
console.log("Full URI: ", url)
|
||||
console.log("Redirect Uri: ", redirectUri)
|
||||
//console.log("Full URI: ", url)
|
||||
//console.log("Redirect Uri: ", redirectUri)
|
||||
// &resource=https%3A%2F%2Fgraph.microsoft.com&
|
||||
|
||||
// FIXME: Awful, but works for prototyping
|
||||
|
||||
@@ -38,6 +38,7 @@ const OrgHeader = (props) => {
|
||||
const [workflowDownloadBranch, setWorkflowDownloadBranch] = React.useState(selectedOrganization.defaults === undefined ? defaultBranch : selectedOrganization.defaults.workflow_download_branch === undefined || selectedOrganization.defaults.workflow_download_branch.length === 0 ? defaultBranch : selectedOrganization.defaults.workflow_download_branch)
|
||||
const [ssoEntrypoint, setSsoEntrypoint] = React.useState(selectedOrganization.sso_config === undefined ? "" : selectedOrganization.sso_config.sso_entrypoint === undefined || selectedOrganization.sso_config.sso_entrypoint.length === 0 ? "" : selectedOrganization.sso_config.sso_entrypoint)
|
||||
const [ssoCertificate, setSsoCertificate] = React.useState(selectedOrganization.sso_config === undefined ? "" : selectedOrganization.sso_config.sso_certificate === undefined || selectedOrganization.sso_config.sso_certificate.length === 0 ? "" : selectedOrganization.sso_config.sso_certificate)
|
||||
const [notificationWorkflow, setNotificationWorkflow] = React.useState(selectedOrganization.defaults === undefined ? "" : selectedOrganization.defaults.notification_workflow === undefined || selectedOrganization.defaults.notification_workflow.length === 0 ? "" : selectedOrganization.defaults.notification_workflow)
|
||||
|
||||
const [file, setFile] = React.useState("")
|
||||
const [fileBase64, setFileBase64] = React.useState(selectedOrganization.image)
|
||||
@@ -113,7 +114,7 @@ const OrgHeader = (props) => {
|
||||
setFile(fileObject)
|
||||
}
|
||||
|
||||
console.log("USER: ", userdata)
|
||||
//console.log("USER: ", userdata)
|
||||
const orgSaveButton =
|
||||
<Tooltip title="Save any unsaved data" placement="bottom">
|
||||
<Button
|
||||
@@ -126,6 +127,7 @@ const OrgHeader = (props) => {
|
||||
"app_download_branch": appDownloadBranch,
|
||||
"workflow_download_repo": workflowDownloadUrl,
|
||||
"workflow_download_branch": workflowDownloadBranch,
|
||||
"notification_workflow": notificationWorkflow,
|
||||
},
|
||||
{
|
||||
"sso_entrypoint": ssoEntrypoint,
|
||||
@@ -232,6 +234,35 @@ const OrgHeader = (props) => {
|
||||
</IconButton>
|
||||
{expanded ?
|
||||
<Grid container spacing={3} style={{textAlign: "left"}}>
|
||||
<Grid item xs={12} style={{}}>
|
||||
<span>
|
||||
<Typography>
|
||||
Notification Workflow ID
|
||||
</Typography>
|
||||
<TextField
|
||||
required
|
||||
style={{flex: "1", marginTop: "5px", marginRight: "15px", backgroundColor: theme.palette.inputColor}}
|
||||
fullWidth={true}
|
||||
type="name"
|
||||
id="outlined-with-placeholder"
|
||||
margin="normal"
|
||||
variant="outlined"
|
||||
placeholder="ID of the workflow to receive notifications"
|
||||
value={notificationWorkflow}
|
||||
onChange={e => {
|
||||
setNotificationWorkflow(e.target.value)
|
||||
}}
|
||||
InputProps={{
|
||||
classes: {
|
||||
notchedOutline: classes.notchedOutline,
|
||||
},
|
||||
style:{
|
||||
color: "white",
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</span>
|
||||
</Grid>
|
||||
<Grid item xs={6} style={{}}>
|
||||
<span>
|
||||
<Typography>
|
||||
|
||||
@@ -49,6 +49,7 @@ const useStyles = makeStyles({
|
||||
// },
|
||||
//)
|
||||
|
||||
const openApiFieldDesc = "Generated by OpenAPI body example"
|
||||
const ParsedAction = (props) => {
|
||||
const {workflow, setWorkflow, setAction, setSelectedAction, setUpdate, appActionArguments, selectedApp, workflowExecutions, setSelectedResult, selectedAction, setSelectedApp, setSelectedTrigger, setSelectedEdge, setCurrentView, cy, setAuthenticationModalOpen,setVariablesModalOpen, setCodeModalOpen, selectedNameChange, rightsidebarStyle, showEnvironment, selectedActionEnvironment, environments, setNewSelectedAction, appApiViewStyle, globalUrl, setSelectedActionEnvironment, requiresAuthentication, hideExtraTypes, scrollConfig, setScrollConfig, authenticationType, appAuthentication, getAppAuthentication } = props
|
||||
|
||||
@@ -56,6 +57,8 @@ const ParsedAction = (props) => {
|
||||
const classes = useStyles()
|
||||
|
||||
const [expansionModalOpen, setExpansionModalOpen] = React.useState(false);
|
||||
const [hideBody, setHideBody] = React.useState(false)
|
||||
const [activateHidingBody, setActivateHidingBody] = React.useState(false)
|
||||
|
||||
const keywords = ["len(", "lower(", "upper(", "trim(", "split(", "length(", "number(", "parse(", "join("]
|
||||
const getParents = (action) => {
|
||||
@@ -258,7 +261,8 @@ const ParsedAction = (props) => {
|
||||
|
||||
if (actionlist.length === 0) {
|
||||
// FIXME: Have previous execution values in here
|
||||
actionlist.push({"type": "Execution Argument", "name": "Execution Argument", "value": "$exec", "highlight": "exec", "autocomplete": "exec", "example": "hello"})
|
||||
actionlist.push({"type": "Execution Argument", "name": "Execution Argument", "value": "$exec", "highlight": "exec", "autocomplete": "exec", "example": ""})
|
||||
actionlist.push({"type": "Shuffle DB", "name": "Shuffle DB", "value": "$shuffle_cache", "highlight": "shuffle", "autocomplete": "shuffle", "example": ""})
|
||||
if (workflow.workflow_variables !== null && workflow.workflow_variables !== undefined && workflow.workflow_variables.length > 0) {
|
||||
for (var key in workflow.workflow_variables) {
|
||||
const item = workflow.workflow_variables[key]
|
||||
@@ -788,12 +792,52 @@ const ParsedAction = (props) => {
|
||||
//setSelectedActionParameters(selectedActionParameters)
|
||||
}
|
||||
|
||||
var hideBodyButton = ""
|
||||
const hideBodyButtonValue =
|
||||
<div style={{marginTop: 25, border:"1px solid rgba(255,255,255,0.7)",borderTop: "1px solid rgba(255,255,255,0.7)", borderRadius: theme.palette.borderRadius, alignItems: "center", textAlign: "center",}}>
|
||||
<Tooltip color="secondary" title={"Automatically change body"} placement="top">
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Checkbox
|
||||
tabIndex="-1"
|
||||
checked={hideBody}
|
||||
style={{
|
||||
color: theme.palette.primary.secondary,
|
||||
}}
|
||||
onChange={(event) => {
|
||||
setHideBody(!hideBody)
|
||||
|
||||
for (var key in selectedActionParameters) {
|
||||
var currentItem = selectedActionParameters[key]
|
||||
|
||||
if (currentItem.description === openApiFieldDesc) {
|
||||
currentItem.field_active = !hideBody
|
||||
console.log("Changing", currentItem)
|
||||
}
|
||||
}
|
||||
}}
|
||||
name="requires_unique"
|
||||
/>
|
||||
}
|
||||
label={"Automatically fix body"}
|
||||
/>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
||||
if (selectedApp.generated && data.name === "body") {
|
||||
const regex = /\${(\w+)}/g
|
||||
const found = placeholder.match(regex)
|
||||
if (found === null) {
|
||||
|
||||
hideBodyButton = hideBodyButtonValue
|
||||
if (found === null || !hideBody) {
|
||||
//setExtraBodyFields([])
|
||||
//
|
||||
if (found === null) {
|
||||
setActivateHidingBody(true)
|
||||
}
|
||||
} else {
|
||||
console.log("SHOW BUTTON")
|
||||
|
||||
rows = "1"
|
||||
disabled = true
|
||||
openApiHelperText = "OpenAPI spec: fill the following fields."
|
||||
@@ -818,7 +862,7 @@ const ParsedAction = (props) => {
|
||||
selectedActionParameters.push({
|
||||
action_field: "",
|
||||
configuration: false,
|
||||
description: "Generated by OpenAPI body example",
|
||||
description: openApiFieldDesc,
|
||||
example: "",
|
||||
id: "",
|
||||
multiline: false,
|
||||
@@ -830,6 +874,7 @@ const ParsedAction = (props) => {
|
||||
tags: null,
|
||||
value: "",
|
||||
variant: "STATIC_VALUE",
|
||||
field_active: true,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -837,10 +882,14 @@ const ParsedAction = (props) => {
|
||||
setSelectedActionParameters(selectedActionParameters)
|
||||
}
|
||||
|
||||
return <Divider key={Math.random()} />
|
||||
return hideBodyButton
|
||||
}
|
||||
}
|
||||
|
||||
if (activateHidingBody === true) {
|
||||
hideBodyButton = ""
|
||||
}
|
||||
|
||||
const clickedFieldId = "rightside_field_"+count
|
||||
//<TextareaAutosize
|
||||
// <CodeMirror
|
||||
@@ -1000,7 +1049,8 @@ const ParsedAction = (props) => {
|
||||
}
|
||||
*/
|
||||
} else if (selectedActionParameters[count].options !== undefined && selectedActionParameters[count].options !== null && selectedActionParameters[count].options.length > 0) {
|
||||
if (selectedActionParameters[count].value === "" && selectedActionParameters[count].required) {
|
||||
if (selectedActionParameters[count].value === "") {
|
||||
// && selectedActionParameters[count].required) {
|
||||
// Rofl, dirty workaround :)
|
||||
const e = {
|
||||
target: {
|
||||
@@ -1009,7 +1059,7 @@ const ParsedAction = (props) => {
|
||||
}
|
||||
|
||||
changeActionParameter(e, count, data)
|
||||
}
|
||||
}
|
||||
|
||||
datafield =
|
||||
<Select
|
||||
@@ -1046,6 +1096,10 @@ const ParsedAction = (props) => {
|
||||
staticcolor = "#f85a3e"
|
||||
}
|
||||
|
||||
if (data.field_active === false) {
|
||||
return null
|
||||
}
|
||||
|
||||
// Shows nested list of nodes > their JSON lists
|
||||
const ActionlistWrapper = (props) => {
|
||||
|
||||
@@ -1296,6 +1350,7 @@ const ParsedAction = (props) => {
|
||||
{/*<div style={{width: 17, height: 17, borderRadius: 17 / 2, backgroundColor: itemColor, marginRight: 10, marginTop: 2, marginTop: "auto", marginBottom: "auto",}}/>*/}
|
||||
return (
|
||||
<div key={data.name}>
|
||||
{hideBodyButton}
|
||||
<div style={{marginTop: 20, marginBottom: 0, display: "flex"}}>
|
||||
{data.configuration === true ?
|
||||
<Tooltip color="primary" title={`Authenticate ${selectedApp.name}`} placement="top">
|
||||
@@ -1306,10 +1361,11 @@ const ParsedAction = (props) => {
|
||||
:
|
||||
null
|
||||
}
|
||||
|
||||
<div style={{flex: "10", marginTop: "auto", marginBottom: "auto",}}>
|
||||
<Tooltip title={tooltipDescription} placement="top">
|
||||
<b>{tmpitem} </b>
|
||||
</Tooltip>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
||||
{/*selectedActionParameters[count].options !== undefined && selectedActionParameters[count].options !== null && selectedActionParameters[count].options.length > 0 ? null :
|
||||
@@ -1355,7 +1411,7 @@ const ParsedAction = (props) => {
|
||||
onChange={(event) => {
|
||||
//console.log("CHECKED!: ", selectedActionParameters[count])
|
||||
selectedActionParameters[count].unique_toggled = !selectedActionParameters[count].unique_toggled
|
||||
selectedAction.parameters[count].unique_toggled = selectedActionParameters[count].unique_toggled
|
||||
selectedAction.parameters[count].unique_toggled = selectedActionParameters[count].unique_toggled
|
||||
setSelectedActionParameters(selectedActionParameters)
|
||||
setSelectedAction(selectedAction)
|
||||
setUpdate(Math.random())
|
||||
@@ -1610,7 +1666,9 @@ const ParsedAction = (props) => {
|
||||
: null}
|
||||
{selectedAction.authentication !== undefined && selectedAction.authentication !== null && selectedAction.authentication.length > 0 ?
|
||||
<div style={{marginTop: 15, }}>
|
||||
Authentication
|
||||
<Typography>
|
||||
Authentication
|
||||
</Typography>
|
||||
<div style={{display: "flex"}}>
|
||||
<Select
|
||||
labelId="select-app-auth"
|
||||
|
||||
@@ -14,6 +14,7 @@ const data = [{
|
||||
'margin': '5px',
|
||||
'border-width': '1px',
|
||||
'text-margin-x': '10px',
|
||||
'cursor': 'pointer',
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -26,6 +27,7 @@ const data = [{
|
||||
'text-margin-y': '-15px',
|
||||
'width': '5px',
|
||||
"color": "white",
|
||||
'cursor': 'pointer',
|
||||
"line-fill": "linear-gradient",
|
||||
"line-gradient-stop-positions": ["0.0", "100"],
|
||||
"line-gradient-stop-colors": ["grey", "grey"],
|
||||
@@ -34,7 +36,7 @@ const data = [{
|
||||
{
|
||||
selector: `node[type="ACTION"]`,
|
||||
css: {
|
||||
'shape': 'square',
|
||||
'shape': 'roundrectangle',
|
||||
'background-color': '#213243',
|
||||
'border-color': '#81c784',
|
||||
'background-width': '100%',
|
||||
@@ -99,6 +101,7 @@ const data = [{
|
||||
selector: `node[type="TRIGGER"]`,
|
||||
css: {
|
||||
'shape': 'octagon',
|
||||
'border-radius': '5px',
|
||||
'border-color': 'orange',
|
||||
'background-color': '#213243',
|
||||
'background-width': '100%',
|
||||
@@ -201,6 +204,16 @@ const data = [{
|
||||
'transition-duration': '0.5s',
|
||||
},
|
||||
},
|
||||
{
|
||||
selector: '.hover-highlight',
|
||||
css: {
|
||||
'background-color': '#5f9265',
|
||||
'border-color': '#5f9265',
|
||||
'border-width': '5px',
|
||||
'transition-property': 'background-color',
|
||||
'transition-duration': '0.5s',
|
||||
},
|
||||
},
|
||||
{
|
||||
selector: '.failure-highlight',
|
||||
css: {
|
||||
|
||||
@@ -2717,7 +2717,7 @@ const Admin = (props) => {
|
||||
style={{minWidth: 150, maxWidth: 150}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary="Orborus running (TBD)"
|
||||
primary="Orborus running"
|
||||
style={{minWidth: 200, maxWidth: 200}}
|
||||
/>
|
||||
<ListItemText
|
||||
@@ -2736,6 +2736,10 @@ const Admin = (props) => {
|
||||
primary="Archived"
|
||||
style={{minWidth: 150, maxWidth: 150}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary="Last Changed"
|
||||
style={{minWidth: 150, maxWidth: 150}}
|
||||
/>
|
||||
</ListItem>
|
||||
{environments === undefined || environments === null ? null : environments.map((environment, index)=> {
|
||||
if (!showArchived && environment.archived) {
|
||||
@@ -2747,19 +2751,19 @@ const Admin = (props) => {
|
||||
return null
|
||||
}
|
||||
|
||||
//var bgColor = "#27292d"
|
||||
//if (index % 2 === 0) {
|
||||
// bgColor = "#1f2023"
|
||||
//}
|
||||
var bgColor = "#27292d"
|
||||
if (index % 2 === 0) {
|
||||
bgColor = "#1f2023"
|
||||
}
|
||||
|
||||
return (
|
||||
<ListItem key={index}>
|
||||
<ListItem key={index} style={{backgroundColor: bgColor}}>
|
||||
<ListItemText
|
||||
primary={environment.Name}
|
||||
style={{minWidth: 150, maxWidth: 150, overflow: "hidden"}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary={environment.Type === "cloud" ? "N/A" : "TBD"}
|
||||
primary={environment.Type !== "cloud" ? environment.running_ip === undefined || environment.running_ip === null || environment.running_ip.length === 0 ? "Not started" : environment.running_ip : "N/A"}
|
||||
style={{minWidth: 200, maxWidth: 200, overflow: "hidden"}}
|
||||
/>
|
||||
<ListItemText
|
||||
@@ -2786,6 +2790,10 @@ const Admin = (props) => {
|
||||
style={{minWidth: 150, maxWidth: 150, overflow: "hidden"}}
|
||||
primary={environment.archived.toString()}
|
||||
/>
|
||||
<ListItemText
|
||||
style={{minWidth: 150, maxWidth: 150, overflow: "hidden"}}
|
||||
primary={environment.edited !== undefined && environment.edited !== null && environment.edited !== 0 ? new Date(environment.edited*1000).toISOString() : 0}
|
||||
/>
|
||||
</ListItem>
|
||||
)
|
||||
})}
|
||||
@@ -2907,7 +2915,7 @@ const Admin = (props) => {
|
||||
style={{minWidth: 150, maxWidth: 150}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary="Orborus running (TBD)"
|
||||
primary="Orborus running"
|
||||
style={{minWidth: 200, maxWidth: 200}}
|
||||
/>
|
||||
<ListItemText
|
||||
|
||||
@@ -11,7 +11,7 @@ import NestedMenuItem from "material-ui-nested-menu-item";
|
||||
import ReactMarkdown from 'react-markdown';
|
||||
|
||||
|
||||
import {TextField, Drawer, Button, Paper, Grid, Tabs, InputAdornment, Tab, ButtonBase, Tooltip, Select, MenuItem, Divider, Dialog, Modal, DialogActions, DialogTitle, InputLabel, DialogContent, FormControl, IconButton, Menu, Input, FormGroup, FormControlLabel, Typography, Checkbox, Breadcrumbs, CircularProgress, Switch, Fade} from '@material-ui/core';
|
||||
import {Slide, TextField, Drawer, Button, Paper, Grid, Tabs, InputAdornment, Tab, ButtonBase, Tooltip, Select, MenuItem, Divider, Dialog, Modal, DialogActions, DialogTitle, InputLabel, DialogContent, FormControl, IconButton, Menu, Input, FormGroup, FormControlLabel, Typography, Checkbox, Breadcrumbs, CircularProgress, Switch, Fade} from '@material-ui/core';
|
||||
import {OpenInNew as OpenInNewIcon,Undo as UndoIcon, FileCopy as FileCopyIcon, GetApp as GetAppIcon, Search as SearchIcon, ArrowUpward as ArrowUpwardIcon, Visibility as VisibilityIcon, Done as DoneIcon, Close as CloseIcon, Error as ErrorIcon, FindReplace as FindreplaceIcon, ArrowLeft as ArrowLeftIcon, Cached as CachedIcon, DirectionsRun as DirectionsRunIcon, Add as AddIcon, Polymer as PolymerIcon, FormatListNumbered as FormatListNumberedIcon, Create as CreateIcon, PlayArrow as PlayArrowIcon, AspectRatio as AspectRatioIcon, MoreVert as MoreVertIcon, Apps as AppsIcon, Schedule as ScheduleIcon, FavoriteBorder as FavoriteBorderIcon, Pause as PauseIcon, Delete as DeleteIcon, AddCircleOutline as AddCircleOutlineIcon, Save as SaveIcon, KeyboardArrowLeft as KeyboardArrowLeftIcon, KeyboardArrowRight as KeyboardArrowRightIcon, ArrowBack as ArrowBackIcon, Settings as SettingsIcon, LockOpen as LockOpenIcon, ExpandMore as ExpandMoreIcon, VpnKey as VpnKeyIcon} from '@material-ui/icons';
|
||||
|
||||
import * as cytoscape from 'cytoscape';
|
||||
@@ -887,6 +887,8 @@ const AngularWorkflow = (props) => {
|
||||
//console.log(curworkflowTrigger)
|
||||
|
||||
newTriggers.push(curworkflowTrigger)
|
||||
} else {
|
||||
alert.info("No handler for type: "+type)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1258,9 +1260,9 @@ const AngularWorkflow = (props) => {
|
||||
selectedAction.selectedAuthentication = item
|
||||
|
||||
for (var key in workflow.actions) {
|
||||
console.log(workflow.actions[key].app_name)
|
||||
//console.log(workflow.actions[key].app_name)
|
||||
if (workflow.actions[key].app_name == selectedApp.name) {
|
||||
console.log("Setting auth at: ", workflow.actions[key], item.id)
|
||||
//console.log("Setting auth at: ", workflow.actions[key], item.id)
|
||||
workflow.actions[key].selectedAuthentication = item
|
||||
workflow.actions[key].authentication_id = item.id
|
||||
appUpdates = true
|
||||
@@ -1593,6 +1595,19 @@ const AngularWorkflow = (props) => {
|
||||
if (event.target.data().decorator) {
|
||||
alert.info("This edge can't be edited.")
|
||||
} else {
|
||||
//console.log("DATA: ", event.target.data())
|
||||
const destinationId = event.target.data("target")
|
||||
//console.log("DATA: ", event.target.data())
|
||||
const curaction = workflow.actions.find(a => a.id === destinationId)
|
||||
//console.log("ACTION: ", curaction)
|
||||
if (curaction !== undefined && curaction !== null) {
|
||||
if (curaction.app_name == "Shuffle Tools" && curaction.name === "router") {
|
||||
alert.info("Router action can't have incoming conditions")
|
||||
event.target.unselect()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
setSelectedEdgeIndex(workflow.branches.findIndex(data => data.id === event.target.data()["id"]))
|
||||
setSelectedEdge(event.target.data())
|
||||
}
|
||||
@@ -1941,6 +1956,7 @@ const AngularWorkflow = (props) => {
|
||||
}
|
||||
|
||||
workflow.start = parentNode.data('id')
|
||||
setLastSaved(true)
|
||||
parentNode.data('isStartNode', true)
|
||||
}
|
||||
|
||||
@@ -2476,7 +2492,7 @@ const AngularWorkflow = (props) => {
|
||||
// Checks for errors in edges when they're added
|
||||
const onEdgeAdded = (event) => {
|
||||
const edge = event.target.data()
|
||||
console.log("EDGE ADDED: ", edge)
|
||||
//console.log("EDGE ADDED: ", edge)
|
||||
//setLastSaved(false)
|
||||
var targetnode = workflow.triggers.findIndex(data => data.id === edge.target)
|
||||
if (targetnode !== -1) {
|
||||
@@ -2488,7 +2504,7 @@ const AngularWorkflow = (props) => {
|
||||
}
|
||||
}
|
||||
|
||||
console.log("TARGET: ", event.target.target().data())
|
||||
//console.log("TARGET: ", event.target.target().data())
|
||||
if (event.target.target().data("isButton") === true || event.target.target().data("isDescriptor") === true) {
|
||||
event.target.remove()
|
||||
return
|
||||
@@ -2496,7 +2512,7 @@ const AngularWorkflow = (props) => {
|
||||
|
||||
targetnode = -1
|
||||
var sourcenode = workflow.triggers.findIndex(data => data.id === edge.source)
|
||||
console.log("SOURCENODE: ", sourcenode)
|
||||
//console.log("SOURCENODE: ", sourcenode)
|
||||
if (sourcenode !== -1) {
|
||||
if (workflow.triggers[sourcenode].app_name === "User Input" || workflow.triggers[sourcenode].app_name === "Shuffle Workflow") {
|
||||
//console.log("NORMAL TRIGGER")
|
||||
@@ -3304,6 +3320,16 @@ const AngularWorkflow = (props) => {
|
||||
}, {
|
||||
duration: animationDuration,
|
||||
})
|
||||
|
||||
const outgoingEdges = event.target.outgoers('edge')
|
||||
const incomingEdges = event.target.incomers('edge')
|
||||
if (outgoingEdges.length > 0) {
|
||||
outgoingEdges.removeClass('hover-highlight')
|
||||
}
|
||||
|
||||
if (incomingEdges.length > 0) {
|
||||
outgoingEdges.removeClass('hover-highlight')
|
||||
}
|
||||
}
|
||||
|
||||
const buttonColor = "rgba(255,255,255,0.9)"
|
||||
@@ -3479,6 +3505,16 @@ const AngularWorkflow = (props) => {
|
||||
})
|
||||
|
||||
previousnodecolor = event.target.style("border-color")
|
||||
|
||||
const outgoingEdges = event.target.outgoers('edge')
|
||||
const incomingEdges = event.target.incomers('edge')
|
||||
if (outgoingEdges.length > 0) {
|
||||
outgoingEdges.addClass('hover-highlight')
|
||||
}
|
||||
|
||||
if (incomingEdges.length > 0) {
|
||||
outgoingEdges.addClass('hover-highlight')
|
||||
}
|
||||
}
|
||||
|
||||
const onEdgeHoverOut = (event) => {
|
||||
@@ -4666,9 +4702,9 @@ const AngularWorkflow = (props) => {
|
||||
</div>
|
||||
:
|
||||
<div style={{textAlign: "center", width: leftBarSize}}>
|
||||
<CircularProgress style={{marginTop: 25, height: 35, width: 35, marginLeft: "auto", marginRight: "auto", }} />
|
||||
<CircularProgress style={{marginTop: "27vh", height: 35, width: 35, marginLeft: "auto", marginRight: "auto", }} />
|
||||
<Typography variant="body1" color="textSecondary">
|
||||
Loading apps
|
||||
Loading Apps
|
||||
</Typography>
|
||||
</div>
|
||||
}
|
||||
@@ -4942,7 +4978,7 @@ const AngularWorkflow = (props) => {
|
||||
top: appBarSize+25,
|
||||
right: 25,
|
||||
height: "80vh",
|
||||
width: 350,
|
||||
width: 365,
|
||||
minWidth: 200,
|
||||
maxWidth: 600,
|
||||
maxHeight: "100vh",
|
||||
@@ -5768,7 +5804,7 @@ const AngularWorkflow = (props) => {
|
||||
<Button
|
||||
fullWidth
|
||||
variant="contained"
|
||||
style={{flex: 1, marginTop: 10, }}
|
||||
style={{flex: 1, textTransform: "none", textAlign: "left", justifyContent: "flex-start", marginTop: 10, padding: 0, backgroundColor: "#4285f4", color: "white", }}
|
||||
color="primary"
|
||||
onClick={() => {
|
||||
//const redirectUri = isCloud ? "https%3A%2F%2Fshuffler.io%2Fapi%2Fv1%2Ftriggers%2Foutlook%2Fregister" : "http%3A%2F%2Flocalhost:5001%2Fapi%2Fv1%2Ftriggers%2Fgmail%2Fregister"
|
||||
@@ -5826,8 +5862,9 @@ const AngularWorkflow = (props) => {
|
||||
}, 2500)
|
||||
|
||||
saveWorkflow(workflow)
|
||||
}} >
|
||||
Sign in with Google
|
||||
}}>
|
||||
<img style={{margin: 0, }} src="/images/btn_google_light_focus_ios.svg" />
|
||||
<Typography style={{margin: 0, marginLeft: 10, }} variant="body1">Sign in with Google</Typography>
|
||||
</Button>
|
||||
|
||||
const outlookButton = selectedTrigger.name !== "Office365" ? null :
|
||||
@@ -6055,12 +6092,12 @@ const AngularWorkflow = (props) => {
|
||||
<div>
|
||||
<Divider style={{marginTop: "20px", height: "1px", width: "100%", backgroundColor: "rgb(91, 96, 100)"}}/>
|
||||
<div style={{marginTop: "20px", marginBottom: "7px", display: "flex"}}>
|
||||
<Button style={{flex: "1",}} disabled={selectedTrigger.status === "running"} onClick={() => {
|
||||
<Button variant="contained" style={{flex: "1",}} disabled={selectedTrigger.status === "running" || triggerFolders === undefined || triggerFolders === null || triggerFolders.length === 0} onClick={() => {
|
||||
startMailSub(selectedTrigger, selectedTriggerIndex)
|
||||
}} color="primary">
|
||||
Start
|
||||
</Button>
|
||||
<Button style={{flex: "1",}} disabled={selectedTrigger.status !== "running" } onClick={() => {
|
||||
<Button variant="outlined" style={{flex: "1",}} disabled={selectedTrigger.status !== "running" } onClick={() => {
|
||||
stopMailSub(selectedTrigger, selectedTriggerIndex)
|
||||
}} color="primary">
|
||||
Stop
|
||||
@@ -7798,46 +7835,46 @@ const AngularWorkflow = (props) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<div id="rightside_actions" style={rightsidebarStyle}>
|
||||
<ParsedAction
|
||||
id="rightside_subactions"
|
||||
getAppAuthentication={getAppAuthentication}
|
||||
appAuthentication={appAuthentication}
|
||||
authenticationType={authenticationType}
|
||||
scrollConfig={scrollConfig}
|
||||
setScrollConfig={setScrollConfig}
|
||||
selectedAction={selectedAction}
|
||||
workflow={workflow}
|
||||
setWorkflow={setWorkflow}
|
||||
setSelectedAction={setSelectedAction}
|
||||
setUpdate={setUpdate}
|
||||
selectedApp={selectedApp}
|
||||
workflowExecutions={workflowExecutions}
|
||||
setSelectedResult={setSelectedResult}
|
||||
setSelectedApp={setSelectedApp}
|
||||
setSelectedTrigger={setSelectedTrigger}
|
||||
setSelectedEdge={setSelectedEdge}
|
||||
setCurrentView={setCurrentView}
|
||||
cy={cy}
|
||||
setAuthenticationModalOpen={setAuthenticationModalOpen}
|
||||
<div id="rightside_actions" style={rightsidebarStyle}>
|
||||
<ParsedAction
|
||||
id="rightside_subactions"
|
||||
getAppAuthentication={getAppAuthentication}
|
||||
appAuthentication={appAuthentication}
|
||||
authenticationType={authenticationType}
|
||||
scrollConfig={scrollConfig}
|
||||
setScrollConfig={setScrollConfig}
|
||||
selectedAction={selectedAction}
|
||||
workflow={workflow}
|
||||
setWorkflow={setWorkflow}
|
||||
setSelectedAction={setSelectedAction}
|
||||
setUpdate={setUpdate}
|
||||
selectedApp={selectedApp}
|
||||
workflowExecutions={workflowExecutions}
|
||||
setSelectedResult={setSelectedResult}
|
||||
setSelectedApp={setSelectedApp}
|
||||
setSelectedTrigger={setSelectedTrigger}
|
||||
setSelectedEdge={setSelectedEdge}
|
||||
setCurrentView={setCurrentView}
|
||||
cy={cy}
|
||||
setAuthenticationModalOpen={setAuthenticationModalOpen}
|
||||
|
||||
setVariablesModalOpen={setVariablesModalOpen}
|
||||
setLastSaved={setLastSaved}
|
||||
setCodeModalOpen={setCodeModalOpen}
|
||||
selectedNameChange={selectedNameChange}
|
||||
rightsidebarStyle={rightsidebarStyle}
|
||||
showEnvironment={showEnvironment}
|
||||
selectedActionEnvironment={selectedActionEnvironment}
|
||||
environments={environments}
|
||||
setNewSelectedAction={setNewSelectedAction}
|
||||
sortByKey={sortByKey}
|
||||
|
||||
appApiViewStyle={appApiViewStyle}
|
||||
globalUrl={globalUrl}
|
||||
setSelectedActionEnvironment={setSelectedActionEnvironment}
|
||||
requiresAuthentication={requiresAuthentication}
|
||||
/>
|
||||
</div>
|
||||
setVariablesModalOpen={setVariablesModalOpen}
|
||||
setLastSaved={setLastSaved}
|
||||
setCodeModalOpen={setCodeModalOpen}
|
||||
selectedNameChange={selectedNameChange}
|
||||
rightsidebarStyle={rightsidebarStyle}
|
||||
showEnvironment={showEnvironment}
|
||||
selectedActionEnvironment={selectedActionEnvironment}
|
||||
environments={environments}
|
||||
setNewSelectedAction={setNewSelectedAction}
|
||||
sortByKey={sortByKey}
|
||||
|
||||
appApiViewStyle={appApiViewStyle}
|
||||
globalUrl={globalUrl}
|
||||
setSelectedActionEnvironment={setSelectedActionEnvironment}
|
||||
requiresAuthentication={requiresAuthentication}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
||||
} else if (Object.getOwnPropertyNames(selectedTrigger).length > 0) {
|
||||
@@ -8097,7 +8134,7 @@ const AngularWorkflow = (props) => {
|
||||
}
|
||||
|
||||
const executionModal =
|
||||
<Drawer anchor={"right"} open={executionModalOpen} onClose={() => setExecutionModalOpen(false)} style={{resize: "both", overflow: "auto", zIndex: 10005}} PaperProps={{style: {resize: "both", overflow: "auto", minWidth: 400, maxWidth: 400, backgroundColor: "#1F2023", color: "white", fontSize: 18, zIndex: 10005}}}>
|
||||
<Drawer anchor={"right"} open={executionModalOpen} onClose={() => setExecutionModalOpen(false)} style={{resize: "both", overflow: "auto", zIndex: 10005}} PaperProps={{style: {resize: "both", overflow: "auto", minWidth: 420, maxWidth: 420, backgroundColor: "#1F2023", color: "white", fontSize: 18, zIndex: 10005}}}>
|
||||
{executionModalView === 0 ?
|
||||
<div style={{padding: 25, }}>
|
||||
<Breadcrumbs aria-label="breadcrumb" separator="›" style={{color: "white", fontSize: 16}}>
|
||||
@@ -8109,6 +8146,7 @@ const AngularWorkflow = (props) => {
|
||||
<Button
|
||||
style={{borderRadius: "0px"}}
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
onClick={() => {
|
||||
getWorkflowExecution(props.match.params.key, "")
|
||||
}} color="primary">
|
||||
@@ -8568,6 +8606,7 @@ const AngularWorkflow = (props) => {
|
||||
maxHeight: 700,
|
||||
overflowY: "auto",
|
||||
overflowX: "hidden",
|
||||
zIndex: 10012,
|
||||
//boxShadow: "none",
|
||||
},
|
||||
}}
|
||||
@@ -8730,60 +8769,70 @@ const AngularWorkflow = (props) => {
|
||||
<div style={{color: "white"}}>
|
||||
<div style={{display: "flex", borderTop: "1px solid rgba(91, 96, 100, 1)"}}>
|
||||
{leftView}
|
||||
<CytoscapeComponent
|
||||
elements={elements}
|
||||
minZoom={0.35}
|
||||
maxZoom={2.00}
|
||||
wheelSensitivity={0.25}
|
||||
style={{width: bodyWidth-leftBarSize-15, height: bodyHeight-appBarSize-5, backgroundColor: surfaceColor}}
|
||||
stylesheet={cystyle}
|
||||
boxSelectionEnabled={true}
|
||||
autounselectify={false}
|
||||
showGrid={true}
|
||||
id="cytoscape_view"
|
||||
cy={(incy) => {
|
||||
// FIXME: There's something specific loading when
|
||||
// you do the first hover of a node. Why is this different?
|
||||
//console.log("CY: ", incy)
|
||||
setCy(incy)
|
||||
}}
|
||||
/>
|
||||
{workflow.id === undefined || workflow.id === null || apps.length === 0 ?
|
||||
<div style={{width: bodyWidth-leftBarSize-15, height: 150, textAlign: "center"}}>
|
||||
<CircularProgress style={{marginTop: "30vh", height: 35, width: 35, marginLeft: "auto", marginRight: "auto", }} />
|
||||
<Typography variant="body1" color="textSecondary">
|
||||
Loading Workflow
|
||||
</Typography>
|
||||
</div>
|
||||
:
|
||||
<CytoscapeComponent
|
||||
elements={elements}
|
||||
minZoom={0.35}
|
||||
maxZoom={2.00}
|
||||
wheelSensitivity={0.25}
|
||||
style={{width: bodyWidth-leftBarSize-15, height: bodyHeight-appBarSize-5, backgroundColor: surfaceColor}}
|
||||
stylesheet={cystyle}
|
||||
boxSelectionEnabled={true}
|
||||
autounselectify={false}
|
||||
showGrid={true}
|
||||
id="cytoscape_view"
|
||||
cy={(incy) => {
|
||||
// FIXME: There's something specific loading when
|
||||
// you do the first hover of a node. Why is this different?
|
||||
//console.log("CY: ", incy)
|
||||
setCy(incy)
|
||||
}}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
{executionModal}
|
||||
<RightSideBar
|
||||
scrollConfig={scrollConfig}
|
||||
setScrollConfig={setScrollConfig}
|
||||
selectedAction={selectedAction}
|
||||
workflow={workflow}
|
||||
setWorkflow={setWorkflow}
|
||||
setSelectedAction={setSelectedAction}
|
||||
setUpdate={setUpdate}
|
||||
selectedApp={selectedApp}
|
||||
workflowExecutions={workflowExecutions}
|
||||
setSelectedResult={setSelectedResult}
|
||||
setSelectedApp={setSelectedApp}
|
||||
setSelectedTrigger={setSelectedTrigger}
|
||||
setSelectedEdge={setSelectedEdge}
|
||||
setCurrentView={setCurrentView}
|
||||
cy={cy}
|
||||
setAuthenticationModalOpen={setAuthenticationModalOpen}
|
||||
{/*<Slide appear={true} direction="right" timeout={5000} in={true}>*/}
|
||||
<RightSideBar
|
||||
scrollConfig={scrollConfig}
|
||||
setScrollConfig={setScrollConfig}
|
||||
selectedAction={selectedAction}
|
||||
workflow={workflow}
|
||||
setWorkflow={setWorkflow}
|
||||
setSelectedAction={setSelectedAction}
|
||||
setUpdate={setUpdate}
|
||||
selectedApp={selectedApp}
|
||||
workflowExecutions={workflowExecutions}
|
||||
setSelectedResult={setSelectedResult}
|
||||
setSelectedApp={setSelectedApp}
|
||||
setSelectedTrigger={setSelectedTrigger}
|
||||
setSelectedEdge={setSelectedEdge}
|
||||
setCurrentView={setCurrentView}
|
||||
cy={cy}
|
||||
setAuthenticationModalOpen={setAuthenticationModalOpen}
|
||||
|
||||
setVariablesModalOpen={setVariablesModalOpen}
|
||||
setLastSaved={setLastSaved}
|
||||
setCodeModalOpen={setCodeModalOpen}
|
||||
selectedNameChange={selectedNameChange}
|
||||
rightsidebarStyle={rightsidebarStyle}
|
||||
showEnvironment={showEnvironment}
|
||||
selectedActionEnvironment={selectedActionEnvironment}
|
||||
environments={environments}
|
||||
setNewSelectedAction={setNewSelectedAction}
|
||||
sortByKey={sortByKey}
|
||||
|
||||
appApiViewStyle={appApiViewStyle}
|
||||
globalUrl={globalUrl}
|
||||
setSelectedActionEnvironment={setSelectedActionEnvironment}
|
||||
requiresAuthentication={requiresAuthentication}
|
||||
/>
|
||||
setVariablesModalOpen={setVariablesModalOpen}
|
||||
setLastSaved={setLastSaved}
|
||||
setCodeModalOpen={setCodeModalOpen}
|
||||
selectedNameChange={selectedNameChange}
|
||||
rightsidebarStyle={rightsidebarStyle}
|
||||
showEnvironment={showEnvironment}
|
||||
selectedActionEnvironment={selectedActionEnvironment}
|
||||
environments={environments}
|
||||
setNewSelectedAction={setNewSelectedAction}
|
||||
sortByKey={sortByKey}
|
||||
|
||||
appApiViewStyle={appApiViewStyle}
|
||||
globalUrl={globalUrl}
|
||||
setSelectedActionEnvironment={setSelectedActionEnvironment}
|
||||
requiresAuthentication={requiresAuthentication}
|
||||
/>
|
||||
<BottomCytoscapeBar />
|
||||
<TopCytoscapeBar />
|
||||
</div>
|
||||
@@ -9299,6 +9348,7 @@ const AngularWorkflow = (props) => {
|
||||
maxHeight: 700,
|
||||
padding: 15,
|
||||
overflow: "hidden",
|
||||
zIndex: 10012,
|
||||
},
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -370,8 +370,13 @@ const Apps = (props) => {
|
||||
}} />
|
||||
|
||||
var newAppname = data.name
|
||||
newAppname = newAppname.charAt(0).toUpperCase()+newAppname.substring(1)
|
||||
newAppname = newAppname.replaceAll("_", " ")
|
||||
if (newAppname === undefined) {
|
||||
newAppname = "Undefined"
|
||||
} else {
|
||||
newAppname = newAppname.charAt(0).toUpperCase()+newAppname.substring(1)
|
||||
newAppname = newAppname.replaceAll("_", " ")
|
||||
}
|
||||
|
||||
var sharing = "public"
|
||||
if (!data.sharing) {
|
||||
sharing = "private"
|
||||
@@ -1073,11 +1078,11 @@ const Apps = (props) => {
|
||||
<CircularProgress style={{width: 40, height: 40, margin: "auto"}}/>
|
||||
:
|
||||
<Paper square style={uploadViewPaperStyle}>
|
||||
<Typography variant="body1" style={{margin: 10}}>
|
||||
<Typography variant="body2" color="textSecondary" style={{margin: 10}}>
|
||||
No apps have been created, uploaded or downloaded yet. Click "Load existing apps" above to get the baseline. This may take a while as its building docker images.
|
||||
</Typography>
|
||||
<Typography variant="body1" style={{margin: 10}}>
|
||||
If you're still not able to see any apps, please follow our <a rel="noopener noreferrer" href={"https://shuffler.io/docs/troubleshooting#load_all_apps_locally"} style={{textDecoration: "none", color: "#f85a3e"}} target="_blank">troubleshooting guide for loading apps!</a>
|
||||
<Typography variant="body2" color="textSecondary" style={{margin: 10}}>
|
||||
If you're still not able to see any apps, please follow our <a href={"https://shuffler.io/docs/troubleshooting#load_all_apps_locally"} style={{textDecoration: "none", color: "#f85a3e"}} target="_blank">troubleshooting guide for loading apps!</a>
|
||||
</Typography>
|
||||
</Paper>
|
||||
}
|
||||
|
||||
@@ -95,6 +95,14 @@ const SetAuthentication = (props) => {
|
||||
if (query[0] === "oauth_url") {
|
||||
appAuthData.fields.push({"key": "oauth_url", "value": query[1]})
|
||||
}
|
||||
|
||||
if (query[0] === "refresh_uri") {
|
||||
appAuthData.fields.push({"key": "refresh_uri", "value": query[1]})
|
||||
}
|
||||
|
||||
if (query[0] === "refresh_url") {
|
||||
appAuthData.fields.push({"key": "refresh_url", "value": query[1]})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@ const Settings = (props) => {
|
||||
const [currentPassword, setCurrentPassword] = useState("");
|
||||
const [newPassword, setNewPassword] = useState("");
|
||||
const [newPassword2, setNewPassword2] = useState("");
|
||||
const [file, setFile] = React.useState("")
|
||||
const [fileBase64, setFileBase64] = React.useState(userdata.image === undefined || userdata.image === null ? theme.palette.defaultImage : userdata.image)
|
||||
|
||||
// Used for error messages etc
|
||||
const [formMessage, ] = useState("");
|
||||
@@ -40,6 +42,7 @@ const Settings = (props) => {
|
||||
const boxStyle = {
|
||||
flex: "1",
|
||||
color: "white",
|
||||
position: "relative",
|
||||
marginLeft: "10px",
|
||||
marginRight: "10px",
|
||||
paddingLeft: "30px",
|
||||
@@ -168,9 +171,81 @@ const Settings = (props) => {
|
||||
})
|
||||
|
||||
// Random names for type & autoComplete. Didn't research :^)
|
||||
var imageData = file.length > 0 ? file : fileBase64
|
||||
imageData = imageData === undefined || imageData.length === 0 ? theme.palette.defaultImage : imageData
|
||||
const imageInfo = <img src={imageData} alt="Click to upload an image (174x174)" id="logo" style={{maxWidth: 100, maxHeight: 100, minWidth: 100, minHeight: 100, position: "absolute", top: -80, left: 1020/2-25, borderRadius: 50, objectFit: "contain", border: "2px solid rgba(255,255,255,0.7)"}} />
|
||||
const landingpageData =
|
||||
<div style={{display: "flex", marginTop: "80px"}}>
|
||||
<div style={{display: "flex", marginTop: 120}}>
|
||||
<Paper style={boxStyle}>
|
||||
{imageInfo}
|
||||
<h2>Settings</h2>
|
||||
<div style={{flex: "1", display: "flex", flexDirection: "row"}}>
|
||||
<TextField
|
||||
style={{backgroundColor: theme.palette.inputColor, flex: "1"}}
|
||||
InputProps={{
|
||||
style:{
|
||||
height: "50px",
|
||||
color: "white",
|
||||
},
|
||||
}}
|
||||
color="primary"
|
||||
required
|
||||
disabled
|
||||
fullWidth={true}
|
||||
value={username}
|
||||
placeholder="Username"
|
||||
type="username"
|
||||
id="standard-required"
|
||||
autoComplete="username"
|
||||
margin="normal"
|
||||
variant="outlined"
|
||||
//onChange={e => setUsername(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div style={{flex: "1", display: "flex", flexDirection: "row"}}>
|
||||
<TextField
|
||||
style={{backgroundColor: theme.palette.inputColor, flex: "1", marginRight: "15px"}}
|
||||
InputProps={{
|
||||
style:{
|
||||
height: "50px",
|
||||
color: "white",
|
||||
},
|
||||
}}
|
||||
color="primary"
|
||||
required
|
||||
fullWidth={true}
|
||||
value={firstname}
|
||||
placeholder="First Name"
|
||||
type="firstname"
|
||||
disabled
|
||||
id="standard-required"
|
||||
autoComplete="firstname"
|
||||
margin="normal"
|
||||
variant="outlined"
|
||||
onChange={e => setFirstname(e.target.value)}
|
||||
/>
|
||||
<TextField
|
||||
style={{backgroundColor: theme.palette.inputColor, flex: "1", marginLeft: "15px"}}
|
||||
InputProps={{
|
||||
style:{
|
||||
height: "50px",
|
||||
color: "white",
|
||||
},
|
||||
}}
|
||||
color="primary"
|
||||
required
|
||||
value={lastname}
|
||||
fullWidth={true}
|
||||
placeholder="Last Name"
|
||||
disabled
|
||||
type="lastname"
|
||||
id="standard-required"
|
||||
autoComplete="lastname"
|
||||
margin="normal"
|
||||
variant="outlined"
|
||||
onChange={e => setLastname(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<h2>APIKEY</h2>
|
||||
<a target="_blank" href="/docs/API#authentication" style={{textDecoration: "none", color: "#f85a3e"}}>What is the API key used for?</a>
|
||||
<TextField
|
||||
@@ -193,78 +268,12 @@ const Settings = (props) => {
|
||||
/>
|
||||
<Button
|
||||
style={{width: "100%", height: "40px", marginTop: "10px"}}
|
||||
variant="contained"
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
onClick={() => generateApikey()}
|
||||
>Re-Generate APIKEY</Button>
|
||||
<Divider style={{marginTop: "40px"}}/>
|
||||
{/*
|
||||
<h2>Settings</h2>
|
||||
<div style={{flex: "1", display: "flex", flexDirection: "row"}}>
|
||||
<TextField
|
||||
style={{backgroundColor: theme.palette.inputColor, flex: "1"}}
|
||||
InputProps={{
|
||||
style:{
|
||||
height: "50px",
|
||||
color: "white",
|
||||
},
|
||||
}}
|
||||
color="primary"
|
||||
required
|
||||
fullWidth={true}
|
||||
value={username}
|
||||
placeholder="Username"
|
||||
type="username"
|
||||
id="standard-required"
|
||||
autoComplete="username"
|
||||
margin="normal"
|
||||
variant="outlined"
|
||||
onChange={e => setUsername(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div style={{flex: "1", display: "flex", flexDirection: "row"}}>
|
||||
<TextField
|
||||
style={{backgroundColor: theme.palette.inputColor, flex: "1", marginRight: "15px"}}
|
||||
InputProps={{
|
||||
style:{
|
||||
height: "50px",
|
||||
color: "white",
|
||||
},
|
||||
}}
|
||||
color="primary"
|
||||
required
|
||||
fullWidth={true}
|
||||
value={firstname}
|
||||
placeholder="First Name"
|
||||
type="firstname"
|
||||
id="standard-required"
|
||||
autoComplete="firstname"
|
||||
margin="normal"
|
||||
variant="outlined"
|
||||
onChange={e => setFirstname(e.target.value)}
|
||||
/>
|
||||
<TextField
|
||||
style={{backgroundColor: theme.palette.inputColor, flex: "1", marginLeft: "15px"}}
|
||||
InputProps={{
|
||||
style:{
|
||||
height: "50px",
|
||||
color: "white",
|
||||
},
|
||||
}}
|
||||
color="primary"
|
||||
required
|
||||
value={lastname}
|
||||
fullWidth={true}
|
||||
placeholder="Last Name"
|
||||
type="lastname"
|
||||
id="standard-required"
|
||||
autoComplete="lastname"
|
||||
margin="normal"
|
||||
variant="outlined"
|
||||
onChange={e => setLastname(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div style={{flex: "1", display: "flex", flexDirection: "row"}}>
|
||||
<TextField
|
||||
style={{backgroundColor: theme.palette.inputColor, flex: "1", marginRight: "15px",}}
|
||||
InputProps={{
|
||||
|
||||
@@ -2,8 +2,9 @@ import React, { useEffect} from 'react';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import { useTheme } from '@material-ui/core/styles';
|
||||
|
||||
import { Grid, Paper, Tooltip, Button, TextField, FormControl, IconButton, Menu, MenuItem, Chip, Typography, CircularProgress, Dialog, DialogTitle, DialogActions, DialogContent} from '@material-ui/core';
|
||||
import {GridOn as GridOnIcon, List as ListIcon, Close as CloseIcon, Compare as CompareIcon, Maximize as MaximizeIcon, Minimize as MinimizeIcon, AddCircle as AddCircleIcon, Toc as TocIcon, Send as SendIcon, Search as SearchIcon, FileCopy as FileCopyIcon, Delete as DeleteIcon, BubbleChart as BubbleChartIcon, Restore as RestoreIcon, Cached as CachedIcon, GetApp as GetAppIcon, Edit as EditIcon, MoreVert as MoreVertIcon, PlayArrow as PlayArrowIcon, Add as AddIcon, Publish as PublishIcon, CloudUpload as CloudUploadIcon, CloudDownload as CloudDownloadIcon} from '@material-ui/icons';
|
||||
import {Badge, Avatar, Grid, Paper, Tooltip, Divider, Button, TextField, FormControl, IconButton, Menu, MenuItem, FormControlLabel, Chip, Switch, Typography, Zoom, CircularProgress, Dialog, DialogTitle, DialogActions, DialogContent} from '@material-ui/core';
|
||||
import {GridOn as GridOnIcon, List as ListIcon, Close as CloseIcon, Compare as CompareIcon, Maximize as MaximizeIcon, Minimize as MinimizeIcon, AddCircle as AddCircleIcon, Toc as TocIcon, Send as SendIcon, Search as SearchIcon, FileCopy as FileCopyIcon, Delete as DeleteIcon, BubbleChart as BubbleChartIcon, Restore as RestoreIcon, Cached as CachedIcon, GetApp as GetAppIcon, Apps as AppsIcon, Edit as EditIcon, MoreVert as MoreVertIcon, PlayArrow as PlayArrowIcon, Add as AddIcon, Publish as PublishIcon, CloudUpload as CloudUploadIcon, CloudDownload as CloudDownloadIcon} from '@material-ui/icons';
|
||||
|
||||
import NestedMenuItem from "material-ui-nested-menu-item";
|
||||
//import {Search as SearchIcon, ArrowUpward as ArrowUpwardIcon, Visibility as VisibilityIcon, Done as DoneIcon, Close as CloseIcon, Error as ErrorIcon, FindReplace as FindreplaceIcon, ArrowLeft as ArrowLeftIcon, Cached as CachedIcon, DirectionsRun as DirectionsRunIcon, Add as AddIcon, Polymer as PolymerIcon, FormatListNumbered as FormatListNumberedIcon, Create as CreateIcon, PlayArrow as PlayArrowIcon, AspectRatio as AspectRatioIcon, MoreVert as MoreVertIcon, Apps as AppsIcon, Schedule as ScheduleIcon, FavoriteBorder as FavoriteBorderIcon, Pause as PauseIcon, Delete as DeleteIcon, AddCircleOutline as AddCircleOutlineIcon, Save as SaveIcon, KeyboardArrowLeft as KeyboardArrowLeftIcon, KeyboardArrowRight as KeyboardArrowRightIcon, ArrowBack as ArrowBackIcon, Settings as SettingsIcon, LockOpen as LockOpenIcon, ExpandMore as ExpandMoreIcon, VpnKey as VpnKeyIcon} from '@material-ui/icons';
|
||||
|
||||
@@ -291,6 +292,7 @@ const Workflows = (props) => {
|
||||
const theme = useTheme();
|
||||
const alert = useAlert()
|
||||
const classes = useStyles(theme);
|
||||
const imgSize = 60
|
||||
|
||||
const referenceUrl = globalUrl+"/api/v1/hooks/"
|
||||
|
||||
@@ -326,6 +328,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([])
|
||||
|
||||
const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io"
|
||||
|
||||
@@ -344,6 +347,7 @@ const Workflows = (props) => {
|
||||
found = filters.map(filter => curWorkflow.name.toLowerCase().includes(filter))
|
||||
} else {
|
||||
found = filters.map(filter => {
|
||||
const newfilter = filter.toLowerCase()
|
||||
if (filter === undefined) {
|
||||
return false
|
||||
}
|
||||
@@ -357,10 +361,9 @@ const Workflows = (props) => {
|
||||
} else if (curWorkflow.org_id === filter) {
|
||||
return true
|
||||
} else if (curWorkflow.actions !== null && curWorkflow.actions !== undefined) {
|
||||
const newfilter = filter.toLowerCase()
|
||||
for (var key in curWorkflow.actions) {
|
||||
const action = curWorkflow.actions[key]
|
||||
if (action.app_name.toLowerCase().includes(newfilter)) {
|
||||
if (action.app_name.toLowerCase() === newfilter || action.app_name.toLowerCase().includes(newfilter)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -390,7 +393,7 @@ const Workflows = (props) => {
|
||||
return
|
||||
}
|
||||
|
||||
if (filters.includes(data)) {
|
||||
if (filters.includes(data) || filters.includes(data.toLowerCase())) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -629,6 +632,27 @@ const Workflows = (props) => {
|
||||
|
||||
if (responseJson !== undefined) {
|
||||
setWorkflows(responseJson)
|
||||
|
||||
if (responseJson !== undefined) {
|
||||
var actionnamelist = []
|
||||
var parsedactionlist = []
|
||||
for (var key in responseJson) {
|
||||
for (var actionkey in responseJson[key].actions) {
|
||||
const action = responseJson[key].actions[actionkey]
|
||||
console.log("Action: ", action)
|
||||
if (actionnamelist.includes(action.app_name)) {
|
||||
continue
|
||||
}
|
||||
|
||||
actionnamelist.push(action.app_name)
|
||||
parsedactionlist.push(action)
|
||||
}
|
||||
}
|
||||
|
||||
console.log(parsedactionlist)
|
||||
setActionImageList(parsedactionlist)
|
||||
}
|
||||
|
||||
setFilteredWorkflows(responseJson)
|
||||
setWorkflowDone(true)
|
||||
} else {
|
||||
@@ -689,6 +713,7 @@ const Workflows = (props) => {
|
||||
display: "flex",
|
||||
flexWrap: 'wrap',
|
||||
alignContent: "space-between",
|
||||
marginTop: 5,
|
||||
}
|
||||
|
||||
const paperAppStyle = {
|
||||
@@ -845,6 +870,16 @@ const Workflows = (props) => {
|
||||
|
||||
if (sanitize === true) {
|
||||
data = sanitizeWorkflow(data)
|
||||
|
||||
if (data.subflows !== null && data.subflows !== undefined) {
|
||||
alert.info("Not exporting with subflows when sanitizing. Please manually export them.")
|
||||
data.subflows = []
|
||||
}
|
||||
|
||||
// for (var key in data.subflows) {
|
||||
// if (data.sublof
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
// Add correct ID's for triggers
|
||||
@@ -1065,14 +1100,45 @@ const Workflows = (props) => {
|
||||
<FileCopyIcon style={{marginLeft: 0, marginRight: 8}}/>
|
||||
{"Duplicate Workflow"}
|
||||
</MenuItem>
|
||||
<NestedMenuItem disabled={userdata.orgs === undefined || userdata.orgs === null || userdata.orgs.length === 1 || userdata.orgs.length >= 0} style={{backgroundColor: inputColor, color: "white"}} onClick={() => {
|
||||
|
||||
{/*<NestedMenuItem disabled={userdata.orgs === undefined || userdata.orgs === null || userdata.orgs.length === 1 || userdata.orgs.length >= 0} style={{backgroundColor: inputColor, color: "white"}} onClick={() => {
|
||||
//copyWorkflow(data)
|
||||
//setOpen(false)
|
||||
}} key={"duplicate"}>
|
||||
<FileCopyIcon style={{marginLeft: 0, marginRight: 8}}/>
|
||||
{"Copy to Child Org"}
|
||||
</NestedMenuItem>
|
||||
</NestedMenuItem>*/}
|
||||
<MenuItem style={{backgroundColor: inputColor, color: "white"}} onClick={() => {
|
||||
setExportModalOpen(true)
|
||||
|
||||
if (data.triggers !== null && data.triggers !== undefined) {
|
||||
var newSubflows = []
|
||||
for (var key in data.triggers) {
|
||||
const trigger = data.triggers[key]
|
||||
|
||||
if (trigger.parameters !== null && trigger.parameters !== undefined) {
|
||||
for (var subkey in trigger.parameters) {
|
||||
const param = trigger.parameters[subkey]
|
||||
if (param.name === "workflow" && param.value !== data.id && !newSubflows.includes(param.value)) {
|
||||
newSubflows.push(param.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var parsedworkflows = []
|
||||
for (var key in newSubflows) {
|
||||
const foundWorkflow = workflows.find(workflow => workflow.id === newSubflows[key])
|
||||
if (foundWorkflow !== undefined && foundWorkflow !== null) {
|
||||
parsedworkflows.push(foundWorkflow)
|
||||
}
|
||||
}
|
||||
|
||||
if (parsedworkflows.length > 0) {
|
||||
console.log("Appending subflows during export: ", parsedworkflows.length)
|
||||
data.subflows = parsedworkflows
|
||||
}
|
||||
}
|
||||
|
||||
setExportData(data)
|
||||
setOpen(false)
|
||||
}} key={"export"}>
|
||||
@@ -1389,7 +1455,7 @@ const Workflows = (props) => {
|
||||
let workflowData = "";
|
||||
if (workflows.length > 0) {
|
||||
const columns = [
|
||||
{ field: 'image', headerName: 'Logo', width: 42, renderCell: (params) => {
|
||||
{ field: 'image', headerName: 'Logo', width: 50, sortable: false, renderCell: (params) => {
|
||||
const data = params.row.record
|
||||
|
||||
var boxColor = "#FECC00"
|
||||
@@ -1430,7 +1496,7 @@ const Workflows = (props) => {
|
||||
|
||||
return (
|
||||
<Grid item>
|
||||
<Link to={`/workflows/{data.id}`} style={{textDecoration: "none", color: "inherit",}}>
|
||||
<Link to={"/workflows/"+data.id} style={{textDecoration: "none", color: "inherit",}}>
|
||||
<Typography>
|
||||
{data.name}
|
||||
</Typography>
|
||||
@@ -1539,7 +1605,7 @@ const Workflows = (props) => {
|
||||
}
|
||||
];
|
||||
let rows = [];
|
||||
rows = workflows.map((data, index) => {
|
||||
rows = filteredWorkflows.map((data, index) => {
|
||||
let obj = {
|
||||
"id":index+1,
|
||||
"title":data.name,
|
||||
@@ -1547,7 +1613,7 @@ const Workflows = (props) => {
|
||||
}
|
||||
|
||||
return obj;
|
||||
});
|
||||
})
|
||||
workflowData =
|
||||
<DataGrid
|
||||
color="primary"
|
||||
@@ -1691,7 +1757,7 @@ const Workflows = (props) => {
|
||||
|
||||
}} color="primary">
|
||||
{submitLoading ?
|
||||
<CircularProgress />
|
||||
<CircularProgress color="secondary" />
|
||||
:
|
||||
"Submit"
|
||||
}
|
||||
@@ -1805,6 +1871,53 @@ const Workflows = (props) => {
|
||||
<h2>Workflows</h2>
|
||||
</div>
|
||||
</div>
|
||||
{/*
|
||||
<div style={flexContainerStyle}>
|
||||
<div style={{...flexBoxStyle, ...activeWorkflowStyle}}>
|
||||
<div style={flexContentStyle}>
|
||||
<div><img src={mobileImage} style={iconStyle} /></div>
|
||||
<div style={ blockRightStyle }>
|
||||
<div style={counterStyle}>{workflows.length}</div>
|
||||
<div style={fontSize_16}>ACTIVE WORKFLOWS</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{...flexBoxStyle, ...availableWorkflowStyle}}>
|
||||
<div style={flexContentStyle}>
|
||||
<div><img src={bookImage} style={iconStyle} /></div>
|
||||
<div style={ blockRightStyle }>
|
||||
<div style={counterStyle}>{workflows.length}</div>
|
||||
<div style={fontSize_16}>AVAILABE WORKFLOWS</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{...flexBoxStyle, ...notificationStyle}}>
|
||||
<div style={flexContentStyle}>
|
||||
<div><img src={bagImage} style={iconStyle} /></div>
|
||||
<div style={ blockRightStyle }>
|
||||
<div style={counterStyle}>{workflows.length}</div>
|
||||
<div style={fontSize_16}>NOTIFICATIONS</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
*/}
|
||||
|
||||
{/*
|
||||
chipRenderer={({ value, isFocused, isDisabled, handleClick, handleRequestDelete }, key) => {
|
||||
console.log("VALUE: ", value)
|
||||
|
||||
return (
|
||||
<Chip
|
||||
key={key}
|
||||
style={chipStyle}
|
||||
|
||||
>
|
||||
{value}
|
||||
</Chip>
|
||||
)
|
||||
}}
|
||||
*/}
|
||||
<div style={{display: "flex", margin: "0px 0px 20px 0px"}}>
|
||||
<div style={{flex: 1}}>
|
||||
<Typography style={{marginTop: 7, marginBottom: "auto"}}>
|
||||
@@ -1836,6 +1949,36 @@ const Workflows = (props) => {
|
||||
</div>
|
||||
</div>
|
||||
<div style={{marginTop: 15,}} />
|
||||
{actionImageList !== undefined && actionImageList !== null && actionImageList.length > 0 ?
|
||||
<div style={{display: "flex", maxWidth: 1024, zIndex: 11, border: "1px solid rgba(255,255,255,0.1)", borderRadius: theme.palette.borderRadius, textAlign: "center", overflow: "auto",}}>
|
||||
{actionImageList.map((data, index) => {
|
||||
if (data.large_image === undefined || data.large_image === null || data.large_image.length === 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (data.app_name.toLowerCase() === "shuffle tools") {
|
||||
data.large_image = theme.palette.defaultImage
|
||||
}
|
||||
|
||||
return (
|
||||
<span style={{zIndex: 10}}>
|
||||
<IconButton style={{backgroundColor: "transparent", margin: 0, padding: 12, }} onClick={() => {
|
||||
console.log("FILTER: ", data)
|
||||
addFilter(data.app_name)
|
||||
}}>
|
||||
<Tooltip title={`Filter by ${data.app_name}`} placement="top">
|
||||
<Badge badgeContent={0} color="secondary" style={{fontSize: 10}}>
|
||||
<div style={{height: imgSize, width: imgSize, position: "relative", filter: "brightness(0.6)", backgroundColor: "#000", borderRadius: imgSize/2, zIndex: 100, overflow: "hidden", display: "flex", justifyContent: "center", }}>
|
||||
<img style={{height: imgSize, width: imgSize, position: "absolute", top: -2, left: -2, cursor: "pointer", zIndex: 99, border: "2px solid rgba(255,255,255,0.7)", }} alt={data.app_name} src={data.large_image}/>
|
||||
</div>
|
||||
</Badge>
|
||||
</Tooltip>
|
||||
</IconButton>
|
||||
</span>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
: null}
|
||||
{view === "grid" ?
|
||||
<Grid container spacing={4} style={paperAppContainer}>
|
||||
<NewWorkflowPaper />
|
||||
|
||||
Reference in New Issue
Block a user