Cloud sync for all edits in May->June
This commit is contained in:
@@ -287,8 +287,8 @@ const Admin2 = (props) => {
|
||||
|
||||
|
||||
const handleStatusChange = (event) => {
|
||||
const { value } = event.target;
|
||||
setSelectedStatus(value);
|
||||
const { value } = event.target
|
||||
setSelectedStatus(value)
|
||||
|
||||
handleEditOrg(
|
||||
selectedOrganization?.name,
|
||||
|
||||
@@ -6,6 +6,7 @@ import { getTheme } from "../theme.jsx";
|
||||
import { useInterval } from "react-powerhooks";
|
||||
import { makeStyles, } from "@mui/styles";
|
||||
|
||||
import YAML from "yaml";
|
||||
import WorkflowTemplatePopup from "../components/WorkflowTemplatePopup.jsx"
|
||||
import { v4 as uuidv4, v5 as uuidv5, validate as isUUID, } from "uuid";
|
||||
import { useNavigate, Link, useParams } from "react-router-dom";
|
||||
@@ -132,6 +133,7 @@ import {
|
||||
ArrowForward as ArrowForwardIcon,
|
||||
OpenInFull as OpenInFullIcon,
|
||||
Difference as DifferenceIcon,
|
||||
DataObject as DataObjectIcon,
|
||||
} from "@mui/icons-material";
|
||||
import SwapHorizIcon from '@mui/icons-material/SwapHoriz';
|
||||
//import * as cytoscape from "cytoscape";
|
||||
@@ -778,9 +780,9 @@ const AngularWorkflow = (defaultprops) => {
|
||||
"name": "action",
|
||||
"value": "list_tickets",
|
||||
"options": [
|
||||
"create_ticket",
|
||||
"list_tickets",
|
||||
"get_ticket",
|
||||
"create_ticket",
|
||||
"close_ticket",
|
||||
"add_comment",
|
||||
"update_ticket",
|
||||
@@ -794,16 +796,6 @@ const AngularWorkflow = (defaultprops) => {
|
||||
"required": false,
|
||||
"multiline": true,
|
||||
},
|
||||
/*{
|
||||
"name": "options",
|
||||
"value": "deduplicate,enrich",
|
||||
"required": false,
|
||||
"multiselect": true,
|
||||
"options": [
|
||||
"deduplicate",
|
||||
"enrich",
|
||||
]
|
||||
}*/
|
||||
]
|
||||
}, {
|
||||
"name": "Communication",
|
||||
@@ -813,9 +805,9 @@ const AngularWorkflow = (defaultprops) => {
|
||||
"name": "action",
|
||||
"value": "list_messages",
|
||||
"options": [
|
||||
"send_message",
|
||||
"list_messages",
|
||||
"get_message",
|
||||
"send_message",
|
||||
"search_messages",
|
||||
"list_attachments",
|
||||
"get_attachment",
|
||||
@@ -838,15 +830,15 @@ const AngularWorkflow = (defaultprops) => {
|
||||
"parameters": [{
|
||||
"name": "action",
|
||||
"value": "get_asset",
|
||||
"options": [
|
||||
"reset_password",
|
||||
"enable_user",
|
||||
"disable_user",
|
||||
"get_identity",
|
||||
"get_asset",
|
||||
"search_identity"
|
||||
],
|
||||
"required": true,
|
||||
"options": [
|
||||
"reset_password",
|
||||
"enable_user",
|
||||
"disable_user",
|
||||
"get_identity",
|
||||
"get_asset",
|
||||
"search_identity"
|
||||
],
|
||||
"required": true,
|
||||
},
|
||||
{
|
||||
"name": "fields",
|
||||
@@ -861,9 +853,9 @@ const AngularWorkflow = (defaultprops) => {
|
||||
"label": "Assets",
|
||||
"parameters": [{
|
||||
"name": "action",
|
||||
"value": "search_vulnerabilities",
|
||||
"value": "list_assets",
|
||||
"options": [
|
||||
"list_assets",
|
||||
"list_assets",
|
||||
"get_asset",
|
||||
"search_assets",
|
||||
"search_users",
|
||||
@@ -915,8 +907,8 @@ const AngularWorkflow = (defaultprops) => {
|
||||
"value": "get_ioc",
|
||||
"options": [
|
||||
"get_ioc",
|
||||
"search_ioc",
|
||||
"create_ioc",
|
||||
"search_ioc",
|
||||
"update_ioc",
|
||||
"delete_ioc"
|
||||
],
|
||||
@@ -975,28 +967,9 @@ const AngularWorkflow = (defaultprops) => {
|
||||
"multiline": true,
|
||||
}]
|
||||
},
|
||||
|
||||
|
||||
]
|
||||
}]
|
||||
|
||||
/*
|
||||
{
|
||||
"name": "Email",
|
||||
"label": "Email",
|
||||
"parameters": [{
|
||||
"name": "action",
|
||||
"value": "list_email",
|
||||
"options": [
|
||||
"list_email",
|
||||
"send_mail",
|
||||
],
|
||||
"required": true,
|
||||
}],
|
||||
}]
|
||||
}]
|
||||
*/
|
||||
|
||||
// For code editor
|
||||
const [codeEditorModalOpen, setCodeEditorModalOpen] = React.useState(false);
|
||||
const [codedata, setcodedata] = React.useState("");
|
||||
@@ -1213,6 +1186,7 @@ const AngularWorkflow = (defaultprops) => {
|
||||
if (workflow?.suborg_distribution !== undefined && workflow?.suborg_distribution !== null && workflow?.suborg_distribution.length > 0) {
|
||||
getChildWorkflows(workflow.id)
|
||||
}
|
||||
|
||||
}, [workflow]);
|
||||
|
||||
// Event for making sure app is correct
|
||||
@@ -2506,9 +2480,11 @@ const AngularWorkflow = (defaultprops) => {
|
||||
console.log("Should redirect to register with redirect.")
|
||||
|
||||
setTimeout(() => {
|
||||
toast("You may not have access to this workflow.")
|
||||
//window.location.href = `/register?view=/workflows/${props.match.params.key}&message=You need sign up to use workflows with Shuffle`
|
||||
window.location.href = `/workflows`
|
||||
// toast("You may not have access to this workflow.")
|
||||
localStorage.setItem("redirectId", props.match.params.key)
|
||||
navigate("/register?view=workflows&message=You need sign up to use workflows with Shuffle");
|
||||
// window.location.href = `/register?view=/workflows/${props.match.params.key}&message=You need sign up to use workflows with Shuffle`
|
||||
// window.location.href = `/workflows`
|
||||
}, 2500)
|
||||
|
||||
return
|
||||
@@ -2878,9 +2854,9 @@ const AngularWorkflow = (defaultprops) => {
|
||||
setSavingState(0);
|
||||
console.log("Workflow failed loading: ", responseJson);
|
||||
if (responseJson.reason !== undefined && responseJson.reason !== null) {
|
||||
toast("Failed to save: " + responseJson.reason);
|
||||
toast.error("Failed to save: " + responseJson.reason);
|
||||
} else {
|
||||
toast(`Failed to save. Please contact your ${supportEmail} or your local admin if this is unexpected.`)
|
||||
toast.error(`Failed to save. Please contact your ${supportEmail} or your local admin if this is unexpected.`)
|
||||
}
|
||||
} else {
|
||||
setSavingState(1);
|
||||
@@ -4590,6 +4566,9 @@ const AngularWorkflow = (defaultprops) => {
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
if(!isLoggedIn){
|
||||
localStorage.setItem("redirectId", props.match.params.key);
|
||||
}
|
||||
window.location.pathname = "/workflows";
|
||||
}, 2500);
|
||||
|
||||
@@ -4880,6 +4859,17 @@ const AngularWorkflow = (defaultprops) => {
|
||||
setOriginalWorkflow(responseJson)
|
||||
}
|
||||
|
||||
const tmpUi = new URLSearchParams(cursearch).get("ui");
|
||||
if (
|
||||
tmpUi !== undefined &&
|
||||
tmpUi !== null &&
|
||||
tmpUi === "yaml"
|
||||
) {
|
||||
setTimeout(() => {
|
||||
setupWorkflowYaml(responseJson)
|
||||
}, 2500)
|
||||
}
|
||||
|
||||
setWorkflow(responseJson);
|
||||
setWorkflowDone(true);
|
||||
|
||||
@@ -4898,6 +4888,9 @@ const AngularWorkflow = (defaultprops) => {
|
||||
|
||||
setConfigureWorkflowModalOpen(true)
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
@@ -9959,6 +9952,191 @@ const AngularWorkflow = (defaultprops) => {
|
||||
});
|
||||
}
|
||||
|
||||
const setupWorkflowYaml = (inputworkflow) => {
|
||||
toast.warn("YAML exploring is an experimental feature - only visible to support users. The goal of this is to make it EASY to edit the workflow as YAML instead of just using the UI")
|
||||
if (userdata?.support !== true) {
|
||||
console.log("Not support: ", userdata)
|
||||
return
|
||||
}
|
||||
|
||||
// This should be getting the workflow based on actual nodes in the workflow
|
||||
// as the goal is to have it be live
|
||||
var copiedWorkflow = JSON.parse(JSON.stringify(inputworkflow))
|
||||
|
||||
const removeObjects = [
|
||||
"execution_org",
|
||||
"categories",
|
||||
"example_argument",
|
||||
"public",
|
||||
"contact_info",
|
||||
"published_id",
|
||||
"revision_id",
|
||||
"usecase_ids",
|
||||
"input_questions",
|
||||
"form_control",
|
||||
"blogpost",
|
||||
"video",
|
||||
"status",
|
||||
"generated",
|
||||
"hidden",
|
||||
"updated_by",
|
||||
"validated",
|
||||
"validation",
|
||||
"childorg_workflow_ids",
|
||||
"backup_config",
|
||||
"auth_groups",
|
||||
"isValid",
|
||||
"workflow_as_code",
|
||||
"image",
|
||||
"sharing",
|
||||
"owner",
|
||||
"configuration",
|
||||
"created",
|
||||
"edited",
|
||||
"last_runtime",
|
||||
"due_date",
|
||||
"is_valid",
|
||||
"execution_environment",
|
||||
"default_return_value",
|
||||
"visual_branches",
|
||||
"previously_saved",
|
||||
"workflow_type",
|
||||
"parentorg_workflow",
|
||||
"suborg_distribution",
|
||||
"id",
|
||||
"comments",
|
||||
"org_id",
|
||||
|
||||
// Failing test
|
||||
"spalabi",
|
||||
]
|
||||
|
||||
for (var i = 0; i < removeObjects.length; i++) {
|
||||
delete copiedWorkflow[removeObjects[i]]
|
||||
}
|
||||
|
||||
const removeActionValues = [
|
||||
"_id",
|
||||
"id",
|
||||
|
||||
"large_image",
|
||||
"description",
|
||||
"is_valid",
|
||||
"isStartNode",
|
||||
"sharing",
|
||||
"public",
|
||||
"generated",
|
||||
"execution_variable",
|
||||
"position",
|
||||
"category",
|
||||
"reference_url",
|
||||
"sub_action",
|
||||
"run_magic_output",
|
||||
"run_magic_input",
|
||||
"category_label",
|
||||
"suggestions",
|
||||
"parent_controlled",
|
||||
"source_workflow",
|
||||
"source_executions",
|
||||
"app_association",
|
||||
"suggestion",
|
||||
"small_image",
|
||||
"long_description",
|
||||
"tags",
|
||||
"errors",
|
||||
"source_executions",
|
||||
"source_execution",
|
||||
"required",
|
||||
"example",
|
||||
"type",
|
||||
|
||||
"test2",
|
||||
]
|
||||
|
||||
const removeActionParamValues = [
|
||||
"id",
|
||||
"multiline",
|
||||
"multiselect",
|
||||
"options",
|
||||
"action_field",
|
||||
"variant",
|
||||
"configuration",
|
||||
"tags",
|
||||
"schema",
|
||||
"skip_multicheck",
|
||||
"value_replace",
|
||||
"unique_toggled",
|
||||
"hidden",
|
||||
"error",
|
||||
"example",
|
||||
|
||||
"test3",
|
||||
]
|
||||
|
||||
if (copiedWorkflow?.actions !== undefined && copiedWorkflow?.actions !== null && copiedWorkflow?.actions.length > 0) {
|
||||
for (var key in copiedWorkflow.actions) {
|
||||
for (var i = 0; i < removeActionValues.length; i++) {
|
||||
delete copiedWorkflow.actions[key][removeActionValues[i]]
|
||||
}
|
||||
|
||||
|
||||
if (copiedWorkflow.actions[key].parameters === undefined || copiedWorkflow.actions[key].parameters === null) {
|
||||
continue
|
||||
}
|
||||
|
||||
for (var j = 0; j < copiedWorkflow.actions[key].parameters.length; j++) {
|
||||
for (var k = 0; k < removeActionParamValues.length; k++) {
|
||||
delete copiedWorkflow.actions[key].parameters[j][removeActionParamValues[k]]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (copiedWorkflow?.triggers !== undefined && copiedWorkflow?.triggers !== null && copiedWorkflow?.triggers.length > 0) {
|
||||
for (var key in copiedWorkflow.triggers) {
|
||||
for (var i = 0; i < removeActionValues.length; i++) {
|
||||
delete copiedWorkflow.triggers[key][removeActionValues[i]]
|
||||
}
|
||||
|
||||
delete copiedWorkflow.triggers[key]["app_name"]
|
||||
delete copiedWorkflow.triggers[key]["app_version"]
|
||||
delete copiedWorkflow.triggers[key]["name"]
|
||||
delete copiedWorkflow.triggers[key]["priority"]
|
||||
delete copiedWorkflow.triggers[key]["replacement_for_trigger"]
|
||||
|
||||
if (copiedWorkflow.triggers[key].parameters === undefined || copiedWorkflow.triggers[key].parameters === null) {
|
||||
continue
|
||||
}
|
||||
|
||||
for (var j = 0; j < copiedWorkflow.triggers[key].parameters.length; j++) {
|
||||
for (var k = 0; k < removeActionParamValues.length; k++) {
|
||||
delete copiedWorkflow.triggers[key].parameters[j][removeActionParamValues[k]]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (copiedWorkflow?.workflow_variables === undefined || copiedWorkflow?.workflow_variables === null || copiedWorkflow?.workflow_variables.length === 0) {
|
||||
delete copiedWorkflow.workflow_variables
|
||||
}
|
||||
|
||||
if (copiedWorkflow?.branches === undefined || copiedWorkflow?.branches === null || copiedWorkflow?.branches.length === 0) {
|
||||
delete copiedWorkflow.branches
|
||||
}
|
||||
|
||||
|
||||
// YAML
|
||||
const sampledata = YAML.stringify(copiedWorkflow)
|
||||
|
||||
navigate("?ui=yaml", { replace: true })
|
||||
|
||||
setCodeEditorModalOpen(true)
|
||||
setEditorData({
|
||||
"name": "workflow yaml",
|
||||
"value": sampledata,
|
||||
})
|
||||
}
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
//useEffect(() => {
|
||||
if (firstrequest) {
|
||||
@@ -10000,6 +10178,7 @@ const AngularWorkflow = (defaultprops) => {
|
||||
//navigate(`?execution_highlight=${parsed_url}`)
|
||||
//props.history.push(curpath + newitem);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -12136,10 +12315,8 @@ const AngularWorkflow = (defaultprops) => {
|
||||
}
|
||||
|
||||
if ((app.id === "integration" || app.id === "shuffle_agent") && userdata.support !== true) {
|
||||
console.log("APPID: ", app.id, isCloud)
|
||||
if (isCloud === false && app.id === "integration") {
|
||||
} else {
|
||||
console.log("RETURNING", app.id)
|
||||
return null
|
||||
}
|
||||
}
|
||||
@@ -12572,7 +12749,7 @@ const AngularWorkflow = (defaultprops) => {
|
||||
// maxiter = max amount of parent nodes to loop
|
||||
// also handles breaks if there are issues
|
||||
var iterations = 0;
|
||||
var maxiter = 10;
|
||||
var maxiter = 100;
|
||||
while (true) {
|
||||
for (let parentkey in allkeys) {
|
||||
var currentnode = cy.getElementById(allkeys[parentkey]);
|
||||
@@ -18553,6 +18730,68 @@ const AngularWorkflow = (defaultprops) => {
|
||||
zoom: isSafari ? undefined : 0.9,
|
||||
}
|
||||
|
||||
|
||||
const changeOrg = () => {
|
||||
localStorage.setItem("globalUrl", "");
|
||||
localStorage.setItem("getting_started_sidebar", "open");
|
||||
fetch(`${globalUrl}/api/v1/orgs/${workflow.org_id}/change`, {
|
||||
mode: "cors",
|
||||
credentials: "include",
|
||||
crossDomain: true,
|
||||
method: "POST",
|
||||
body: JSON.stringify({ "org_id": workflow.org_id }),
|
||||
withCredentials: true,
|
||||
headers: {
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
},
|
||||
})
|
||||
.then(function (response) {
|
||||
if (response.status !== 200) {
|
||||
console.log("Error in response");
|
||||
} else {
|
||||
localStorage.removeItem("apps")
|
||||
localStorage.removeItem("workflows")
|
||||
localStorage.removeItem("userinfo")
|
||||
}
|
||||
|
||||
return response.json();
|
||||
})
|
||||
.then(function (responseJson) {
|
||||
console.log("In here?")
|
||||
if (responseJson.success === true) {
|
||||
if (responseJson.region_url !== undefined && responseJson.region_url !== null && responseJson.region_url.length > 0) {
|
||||
console.log("Region Change: ", responseJson.region_url);
|
||||
localStorage.setItem("globalUrl", responseJson.region_url);
|
||||
//globalUrl = responseJson.region_url
|
||||
}
|
||||
|
||||
if (responseJson["reason"] === "SSO_REDIRECT") {
|
||||
setTimeout(() => {
|
||||
toast.info("Redirecting to SSO login page as SSO is required for this organization.")
|
||||
window.location.href = responseJson["url"]
|
||||
return
|
||||
}, 2000)
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
window.location.reload();
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
toast.info("Successfully changed active organisation - refreshing!");
|
||||
} else {
|
||||
if (responseJson.reason !== undefined && responseJson.reason !== null && responseJson.reason.length > 0) {
|
||||
toast(responseJson.reason);
|
||||
} else {
|
||||
toast(`Failed changing org. Try again or contact ${supportEmail} if this persists.`);
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log("error changing: ", error);
|
||||
//removeCookie("session_token", {path: "/"})
|
||||
})
|
||||
}
|
||||
|
||||
const TopCytoscapeBar = (props) => {
|
||||
const [hovered, setHovered] = useState(false)
|
||||
|
||||
@@ -18620,72 +18859,15 @@ const AngularWorkflow = (defaultprops) => {
|
||||
</Tooltip>
|
||||
)}
|
||||
|
||||
{!distributedFromParent ?
|
||||
isCorrectOrg ? null :
|
||||
{!distributedFromParent || userdata?.support === true ?
|
||||
isCorrectOrg ? null :
|
||||
<Typography variant="body2" style={{ marginLeft: 10, }}>
|
||||
<b>Warning</b>: <span
|
||||
style={{ color: "#FF8544", cursor: "pointer", pointerEvents: "auto", }}
|
||||
onClick={() => {
|
||||
toast("Changing to correct organisation. Please wait a few seconds.")
|
||||
|
||||
localStorage.setItem("globalUrl", "");
|
||||
localStorage.setItem("getting_started_sidebar", "open");
|
||||
fetch(`${globalUrl}/api/v1/orgs/${workflow.org_id}/change`, {
|
||||
mode: "cors",
|
||||
credentials: "include",
|
||||
crossDomain: true,
|
||||
method: "POST",
|
||||
body: JSON.stringify({ "org_id": workflow.org_id }),
|
||||
withCredentials: true,
|
||||
headers: {
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
},
|
||||
})
|
||||
.then(function (response) {
|
||||
if (response.status !== 200) {
|
||||
console.log("Error in response");
|
||||
} else {
|
||||
localStorage.removeItem("apps")
|
||||
localStorage.removeItem("workflows")
|
||||
localStorage.removeItem("userinfo")
|
||||
}
|
||||
|
||||
return response.json();
|
||||
})
|
||||
.then(function (responseJson) {
|
||||
console.log("In here?")
|
||||
if (responseJson.success === true) {
|
||||
if (responseJson.region_url !== undefined && responseJson.region_url !== null && responseJson.region_url.length > 0) {
|
||||
console.log("Region Change: ", responseJson.region_url);
|
||||
localStorage.setItem("globalUrl", responseJson.region_url);
|
||||
//globalUrl = responseJson.region_url
|
||||
}
|
||||
|
||||
if (responseJson["reason"] === "SSO_REDIRECT") {
|
||||
setTimeout(() => {
|
||||
toast.info("Redirecting to SSO login page as SSO is required for this organization.")
|
||||
window.location.href = responseJson["url"]
|
||||
return
|
||||
}, 2000)
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
window.location.reload();
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
toast("Successfully changed active organisation - refreshing!");
|
||||
} else {
|
||||
if (responseJson.reason !== undefined && responseJson.reason !== null && responseJson.reason.length > 0) {
|
||||
toast(responseJson.reason);
|
||||
} else {
|
||||
toast(`Failed changing org. Try again or contact ${supportEmail} if this persists.`);
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log("error changing: ", error);
|
||||
//removeCookie("session_token", {path: "/"})
|
||||
})
|
||||
changeOrg()
|
||||
|
||||
|
||||
|
||||
@@ -18707,6 +18889,11 @@ const AngularWorkflow = (defaultprops) => {
|
||||
<div>
|
||||
{originalWorkflow?.parentorg_workflow !== undefined && originalWorkflow?.parentorg_workflow !== null && originalWorkflow?.parentorg_workflow.length > 0 || workflow?.parentorg_workflow !== undefined && workflow?.parentorg_workflow !== null && workflow?.parentorg_workflow.length > 0 ?
|
||||
|
||||
null
|
||||
|
||||
/*
|
||||
* Disabled because redirects occurred anyway
|
||||
|
||||
<Button
|
||||
color="secondary"
|
||||
variant="outlined"
|
||||
@@ -18717,17 +18904,20 @@ const AngularWorkflow = (defaultprops) => {
|
||||
marginLeft: 10,
|
||||
}}
|
||||
onClick={() => {
|
||||
navigate(`/workflows/${workflow.parentorg_workflow}`)
|
||||
//changeOrg()
|
||||
|
||||
// Reload the page
|
||||
navigate(`/workflows/${workflow.parentorg_workflow}`)
|
||||
window.location.reload()
|
||||
}}
|
||||
>
|
||||
Go to parent org workflow
|
||||
</Button>
|
||||
*/
|
||||
|
||||
: null}
|
||||
|
||||
{userdata !== undefined && userdata !== null && userdata.orgs !== undefined && userdata.orgs !== null && userdata.orgs.length > 1 && workflow?.id !== undefined && workflow?.id && workflow?.id?.length > 0 ?
|
||||
{userdata !== undefined && userdata !== null && userdata.orgs !== undefined && userdata.orgs !== null && userdata.orgs.length > 1 && workflow?.id !== undefined && workflow?.id && workflow?.id?.length > 0 && userdata?.active_org?.creator_org?.length === 0 && userdata?.active_org?.id == workflow?.org_id ?
|
||||
<Button
|
||||
color="secondary"
|
||||
variant="outlined"
|
||||
@@ -19575,7 +19765,7 @@ const AngularWorkflow = (defaultprops) => {
|
||||
>
|
||||
|
||||
<Tooltip
|
||||
title="Hide error messages. They will show up the next refresh."
|
||||
title="Hides error messages this session."
|
||||
placement="top"
|
||||
>
|
||||
<IconButton
|
||||
@@ -19924,7 +20114,7 @@ const AngularWorkflow = (defaultprops) => {
|
||||
.catch((error) => {
|
||||
console.log("Dupe workflow for suborg error: ", error.toString())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const BottomCytoscapeBar = () => {
|
||||
if (workflow.id === undefined || workflow.id === null || (!workflow.public && apps.length === 0)) {
|
||||
@@ -20277,6 +20467,29 @@ const AngularWorkflow = (defaultprops) => {
|
||||
</Button>
|
||||
</span>
|
||||
</Tooltip>
|
||||
|
||||
|
||||
{userdata?.support === true ?
|
||||
<Tooltip
|
||||
color="secondary"
|
||||
title="Show simplified YAML (support only)"
|
||||
placement="top"
|
||||
>
|
||||
<span>
|
||||
<Button
|
||||
disabled={workflow.public}
|
||||
color="secondary"
|
||||
variant="text"
|
||||
style={{ width: 65, height: buttonHeights, }}
|
||||
onClick={() => {
|
||||
setupWorkflowYaml(workflow)
|
||||
}}
|
||||
>
|
||||
<DataObjectIcon />
|
||||
</Button>
|
||||
</span>
|
||||
</Tooltip>
|
||||
: null}
|
||||
</ButtonGroup>
|
||||
|
||||
|
||||
@@ -20408,10 +20621,11 @@ const AngularWorkflow = (defaultprops) => {
|
||||
position,
|
||||
backgroundcolor: "#1f2023",
|
||||
color: "#ffffff",
|
||||
textHalign: "center",
|
||||
textValign: "center",
|
||||
textMarginX: "0px",
|
||||
textMarginY: "0px",
|
||||
|
||||
textHalign: "right",
|
||||
textValign: "bottom",
|
||||
textMarginX: "-250px",
|
||||
textMarginY: "-150px",
|
||||
},
|
||||
position,
|
||||
});
|
||||
@@ -25509,6 +25723,7 @@ const AngularWorkflow = (defaultprops) => {
|
||||
|
||||
|
||||
setAiQueryModalOpen={setAiQueryModalOpen}
|
||||
isWorkflowEditor={editorData?.name === "workflow yaml"}
|
||||
/>
|
||||
: null}
|
||||
|
||||
|
||||
@@ -745,7 +745,7 @@ const AppCreator = (defaultprops) => {
|
||||
}
|
||||
|
||||
setBasedata(data);
|
||||
console.log("Info: ", data)
|
||||
console.log("Loaded Info: ", data)
|
||||
|
||||
try {
|
||||
if (data.info !== null && data.info !== undefined) {
|
||||
@@ -759,7 +759,12 @@ const AppCreator = (defaultprops) => {
|
||||
if (data.info.title.length > 29) {
|
||||
setName(data.info.title.slice(0, 29));
|
||||
} else {
|
||||
setName(data.info.title);
|
||||
// Check if fork=true in URL
|
||||
if (window.location.search.includes("fork=true")) {
|
||||
setName(data.info.title + " Fork");
|
||||
} else {
|
||||
setName(data.info.title)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4066,7 +4066,7 @@ const buttonBackground = "linear-gradient(to right, #f86a3e, #f34079)";
|
||||
</Button>
|
||||
}
|
||||
|
||||
{isMobile ? null : (
|
||||
{isMobile || app?.reference_org === userdata?.active_org?.id ? null : (
|
||||
<Button
|
||||
variant={userdata.active_apps !== undefined && userdata.active_apps !== null && userdata.active_apps.includes(appId) ? "outlined": "contained"}
|
||||
component="label"
|
||||
@@ -4142,7 +4142,7 @@ const buttonBackground = "linear-gradient(to right, #f86a3e, #f34079)";
|
||||
component="label"
|
||||
color="secondary"
|
||||
onClick={() => {
|
||||
navigate(`/apps/new?id=${appId}`)
|
||||
navigate(`/apps/new?id=${appId}&fork=true`)
|
||||
}}
|
||||
style={{ height: 40, marginTop: 5, marginLeft: 5, }}
|
||||
>
|
||||
|
||||
@@ -154,7 +154,7 @@ const AppCard = ({ data, index, mouseHoverIndex, setMouseHoverIndex, globalUrl,
|
||||
whiteSpace: "nowrap",
|
||||
color: theme.palette.text.primary,
|
||||
}}>
|
||||
{data.name.replace(/_/g, ' ').replace(/\b\w/g, char => char.toUpperCase())}
|
||||
{data?.name?.replace(/_/g, ' ')?.replace(/\b\w/g, char => char?.toUpperCase())}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -165,7 +165,7 @@ const AppCard = ({ data, index, mouseHoverIndex, setMouseHoverIndex, globalUrl,
|
||||
marginLeft: 8,
|
||||
color: theme.palette.text.secondary,
|
||||
}}>
|
||||
{data.categories ? data.categories.join(", ") : "NA"}
|
||||
{data?.categories ? data?.categories?.join(", ") : "NA"}
|
||||
</div>
|
||||
|
||||
<div style={{
|
||||
@@ -186,7 +186,7 @@ const AppCard = ({ data, index, mouseHoverIndex, setMouseHoverIndex, globalUrl,
|
||||
whiteSpace: "nowrap",
|
||||
color: "rgba(158, 158, 158, 1)",
|
||||
}}>
|
||||
{data.generated !== true && data.tags && data.tags.slice(0, 2).map((tag, tagIndex) => (
|
||||
{data?.generated !== true && data?.tags && data?.tags?.slice(0, 2).map((tag, tagIndex) => (
|
||||
<span key={tagIndex}>
|
||||
{tag}
|
||||
{tagIndex < data.tags.length - 1 ? ", " : ""}
|
||||
|
||||
@@ -447,20 +447,27 @@ const LoginPage = props => {
|
||||
}
|
||||
|
||||
if (isLoggedIn === true && serverside !== true) {
|
||||
const tmpView = new URLSearchParams(window.location.search).get("view");
|
||||
if (tmpView !== undefined && tmpView !== null) {
|
||||
let pathOnly = tmpView.split("?")[0];
|
||||
if (!pathOnly.startsWith("/")) pathOnly = "/" + pathOnly;
|
||||
setTimeout(() => {
|
||||
const tmpView = new URLSearchParams(window.location.search).get("view");
|
||||
if (tmpView !== undefined && tmpView !== null) {
|
||||
let pathOnly = tmpView.split("?")[0];
|
||||
if (!pathOnly.startsWith("/")) pathOnly = "/" + pathOnly;
|
||||
|
||||
if (pathOnly === "/pricing" || pathOnly === "admin") {
|
||||
window.location.replace(pathOnly + window.location.search);
|
||||
} else {
|
||||
window.location.replace(pathOnly);
|
||||
if (pathOnly === "/pricing" || pathOnly === "admin") {
|
||||
window.location.replace(pathOnly + window.location.search);
|
||||
} else {
|
||||
if(localStorage.getItem("redirectId") !== null && localStorage.getItem("redirectId") !== undefined) {
|
||||
const redirectId = localStorage.getItem("redirectId")
|
||||
localStorage.removeItem("redirectId")
|
||||
pathOnly = pathOnly + "/" + redirectId
|
||||
}
|
||||
window.location.replace(pathOnly);
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
window.location.pathname = "/workflows"
|
||||
window.location.pathname = "/workflows"
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
const checkAdmin = () => {
|
||||
@@ -537,51 +544,52 @@ const LoginPage = props => {
|
||||
'Content-Type': 'application/json; charset=utf-8',
|
||||
},
|
||||
})
|
||||
.then((response) => {
|
||||
if (response.status !== 200) {
|
||||
console.log("Status not 200 for login:O!");
|
||||
.then((response) => {
|
||||
if (response.status !== 200) {
|
||||
console.log("Status not 200 for login:O!");
|
||||
}
|
||||
|
||||
return response.json();
|
||||
})
|
||||
.then((responseJson) => {
|
||||
|
||||
setLoginLoading(false)
|
||||
|
||||
if (responseJson["success"] === false) {
|
||||
setLoginInfo(responseJson["reason"])
|
||||
} else {
|
||||
if (responseJson?.region_url !== undefined && responseJson?.region_url !== null && responseJson?.region_url !== "") {
|
||||
toast.info("Set region to " + responseJson.region_url)
|
||||
localStorage.setItem("globalUrl", responseJson.region_url)
|
||||
}
|
||||
|
||||
return response.json();
|
||||
})
|
||||
.then((responseJson) => {
|
||||
if (responseJson["reason"] === "MFA_REDIRECT") {
|
||||
setLoginInfo("Enter the 6-digit MFA code.")
|
||||
setMFAField(true)
|
||||
return
|
||||
|
||||
setLoginLoading(false)
|
||||
|
||||
console.log("Resp from backend: ", responseJson)
|
||||
|
||||
if (responseJson["success"] === false) {
|
||||
}
|
||||
else if (responseJson["reason"] === "MFA_SETUP") {
|
||||
window.location.href = `/login/${responseJson.url}/mfa-setup`;
|
||||
return;
|
||||
}
|
||||
else if (responseJson["reason"] === "SSO_REDIRECT") {
|
||||
//navigate(responseJson["url"])
|
||||
window.location.href = responseJson["url"]
|
||||
return
|
||||
}
|
||||
else if (responseJson["reason"] !== undefined && responseJson["reason"] !== null && responseJson["reason"].includes("error")) {
|
||||
setLoginInfo(responseJson["reason"])
|
||||
return
|
||||
}
|
||||
else {
|
||||
|
||||
if (responseJson["reason"] === "MFA_REDIRECT") {
|
||||
setLoginInfo("Enter the 6-digit MFA code.")
|
||||
setMFAField(true)
|
||||
return
|
||||
|
||||
}
|
||||
else if (responseJson["reason"] === "MFA_SETUP") {
|
||||
window.location.href = `/login/${responseJson.url}/mfa-setup`;
|
||||
return;
|
||||
}
|
||||
else if (responseJson["reason"] === "SSO_REDIRECT") {
|
||||
//navigate(responseJson["url"])
|
||||
window.location.href = responseJson["url"]
|
||||
return
|
||||
|
||||
}
|
||||
else if (responseJson["reason"] !== undefined && responseJson["reason"] !== null && responseJson["reason"].includes("error")) {
|
||||
setLoginInfo(responseJson["reason"])
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
setLoginInfo("Successful login! Redirecting you in 3 seconds...")
|
||||
for (var key in responseJson["cookies"]) {
|
||||
setCookie(responseJson["cookies"][key].key, responseJson["cookies"][key].value, { path: "/" })
|
||||
}
|
||||
setLoginInfo("Successful login! Redirecting you in 3 seconds...")
|
||||
for (var key in responseJson["cookies"]) {
|
||||
setCookie(responseJson["cookies"][key].key, responseJson["cookies"][key].value, { path: "/" })
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
const tmpView = new URLSearchParams(window.location.search).get("view");
|
||||
if (tmpView !== undefined && tmpView !== null) {
|
||||
let pathOnly = tmpView.split("?")[0];
|
||||
@@ -590,18 +598,21 @@ const LoginPage = props => {
|
||||
if (pathOnly === "/pricing" || pathOnly === "admin") {
|
||||
window.location.replace(pathOnly + window.location.search);
|
||||
} else {
|
||||
if(localStorage.getItem("redirectId") !== null && localStorage.getItem("redirectId") !== undefined) {
|
||||
const redirectId = localStorage.getItem("redirectId")
|
||||
localStorage.removeItem("redirectId")
|
||||
pathOnly = pathOnly + "/" + redirectId
|
||||
}
|
||||
window.location.replace(pathOnly);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("LOGIN DATA: ", responseJson)
|
||||
if (responseJson.tutorials !== undefined && responseJson.tutorials !== null) {
|
||||
// Find welcome in responseJson.tutorials under key name
|
||||
const welcome = responseJson.tutorials.find(function (element) {
|
||||
return element.name === "welcome";
|
||||
})
|
||||
|
||||
console.log("Welcome: ", welcome)
|
||||
if (welcome === undefined || welcome === null) {
|
||||
console.log("RUN login Welcome!!")
|
||||
@@ -613,12 +624,13 @@ const LoginPage = props => {
|
||||
}
|
||||
|
||||
window.location.pathname = "/workflows"
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
setLoginInfo("Error from login API: " + error)
|
||||
setLoginLoading(false)
|
||||
});
|
||||
}, 2000);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
setLoginInfo("Error from login API: " + error)
|
||||
setLoginLoading(false)
|
||||
});
|
||||
} else {
|
||||
url = baseurl + '/api/v1/register';
|
||||
fetch(url, {
|
||||
@@ -641,11 +653,15 @@ const LoginPage = props => {
|
||||
//setLoginInfo("Successful register!")
|
||||
//var newpath = "/login?message=Successfully signed up. You can now sign in."
|
||||
//const tmpMessage = new URLSearchParams(window.location.search).get("message")
|
||||
setLoginInfo("Successful registration! Redirecting in 3 seconds...")
|
||||
|
||||
for (var key in responseJson["cookies"]) {
|
||||
setCookie(responseJson["cookies"][key].key, responseJson["cookies"][key].value, { path: "/" })
|
||||
}
|
||||
|
||||
setLoginLoading(false)
|
||||
setLoginInfo("Successful registration! Redirecting in 3 seconds...")
|
||||
|
||||
|
||||
setTimeout(() => {
|
||||
console.log("LOGIN DATA: ", responseJson)
|
||||
|
||||
@@ -657,6 +673,11 @@ const LoginPage = props => {
|
||||
if (pathOnly === "/pricing" || pathOnly === "admin") {
|
||||
window.location.replace(pathOnly + window.location.search);
|
||||
} else {
|
||||
if(localStorage.getItem("redirectId") !== null && localStorage.getItem("redirectId") !== undefined) {
|
||||
const redirectId = localStorage.getItem("redirectId")
|
||||
localStorage.removeItem("redirectId")
|
||||
pathOnly = pathOnly + "/" + redirectId
|
||||
}
|
||||
window.location.replace(pathOnly);
|
||||
}
|
||||
return
|
||||
@@ -666,9 +687,8 @@ const LoginPage = props => {
|
||||
console.log("RUN Welcome!!")
|
||||
//window.location.pathname = "/welcome?tab=2"
|
||||
window.location.href = "/welcome"
|
||||
}, 1500);
|
||||
}, 2000);
|
||||
}
|
||||
setLoginLoading(false)
|
||||
}),
|
||||
)
|
||||
.catch(error => {
|
||||
|
||||
@@ -3,6 +3,7 @@ import React, { useEffect, useContext, memo, useState, useRef } from "react";
|
||||
import { useLocation, useNavigate, Link } from "react-router-dom";
|
||||
import ReactDOM from "react-dom"
|
||||
import { getTheme } from "../theme.jsx";
|
||||
|
||||
// Material UI Icons
|
||||
import Add from '@mui/icons-material/Add';
|
||||
import Search from '@mui/icons-material/Search';
|
||||
@@ -12,6 +13,7 @@ import GridOnIcon from '@mui/icons-material/GridOn';
|
||||
import ListIcon from '@mui/icons-material/List';
|
||||
import PublishIcon from '@mui/icons-material/Publish';
|
||||
import GetAppIcon from '@mui/icons-material/GetApp';
|
||||
|
||||
// Material UI & Components
|
||||
import { makeStyles } from "@mui/styles";
|
||||
import { Navigate } from "react-router-dom";
|
||||
@@ -92,6 +94,11 @@ import {
|
||||
Visibility as VisibilityIcon,
|
||||
EditNote as EditNoteIcon,
|
||||
ErrorOutline as ErrorOutlineIcon,
|
||||
Coronavirus as CoronavirusIcon,
|
||||
Fingerprint as FingerprintIcon,
|
||||
Psychology as PsychologyIcon,
|
||||
Wifi as WifiIcon,
|
||||
Devices as DevicesIcon,
|
||||
} from "@mui/icons-material";
|
||||
|
||||
// Additional Components
|
||||
@@ -128,19 +135,20 @@ const imagesize = 22;
|
||||
export const GetIconInfo = (action) => {
|
||||
// Finds the icon based on the action. Should be verbs.
|
||||
const iconList = [
|
||||
{ key: "cases", values: ["cases"] },
|
||||
{ key: "cases", values: ["cases", "ticket", "alert"] },
|
||||
{ key: "cache_add", values: ["set_cache"] },
|
||||
{ key: "cache_get", values: ["get_cache"] },
|
||||
{ key: "filter", values: ["filter"] },
|
||||
{ key: "merge", values: ["join", "merge", "route", "router"] },
|
||||
{
|
||||
key: "search",
|
||||
values: ["search", "find", "locate", "index", "analyze", "anal", "match", "check cache", "check", "verify", "validate"],
|
||||
values: ["search", "find", "locate", "index", "analyze", "anal", "match", "check cache", "check", "verify", "validate", "siem", ],
|
||||
},
|
||||
{ key: "list", values: ["list", "head", "options"] },
|
||||
{
|
||||
key: "download",
|
||||
values: [
|
||||
"ingest",
|
||||
"capture",
|
||||
"get",
|
||||
"download",
|
||||
@@ -154,20 +162,6 @@ export const GetIconInfo = (action) => {
|
||||
},
|
||||
{ key: "add", values: ["add", "accept",] },
|
||||
{ key: "delete", values: ["delete", "remove", "clear", "clean", "dismiss",] },
|
||||
{
|
||||
key: "send",
|
||||
values: [
|
||||
"send",
|
||||
"dispatch",
|
||||
"mail",
|
||||
"forward",
|
||||
"post",
|
||||
"submit",
|
||||
"mark",
|
||||
"set",
|
||||
"release",
|
||||
],
|
||||
},
|
||||
{
|
||||
key: "repeat",
|
||||
values: ["repeat", "retry", "pause", "skip", "copy", "replicat", "demo",],
|
||||
@@ -197,8 +191,29 @@ export const GetIconInfo = (action) => {
|
||||
key: "compare",
|
||||
values: ["compare", "convert", "to", "filter", "translate", "parse"],
|
||||
},
|
||||
{ key: "assets", values: ["cmdb", "assets", "asset", "cmdb", "inventory", "host", "hosts", "device", "devices"] },
|
||||
{ key: "close", values: ["close", "stop", "cancel", "block"] },
|
||||
{ key: "communication", values: ["communication", "comms", "email", "mail",] },
|
||||
{ key: "eradication", values: ["eradication", "edr", "xdr"] },
|
||||
{ key: "iam", values: ["iam", "identity", "access", "auth", "authentication", "authorization", "oauth", "sso", "openid"] },
|
||||
{ key: "intel", values: ["intel", "feed", "threat intel", "threat intelligence", "ti", "t.i.", "t.i", "ti.", "rule", "technique", "tactic", "techniques", "tactics", "ioc", "indicator",] },
|
||||
{ key: "network", values: ["network", "net", "networking", "firewall", "proxy", "vpn", "sdwan", "sd-wan"] },
|
||||
{
|
||||
key: "send",
|
||||
values: [
|
||||
"send",
|
||||
"dispatch",
|
||||
"mail",
|
||||
"forward",
|
||||
"post",
|
||||
"submit",
|
||||
"mark",
|
||||
"set",
|
||||
"release",
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
];
|
||||
|
||||
var selectedKey = ""
|
||||
@@ -357,7 +372,45 @@ export const GetIconInfo = (action) => {
|
||||
iconBackgroundColor: "green",
|
||||
originalIcon: <SearchIcon />,
|
||||
},
|
||||
};
|
||||
eradication: {
|
||||
icon: "",
|
||||
iconColor: "white",
|
||||
iconBackgroundColor: "green",
|
||||
originalIcon: <CoronavirusIcon />,
|
||||
},
|
||||
iam: {
|
||||
icon: "",
|
||||
iconColor: "white",
|
||||
iconBackgroundColor: "green",
|
||||
originalIcon: <FingerprintIcon />,
|
||||
},
|
||||
intel: {
|
||||
icon: "",
|
||||
iconColor: "white",
|
||||
iconBackgroundColor: "green",
|
||||
originalIcon: <PsychologyIcon />,
|
||||
},
|
||||
network: {
|
||||
icon: "",
|
||||
iconColor: "white",
|
||||
iconBackgroundColor: "green",
|
||||
originalIcon: <WifiIcon />,
|
||||
},
|
||||
assets: {
|
||||
icon: "",
|
||||
iconColor: "white",
|
||||
iconBackgroundColor: "green",
|
||||
originalIcon: <DevicesIcon />,
|
||||
},
|
||||
}
|
||||
|
||||
/*
|
||||
{ key: "eradication", values: ["eradication", "edr", "xdr"] },
|
||||
{ key: "iam", values: ["iam", "identity", "access", "auth", "authentication", "authorization", "oauth", "sso", "openid"] },
|
||||
{ key: "intel", values: ["intel", "threat intel", "threat intelligence", "ti", "t.i.", "t.i", "ti."] },
|
||||
{ key: "network", values: ["network", "net", "networking", "firewall", "proxy", "vpn", "sdwan", "sd-wan"] },
|
||||
{ key: "siem", values: ["siem", "security information and event management", "security information and event management", "security information and event management"] },
|
||||
*/
|
||||
|
||||
var selectedItem = parsedIcons[selectedKey];
|
||||
if (selectedItem === undefined || selectedItem === null) {
|
||||
@@ -374,11 +427,8 @@ export const GetIconInfo = (action) => {
|
||||
selectedItem.iconBackgroundColor = defaultColor;
|
||||
}
|
||||
|
||||
if (selectedItem.icon === "" || selectedItem.icon === undefined) {
|
||||
console.log(
|
||||
`MISSING PATH FOR ${selectedKey} (find in scope): `,
|
||||
selectedItem.originalIcon.type.type
|
||||
);
|
||||
if ((selectedItem.icon === "" || selectedItem.icon === undefined) && (selectedItem.originalIcon === undefined || selectedItem.originalIcon === "")) {
|
||||
console.log(`MISSING PATH FOR ${selectedKey} (find in scope): `, selectedItem.originalIcon.type.type)
|
||||
}
|
||||
|
||||
if (
|
||||
@@ -753,6 +803,12 @@ const Workflows2 = (props) => {
|
||||
|
||||
const handleTabChange = (event, newValue) => {
|
||||
setCurrTab(newValue);
|
||||
|
||||
//if (view === "list" && currTab > 0) {
|
||||
// setView("grid")
|
||||
// setUpdate(Math.random())
|
||||
//}
|
||||
|
||||
// Update URL query params based on tab index
|
||||
const tabMapping = {
|
||||
0: 'org_workflows',
|
||||
@@ -767,9 +823,6 @@ const Workflows2 = (props) => {
|
||||
navigate(`${location.pathname}?${queryParams.toString()}`);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
const handleCreateWorkflow = () => {
|
||||
setModalOpen(true)
|
||||
setIsEditing(false)
|
||||
@@ -1854,9 +1907,9 @@ const Workflows2 = (props) => {
|
||||
data = JSON.parse(JSON.stringify(data));
|
||||
data = sanitizeWorkflow(data);
|
||||
toast("Sanitizing and publishing " + data.name);
|
||||
|
||||
|
||||
// This ALWAYS talks to Shuffle cloud
|
||||
fetch(globalUrl + "/api/v1/workflows/" + data.id + "/publish", {
|
||||
fetch(globalUrl + "/api/v1/workflows/" + data.id + "/publish" , {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
@@ -3414,6 +3467,8 @@ const Workflows2 = (props) => {
|
||||
return obj;
|
||||
})
|
||||
|
||||
console.log("ROWS: ", rows)
|
||||
|
||||
workflowData = (
|
||||
<DataGrid
|
||||
color="primary"
|
||||
@@ -3851,6 +3906,8 @@ const Workflows2 = (props) => {
|
||||
onClick={() => {
|
||||
localStorage.setItem("view", "list");
|
||||
setView("list");
|
||||
|
||||
setCurrTab(0)
|
||||
}}
|
||||
>
|
||||
<ListIcon />
|
||||
@@ -4005,20 +4062,30 @@ const Workflows2 = (props) => {
|
||||
// }
|
||||
|
||||
useEffect(() => {
|
||||
if (currTab === 2) return;
|
||||
if (userdata !== undefined && userdata !== null && filteredWorkflows.length > 0) {
|
||||
if (filteredWorkflows.length > 0) {
|
||||
|
||||
var categoryWorkflows = []
|
||||
if (currTab === 0) {
|
||||
categoryWorkflows = filteredWorkflows.filter(workflow => workflow?.org_id === userdata?.active_org?.id)
|
||||
setOrgWorkflows(categoryWorkflows)
|
||||
|
||||
if (categoryWorkflows.length === 0) {
|
||||
setOrgWorkflows(filteredWorkflows)
|
||||
} else {
|
||||
setOrgWorkflows(categoryWorkflows)
|
||||
}
|
||||
}
|
||||
else if (currTab === 1) {
|
||||
categoryWorkflows = filteredWorkflows.filter(workflow => workflow?.org_id === userdata?.active_org?.id && workflow?.owner === userdata?.id)
|
||||
setMyWorkflows(categoryWorkflows)
|
||||
}
|
||||
|
||||
setIsLoadingWorkflow(false);
|
||||
|
||||
}
|
||||
} else {
|
||||
if (currTab === 0 && workflows?.length > 0) {
|
||||
setOrgWorkflows(workflows)
|
||||
}
|
||||
}
|
||||
}, [currTab, workflows, userdata, filteredWorkflows, filters])
|
||||
|
||||
|
||||
@@ -4607,13 +4674,17 @@ const Workflows2 = (props) => {
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip title={view === "grid" ? "List view" : "Grid view"} placement="top">
|
||||
<Tooltip title={view === "grid" ? "List view (Org Workflows only)" : "Grid view"} placement="top">
|
||||
<IconButton
|
||||
style={currTab === 2 ? iconButtonDisabledStyle : iconButtonStyle}
|
||||
onClick={() => {
|
||||
const newView = view === "grid" ? "list" : "grid";
|
||||
localStorage.setItem("workflowView", newView);
|
||||
setView(newView);
|
||||
|
||||
if (view === "grid") {
|
||||
setCurrTab(0)
|
||||
}
|
||||
}}
|
||||
disabled={currTab === 2}
|
||||
>
|
||||
@@ -4699,25 +4770,30 @@ const Workflows2 = (props) => {
|
||||
paddingBottom: 40
|
||||
}}>
|
||||
|
||||
{currTab === 0 && orgWorkflows.map((data, index) => {
|
||||
// Shouldn't be a part of this list
|
||||
if (data.public === true) {
|
||||
return null
|
||||
}
|
||||
{currTab !== 0 ? null :
|
||||
orgWorkflows.length === 0 ?
|
||||
<Typography variant="h6" style={{margin: "auto", minWidth: 500, }} >
|
||||
No workflows found in this org with the Org ID filter. If this is an error, please click the "List View" button at the top to see ALL available workflows ({workflows.length}).
|
||||
</Typography> :
|
||||
orgWorkflows.map((data, index) => {
|
||||
// Shouldn't be a part of this list
|
||||
if (data.public === true) {
|
||||
return null
|
||||
}
|
||||
|
||||
// if (firstLoad) {
|
||||
// workflowDelay += 75
|
||||
// } else {
|
||||
// return <WorkflowPaper key={index} data={data} />
|
||||
// }
|
||||
// if (firstLoad) {
|
||||
// workflowDelay += 75
|
||||
// } else {
|
||||
// return <WorkflowPaper key={index} data={data} />
|
||||
// }
|
||||
|
||||
return (
|
||||
<span key={index}>
|
||||
{/*<Zoom key={index} in={true} style={{ transitionDelay: `${workflowDelay}ms` }}>*/}
|
||||
<WorkflowPaper data={data} />
|
||||
{/*</Zoom>*/}
|
||||
</span>
|
||||
)
|
||||
return (
|
||||
<span key={index}>
|
||||
{/*<Zoom key={index} in={true} style={{ transitionDelay: `${workflowDelay}ms` }}>*/}
|
||||
<WorkflowPaper data={data} />
|
||||
{/*</Zoom>*/}
|
||||
</span>
|
||||
)
|
||||
})}
|
||||
|
||||
{currTab === 3 && backupWorkflows.map((data, index) => {
|
||||
@@ -4742,24 +4818,29 @@ const Workflows2 = (props) => {
|
||||
})}
|
||||
|
||||
{
|
||||
currTab === 1 && myWorkflows.map((data, index) => {
|
||||
if (data.public === true) {
|
||||
return null
|
||||
}
|
||||
currTab !== 1 ? null :
|
||||
myWorkflows.length === 0 ?
|
||||
<Typography variant="h6" style={{margin: "auto", width: 500, }} >
|
||||
No workflows found in this org for your user.
|
||||
</Typography> :
|
||||
myWorkflows.map((data, index) => {
|
||||
if (data.public === true) {
|
||||
return null
|
||||
}
|
||||
|
||||
// if (firstLoad) {
|
||||
// workflowDelay += 75
|
||||
// } else {
|
||||
// return <WorkflowPaper key={index} data={data} />
|
||||
// }
|
||||
// if (firstLoad) {
|
||||
// workflowDelay += 75
|
||||
// } else {
|
||||
// return <WorkflowPaper key={index} data={data} />
|
||||
// }
|
||||
|
||||
return (
|
||||
<span key={index}>
|
||||
{/*<Zoom key={index} in={true} style={{ transitionDelay: `${workflowDelay}ms` }}>*/}
|
||||
<WorkflowPaper data={data} />
|
||||
{/*</Zoom>*/}
|
||||
</span>
|
||||
)
|
||||
return (
|
||||
<span key={index}>
|
||||
{/*<Zoom key={index} in={true} style={{ transitionDelay: `${workflowDelay}ms` }}>*/}
|
||||
<WorkflowPaper data={data} />
|
||||
{/*</Zoom>*/}
|
||||
</span>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
@@ -5123,7 +5204,7 @@ const Workflows2 = (props) => {
|
||||
|
||||
//isLoaded && isLoggedIn && workflowDone ? (
|
||||
const loadedCheck =
|
||||
workflowDone ? (
|
||||
workflowDone && isLoaded ? (
|
||||
<div>
|
||||
{/*
|
||||
<ShepherdTour steps={newSteps} tourOptions={tourOptions}>
|
||||
|
||||
Reference in New Issue
Block a user