import React, { useState, useEffect } from "react";
import { toast } from 'react-toastify';
import theme from '../theme.jsx';
import { useNavigate, Link } from "react-router-dom";
//import { useAlert
import ConfigureWorkflow from "../components/ConfigureWorkflow.jsx";
import PaperComponent from "../components/PaperComponent.jsx"
import AuthenticationOauth2 from "../components/Oauth2Auth.jsx";
import AuthenticationNormal from "../components/AuthenticationNormal.jsx";
import AppsearchPopout from "../components/AppsearchPopout.jsx";
import {
ExpandLess as ExpandLessIcon,
ExpandMore as ExpandMoreIcon,
AddCircleOutline as AddCircleOutlineIcon,
Delete as DeleteIcon,
Description as DescriptionIcon,
Close as CloseIcon,
} from '@mui/icons-material';
import {
Dialog,
IconButton,
Typography,
Button,
CircularProgress,
Tooltip,
Divider,
} from "@mui/material";
const defaultValue = {"id": "", "name": "Build your own",
"source": {"text": "No trigger selected", "error": ""},
"destination": {"text": "No subflow selected", "error": ""},
"middle": []
}
export const usecaseTypes = [{
"name": "enrichment",
"aliases": ["enrichment", "enrich"],
"value": [{
"name": "EDR Ticket Enrichment",
"usecase_references": ["EDR to ticket"],
"active": true,
"items": [{
"name": "When an EDR alert is found",
"app_type": "edr",
"type": "trigger",
}, {
"name": "Create a ticket",
"app_type": "cases",
"type": "subflow",
}],
},
{
"name": "SIEM alert Enrichment",
"aliases": ["siem alert enrichment", "siem alert enrich"],
"usecase_references": ["SIEM to ticket"],
"active": true,
"items": [{
"name": "When a SIEM alert is found",
"app_type": "siem",
"type": "trigger",
},
{
"name": "Create a ticket",
"app_type": "cases",
"type": "subflow",
}],
},
{
"name": "Email Enrichment",
"aliases": ["email enrichment", "email enrich"],
"usecase_references": ["Email management"],
"active": true,
"items": [{
"name": "When I get an email",
"app_type": "email",
"type": "trigger",
},
{
"name": "Create a ticket",
"app_type": "cases",
"type": "subflow",
}],
}]
},
{
"name": "phishing",
"aliases": ["ransomware", "ransomware handling"],
"value": [
{
"name": "Email analysis",
"usecase_references": ["Email management"],
"active": true,
"items": [{
"name": "When I get an email",
"app_type": "email",
"type": "trigger",
},{
"name": "Create a ticket",
"app_type": "cases",
"type": "subflow",
}],
}]
},
{
"name": "detection",
"aliases": ["detection", "detect", "siem alerts", "new detections",],
"value": [
{
"name": "Sigma rule detection",
"active": false,
"items": [{
"name": "When a sigma rule triggers",
"app_type": "siem",
"type": "trigger",
},
{
"name": "Create a ticket",
"app_type": "cases",
"type": "subflow",
}],
}]
},
{
"name": "response",
"aliases": ["response", "respond", "exploits", "eradication",],
"value": [
{
"name": "EDR host isolation",
"active": false,
"items": [{
"name": "When exploits are detected",
"app_type": "edr",
"type": "trigger",
},
{
"name": "Isolate the host",
"app_type": "edr",
"type": "subflow",
}],
}]
},
{
"name": "vulnerabilities",
"aliases": [],
"value": [
{
"name": "Vulnerability is found",
"active": false,
"items": [{
"name": "When a vulnerability is found",
"app_type": "assets",
"type": "trigger",
},
{
"name": "Patch the vulnerability",
"app_type": "edr",
"type": "subflow",
}],
}]
},
{
"name": "approvals",
"aliases": ["approval"],
"value": [
{
"name": "Approval is needed",
"active": false,
"items": [{
"name": "When approval is needed",
"app_type": "iam",
"type": "trigger",
},
{
"name": "Notify the user",
"app_type": "communication",
"type": "subflow",
}],
}]
},
]
export const triggerlist = [
{
"app_id": "",
"app_name": "",
"app_version": "",
"text": "No trigger selected",
"image": "",
"type": "",
"action_type": "",
"error": "",
},
{
"app_id": "",
"app_name": "",
"app_version": "",
"text": "When I get an email",
"image": "",
"type": "email",
"action_type": "receive",
},
{
"app_id": "",
"app_name": "",
"app_version": "",
"text": "When a ticket is created",
"image": "",
"type": "cases",
"action_type": "case_opened",
},
{
"app_id": "",
"app_name": "",
"app_version": "",
"text": "When an EDR alert is found",
"image": "",
"type": "edr",
"action_type": "case_opened",
},
{
"app_id": "",
"app_name": "",
"app_version": "",
"text": "When a SIEM alert is found",
"image": "",
"type": "siem",
"action_type": "case_opened",
},
{
"app_id": "",
"app_name": "",
"app_version": "",
"text": "When a sigma rule triggers",
"image": "",
"type": "siem",
"action_type": "case_opened",
"disabled": true,
},
{
"app_id": "",
"app_name": "",
"app_version": "",
"text": "When malicious endpoint activity is detected",
"image": "",
"type": "edr",
"action_type": "case_opened",
"disabled": true,
}
]
export const midflows = [
{
"app_id": "",
"app_name": "",
"app_version": "",
"text": "Enrich",
"image": "",
"type": "intel",
"action_type": "enrich",
},
{
"app_id": "",
"app_name": "",
"app_version": "",
"text": "Analyze",
"image": "",
"type": "intel",
"action_type": "analyze",
"disabled": true,
}
]
export const subflows = [
{
"app_id": "",
"app_name": "",
"app_version": "",
"text": "No subflow selected",
"image": "",
"type": "",
"action_type": "",
"error": "",
},
{
"app_id": "",
"app_name": "",
"app_version": "",
"text": "Create a ticket",
"image": "",
"type": "cases",
"action_type": "case_create",
},
{
"app_id": "",
"app_name": "",
"app_version": "",
"text": "Update a ticket",
"image": "",
"type": "cases",
"action_type": "case_update",
"disabled": true,
//"source_type": "case_opened",
},
{
"app_id": "",
"app_name": "",
"app_version": "",
"text": "Answer the sender",
"image": "",
"type": "email",
"action_type": "send",
"disabled": true,
//"source_type": "case_opened",
},
{
"app_id": "",
"app_name": "",
"app_version": "",
"text": "Isolate the host",
"image": "",
"type": "edr",
"action_type": "respond",
"disabled": true,
//"source_type": "case_opened",
},
]
const UsecaseSearch = (props) => {
const { defaultSearch, appFramework, globalUrl, showTitle, canExpand, apps, setFoundWorkflowId, getFramework, userdata, usecaseSearch, setUsecaseSearch, autotry, setCloseWindow, sourceapp, destinationapp} = props
const [allusecases, setAllUsecases] = React.useState([
JSON.parse(JSON.stringify(defaultValue))
])
const [searchType, setSearchType] = React.useState("")
const [usecaseIndex, setUsecaseIndex] = React.useState(0)
const [_, setUpdate] = useState(""); // Used for rendring, don't remove
const [isUploading, setIsUploading] = React.useState(false)
const [configureWorkflowModalOpen, setConfigureWorkflowModalOpen] = React.useState(false);
const [configureWorkflowAuth, setConfigureWorkflowAuth] = React.useState([]);
const [workflow, setWorkflow] = React.useState({});
const [appAuthentication, setAppAuthentication] = React.useState([]);
const [authenticationType, setAuthenticationType] = React.useState("");
const [authenticationModalOpen, setAuthenticationModalOpen] = React.useState(false);
const [selectedApp, setSelectedApp] = React.useState({});
const [selectedAction, setSelectedAction] = React.useState({});
const [firstRequest, setFirstRequest] = React.useState(true);
const isCloud = (window.location.host === "localhost:3002" || window.location.host === "shuffler.io") ? true : (process.env.IS_SSR === "true");
//const alert = useAlert()
useEffect(() => {
// if (firstRequest !== true && workflow.id !== undefined && autotry === true && setUsecaseSearch !== undefined && authenticationModalOpen === false && configureWorkflowModalOpen === false) {
//
if (autotry === true && configureWorkflowModalOpen === false && workflow.id !== undefined && setUsecaseSearch !== undefined) {
console.log("Close it?")
toast("Workflow successfully added! Add more apps, and we will suggest more workflows")
if (setCloseWindow !== undefined) {
setCloseWindow(true)
}
setUsecaseSearch("")
}
}, [configureWorkflowModalOpen])
const rerunWorkflowCheck = (defaultSearch, usecaseSearch) => {
const foundusecase = usecaseTypes.find(data => data.name.toLowerCase() === defaultSearch.toLowerCase())
//console.log("FOUND: ", usecaseTypes, defaultSearch.toLowerCase(), foundusecase)
if (foundusecase !== undefined && foundusecase !== null) {
// Just choose the first one.
if (foundusecase.value !== undefined && foundusecase.value !== null && foundusecase.value.length > 0) {
var selectedusecase = foundusecase.value[0]
if (usecaseSearch !== undefined && usecaseSearch !== null) {
const foundSubcase = foundusecase.value.find(usecase => usecase.name.toLowerCase() === usecaseSearch.toLowerCase())
if (foundSubcase !== undefined && foundSubcase !== null) {
selectedusecase = foundSubcase
}
}
var newitem = JSON.parse(JSON.stringify(defaultValue))
for (var key in selectedusecase.items) {
// Check in different types
const itemname = selectedusecase.items[key].name.toLowerCase()
const trigger = triggerlist.find(data => data.text.toLowerCase() === itemname)
if (trigger !== undefined && trigger !== null) {
newitem.name = selectedusecase.name
newitem.source = trigger
continue
}
const midflow = midflows.find(data => data.text.toLowerCase() === itemname)
if (midflow !== undefined && midflow !== null) {
newitem.name = selectedusecase.name
newitem.middle.push(midflow)
continue
}
const subflow = subflows.find(data => data.text.toLowerCase() === itemname)
if (subflow !== undefined && subflow !== null) {
newitem.name = selectedusecase.name
newitem.destination = subflow
continue
}
}
setAllUsecases([newitem])
setUpdate(Math.random())
}
} else {
setAllUsecases([JSON.parse(JSON.stringify(defaultValue))])
setUpdate(Math.random())
}
}
if (defaultSearch !== undefined && defaultSearch !== null && defaultSearch !== searchType) {
setSearchType(defaultSearch)
setUsecaseIndex(0)
rerunWorkflowCheck(defaultSearch, usecaseSearch)
}
//if (defaultSearch !== undefined && defaultSearch.length > 0 && allusecases[usecaseIndex].name === "") {
// rerunWorkflowCheck()
//}
/*
defaultSearch === "Enrichment" ?
[{
"id": "",
"source": {
"app_id": "",
"app_name": "",
"app_version": "",
"text": "When I get an email",
"image": "",
"type": "email",
"action_type": "receive",
},
"middle": [{
"app_id": "",
"app_name": "",
"app_version": "",
"text": "Enrich the data",
"image": "",
"type": "intel",
"action_type": "case_create",
}],
"destination": {
"app_id": "",
"app_name": "",
"app_version": "",
"text": "Create a ticket",
"image": "",
"type": "cases",
"action_type": "case_create",
},
}]
: []
)
*/
/*
if (defaultSearch === undefined || defaultSearch === null || defaultSearch.length === 0) {
return (
Choose a Usecase
)
}
*/
// Image = the source EMAIL system used
var usecases = JSON.parse(JSON.stringify(allusecases))
const imagestyle = {
height: 40,
width: 40,
borderRadius: 25,
border: "1px solid rgba(255,255,255,0.7)",
cursor: "pointer",
}
const getType = (inputtype) => {
if (inputtype === undefined) {
return inputtype
}
if (inputtype.toLowerCase() === "email" || inputtype.toLowerCase() === "comms") {
inputtype = "communication"
}
return inputtype
}
// FIXME: Add a way for it to automatically discover
// relevant workflows from the app at this point
// or maybe it should be added directly to the app frameworks'
// data
const getAppAuthentication = (updateAction) => {
fetch(globalUrl + "/api/v1/apps/authentication", {
method: "GET",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
credentials: "include",
})
.then((response) => {
if (response.status !== 200) {
console.log("Status not 200 for app auth :O!");
}
return response.json();
})
.then((responseJson) => {
if (responseJson.success) {
setAppAuthentication(responseJson.data);
}
})
.catch((error) => {
console.log("App auth loading error: "+error.toString());
})
}
//saveWorkflow={undefined} {/*saveWorkflow*/}
//setNewAppAuth={undefined} {/*setNewAppAuth*/}
const authenticationModal = authenticationModalOpen ? (
) : null
const deleteWorkflow = (workflow_id) => {
fetch(globalUrl + "/api/v1/workflows/" + workflow_id, {
method: "DELETE",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
credentials: "include",
})
.then((response) => {
if (response.status !== 200) {
console.log("Status not 200 for workflows :O!");
}
return response.json();
})
.then((responseJson) => {
console.log("Deleted workflow")
})
.catch((error) => {
//toast(error.toString());
console.log("Delete workflow error: ", error.toString());
})
}
const getWorkflow = (workflow_id) => {
fetch(globalUrl + "/api/v1/workflows/" + workflow_id, {
method: "GET",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
credentials: "include",
})
.then((response) => {
if (response.status !== 200) {
console.log("Status not 200 for workflows :O!");
}
return response.json();
})
.then((responseJson) => {
setWorkflow(responseJson)
if (window !== undefined && !window.location.href.includes("/workflows")) {
setConfigureWorkflowModalOpen(true)
}
})
.catch((error) => {
//toast(error.toString());
console.log("Get workflows error: ", error.toString());
})
}
// Stolen from /views/Workflows
// Due to states, not easy to just import as component~
const setNewWorkflow = (
name,
description,
tags,
defaultReturnValue,
editingWorkflow,
redirect,
currentUsecases,
inputblogpost,
inputstatus,
) => {
var method = "POST";
var extraData = "";
var workflowdata = {};
if (editingWorkflow.id !== undefined) {
console.log("Building original workflow");
method = "PUT";
extraData = "/" + editingWorkflow.id + "?skip_save=true";
workflowdata = editingWorkflow;
console.log("REMOVING OWNER");
workflowdata["owner"] = "";
// FIXME: Loop triggers and turn them off?
}
workflowdata["name"] = name;
workflowdata["description"] = description;
if (tags !== undefined) {
workflowdata["tags"] = tags;
}
workflowdata["blogpost"] = inputblogpost
workflowdata["status"] = inputstatus
if (defaultReturnValue !== undefined) {
workflowdata["default_return_value"] = defaultReturnValue;
}
if (currentUsecases !== undefined && currentUsecases !== null) {
workflowdata["usecase_ids"] = currentUsecases
//workflows[0].category = ["detect"]
//workflows[0].usecase_ids = ["Correlate tickets"]
}
const new_url = `${globalUrl}/api/v1/workflows${extraData}`
return fetch(new_url, {
method: method,
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify(workflowdata),
credentials: "include",
})
.then((response) => {
if (response.status !== 200) {
console.log("Status not 200 for workflows :O!");
return;
}
return response.json();
})
.then((responseJson) => {
if (responseJson.success === false) {
if (responseJson.reason !== undefined) {
toast("Error setting workflow: ", responseJson.reason)
} else {
toast("Error setting workflow.")
}
return
}
return responseJson;
})
.catch((error) => {
toast(error.toString());
});
}
const mergeWorkflowUsecases = (usecasedata) => {
// To properly handle multiple-locations
const url = isCloud ? `${globalUrl}/api/v1/workflows/merge` : `https://shuffler.io/api/v1/workflows/merge`;
fetch(url, {
mode: "cors",
method: "POST",
body: JSON.stringify(usecasedata),
credentials: "include",
crossDomain: true,
withCredentials: true,
headers: {
"Content-Type": "application/json; charset=utf-8",
},
})
.then((response) =>
response.json().then((responseJson) => {
setIsUploading(false)
var changed = false
if (responseJson.success === false) {
if (responseJson.reason !== null && responseJson.reason !== undefined) {
//toast(responseJson.reason)
}
if (responseJson.source === "") {
const appname =
usecasedata.source.error = usecasedata.source.app_name === undefined ? "Select a Trigger workflow first" : `${usecasedata.source.app_name} has no public trigger workflow yet. Click this to try another app`
changed = true
} else {
usecasedata.source.error = ""
changed = true
}
if (responseJson.destination === "") {
usecasedata.destination.error = usecasedata.destination.app_name === undefined ? "Select a Subflow first" : `${usecasedata.destination.app_name} has no public subflow yet. Click this to try another app`
changed = true
} else {
usecasedata.destination.error = ""
changed = true
}
if (responseJson.middle !== undefined) {
for (var key in responseJson.middle) {
for (var subkey in usecasedata.middle) {
if (responseJson.middle[key] === usecasedata.middle[key].text) {
console.log("Found: ")
if (usecasedata.middle[subkey].app_name === undefined || usecasedata.middle[subkey].app_name === "") {
usecasedata.middle[subkey].error = `${usecasedata.middle[subkey].type} app must be selected first. Click this to change`
} else {
usecasedata.middle[subkey].error = `${usecasedata.middle[subkey].app_name} has no public subflow yet. Click this to change`
}
changed = true
break
}
}
}
}
} else {
// Gets a full workflow that has to be handled from cloud directly
//
if (!isCloud) {
console.log("Not cloud!")
if (setFoundWorkflowId !== undefined) {
setFoundWorkflowId(responseJson.id)
}
setWorkflow(responseJson)
setNewWorkflow(
responseJson.name,
responseJson.description,
responseJson.tags,
responseJson.default_return_value,
{},
false,
[],
"",
responseJson.status,
)
.then((response) => {
if (response !== undefined) {
// SET THE FULL THING
responseJson.id = response.id;
responseJson.first_save = false;
responseJson.previously_saved = false;
responseJson.is_valid = false;
// Actually create it
setNewWorkflow(
responseJson.name,
responseJson.description,
responseJson.tags,
responseJson.default_return_value,
responseJson,
false,
[],
"",
responseJson.status,
).then((response) => {
if (response !== undefined) {
toast("Successfully generated " + responseJson.name);
}
});
}
})
.catch((error) => {
toast("Generate error: " + error.toString());
})
} else if (isCloud) {
if (responseJson.workflow_id !== null && responseJson.workflow_id !== undefined) {
if (responseJson.added_auth !== undefined && responseJson.added_auth !== null && responseJson.added_auth.length > 0) {
setConfigureWorkflowAuth(responseJson.added_auth)
if (setFoundWorkflowId !== undefined) {
console.log("Set found workflow id: ", responseJson.workflow_id)
setFoundWorkflowId(responseJson.workflow_id)
}
getWorkflow(responseJson.workflow_id)
getAppAuthentication()
} else {
if (setFoundWorkflowId !== undefined) {
console.log("Set found workflow id: ", responseJson.workflow_id)
setFoundWorkflowId(responseJson.workflow_id)
}
setWorkflow({"id": responseJson.workflow_id})
}
}
if (responseJson.auth_required === true) {
console.log("SET AUTH AS NEXT STEP!")
}
}
}
if (changed === true) {
setAllUsecases([usecasedata])
}
})
)
.catch((error) => {
setIsUploading(false)
console.log("Merge err: ", error.toString())
//toast("Err: " + error.toString());
});
}
// Autosearch in framework & set it?
if (sourceapp !== undefined && destinationapp !== undefined) {
console.log("FIND APPS", sourceapp, destinationapp)
}
if (appFramework !== undefined && usecases !== undefined) {
for (var key in usecases) {
// source
const usecase = usecases[key]
if (usecase.source.type === undefined || usecase.source.image === "" || usecase.source.image === undefined) {
usecases[key].source.image = theme.palette.defaultImage
}
if (usecase.destination.type === undefined || usecase.destination.image === "" || usecase.destination.image === undefined) {
usecases[key].destination.image = theme.palette.defaultImage
}
const srctype = getType(usecase.source.type)
const dsttype = getType(usecase.destination.type)
const srcinfo = appFramework[srctype]
if (srcinfo !== undefined && srcinfo.large_image !== undefined && srcinfo.large_image !== "" && (usecases[key].source.app_name === undefined || usecases[key].source.app_name === "")) {
usecases[key].source.image = srcinfo.large_image
usecases[key].source.app_id = srcinfo.id
usecases[key].source.app_name = srcinfo.name
}
const destinfo = appFramework[dsttype]
if (destinfo !== undefined && destinfo.large_image !== undefined && destinfo.large_image !== "" && (usecases[key].destination.app_name === undefined || usecases[key].destination.app_name === "")) {
usecases[key].destination.image = destinfo.large_image
usecases[key].destination.app_id = destinfo.id
usecases[key].destination.app_name = destinfo.name
}
if (usecase.middle !== undefined && usecase.middle !== null && usecase.middle.length > 0) {
for (var subkey in usecase.middle) {
const midcase = usecase.middle[subkey]
const midtype = getType(midcase.type)
const midinfo = appFramework[midtype]
if (midinfo !== undefined && midinfo.large_image !== undefined && midinfo.large_image !== "" && (usecases[key].middle[subkey].app_name === undefined || usecases[key].middle[subkey].app_name === "")) {
usecases[key].middle[subkey].image = midinfo.large_image
usecases[key].middle[subkey].app_id = midinfo.id
usecases[key].middle[subkey].app_name = midinfo.name
} else {
if (usecases[key].middle[subkey].image === undefined || usecases[key].middle[subkey].image === "") {
usecases[key].middle[subkey].image = theme.palette.defaultImage
}
}
}
}
}
//if (firstRequest) {
// setAllUsecases(usecases)
// setFirstRequest(false)
//}
}
const configureWorkflowModal =
configureWorkflowModalOpen ? (
) : null
const createWorkflowFromTemplate = (data) => {
if (workflow.id !== undefined && workflow.id !== null && workflow.id.length !== 0) {
console.log("Should delete old one: ", workflow.id)
deleteWorkflow(workflow.id)
}
// Should be searched?
setIsUploading(true)
var changed = false
if (data.source.app_name === "") {
data.source.error = `'${data.source.type}' app must be selected first`
changed = true
}
if (data.destination.app_name === "") {
data.destination.error = `'${data.destination.type}' app must be selected first`
changed = true
}
if (data.middle !== undefined && data.middle !== null && data.middle.length > 0) {
for (var key in data.middle) {
const middleItem = data.middle[key]
if (middleItem.app_name === "") {
data.middle[key].error = `'${middleItem.type}' app must be selected first`
//changed = true
}
}
}
if (changed) {
//toast("Errors were found. Click them to sort sort them out or go to the next usecase.")
//setUpdate(Math.random())
//setIsUploading(false)
//return
}
// Auto finding these during deploy
//data.source.workflow_id = "e506060f-0c58-4f95-a0b8-f671103d78e5"
//data.destination.workflow_id = "ffe8122d-0787-425a-aa20-c2587ee75a83"
//if (data.middle !== undefined && data.middle !== null && data.middle.length > 0) {
// data.middle[0].workflow_id = "1077d9ee-b571-4410-a7e6-261f32f346c5"
//}
mergeWorkflowUsecases(data)
}
if (autotry === true && firstRequest === true && appFramework !== undefined && usecases !== undefined && isUploading === false) {
console.log("Should autotry the usecase! Make sure data is in order first. Usecase: ", usecases)
if (usecases !== undefined && usecases !== null && usecases.length > 0 && usecases[0].name !== "Build your own" && usecases[0].name !== "") {
setFirstRequest(false)
createWorkflowFromTemplate(usecases[0])
}
//{usecases.map((data, index) => {
}
const ShowBox = (props) => {
const { data, type, index, miditem, subindex } = props
const [expanded, setexpanded] = React.useState(false)
const [newSelectedApp, setNewSelectedApp] = React.useState({})
const [paperTitle, setPaperTitle] = React.useState(data.type)
const [selectionOpen, setSelectionOpen] = React.useState(false)
const [discoveryData, setDiscoveryData] = React.useState({
"id": "",
"label": "",
"name": "",
"large_image": "",
})
//console.log("Data: ", data)
const activateApp = (appid) => {
fetch(globalUrl+"/api/v1/apps/"+appid+"/activate", {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
credentials: "include",
})
.then((response) => {
return response.json()
})
.then((responseJson) => {
if (responseJson.success === false) {
var msgString = "Failed to activate the app"
if (responseJson.reason !== undefined) {
msgString += ": " + responseJson.reason
}
toast(msgString)
} else {
//toast("App activated for your organization! Refresh the page to use the app.")
}
})
.catch(error => {
//toast(error.toString())
console.log("Activate app error: ", error.toString())
});
}
const setFrameworkItem = (data) => {
// Making sure the app is being auto-built and added
if (!isCloud) {
activateApp(data.id)
}
fetch(globalUrl + "/api/v1/apps/frameworkConfiguration", {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify(data),
credentials: "include",
})
.then((response) => {
if (response.status !== 200) {
console.log("Status not 200 for framework!");
}
return response.json();
})
.then((responseJson) => {
if (responseJson.success === false) {
if (responseJson.reason !== undefined) {
toast("Failed updating default app: " + responseJson.reason)
} else {
toast("Failed to update framework for your org.")
}
} else {
if (getFramework !== undefined) {
getFramework()
}
}
//setFrameworkLoaded(true)
//setFrameworkData(responseJson)
})
.catch((error) => {
toast(error.toString());
//setFrameworkLoaded(true)
})
}
useEffect(() => {
if (newSelectedApp.objectID === undefined) {
return
}
var discoveredtype = ""
if (type === "middle") {
console.log("Updating middle index", subindex)
allusecases[index][type][subindex]["app_id"] = newSelectedApp.objectID
allusecases[index][type][subindex]["app_name"] = newSelectedApp.name
allusecases[index][type][subindex]["app_version"] = newSelectedApp.app_version
allusecases[index][type][subindex]["image"] = newSelectedApp.image_url
allusecases[index][type][subindex]["error"] = ""
discoveredtype = allusecases[index][type][subindex]["type"]
} else {
allusecases[index][type]["app_id"] = newSelectedApp.objectID
allusecases[index][type]["app_name"] = newSelectedApp.name
allusecases[index][type]["app_version"] = newSelectedApp.app_version
allusecases[index][type]["image"] = newSelectedApp.image_url
allusecases[index][type]["error"] = ""
discoveredtype = allusecases[index][type]["type"]
}
setSelectionOpen(false)
setUpdate(Math.random())
setAllUsecases(allusecases)
const submitValue = {
"type": discoveredtype,
"name": newSelectedApp.name,
"id": newSelectedApp.objectID,
"large_image": newSelectedApp.image_url,
"description": newSelectedApp.description,
}
setFrameworkItem(submitValue)
}, [newSelectedApp])
if (data.text === undefined || data.text === null || data.text.length === 0) {
return null
}
const changeAppType = () => {
setSelectionOpen(true)
}
const looplist = type === "source" ? triggerlist : type === "destination" ? subflows : midflows
const hasError = data.error !== undefined && data.error !== null && data.error.length > 0
const borderColor = hasError ? theme.palette.primary.main : "rgba(255,255,255,0.3)"
const startText = miditem ? "" : type === "source" ? "When" : "Then"
if (data.text.includes(startText)) {
data.text = data.text.replace(startText, "")
}
return (
{startText}
{selectionOpen === true ?
: null}
{
if (data.type === undefined || data.type === null || data.type === "") {
setexpanded(true)
console.log("No type. Skipping window open.")
return
}
changeAppType()
}}/>
{data.text}
{hasError ?
{
if (data.type === undefined || data.type === null || data.type === "") {
setexpanded(true)
console.log("No type. Skipping window open.")
return
}
changeAppType()
}}>
{data.error}
:
null}
{
}}
>
{type === "middle" ?
{
allusecases[index][type] = []
setAllUsecases(allusecases)
setUpdate(Math.random())
}}
style={{marginTop: 0, paddingTop: 8,}}
>
: null}
{
setexpanded(!expanded)
}}
>
{expanded ? : }
{expanded ?
looplist.map((subdata, curindex) => {
if (appFramework === undefined) {
subdata.image = theme.palette.defaultImage
} else {
const srctype = getType(subdata.type)
const srcinfo = appFramework[srctype]
if (srcinfo !== undefined && srcinfo.large_image !== undefined && srcinfo.large_image !== "" && (subdata.app_name === undefined || subdata.app_name === "")) {
subdata.image = srcinfo.large_image
subdata.app_id = srcinfo.id
subdata.app_name = srcinfo.name
} else {
subdata.image = theme.palette.defaultImage
}
}
return (
{
if (subdata.disabled === true) {
//toast("Usecase not available yet.")
return
}
if (type === "middle") {
allusecases[index][type][subindex] = subdata
} else {
allusecases[index][type] = subdata
}
setAllUsecases(allusecases)
setUpdate(Math.random())
setexpanded(false)
}}>

{
}}/>
{subdata.text}
)
})
:
null
}
)
}
//console.log("ALLUSECASES: ", allusecases)
// {defaultSearch}: {allusecases[usecaseIndex].name}
//console.log("UseCase: ", usecases)
return (
{configureWorkflowModal}
{authenticationModal}
{showTitle !== false && defaultSearch !== undefined ?
{allusecases[usecaseIndex].name}
: null}
{usecases.map((data, index) => {
return (
{data.middle !== undefined && data.middle !== null && data.middle.length > 0 ?
data.middle.map((innerdata, innerindex) => {
return (
)
})
: null}
{defaultSearch !== undefined && data.middle.length === 0 ?
{
console.log("Click add middle!")
allusecases[index].middle.push(midflows[0])
setAllUsecases(allusecases)
setUpdate(Math.random())
}}
>
: null}
{showTitle !== false && workflow.id === undefined ?
: null}
{workflow.id === undefined || defaultSearch === undefined ?
null
:
}
)
})}
)
}
export default UsecaseSearch