added notification workflow stuff

This commit is contained in:
dhaval055
2024-02-17 10:15:54 +00:00
parent 51935b96a8
commit ce5e89e292
+464 -1
View File
@@ -2,7 +2,9 @@ import React, { useEffect } from "react";
import { makeStyles } from "@mui/styles"; import { makeStyles } from "@mui/styles";
import theme from '../theme.jsx'; import theme from '../theme.jsx';
import { toast } from "react-toastify" import { toast } from "react-toastify"
import Chip from '@mui/material/Chip';
import Stack from '@mui/material/Stack';
import { import {
FormControl, FormControl,
@@ -25,6 +27,11 @@ import {
Grid, Grid,
IconButton, IconButton,
Autocomplete, Autocomplete,
Dialog,
DialogTitle,
DialogActions,
DialogContent,
Box
} from "@mui/material"; } from "@mui/material";
import { import {
@@ -158,6 +165,19 @@ const OrgHeaderexpanded = (props) => {
const [workflows, setWorkflows] = React.useState([]) const [workflows, setWorkflows] = React.useState([])
const [workflow, setWorkflow] = React.useState({}) const [workflow, setWorkflow] = React.useState({})
// notification workflow
const [notificationApp, setNotificationApp] = React.useState("")
const [notificationWorkflowModal, setNotificationWorkflowModal] = React.useState(false);
const [selectedAppDetails, setSelectedAppDetails] = React.useState({});
const [notificationWorkflowTestModal, setNotificationWorkflowTestModal] = React.useState(false);
const [webhookInputValue, setWebhookInputValue] = React.useState("");
const [authOptions, setAuthOptions] = React.useState([]);
const [selectedAuth, setSelectedAuth] = React.useState('');
// for jira modal
const [jiraIssueType, setJiraIssueType] = React.useState("");
const [jiraProjectKey, setJiraProjectKey] = React.useState("");
const getAvailableWorkflows = (trigger_index) => { const getAvailableWorkflows = (trigger_index) => {
fetch(globalUrl + "/api/v1/workflows", { fetch(globalUrl + "/api/v1/workflows", {
method: "GET", method: "GET",
@@ -295,12 +315,455 @@ const OrgHeaderexpanded = (props) => {
</Tooltip> </Tooltip>
); );
const executeTestWorkflow = async (workflowid) => {
const data = { "execution_argument": '{"title":"THIS IS TEST ALERT","description":"TEST ALERT FROM SHUFFLE","reference_url": "shuffler.io"}' }
fetch(globalUrl + `/api/v1/workflows/${workflowid}/execute`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify(data),
credentials: "include",
})
.then((response) => {
if (response.status !== 200) {
toast("Failed setting notification workflow: ", response.reason);
console.log("Status not 200 for workflows :O!");
return;
}
toast("Notification workflow ran successfully");
return response.json();
}).catch((error) => {
console.log("Error getting workflows: " + error);
})
}
const generateNotificationWorkflow = async (appname,appImage,appAuthId,projectId,issuetype) => {
//currently only supports JIRA figure out a way to support more apps
var workflowName = `[GENARATED] ${appname} notification workflow`
var workflowDescription = "Generated by Shuffle for sending error notifications."
var data = {
"name": workflowName,
"description": workflowDescription,
}
fetch(globalUrl + "/api/v1/workflows", {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify(data),
credentials: "include",
})
.then((response) => {
if (response.status !== 200) {
toast("Failed setting notification workflow: ", response.reason);
console.log("Status not 200 for workflows :O!");
return;
}
return response.json();
}).then((responseJson)=>{
if (responseJson !== undefined) {
console.log("Notification workflow created successfully")
var workflow_id = responseJson.id
if (appname.toLowerCase() === "jira"){
console.log("updating workflow for JIRA")
var workflowBody = {
"name": workflowName,
"Description": workflowDescription,
"id": workflow_id,
"actions": [
{
"app_name": "Jira",
"name": "post_create_issue",
"authentication_id":appAuthId,
"large_image":appImage,
"isStartNode": true,
"label": "create_issue",
"app_version": "1.1.0",
"parameters": [
{
"name": "body",
"value": `{"fields": { "project": {"key": "${projectId}"},"summary": "$exec.title","issuetype": {"name": "${issuetype}"},"description": {"content": [{"content":[{"type":"text","text":"$exec.description"}],"type": "paragraph"}],"type": "doc","version": 1}}}`
},
{
"name": "username_basic",
"value": ""
},
{
"name": "password_basic",
"value": ""
},
{
"name": "url",
"value": ""
},
{
"name": "headers",
"value": "Content-type=application/json \nAccept=application/json"
},
{
"name": "queries",
"value": ""
},
{
"name": "ssl_verify",
"value": "False"
}
]
}
]
}
}
fetch(globalUrl + `/api/v1/workflows/${workflow_id}`, {
method: "PUT",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify(workflowBody),
credentials: "include",
})
.then((response) => {
if (response.status !== 200) {
toast("Failed setting notification workflow: ", response.reason);
console.log("Status not 200 for workflows :O!");
return;
}
return response.json();
}).then((responseJson)=>{
if (responseJson !== undefined) {
handleEditOrg(
orgName,
orgDescription,
selectedOrganization.id,
selectedOrganization.image,
{
app_download_repo: appDownloadUrl,
app_download_branch: appDownloadBranch,
workflow_download_repo: workflowDownloadUrl,
workflow_download_branch: workflowDownloadBranch,
notification_workflow: workflow_id,
documentation_reference: documentationReference,
},
{
sso_entrypoint: ssoEntrypoint,
sso_certificate: ssoCertificate,
client_id: openidClientId,
client_secret: openidClientSecret,
openid_authorization: openidAuthorization,
openid_token: openidToken,
}
)
console.log("Notification workflow updated successfully")
toast("Notification workflow updated successfully")
}
})
}
}).catch((error) => {
console.log("Error setting workflows: " + error);
})
}
const getAppAuth = async (appName) => {
fetch(globalUrl + "/api/v1/apps/authentication", {
method: "GET",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
credentials: "include",
})
.then((response) => {
if (response.status !== 200) {
toast(`Failed getting auth for ${appName}: `, response.reason);
console.log("Status not 200 for app auth :O!");
return;
}
return response.json();
}).then((responseJson) => {
if (!responseJson.success) {
console.log("Could not get app auth")
return;
}
var authList = responseJson.data.filter(entry => entry.app.name === appName)
console.log("authList: ", authList)
setAuthOptions(authList);
}).catch((error) => {
console.log("Error getting app auth: " + error);
})
}
const testWorkflowModal = notificationWorkflowTestModal ?
(<Dialog
open={notificationWorkflowTestModal}
PaperProps={{
style: {
backgroundColor: theme.palette.surfaceColor,
color: "white",
minWidth: 500,
},
}}
onClose={() => {
setNotificationWorkflowTestModal(false);
}}
>
<FormControl>
{/* <DialogTitle>
<div style={{ color: "rgba(255,255,255,0.9)" }}>
Notification workflow
</div>
</DialogTitle> */}
<DialogContent style={{ color: "rgba(255,255,255,0.65)" }}>
We have updated the Notification workflow. Do you want to test it?
</DialogContent>
<DialogActions>
<Button
style={{ borderRadius: "0px" }}
onClick={() => {
setNotificationWorkflowTestModal(false);
}}
color="primary"
>
No
</Button>
<Button
variant="contained"
style={{ borderRadius: "0px" }}
onClick={() => {
executeTestWorkflow(selectedOrganization.defaults.notification_workflow);
setNotificationWorkflowTestModal(false);
}}
color="primary"
>
Yes
</Button>
</DialogActions>
</FormControl>
</Dialog>) : null
const notificationWorkflowModalValid = () => {
return selectedAuth && webhookInputValue;
};
const modalView = notificationWorkflowModal ? (
<Dialog
open={notificationWorkflowModal}
PaperProps={{
style: {
backgroundColor: theme.palette.grey,
minWidth: 500,
},
}}
onClose={() => {
setNotificationWorkflowModal(false);
}}
>
<FormControl>
<DialogTitle>
<div style={{ color: "rgba(255,255,255,0.9)" }}>
{`Configure ${selectedAppDetails.name} workflow`}
</div>
</DialogTitle>
<DialogContent style={{ color: "rgba(255,255,255,0.65)", overflowY: 'auto', maxHeight: '450px' }}>
<Divider style={{ marginBottom: '1em', backgroundColor: 'rgba(255,255,255,0.12)' }} />
{authOptions.length > 0 ?
<>
<Box mb={2}>
<Typography variant="body1" style={{ marginBottom: '0.5rem' }}>
Pick an authentication method from the list
</Typography>
<FormControl fullWidth style={{ marginBottom: 10 }}>
<InputLabel id="demo-simple-select-label">Available authentications</InputLabel>
<Select
labelId="demo-simple-select-label"
id="demo-simple-select"
value={selectedAuth}
onChange={(event) => {setSelectedAuth(event.target.value)
console.log("Selected auth: ", selectedAuth)
}}
label="Available authentications"
required={true}
>
{authOptions.map((option) => (
<MenuItem key={option.id} value={option.id}>
<div style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>
<Chip label={option.app.app_version} variant="outlined" />
{option.label}
</div>
</MenuItem>))}
</Select>
</FormControl>
</Box>
<Box mt={2}>
<Typography variant="body1">
Provide additional required details:
</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="Project key"
// value={webhookInputValue}
onChange={(e) => {
setJiraProjectKey(e.target.value)
}}
InputProps={{
classes: {
notchedOutline: classes.notchedOutline,
},
style: {
color: "white",
},
}} />
<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="Issue type"
// value={webhookInputValue}
onChange={(e) => {
setJiraIssueType(e.target.value)
}}
InputProps={{
classes: {
notchedOutline: classes.notchedOutline,
},
style: {
color: "white",
},
}} />
</Box>
</> : <>
<Typography
variant="subtitle1"
style={{
whiteSpace: 'nowrap',
overflow: 'hidden',
}}
>
{`No ${selectedAppDetails.name} auth found. Click below to set one up.`}
</Typography>
<Button
style={{ borderRadius: "0px", marginTop: 10 }}
variant="outlined"
onClick={() => {
setNotificationWorkflowModal(false);
}}
color="primary"
>
Configure
</Button>
</>
}
</DialogContent>
<DialogActions>
<Button
style={{ borderRadius: "0px" }}
onClick={() => {
setNotificationWorkflowModal(false);
}}
color="primary"
>
Cancel
</Button>
<Button
variant="contained"
style={{ borderRadius: "0px" }}
disabled={(authOptions.length > 0 ? false : true) || !notificationWorkflowModalValid}
onClick={async () => {
// var workflowUpdate = await setTeamsWorkflow(webhookInputValue)
console.log("Selectedappdetails: ", selectedAppDetails)
generateNotificationWorkflow(selectedAppDetails.name, selectedAppDetails.large_image,selectedAuth, jiraProjectKey, jiraIssueType)
setNotificationWorkflowModal(false);
}}
color="primary"
>
Submit
</Button>
</DialogActions>
</FormControl>
</Dialog >
) : null
// getting comms & cases app from app framework
var notificationAppList = [];
if (selectedOrganization.security_framework.cases && selectedOrganization.security_framework.cases.name.length > 0) {
notificationAppList = notificationAppList.concat(selectedOrganization.security_framework.cases);
}
if (selectedOrganization.security_framework.communication && selectedOrganization.security_framework.communication.name.length > 0) {
notificationAppList = notificationAppList.concat(selectedOrganization.security_framework.communication);
}
const renderChips = (apps) => {
if (!apps || apps.length === 0) {
return (<Typography variant="caption" display="block" gutterBottom>
<Chip
label="email"
variant="outlined"
onClick={() => {
console.log(`Clicked EMAIL`)
setNotificationWorkflowModal(true)
}}
avatar={<img src={"https://storage.googleapis.com/shuffle_public/app_images/email_f33aa6a9c04e64cbf5d89d927ff0cd38.png"} alt={"email app logo"} style={{ width: 24, height: 24, borderRadius: '50%' }} />}
/>
</Typography>)
}
return (
<Stack direction="row" spacing={1}>
{apps.map((app) => (
<Chip
key={app.id}
label={app.name}
variant="outlined"
onClick={() => {
console.log(`Clicked ${app.name}`)
setSelectedAppDetails(app)
setNotificationWorkflowModal(true)
getAppAuth(app.name)
console.log(selectedAppDetails)
}}
avatar={<img src={app.large_image} alt={app.name} style={{ width: 24, height: 24, borderRadius: '50%' }} />}
/>
))}
</Stack>
);
};
return ( return (
<div style={{ textAlign: "center" }}> <div style={{ textAlign: "center" }}>
<Grid container spacing={3} style={{ textAlign: "left" }}> <Grid container spacing={3} style={{ textAlign: "left" }}>
<Grid item xs={12} style={{}}> <Grid item xs={12} style={{}}>
<span> <span>
<Typography>Notification Workflow</Typography> <Typography>Notification Workflow</Typography>
{modalView}
{/*{testWorkflowModal} */}
<div style={{ marginBottom: '10px' }}>
{renderChips(notificationAppList)}</div>
{/* {/*
<Typography variant="body2" color="textSecondary"> <Typography variant="body2" color="textSecondary">
Add a Workflow that receives notifications from Shuffle when an error occurs in one of your workflows Add a Workflow that receives notifications from Shuffle when an error occurs in one of your workflows