Added fixes for public workflows with app visuals
This commit is contained in:
+2
-2
@@ -47,10 +47,10 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
environment:
|
environment:
|
||||||
- SHUFFLE_WORKER_VERSION=0.9.52
|
- SHUFFLE_WORKER_VERSION=nightly
|
||||||
- ORG_ID=${ORG_ID}
|
- ORG_ID=${ORG_ID}
|
||||||
- ENVIRONMENT_NAME=${ENVIRONMENT_NAME}
|
- ENVIRONMENT_NAME=${ENVIRONMENT_NAME}
|
||||||
- BASE_URL=https://frikky-shuffle-5gvr4xx62w64-5001.githubpreview.dev
|
- BASE_URL=https://${OUTER_HOSTNAME}:${BACKEND_PORT}
|
||||||
- DOCKER_API_VERSION=1.40
|
- DOCKER_API_VERSION=1.40
|
||||||
- SHUFFLE_BASE_IMAGE_NAME=${SHUFFLE_BASE_IMAGE_NAME}
|
- SHUFFLE_BASE_IMAGE_NAME=${SHUFFLE_BASE_IMAGE_NAME}
|
||||||
- SHUFFLE_BASE_IMAGE_REGISTRY=${SHUFFLE_BASE_IMAGE_REGISTRY}
|
- SHUFFLE_BASE_IMAGE_REGISTRY=${SHUFFLE_BASE_IMAGE_REGISTRY}
|
||||||
|
|||||||
@@ -114,6 +114,10 @@ const AuthenticationOauth2 = (props) => {
|
|||||||
setButtonClicked(true);
|
setButtonClicked(true);
|
||||||
console.log("SCOPES: ", scopes);
|
console.log("SCOPES: ", scopes);
|
||||||
|
|
||||||
|
client_id = client_id.trim()
|
||||||
|
client_secret = client_secret.trim()
|
||||||
|
oauth_url = oauth_url.trim()
|
||||||
|
|
||||||
var resources = "";
|
var resources = "";
|
||||||
if (scopes !== undefined && (scopes !== null) & (scopes.length > 0)) {
|
if (scopes !== undefined && (scopes !== null) & (scopes.length > 0)) {
|
||||||
if (offlineAccess === true && !scopes.includes("offline_access")) {
|
if (offlineAccess === true && !scopes.includes("offline_access")) {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import theme from '../theme';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
Zoom,
|
Zoom,
|
||||||
|
Avatar,
|
||||||
Popover,
|
Popover,
|
||||||
TextField,
|
TextField,
|
||||||
Drawer,
|
Drawer,
|
||||||
@@ -45,8 +46,13 @@ import {
|
|||||||
Breadcrumbs,
|
Breadcrumbs,
|
||||||
CircularProgress,
|
CircularProgress,
|
||||||
Switch,
|
Switch,
|
||||||
|
Chip,
|
||||||
} from "@material-ui/core";
|
} from "@material-ui/core";
|
||||||
|
|
||||||
|
import {
|
||||||
|
AvatarGroup,
|
||||||
|
} from "@mui/material"
|
||||||
|
|
||||||
import {
|
import {
|
||||||
OpenInNew as OpenInNewIcon,
|
OpenInNew as OpenInNewIcon,
|
||||||
Undo as UndoIcon,
|
Undo as UndoIcon,
|
||||||
@@ -248,6 +254,9 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
const [subworkflowStartnode, setSubworkflowStartnode] = React.useState("");
|
const [subworkflowStartnode, setSubworkflowStartnode] = React.useState("");
|
||||||
const [leftViewOpen, setLeftViewOpen] = React.useState(true);
|
const [leftViewOpen, setLeftViewOpen] = React.useState(true);
|
||||||
const [leftBarSize, setLeftBarSize] = React.useState(350);
|
const [leftBarSize, setLeftBarSize] = React.useState(350);
|
||||||
|
const [creatorProfile, setCreatorProfile] = React.useState({});
|
||||||
|
const [appGroup, setAppGroup] = React.useState([]);
|
||||||
|
const [triggerGroup, setTriggerGroup] = React.useState([]);
|
||||||
const [executionText, setExecutionText] = React.useState("");
|
const [executionText, setExecutionText] = React.useState("");
|
||||||
const [executionRequestStarted, setExecutionRequestStarted] =
|
const [executionRequestStarted, setExecutionRequestStarted] =
|
||||||
React.useState(false);
|
React.useState(false);
|
||||||
@@ -1346,7 +1355,7 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
})
|
})
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
if (response.status !== 200) {
|
if (response.status !== 200) {
|
||||||
console.log("Status not 200 for apps :O!");
|
console.log("Status not 200 for app auth :O!");
|
||||||
}
|
}
|
||||||
|
|
||||||
return response.json();
|
return response.json();
|
||||||
@@ -1460,6 +1469,10 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
return response.json();
|
return response.json();
|
||||||
})
|
})
|
||||||
.then((responseJson) => {
|
.then((responseJson) => {
|
||||||
|
if (responseJson.success === false) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME - handle versions on left bar
|
// FIXME - handle versions on left bar
|
||||||
//handleAppVersioning(responseJson)
|
//handleAppVersioning(responseJson)
|
||||||
//var tmpapps = []
|
//var tmpapps = []
|
||||||
@@ -1495,7 +1508,7 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
alert.error(error.toString());
|
alert.error("App loading error: ", error.toString());
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1530,12 +1543,51 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
responseJson.errors = [];
|
responseJson.errors = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (responseJson.actions === undefined || responseJson.actions === null) {
|
||||||
|
responseJson.actions = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (responseJson.triggers === undefined || responseJson.triggers === null) {
|
||||||
|
responseJson.triggers = [];
|
||||||
|
}
|
||||||
|
|
||||||
if (responseJson.public) {
|
if (responseJson.public) {
|
||||||
alert.info(
|
alert.info(
|
||||||
"This workflow is public. You will have to save it to make it your own!"
|
"This workflow is public. Save the workflow to "
|
||||||
);
|
);
|
||||||
|
|
||||||
|
console.log("RESP: ", responseJson)
|
||||||
|
if (Object.getOwnPropertyNames(creatorProfile).length === 0) {
|
||||||
|
getUserProfile("frikky")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//{appGroup.map((data, index) => {
|
||||||
|
//const [appGroup, setAppGroup] = React.useState([]);
|
||||||
|
var appsFound = []
|
||||||
|
for (var key in responseJson.actions) {
|
||||||
|
const parsedAction = responseJson.actions[key]
|
||||||
|
if (parsedAction.large_image === undefined || parsedAction.large_image === null || parsedAction.large_image === "") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (appsFound.findIndex(data => data.app_name === parsedAction.app_name) < 0){
|
||||||
|
appsFound.push(parsedAction)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setAppGroup(appsFound)
|
||||||
|
|
||||||
|
appsFound = []
|
||||||
|
for (var key in responseJson.triggers) {
|
||||||
|
const parsedAction = responseJson.triggers[key]
|
||||||
|
if (appsFound.findIndex(data => data.app_name === parsedAction.app_name) < 0){
|
||||||
|
appsFound.push(parsedAction)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setTriggerGroup(appsFound)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Appends SUBFLOWS. Does NOT run during normal grabbing of workflows.
|
// Appends SUBFLOWS. Does NOT run during normal grabbing of workflows.
|
||||||
if (sourcenode.id !== undefined) {
|
if (sourcenode.id !== undefined) {
|
||||||
console.log("WORKFLOW: ", responseJson);
|
console.log("WORKFLOW: ", responseJson);
|
||||||
@@ -2107,10 +2159,12 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
if (!lastSaved) {
|
if (!lastSaved) {
|
||||||
return unloadText;
|
return unloadText;
|
||||||
} else {
|
} else {
|
||||||
|
if (workflow.public === false) {
|
||||||
//document.removeEventListener("mousemove", onMouseUpdate, true);
|
//document.removeEventListener("mousemove", onMouseUpdate, true);
|
||||||
document.removeEventListener("keydown", handleKeyDown, true);
|
document.removeEventListener("keydown", handleKeyDown, true);
|
||||||
document.removeEventListener("paste", handlePaste, true);
|
document.removeEventListener("paste", handlePaste, true);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Nodeselectbatching:
|
// Nodeselectbatching:
|
||||||
@@ -3393,7 +3447,7 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
})
|
})
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
if (response.status !== 200) {
|
if (response.status !== 200) {
|
||||||
console.log("Status not 200 for apps :O!");
|
console.log("Status not 200 for envs :O!");
|
||||||
if (isCloud) {
|
if (isCloud) {
|
||||||
setEnvironments([{ Name: "Cloud", Type: "cloud" }]);
|
setEnvironments([{ Name: "Cloud", Type: "cloud" }]);
|
||||||
} else {
|
} else {
|
||||||
@@ -3820,7 +3874,7 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
//var parentNode = cy.$("#" + event.target.data("id"));
|
//var parentNode = cy.$("#" + event.target.data("id"));
|
||||||
//if (parentNode.data("isButton") || parentNode.data("buttonId")) return;
|
//if (parentNode.data("isButton") || parentNode.data("buttonId")) return;
|
||||||
|
|
||||||
if (nodedata.app_name !== undefined) {
|
if (nodedata.app_name !== undefined && !workflow.public === true) {
|
||||||
const allNodes = cy.nodes().jsons();
|
const allNodes = cy.nodes().jsons();
|
||||||
|
|
||||||
var found = false;
|
var found = false;
|
||||||
@@ -9893,6 +9947,10 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const TopCytoscapeBar = (props) => {
|
const TopCytoscapeBar = (props) => {
|
||||||
|
if (workflow.public === true) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={topBarStyle}>
|
<div style={topBarStyle}>
|
||||||
<div style={{ margin: "0px 10px 0px 10px" }}>
|
<div style={{ margin: "0px 10px 0px 10px" }}>
|
||||||
@@ -9916,10 +9974,6 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
</h2>
|
</h2>
|
||||||
</Link>
|
</Link>
|
||||||
<h2 style={{ margin: 0 }}>{workflow.name}</h2>
|
<h2 style={{ margin: 0 }}>{workflow.name}</h2>
|
||||||
|
|
||||||
{workflow.public ? (
|
|
||||||
<h2 style={{ margin: 0 }}>Public Workflow PREVIEW</h2>
|
|
||||||
) : null}
|
|
||||||
</Breadcrumbs>
|
</Breadcrumbs>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -10519,7 +10573,143 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
//}}>Execute websocket</Button>
|
//}}>Execute websocket</Button>
|
||||||
//
|
//
|
||||||
|
|
||||||
const leftView = leftViewOpen ? (
|
const getUserProfile = (username) => {
|
||||||
|
fetch(`${globalUrl}/api/v1/users/creators/${username}`, {
|
||||||
|
method: "GET",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
Accept: "application/json",
|
||||||
|
},
|
||||||
|
credentials: "include",
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (response.status !== 200) {
|
||||||
|
console.log("Status not 200 for WORKFLOW EXECUTION :O!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then((responseJson) => {
|
||||||
|
console.log("FOUND USER FOR: ", username, responseJson)
|
||||||
|
if (responseJson.success !== false) {
|
||||||
|
setCreatorProfile(responseJson)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.log(error);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const leftView = workflow.public === true ?
|
||||||
|
<div style={{minHeight: "80vh", height: "100%", minWidth: leftBarSize-70, maxWidth: leftBarSize-70, zIndex: 0, padding: 35, borderRight: "1px solid rgba(91,96,100,1)",}}>
|
||||||
|
<Typography variant="h6" color="textPrimary" style={{
|
||||||
|
margin: "0px 0px 0px 0px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{workflow.name}
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body2" color="textSecondary">
|
||||||
|
This workflow is public and <span style={{color: "#f86a3e", cursor: "pointer", }} onClick={() => {
|
||||||
|
saveWorkflow()
|
||||||
|
}}>must be saved</span> to be used in your organization.
|
||||||
|
</Typography>
|
||||||
|
{Object.getOwnPropertyNames(creatorProfile).length !== 0 && creatorProfile.github_avatar !== undefined && creatorProfile.github_avatar !== null ?
|
||||||
|
<div style={{display: "flex", marginTop: 10, }}>
|
||||||
|
<IconButton color="primary" style={{padding: 0, marginRight: 10, }} aria-controls="simple-menu" aria-haspopup="true" onClick={(event) => {
|
||||||
|
}}>
|
||||||
|
<Link to={`/creators/${creatorProfile.github_username}`} style={{textDecoration: "none", color: "#f86a3e"}}>
|
||||||
|
<Avatar style={{height: 30, width: 30,}} alt={"Workflow creator"} src={creatorProfile.github_avatar} />
|
||||||
|
</Link>
|
||||||
|
</IconButton>
|
||||||
|
<Typography variant="body1" color="textSecondary" style={{color: ""}}>
|
||||||
|
Shared by <Link to={`/creators/${creatorProfile.github_username}`} style={{textDecoration: "none", color: "#f86a3e"}}>{creatorProfile.github_username}</Link>
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
: null}
|
||||||
|
<div style={{marginTop: 15}} />
|
||||||
|
{workflow.tags !== undefined && workflow.tags !== null && workflow.tags.length > 0 ?
|
||||||
|
<div style={{display: "flex", overflow: "hidden",marginTop: 5, }}>
|
||||||
|
<Typography variant="body1" style={{marginRight: 10, }}>
|
||||||
|
Tags
|
||||||
|
</Typography>
|
||||||
|
<div style={{display: "flex"}}>
|
||||||
|
{workflow.tags.map((tag, index) => {
|
||||||
|
if (index >= 3) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Chip
|
||||||
|
key={index}
|
||||||
|
style={{backgroundColor: "#3d3f43", height: 30, marginRight: 5, paddingLeft: 5, paddingRight: 5, height: 28, cursor: "pointer", borderColor: "#3d3f43", color: "white",}}
|
||||||
|
label={tag}
|
||||||
|
variant="outlined"
|
||||||
|
color="primary"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
: null }
|
||||||
|
<div style={{display: "flex", marginTop: 10, }}>
|
||||||
|
<Typography variant="body1">
|
||||||
|
Mitre Att&ck:
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body1" color="textSecondary">
|
||||||
|
TBD
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
{appGroup.length > 0 ?
|
||||||
|
<div style={{display: "flex", marginTop: 10, }}>
|
||||||
|
<Typography variant="body1">
|
||||||
|
Apps
|
||||||
|
</Typography>
|
||||||
|
<AvatarGroup max={6} style={{marginLeft: 10, }}>
|
||||||
|
{appGroup.map((data, index) => {
|
||||||
|
return (
|
||||||
|
<Link to={`/apps/${data.app_id}`}>
|
||||||
|
<Avatar alt={data.app_name} src={data.large_image} style={{width: 30, height: 30}}/>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</AvatarGroup>
|
||||||
|
</div>
|
||||||
|
: null}
|
||||||
|
{triggerGroup.length > 0 ?
|
||||||
|
<div style={{display: "flex", marginTop: 10, }}>
|
||||||
|
<Typography variant="body1">
|
||||||
|
Triggers
|
||||||
|
</Typography>
|
||||||
|
<AvatarGroup max={6} style={{marginLeft: 10, }}>
|
||||||
|
{triggerGroup.map((data, index) => {
|
||||||
|
return (
|
||||||
|
<Avatar alt={data.app_name} src={data.large_image} style={{width: 30, height: 30}}/>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</AvatarGroup>
|
||||||
|
</div>
|
||||||
|
: null}
|
||||||
|
<div style={{display: "flex", marginTop: 10, }}>
|
||||||
|
<Typography variant="body1">
|
||||||
|
Related Workflows:
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body1" color="textSecondary">
|
||||||
|
TBD
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
{workflow.description !== undefined && workflow.description !== null && workflow.description.length > 0 ?
|
||||||
|
<div style={{marginTop: 5, }}>
|
||||||
|
<Typography variant="body1">
|
||||||
|
Description
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body1" color="textSecondary">
|
||||||
|
{workflow.description}
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
: null}
|
||||||
|
</div>
|
||||||
|
: leftViewOpen ? (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
minWidth: leftBarSize,
|
minWidth: leftBarSize,
|
||||||
@@ -10529,7 +10719,7 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
>
|
>
|
||||||
<HandleLeftView />
|
<HandleLeftView />
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
minWidth: leftBarSize,
|
minWidth: leftBarSize,
|
||||||
@@ -10549,9 +10739,9 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
const executionPaperStyle = {
|
const executionPaperStyle = {
|
||||||
minWidth: "95%",
|
minWidth: "95%",
|
||||||
maxWidth: "95%",
|
maxWidth: "95%",
|
||||||
marginTop: "5px",
|
marginTop: "5px",
|
||||||
@@ -10563,9 +10753,9 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
display: "flex",
|
display: "flex",
|
||||||
minHeight: 40,
|
minHeight: 40,
|
||||||
maxHeight: 40,
|
maxHeight: 40,
|
||||||
};
|
};
|
||||||
|
|
||||||
const parsedExecutionArgument = () => {
|
const parsedExecutionArgument = () => {
|
||||||
var showResult = executionData.execution_argument.trim();
|
var showResult = executionData.execution_argument.trim();
|
||||||
const validate = validateJson(showResult);
|
const validate = validateJson(showResult);
|
||||||
|
|
||||||
|
|||||||
@@ -352,7 +352,7 @@ const Docs = (defaultprops) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Img(props) {
|
function Img(props) {
|
||||||
return <img style={{ maxWidth: "100%" }} alt={props.alt} src={props.src} />;
|
return <img style={{ borderRadius: theme.palette.borderRadius, maxWidth: "100%", marginTop: 15, marginBottom: 15, }} alt={props.alt} src={props.src} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
function CodeHandler(props) {
|
function CodeHandler(props) {
|
||||||
|
|||||||
@@ -33,6 +33,10 @@ import {
|
|||||||
DialogContent,
|
DialogContent,
|
||||||
} from "@material-ui/core";
|
} from "@material-ui/core";
|
||||||
|
|
||||||
|
import {
|
||||||
|
AvatarGroup,
|
||||||
|
} from "@mui/material"
|
||||||
|
|
||||||
import {
|
import {
|
||||||
GridOn as GridOnIcon,
|
GridOn as GridOnIcon,
|
||||||
List as ListIcon,
|
List as ListIcon,
|
||||||
@@ -1310,6 +1314,30 @@ const Workflows = (props) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getWorkflowAppgroup = (data) => {
|
||||||
|
if (data.actions === undefined || data.actions === null) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
var appsFound = []
|
||||||
|
for (var key in data.actions) {
|
||||||
|
const parsedAction = data.actions[key]
|
||||||
|
if (parsedAction.large_image === undefined || parsedAction.large_image === null || parsedAction.large_image === "") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parsedAction.app_name === "Shuffle Tools" || parsedAction.app_id === "bc78f35c6c6351b07a09b7aed5d29652") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (appsFound.findIndex(data => data.app_name === parsedAction.app_name) < 0){
|
||||||
|
appsFound.push(parsedAction)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return appsFound
|
||||||
|
}
|
||||||
|
|
||||||
const WorkflowPaper = (props) => {
|
const WorkflowPaper = (props) => {
|
||||||
const { data } = props;
|
const { data } = props;
|
||||||
const [open, setOpen] = React.useState(false);
|
const [open, setOpen] = React.useState(false);
|
||||||
@@ -1339,6 +1367,7 @@ const Workflows = (props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const actions = data.actions !== null ? data.actions.length : 0;
|
const actions = data.actions !== null ? data.actions.length : 0;
|
||||||
|
const appGroup = getWorkflowAppgroup(data)
|
||||||
const [triggers, subflows] = getWorkflowMeta(data);
|
const [triggers, subflows] = getWorkflowMeta(data);
|
||||||
|
|
||||||
const workflowMenuButtons = (
|
const workflowMenuButtons = (
|
||||||
@@ -1561,6 +1590,31 @@ const Workflows = (props) => {
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item style={workflowActionStyle}>
|
<Grid item style={workflowActionStyle}>
|
||||||
|
{appGroup.length > 0 ?
|
||||||
|
<div style={{display: "flex", marginTop: 8, }}>
|
||||||
|
<AvatarGroup max={4} style={{marginLeft: 5, maxHeight: 24,}}>
|
||||||
|
{appGroup.map((data, index) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: 24,
|
||||||
|
width: 24,
|
||||||
|
filter: "brightness(0.6)",
|
||||||
|
cursor: "pointer",
|
||||||
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
addFilter(data.app_name);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Tooltip color="primary" title={data.app_name} placement="bottom">
|
||||||
|
<Avatar alt={data.app_name} src={data.large_image} style={{width: 24, height: 24}}/>
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</AvatarGroup>
|
||||||
|
</div>
|
||||||
|
:
|
||||||
<Tooltip color="primary" title="Action amount" placement="bottom">
|
<Tooltip color="primary" title="Action amount" placement="bottom">
|
||||||
<span style={{ color: "#979797", display: "flex" }}>
|
<span style={{ color: "#979797", display: "flex" }}>
|
||||||
<BubbleChartIcon
|
<BubbleChartIcon
|
||||||
@@ -1577,6 +1631,7 @@ const Workflows = (props) => {
|
|||||||
</Typography>
|
</Typography>
|
||||||
</span>
|
</span>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
}
|
||||||
<Tooltip
|
<Tooltip
|
||||||
color="primary"
|
color="primary"
|
||||||
title="Trigger amount"
|
title="Trigger amount"
|
||||||
@@ -1681,7 +1736,7 @@ const Workflows = (props) => {
|
|||||||
marginTop: 5,
|
marginTop: 5,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{data.tags !== undefined
|
{data.tags !== undefined && data.tags !== null
|
||||||
? data.tags.map((tag, index) => {
|
? data.tags.map((tag, index) => {
|
||||||
if (index >= 3) {
|
if (index >= 3) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
Reference in New Issue
Block a user