import React, { useState, useEffect } from "react"; import theme from '../theme.jsx'; import { useNavigate, Link } from "react-router-dom"; import { useAlert } from "react-alert"; 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 "@material-ui/core"; 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"; 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?") alert.info("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 ? ( { //if (configureWorkflowModalOpen) { // setSelectedAction({}); //} }} PaperProps={{ style: { pointerEvents: "auto", backgroundColor: theme.palette.surfaceColor, color: "white", minWidth: 1100, minHeight: 700, maxHeight: 700, padding: 15, overflow: "hidden", zIndex: 10012, border: theme.palette.defaultBorder, }, }} >
{selectedApp.reference_info === undefined || selectedApp.reference_info === null || selectedApp.reference_info.github_url === undefined || selectedApp.reference_info.github_url === null || selectedApp.reference_info.github_url.length === 0 ? ( {`Documentation ) : ( {`Documentation )}
{ setAuthenticationModalOpen(false); if (configureWorkflowModalOpen) { setSelectedAction({}); } }} >
{authenticationType.type === "oauth2" ? ( ) : ( )}
{selectedApp.documentation === undefined || selectedApp.documentation === null || selectedApp.documentation.length === 0 ? ( {selectedApp.description} There is currently no extended documentation available for this app. Want help help making or using this app?{" "} Join the community on Discord! Want to help change this app directly? {selectedApp.reference_info === undefined || selectedApp.reference_info === null || selectedApp.reference_info.github_url === undefined || selectedApp.reference_info.github_url === null || selectedApp.reference_info.github_url.length === 0 ? ( Check it out on Github! ) : ( Check it out on Github! )} ) : null }
) : 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) => { //alert.error(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) => { //alert.error(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) { alert.error("Error setting workflow: ", responseJson.reason) } else { alert.error("Error setting workflow.") } return } return responseJson; }) .catch((error) => { alert.error(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) { //alert.error(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) { alert.success("Successfully generated " + responseJson.name); } }); } }) .catch((error) => { alert.error("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()) //alert.error("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 ? ( { setConfigureWorkflowModalOpen(false); }} > {/* referenceUrl={referenceUrl} submitSchedule={submitSchedule} appAuthentication={appAuthentication} selectedAction={selectedAction} saveWorkflow={saveWorkflow} newWebhook={newWebhook} */} ) : 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) { //alert.error("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) => { if (response.status !== 200) { console.log("Failed to activate") } return response.json() }) .then((responseJson) => { if (responseJson.success === false) { alert.error("Failed to activate the app") } else { //alert.success("App activated for your organization! Refresh the page to use the app.") } }) .catch(error => { //alert.error(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) { alert.error("Failed updating default app: " + responseJson.reason) } else { alert.error("Failed to update framework for your org.") } } else { if (getFramework !== undefined) { getFramework() } } //setFrameworkLoaded(true) //setFrameworkData(responseJson) }) .catch((error) => { alert.error(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}
{data.app_name} { 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) { //alert.info("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.app_name} { }}/> {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