Added sharing and fixed OpenAPI issue
This commit is contained in:
@@ -129,13 +129,14 @@ const App = (message, props) => {
|
||||
<Route exact path="/contact" render={props => <Contact isLoaded={isLoaded} globalUrl={globalUrl} {...props} />} />
|
||||
<Route exact path="/login" render={props => <LoginPage isLoggedIn={isLoggedIn} setIsLoggedIn={setIsLoggedIn} register={true} isLoaded={isLoaded} globalUrl={globalUrl} setCookie={setCookie} cookies={cookies} {...props} />} />
|
||||
<Route exact path="/admin" render={props => <Admin isLoggedIn={isLoggedIn} setIsLoggedIn={setIsLoggedIn} register={true} isLoaded={isLoaded} globalUrl={globalUrl} setCookie={setCookie} cookies={cookies} {...props} />} />
|
||||
<Route exact path="/admin/:key" render={props => <Admin isLoggedIn={isLoggedIn} setIsLoggedIn={setIsLoggedIn} register={true} isLoaded={isLoaded} globalUrl={globalUrl} setCookie={setCookie} cookies={cookies} {...props} />} />
|
||||
<Route exact path="/settings" render={props => <SettingsPage isLoaded={isLoaded} userdata={userdata} globalUrl={globalUrl} {...props} />} />
|
||||
<Route exact path="/AdminSetup" render={props => <AdminSetup isLoaded={isLoaded} userdata={userdata} globalUrl={globalUrl} {...props} />} />
|
||||
<Route exact path="/webhooks" render={props => <Webhooks isLoaded={isLoaded} globalUrl={globalUrl} {...props} />} />
|
||||
<Route exact path="/webhooks/:key" render={props => <EditWebhook isLoaded={isLoaded} globalUrl={globalUrl} {...props} />} />
|
||||
<Route exact path="/schedules" render={props => <Schedules globalUrl={globalUrl} {...props} />} />
|
||||
<Route exact path="/dashboard" render={props => <Dashboard isLoaded={isLoaded} isLoggedIn={isLoggedIn} globalUrl={globalUrl} {...props} />} />
|
||||
<Route exact path="/apps" render={props => <Apps isLoaded={isLoaded} isLoggedIn={isLoggedIn} globalUrl={globalUrl} {...props} />} />
|
||||
<Route exact path="/apps" render={props => <Apps isLoaded={isLoaded} isLoggedIn={isLoggedIn} globalUrl={globalUrl} userdata={userdata} {...props} />} />
|
||||
<Route exact path="/apps/new" render={props => <AppCreator isLoaded={isLoaded} isLoggedIn={isLoggedIn} globalUrl={globalUrl} {...props} />} />
|
||||
<Route exact path="/apps/edit/:appid" render={props => <AppCreator isLoaded={isLoaded} isLoggedIn={isLoggedIn} globalUrl={globalUrl} {...props} />} />
|
||||
<Route exact path="/schedules/:key" render={props => <EditSchedule globalUrl={globalUrl} {...props} />} />
|
||||
|
||||
@@ -49,6 +49,71 @@ const Admin = (props) => {
|
||||
const [selectedAuthenticationModalOpen, setSelectedAuthenticationModalOpen] = React.useState(false)
|
||||
const [showArchived, setShowArchived] = React.useState(false)
|
||||
|
||||
const getApps = () => {
|
||||
fetch(globalUrl+"/api/v1/workflows/apps", {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
},
|
||||
credentials: "include",
|
||||
})
|
||||
.then((response) => {
|
||||
if (response.status !== 200) {
|
||||
console.log("Status not 200 for apps :O!")
|
||||
}
|
||||
|
||||
return response.json()
|
||||
})
|
||||
.then((responseJson) => {
|
||||
console.log("apps: ", responseJson)
|
||||
//setApps(responseJson)
|
||||
//setFilteredApps(responseJson)
|
||||
//if (responseJson.length > 0) {
|
||||
// setSelectedApp(responseJson[0])
|
||||
// if (responseJson[0].actions !== null && responseJson[0].actions.length > 0) {
|
||||
// setSelectedAction(responseJson[0].actions[0])
|
||||
// } else {
|
||||
// setSelectedAction({})
|
||||
// }
|
||||
//}
|
||||
})
|
||||
.catch(error => {
|
||||
alert.error(error.toString())
|
||||
});
|
||||
}
|
||||
|
||||
const categories = [
|
||||
{
|
||||
"name": "Ticketing",
|
||||
"apps": [
|
||||
"TheHive",
|
||||
"Service-Now",
|
||||
"SecureWorks",
|
||||
],
|
||||
"categories": ["tickets", "ticket", "ticketing"]
|
||||
},
|
||||
]
|
||||
/*
|
||||
"SIEM",
|
||||
"Active Directory",
|
||||
"Firewalls",
|
||||
"Proxies web",
|
||||
"SIEM",
|
||||
"SOAR",
|
||||
"Mail",
|
||||
"EDR",
|
||||
"AV",
|
||||
"MDM/MAM",
|
||||
"DNS",
|
||||
"Ticketing platform",
|
||||
"TIP",
|
||||
"Communication",
|
||||
"DDOS protection",
|
||||
"VMS",
|
||||
]
|
||||
*/
|
||||
|
||||
const alert = useAlert()
|
||||
|
||||
const deleteAuthentication = (data) => {
|
||||
@@ -905,6 +970,82 @@ const Admin = (props) => {
|
||||
</div>
|
||||
: null
|
||||
|
||||
const appCategoryView = curTab === 6 ?
|
||||
<div>
|
||||
<div style={{marginTop: 20, marginBottom: 20,}}>
|
||||
<h2 style={{display: "inline",}}>Categories</h2>
|
||||
<span style={{marginLeft: 25}}>
|
||||
Categories are the categories supported by Shuffle, which are mapped to apps and workflows
|
||||
</span>
|
||||
</div>
|
||||
<Divider style={{marginTop: 20, marginBottom: 20, backgroundColor: theme.palette.inputColor}}/>
|
||||
<List>
|
||||
<ListItem>
|
||||
<ListItemText
|
||||
primary="Category"
|
||||
style={{minWidth: 150, maxWidth: 150}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary="Apps"
|
||||
style={{minWidth: 250, maxWidth: 250}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary="Workflows"
|
||||
style={{minWidth: 150, maxWidth: 150}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary="Authentication"
|
||||
style={{minWidth: 150, maxWidth: 150, overflow: "hidden"}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary="Actions"
|
||||
style={{minWidth: 150, maxWidth: 150, overflow: "hidden"}}
|
||||
/>
|
||||
</ListItem>
|
||||
{categories.map(data => {
|
||||
if (data.apps.length === 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<ListItem>
|
||||
<ListItemText
|
||||
primary={data.name}
|
||||
style={{minWidth: 150, maxWidth: 150}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary={""}
|
||||
style={{minWidth: 250, maxWidth: 250}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary={""}
|
||||
style={{minWidth: 150, maxWidth: 150}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary={""}
|
||||
style={{minWidth: 150, maxWidth: 150, overflow: "hidden"}}
|
||||
/>
|
||||
<ListItemText
|
||||
style={{minWidth: 150, maxWidth: 150, overflow: "hidden"}}
|
||||
>
|
||||
<Button
|
||||
style={{}}
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
onClick={() => {
|
||||
console.log("Show apps with this category")
|
||||
}}
|
||||
>
|
||||
Find app ({data.apps.length})
|
||||
</Button>
|
||||
</ListItemText>
|
||||
</ListItem>
|
||||
)
|
||||
})}
|
||||
</List>
|
||||
</div>
|
||||
: null
|
||||
|
||||
const authenticationView = curTab === 1 ?
|
||||
<div>
|
||||
<div style={{marginTop: 20, marginBottom: 20,}}>
|
||||
@@ -1182,6 +1323,10 @@ const Admin = (props) => {
|
||||
getSchedules()
|
||||
}
|
||||
|
||||
if (newValue === 6) {
|
||||
console.log("Should get apps for categories.")
|
||||
}
|
||||
|
||||
setModalUser({})
|
||||
setCurTab(newValue)
|
||||
}
|
||||
@@ -1202,10 +1347,12 @@ const Admin = (props) => {
|
||||
<Tab label=<span><ScheduleIcon style={iconStyle} />Schedules</span> />
|
||||
{window.location.protocol == "http:" && window.location.port === "3000" ? <Tab label=<span><CloudIcon style={iconStyle} /> Hybrid</span>/> : null}
|
||||
{window.location.protocol == "http:" && window.location.port === "3000" ? <Tab label=<span><BusinessIcon style={iconStyle} /> Organizations</span>/> : null}
|
||||
{window.location.protocol === "http:" && window.location.port === "3000" ? <Tab label=<span><LockIcon style={iconStyle} />Categories</span>/> : null}
|
||||
</Tabs>
|
||||
<Divider style={{marginTop: 0, marginBottom: 10, backgroundColor: "rgb(91, 96, 100)"}} />
|
||||
<div style={{padding: 15}}>
|
||||
{authenticationView}
|
||||
{appCategoryView}
|
||||
{usersView}
|
||||
{environmentView}
|
||||
{schedulesView}
|
||||
|
||||
+132
-16
@@ -112,6 +112,7 @@ const Apps = (props) => {
|
||||
const [openApiError, setOpenApiError] = React.useState("")
|
||||
const [field1, setField1] = React.useState("")
|
||||
const [field2, setField2] = React.useState("")
|
||||
const [sharingConfiguration, setSharingConfiguration] = React.useState("you")
|
||||
|
||||
const { start, stop } = useInterval({
|
||||
duration: 5000,
|
||||
@@ -134,6 +135,24 @@ const Apps = (props) => {
|
||||
}
|
||||
})
|
||||
|
||||
function sortByKey(array, key) {
|
||||
return array.sort(function(a, b) {
|
||||
var x = a[key];
|
||||
var y = b[key];
|
||||
|
||||
if (typeof x == "string")
|
||||
{
|
||||
x = (""+x).toLowerCase();
|
||||
}
|
||||
if (typeof y == "string")
|
||||
{
|
||||
y = (""+y).toLowerCase();
|
||||
}
|
||||
|
||||
return ((x < y) ? 1 : ((x > y) ? -1 : 0));
|
||||
});
|
||||
}
|
||||
|
||||
const appViewStyle = {
|
||||
color: "#ffffff",
|
||||
width: "100%",
|
||||
@@ -169,6 +188,8 @@ const Apps = (props) => {
|
||||
return response.json()
|
||||
})
|
||||
.then((responseJson) => {
|
||||
responseJson = sortByKey(responseJson, "large_image")
|
||||
|
||||
setApps(responseJson)
|
||||
setFilteredApps(responseJson)
|
||||
if (responseJson.length > 0) {
|
||||
@@ -290,12 +311,18 @@ const Apps = (props) => {
|
||||
<Paper square key={data.id} style={paperAppStyle} onClick={() => {
|
||||
if (selectedApp.id !== data.id) {
|
||||
setSelectedApp(data)
|
||||
|
||||
console.log(data)
|
||||
if (data.actions !== undefined && data.actions !== null && data.actions.length > 0) {
|
||||
setSelectedAction(data.actions[0])
|
||||
} else {
|
||||
setSelectedAction({})
|
||||
}
|
||||
|
||||
console.log("Sharing: ", data.sharing_config)
|
||||
if (data.sharing) {
|
||||
setSharingConfiguration("everyone")
|
||||
}
|
||||
}
|
||||
}}>
|
||||
<Grid container style={{margin: 10, flex: "10"}}>
|
||||
@@ -314,9 +341,20 @@ const Apps = (props) => {
|
||||
{description}
|
||||
</Grid>
|
||||
</div>
|
||||
<Grid item style={{flex: "1", justifyContent: "center"}}>
|
||||
Sharing: {sharing}
|
||||
, Valid: {valid}
|
||||
<Grid item style={{flex: "1", justifyContent: "center", marginTop: 5}}>
|
||||
{data.tags === null || data.tags === undefined ? null : data.tags.map((tag, index) => {
|
||||
if (index >= 3) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<Chip
|
||||
style={{height: 25, marginRight: 5, cursor: "pointer",}}
|
||||
label={tag}
|
||||
color="primary"
|
||||
/>
|
||||
)
|
||||
})}
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
@@ -324,7 +362,7 @@ const Apps = (props) => {
|
||||
|
||||
{data.activated && data.private_id !== undefined && data.private_id.length > 0 && data.generated ?
|
||||
<Grid container style={{margin: "10px 10px 10px 10px", flex: "1"}} onClick={() => {downloadApp(data)}}>
|
||||
<Tooltip title={"Download"} style={{marginTop: "28px", width: "100%"}} aria-label={data.name}>
|
||||
<Tooltip title={"Download OpenAPI"} style={{marginTop: "28px", width: "100%"}} aria-label={data.name}>
|
||||
<CloudDownload />
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
@@ -450,6 +488,7 @@ const Apps = (props) => {
|
||||
</MenuItem>
|
||||
)
|
||||
})}
|
||||
{/*
|
||||
<ReactJson
|
||||
src={JSON.parse(showResult)}
|
||||
theme="solarized"
|
||||
@@ -457,19 +496,26 @@ const Apps = (props) => {
|
||||
displayDataTypes={true}
|
||||
name={"Example return value"}
|
||||
/>
|
||||
*/}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div style={{marginTop: 10}}>
|
||||
<b>Example return</b><div/>
|
||||
{selectedAction.returns.example}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
//fetch(globalUrl+"/api/v1/get_openapi/"+urlParams.get("id"), {
|
||||
const userRoles = [
|
||||
"you",
|
||||
"everyone",
|
||||
]
|
||||
|
||||
//fetch(globalUrl+"/api/v1/get_openapi/"+urlParams.get("id"),
|
||||
console.log("User: ", props.userdata)
|
||||
var baseInfo = newAppname.length > 0 ?
|
||||
<div>
|
||||
<div style={{display: "flex"}}>
|
||||
@@ -482,15 +528,23 @@ const Apps = (props) => {
|
||||
</div>
|
||||
</div>
|
||||
{activateButton}
|
||||
{downloadButton}
|
||||
{editButton}
|
||||
{deleteButton}
|
||||
{props.userdata.role === "admin" || props.userdata.id === selectedApp.owner ?
|
||||
<div>
|
||||
{downloadButton}
|
||||
{editButton}
|
||||
{deleteButton}
|
||||
</div>
|
||||
: null}
|
||||
{selectedApp.tags !== undefined && selectedApp.tags !== null ?
|
||||
<div style={{display: "inline-block", marginLeft: 15, float: "right",}}>
|
||||
{selectedApp.tags.map(tag => {
|
||||
{selectedApp.tags.map((tag, index) => {
|
||||
if (index >= 3) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<Chip
|
||||
style={{marginRight: 5, marginTop: 7, cursor: "pointer",}}
|
||||
style={{height: 25, marginRight: 5, marginTop: 7, cursor: "pointer",}}
|
||||
label={tag}
|
||||
color="primary"
|
||||
/>
|
||||
@@ -498,11 +552,41 @@ const Apps = (props) => {
|
||||
})}
|
||||
</div>
|
||||
: null}
|
||||
<Divider style={{marginBottom: "10px", marginTop: "10px", backgroundColor: dividerColor}}/>
|
||||
{selectedApp.link.length > 0 ? <p><b>URL:</b> {selectedApp.link}</p> : null}
|
||||
<p><b>ID:</b> {selectedApp.id}</p>
|
||||
{props.userdata.id === selectedApp.owner ?
|
||||
<div style={{marginTop: 15}}>
|
||||
{/*<p><b>ID:</b> {selectedApp.id}</p>*/}
|
||||
<b style={{marginRight: 15}}>Sharing:</b>
|
||||
<Select
|
||||
value={sharingConfiguration}
|
||||
onChange={(event) => {
|
||||
setSharingConfiguration(event.target.value)
|
||||
alert.info("Changed sharing to "+event.target.value)
|
||||
|
||||
updateAppField(selectedApp.id, "sharing", !selectedApp.sharing)
|
||||
//setSelectedAction(event.target.value)
|
||||
}}
|
||||
style={{width: 150, backgroundColor: inputColor, color: "white", height: 35, marginleft: 10,}}
|
||||
SelectDisplayProps={{
|
||||
style: {
|
||||
marginLeft: 10,
|
||||
}
|
||||
}}
|
||||
>
|
||||
{userRoles.map(data => {
|
||||
return (
|
||||
<MenuItem key={data} style={{backgroundColor: inputColor, color: "white"}} value={data}>
|
||||
{data}
|
||||
|
||||
</MenuItem>
|
||||
)
|
||||
})}
|
||||
</Select>
|
||||
</div>
|
||||
: null}
|
||||
{/*<p><b>Owner:</b> {selectedApp.owner}</p>*/}
|
||||
{selectedApp.privateId !== undefined && selectedApp.privateId.length > 0 ? <p><b>PrivateID:</b> {selectedApp.privateId}</p> : null}
|
||||
|
||||
<Divider style={{marginBottom: 10, marginTop: 10, backgroundColor: dividerColor}}/>
|
||||
{selectedApp.link.length > 0 ? <p><b>URL:</b> {selectedApp.link}</p> : null}
|
||||
<div style={{marginTop: 15, marginBottom: 15}}>
|
||||
<b>Actions</b>
|
||||
{selectedApp.actions !== null && selectedApp.actions.length > 0 ?
|
||||
@@ -884,6 +968,36 @@ const Apps = (props) => {
|
||||
});
|
||||
}
|
||||
|
||||
const updateAppField = (app_id, fieldname, fieldvalue) => {
|
||||
const data = {}
|
||||
data[fieldname] = fieldvalue
|
||||
|
||||
fetch(globalUrl+"/api/v1/apps/"+app_id, {
|
||||
method: 'PATCH',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
credentials: "include",
|
||||
})
|
||||
.then((response) => {
|
||||
//setAppSearchLoading(false)
|
||||
return response.json()
|
||||
})
|
||||
.then((responseJson) => {
|
||||
//console.log(responseJson)
|
||||
//alert.info(responseJson)
|
||||
if (responseJson.success) {
|
||||
alert.info("Success")
|
||||
} else {
|
||||
alert.error("Error updating app")
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
alert.error(error.toString())
|
||||
});
|
||||
}
|
||||
|
||||
const runAppSearch = (searchterm) => {
|
||||
const data = {"search": searchterm}
|
||||
|
||||
@@ -1165,11 +1279,13 @@ const Apps = (props) => {
|
||||
placeholder="OpenAPI URI"
|
||||
fullWidth
|
||||
/>
|
||||
{/*
|
||||
<div style={{marginTop: "15px"}}/>
|
||||
Example:
|
||||
<div />
|
||||
https://raw.githubusercontent.com/OAI/OpenAPI-Specification/master/examples/v2.0/json/uber.json
|
||||
<h4>or paste the yaml/JSON directly below</h4>
|
||||
*/}
|
||||
<h4>Or paste the yaml/JSON directly below</h4>
|
||||
<TextField
|
||||
style={{backgroundColor: inputColor}}
|
||||
variant="outlined"
|
||||
|
||||
@@ -14,6 +14,7 @@ import MenuItem from '@material-ui/core/MenuItem';
|
||||
import FormControlLabel from '@material-ui/core/FormControlLabel';
|
||||
import Chip from '@material-ui/core/Chip';
|
||||
import Switch from '@material-ui/core/Switch';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
|
||||
import CircularProgress from '@material-ui/core/CircularProgress';
|
||||
import CachedIcon from '@material-ui/icons/Cached';
|
||||
@@ -201,7 +202,7 @@ const Workflows = (props) => {
|
||||
marginTop: "10px",
|
||||
overflow: "scroll",
|
||||
height: "90%",
|
||||
overflowX: "auto",
|
||||
overflowX: "hidden",
|
||||
overflowY: "auto",
|
||||
}
|
||||
|
||||
@@ -212,6 +213,8 @@ const Workflows = (props) => {
|
||||
marginTop: "5px",
|
||||
color: "white",
|
||||
backgroundColor: surfaceColor,
|
||||
borderRadius: 5,
|
||||
padding: 10,
|
||||
cursor: "pointer",
|
||||
display: "flex",
|
||||
}
|
||||
@@ -241,6 +244,8 @@ const Workflows = (props) => {
|
||||
setWorkflowExecutions(responseJson)
|
||||
} else {
|
||||
alert.info("Couldn't find executions for the workflow")
|
||||
setSelectedExecution({})
|
||||
setWorkflowExecutions([])
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -393,6 +398,7 @@ const Workflows = (props) => {
|
||||
}
|
||||
|
||||
// dropdown with copy etc I guess
|
||||
console.log("Why reset?")
|
||||
const WorkflowPaper = (props) => {
|
||||
const { data } = props;
|
||||
const [open, setOpen] = React.useState(false);
|
||||
@@ -419,7 +425,6 @@ const Workflows = (props) => {
|
||||
var webhookImg = ""
|
||||
var scheduleImg = ""
|
||||
if (data.triggers !== undefined && data.triggers !== null && data.triggers.length > 0) {
|
||||
console.log("Triggers: ", data.triggers)
|
||||
for (var key in data.triggers) {
|
||||
if (data.triggers[key].app_name === "Webhook") {
|
||||
webhooks += 1
|
||||
@@ -434,14 +439,9 @@ const Workflows = (props) => {
|
||||
const imgSize = 25
|
||||
return (
|
||||
<Paper square style={paperAppStyle} onClick={(e) => {
|
||||
}}>
|
||||
<Grid container style={{margin: "10px 0px 10px 5px", maxWidth: 35,}}>
|
||||
<AppsIcon style={{width: imgSize, height: imgSize}} />
|
||||
{webhooks > 0 ? <img alt={data.title} style={{width: imgSize, height: imgSize, marginTop: 5}} src={webhookImg} /> : null}
|
||||
{schedules > 0 ? <img alt={data.title} style={{width: imgSize, height: imgSize, marginTop: 5}} src={scheduleImg} /> : null}
|
||||
</Grid>
|
||||
<div style={{marginTop: 5, marginBottom: 5, width: boxWidth, backgroundColor: boxColor}} />
|
||||
<Grid container style={{margin: "10px 10px 10px 10px", flex: 10}}>
|
||||
}}>
|
||||
<div style={{width: boxWidth, backgroundColor: boxColor}} />
|
||||
<Grid container style={{margin: "0px 10px 0px 10px", flex: 10}}>
|
||||
<Grid style={{display: "flex", flexDirection: "column", width: "100%"}}>
|
||||
<Grid item style={{flex: 1, display: "flex"}}>
|
||||
<div style={{flex: "10",}} onClick={() => {
|
||||
@@ -450,9 +450,11 @@ const Workflows = (props) => {
|
||||
getWorkflowExecution(data.id)
|
||||
}
|
||||
}}>
|
||||
<h3 style={{marginBottom: "0px", marginTop: "10px"}}>{data.name}</h3>
|
||||
<Typography variant="h6" style={{marginTop: 10, marginBottom: 0, }}>
|
||||
{data.name}
|
||||
</Typography>
|
||||
</div>
|
||||
<div style={{flex: "1"}}>
|
||||
<div style={{flex: 1, }}>
|
||||
<IconButton
|
||||
aria-label="more"
|
||||
aria-controls="long-menu"
|
||||
@@ -505,7 +507,7 @@ const Workflows = (props) => {
|
||||
getWorkflowExecution(data.id)
|
||||
}
|
||||
}}>
|
||||
<Grid item style={{flex: "1", justifyContent: "center", overflow: "hidden"}}>
|
||||
<Grid item style={{flex: "1", justifyContent: "center", overflow: "hidden", float: "bottom",}}>
|
||||
<Link to={"/workflows/"+data.id}>
|
||||
<Tooltip color="primary" title="Edit workflow" placement="bottom">
|
||||
<Button style={{}} color="secondary" variant="text" style={{marginRight: 10}} onClick={() => {}}>
|
||||
@@ -514,9 +516,11 @@ const Workflows = (props) => {
|
||||
</Tooltip>
|
||||
</Link>
|
||||
<Tooltip color="primary" title="Execute workflow" placement="bottom">
|
||||
<Button style={{}} color="secondary" variant="text" onClick={() => executeWorkflow(data.id)}>
|
||||
<PlayArrowIcon />
|
||||
</Button>
|
||||
<span>
|
||||
<Button style={{}} disabled={!data.is_valid} color="secondary" variant="text" onClick={() => executeWorkflow(data.id)}>
|
||||
<PlayArrowIcon />
|
||||
</Button>
|
||||
</span>
|
||||
</Tooltip>
|
||||
{data.tags !== undefined ?
|
||||
data.tags.map(tag => {
|
||||
@@ -533,6 +537,22 @@ const Workflows = (props) => {
|
||||
</div>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container style={{maxWidth: 35, marginRight: 10,}}>
|
||||
<Tooltip title={data.actions.length} placement="right">
|
||||
<AppsIcon style={{width: imgSize, height: imgSize}} />
|
||||
</Tooltip>
|
||||
|
||||
{webhooks > 0 ?
|
||||
<Tooltip title={webhooks} placement="right">
|
||||
<img alt={data.title} style={{width: imgSize, height: imgSize, marginTop: 5}} src={webhookImg} />
|
||||
</Tooltip>
|
||||
: null}
|
||||
{schedules > 0 ?
|
||||
<Tooltip title={webhooks} placement="right">
|
||||
<img alt={data.title} style={{width: imgSize, height: imgSize, marginTop: 5}} src={scheduleImg} />
|
||||
</Tooltip>
|
||||
: null}
|
||||
</Grid>
|
||||
</Paper>
|
||||
)
|
||||
}
|
||||
@@ -938,7 +958,6 @@ const Workflows = (props) => {
|
||||
setLoadWorkflowsModalOpen(false)
|
||||
}
|
||||
|
||||
console.log("WOrkflowtags: ", newWorkflowTags)
|
||||
const modalView = modalOpen ?
|
||||
<Dialog
|
||||
open={modalOpen}
|
||||
|
||||
Reference in New Issue
Block a user