A lot of things

This commit is contained in:
Frikky
2024-02-15 18:53:39 +01:00
parent bf776409bd
commit 858d18c7dc
12 changed files with 512 additions and 257 deletions
+4 -4
View File
@@ -4406,7 +4406,7 @@ If you're interested, please let me know a time that works for you, or set up a
/>
<ListItemText
primary="Default"
style={{ minWidth: 100, maxWidth: 100 }}
style={{ minWidth: 110, maxWidth: 110, }}
/>
<ListItemText
primary="Actions"
@@ -4550,8 +4550,8 @@ If you're interested, please let me know a time that works for you, or set up a
/>
<ListItemText
style={{
minWidth: 80,
maxWidth: 80,
minWidth: 100,
maxWidth: 100,
overflow: "hidden",
}}
primary={environment.default ? "true" : null}
@@ -4559,7 +4559,7 @@ If you're interested, please let me know a time that works for you, or set up a
{environment.default ? null : (
<Button
variant="outlined"
style={{ marginLeft: 0, marginRight: 0, }}
style={{ marginLeft: 0, marginRight: 0, maxWidth: 150, }}
onClick={() => setDefaultEnvironment(environment)}
color="primary"
>
+251 -63
View File
@@ -13362,6 +13362,67 @@ const AngularWorkflow = (defaultprops) => {
</Link>
<h2 style={{ margin: 0 }}>{workflow.name}</h2>
</Breadcrumbs>
{workflow.public === true || userdata.active_org.id === undefined || userdata.active_org.id === null || workflow.org_id === null || workflow.org_id === undefined || workflow.org_id.length === 0 || userdata.active_org.id === workflow.org_id ? null :
<Typography variant="body1">
<b>Warning</b>: Change <span
style={{color: "#f85a3e", cursor: "pointer"}}
onClick={() => {
toast("Changing to correct organization. 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");
}
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
}
setTimeout(() => {
window.location.reload();
}, 2000);
toast("Successfully changed active organization - 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 support@shuffler.io if this persists.");
}
}
})
.catch((error) => {
console.log("error changing: ", error);
//removeCookie("session_token", {path: "/"})
})
}}
>Active Organization</span> to edit this Workflow.
</Typography>
}
</div>
<div style={{display: "flex", marginLeft: 10, }}>
{parentWorkflows.slice(0,5).map((wf, index) => {
@@ -13740,9 +13801,64 @@ const AngularWorkflow = (defaultprops) => {
</div>
: null
const RightsideBar = () => {
const [hovered, setHovered] = useState(false)
useEffect(() => {
const handleKeyDown = (event) => {
if ((event.metaKey || event.ctrlKey) && event.key === '/') {
event.preventDefault(); // Prevent default browser behavior (like opening search bar)
if (!workflow.public && !executionRequestStarted) {
executeWorkflow(executionText, workflow.start, lastSaved);
}
}
if ((event.ctrlKey || event.metaKey) && event.key === "'") {
// Check if Ctrl (Windows/Linux) or Command (Mac) key is pressed along with '/'
if (!workflow.public && !executionModalOpen) {
setExecutionModalOpen(true);
getWorkflowExecution(props.match.params.key, "");
} else if (!workflow.public && executionModalOpen) {
setExecutionModalOpen(false);
}
}
if ((event.ctrlKey || event.metaKey) && event.key === "]") {
console.log("Show workflow revisions key pressed")
if (!workflow.public) {
setShowWorkflowRevisions(true)
setSelectedRevision(workflow)
//setOriginalWorkflow(workflow)
}
}
if (( event.ctrlKey || event.metaKey ) && event.key === ";") {
if (!workflow.public && executionModalOpen) {
getWorkflowExecution(props.match.params.key, "");
}
}
if (( event.ctrlKey || event.metaKey ) && event.shiftKey) {
console.log("Shift key pressed")
if (!workflow.public && executionModalOpen) {
setExecutionRunning(false);
stop()
const cursearch = typeof window === "undefined" || window.location === undefined ? "" : window.location.search;
const newitem = removeParam("execution_id", cursearch);
navigate(curpath + newitem)
setExecutionModalView(0);
}
}
};
document.addEventListener('keydown', handleKeyDown);
return () => {
document.removeEventListener('keydown', handleKeyDown);
};
}, [executeWorkflow, executionText, workflow, lastSaved, executionRequestStarted]);
return (
<div
style={{
@@ -13798,7 +13914,7 @@ const AngularWorkflow = (defaultprops) => {
</span>
</Tooltip>
) : (
<Tooltip color="primary" title="Test Execution" placement="top">
<Tooltip color="primary" title="Test Execution (Ctrl + /)" placement="top">
<span>
<Button
disabled={
@@ -13996,7 +14112,7 @@ const AngularWorkflow = (defaultprops) => {
</Tooltip>
<Tooltip
color="secondary"
title={`Show executions (${workflowExecutions.length})`}
title={`Show executions (${workflowExecutions.length}) (Ctrl + ')`}
placement="top-start"
>
<span>
@@ -14065,7 +14181,7 @@ const AngularWorkflow = (defaultprops) => {
</Tooltip>
<Tooltip
color="secondary"
title="Show Workflow Revision History (Beta)"
title="Show Workflow Revision History (Beta) (Ctrl + ])"
placement="top"
>
<span>
@@ -14076,8 +14192,8 @@ const AngularWorkflow = (defaultprops) => {
variant={"outlined"}
onClick={() => {
setShowWorkflowRevisions(true)
setSelectedRevision(workflow)
//setOriginalWorkflow(workflow)
setSelectedRevision(workflow)
//setOriginalWorkflow(workflow)
}}
>
<RestoreIcon />
@@ -14279,6 +14395,52 @@ const AngularWorkflow = (defaultprops) => {
//return null;
};
const unPublishWorkflow = (data) => {
if (!isCloud) {
toast("Function only supported on cloud")
return
}
if (data.public !== true) {
toast("Workflow is not public. Can't unpublish");
return
}
// This ALWAYS talks to Shuffle cloud
data = JSON.parse(JSON.stringify(data));
const url = `${globalUrl}/api/v1/workflows/${data.id}/unpublish`;
fetch(url, {
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 workflow publish :O!");
}
return response.json();
})
.then((responseJson) => {
if (responseJson.reason !== undefined) {
toast("Unpublishing: "+responseJson.reason)
}
if (responseJson.success === true) {
workflow.public = false
setWorkflow(workflow)
}
})
.catch((error) => {
toast("Failed publishing: is the workflow valid? Remember to save the workflow first.")
console.log(error.toString())
})
}
// This can execute a workflow with firestore. Used for test, as datastore is old and stuff
// Too much work to move everything over alone, so won't touch it for now
//<Button style={{borderRadius: "0px"}} color="primary" variant="contained" onClick={() => {
@@ -14534,8 +14696,8 @@ const AngularWorkflow = (defaultprops) => {
</Button>
<Button
color="secondary"
disabled
variant="outlined"
disabled={workflow.public !== true}
fullWidth
style={{ marginTop: 15, }}
onClick={() => {
@@ -14543,6 +14705,8 @@ const AngularWorkflow = (defaultprops) => {
// workflow.public = false
// setWorkflow(workflow)
// setUpdate(Math.random());
toast("Unpublishing this workflow from the search engine. It will remain public until it is deleted, as it is a copy of the original workflow.")
unPublishWorkflow(workflow)
}}
>
Unpublish Workflow
@@ -15108,6 +15272,7 @@ const AngularWorkflow = (defaultprops) => {
</a>
</Tooltip>
</div>
<Tooltip title="Refresh runs (Ctrl + ;)" arrow>
<Button
style={{ borderRadius: "0px" }}
variant="outlined"
@@ -15120,6 +15285,7 @@ const AngularWorkflow = (defaultprops) => {
<CachedIcon style={{ marginRight: 10 }} />
Refresh Runs
</Button>
</Tooltip>
<Divider
style={{
backgroundColor: "rgba(255,255,255,0.5)",
@@ -15347,48 +15513,51 @@ const AngularWorkflow = (defaultprops) => {
</div>
) : (
<div style={{ padding: isMobile ? "0px 10px 25px 10px" : "25px 15px 25px 15px", maxWidth: isMobile ? "100%" : 400, overflowX: "hidden" }}>
<Breadcrumbs
aria-label="breadcrumb"
separator=""
style={{ color: "white", fontSize: 16 }}
>
<span
style={{ color: "rgba(255,255,255,0.5)", display: "flex" }}
onClick={() => {
setExecutionRunning(false);
stop();
getWorkflowExecution(props.match.params.key, "");
setExecutionModalView(0);
setLastExecution(executionData.execution_id);
}}
<Breadcrumbs
aria-label="breadcrumb"
separator=""
style={{ color: "white", fontSize: 16 }}
>
<IconButton
style={{
paddingLeft: 0,
marginTop: "auto",
marginBottom: "auto",
}}
onClick={() => {
setExecutionRunning(false);
stop()
}}
>
<ArrowBackIcon style={{ color: "rgba(255,255,255,0.5)" }} />
</IconButton>
<h2
style={{ color: "rgba(255,255,255,0.5)", cursor: "pointer" }}
onClick={() => {
const cursearch = typeof window === "undefined" || window.location === undefined ? "" : window.location.search;
const newitem = removeParam("execution_id", cursearch);
navigate(curpath + newitem)
setExecutionRunning(false);
stop()
}}
>
See more runs
</h2>
</span>
</Breadcrumbs>
<span
style={{ color: "rgba(255,255,255,0.5)", display: "flex" }}
onClick={() => {
setExecutionRunning(false);
stop();
getWorkflowExecution(props.match.params.key, "");
setExecutionModalView(0);
setLastExecution(executionData.execution_id);
}}
>
<IconButton
style={{
paddingLeft: 0,
marginTop: "auto",
marginBottom: "auto",
}}
onClick={() => {
setExecutionRunning(false);
stop()
}}
>
<ArrowBackIcon style={{ color: "rgba(255,255,255,0.5)" }} />
</IconButton>
<Tooltip title="See more runs (Ctrl + Shift)" arrow>
<h2
style={{ color: "rgba(255,255,255,0.5)", cursor: "pointer" }}
onClick={() => {
const cursearch = typeof window === "undefined" || window.location === undefined ? "" : window.location.search;
const newitem = removeParam("execution_id", cursearch);
navigate(curpath + newitem)
setExecutionRunning(false);
stop()
}}
>
See more runs
</h2>
</Tooltip>
</span>
</Breadcrumbs>
<Divider
style={{
backgroundColor: "rgba(255,255,255,0.6)",
@@ -15452,15 +15621,19 @@ const AngularWorkflow = (defaultprops) => {
color="primary"
title="Explore logs for the workflow"
placement="top"
style={{ zIndex: 50000 }}
style={{ zIndex: 50000, }}
>
<span style={{}}>
<Button
color="primary"
style={{ float: "right", marginTop: 20, marginLeft: 10 }}
disabled={!userdata.support}
disabled={userdata.region_url !== "https://shuffler.io"}
onClick={() => {
window.open(`/api/v1/workflows/search/${executionData.execution_id}`, "_blank")
toast("Opening logs in a new tab")
setTimeout(() => {
window.open(`/api/v1/workflows/search/${executionData.execution_id}`, "_blank")
}, 250)
}}
>
<InsightsIcon color="secondary" />
@@ -17851,42 +18024,45 @@ const AngularWorkflow = (defaultprops) => {
return null
}
var newrevision = JSON.parse(JSON.stringify(revision))
// Make unix timestamp into ISO timestamp in the format July 27th, 3:05 AM
// Format: July 27th, 3:05 AM
console.log("Edited time: ", revision.edited)
//console.log("Edited time: ", revision.edited)
// Convert 1692128391 to valid timestamp
const validTimestamp = revision.edited.toString().length === 10 ? revision.edited * 1000 : revision.edited
const validTimestamp = newrevision.edited.toString().length === 10 ? newrevision.edited * 1000 : newrevision.edited
const translatedDate = new Date(validTimestamp).toLocaleString('en-US', { month: 'long', day: 'numeric', hour: 'numeric', minute: 'numeric', hour12: true })
var workflowStatus = revision.status !== undefined && revision.status !== null && revision.status !== "" ? revision.status : "test"
if (revision.name !== undefined && revision.name !== null && revision.name !== "") {
if (revision.name.toLowerCase().includes("test")) {
var workflowStatus = newrevision.status !== undefined && newrevision.status !== null && newrevision.status !== "" ? newrevision.status : "test"
if (newrevision.name !== undefined && newrevision.name !== null && newrevision.name !== "") {
if (newrevision.name.toLowerCase().includes("test")) {
workflowStatus = "test"
}
if (revision.name.toLowerCase().includes("dev") || revision.name.toLowerCase().includes("staging") || revision.name.toLowerCase().includes("rollback")) {
if (newrevision.name.toLowerCase().includes("dev") || newrevision.name.toLowerCase().includes("staging") || newrevision.name.toLowerCase().includes("rollback")) {
workflowStatus = "dev"
}
if (revision.name.toLowerCase().includes("prod") || revision.name.toLowerCase().includes("main")) {
if (newrevision.name.toLowerCase().includes("prod") || newrevision.name.toLowerCase().includes("main")) {
workflowStatus = "prod"
}
}
return (
<Paper
style={{padding: "15px 15px 15px 25px", minHeight: 105, maxHeight: 105, cursor: "pointer", backgroundColor: revision.edited === selectedRevision.edited ? "rgba(255,255,255,0.3)" : theme.palette.surfaceColor, border: "1px solid rgba(255,255,255,0.3)", marginBottom: 10,
style={{padding: "15px 15px 15px 25px", minHeight: 105, maxHeight: 105, cursor: "pointer", backgroundColor: newrevision.edited === selectedRevision.edited ? "rgba(255,255,255,0.3)" : theme.palette.surfaceColor, border: "1px solid rgba(255,255,255,0.3)", marginBottom: 10,
}} onClick={(e) => {
if (revision.edited === selectedRevision.edited) {
if (newrevision.edited === selectedRevision.edited) {
console.log("Same revision! No setting.")
return
}
// Should render if it's not the same as workflow.edited
console.log("Clicked revision: ", revision)
console.log("Clicked revision: ", newrevision)
setLastSaved(false)
setSelectedRevision(revision)
setWorkflow(revision)
setSelectedRevision(newrevision)
setWorkflow(newrevision)
setSelectedAction({});
setSelectedApp({})
@@ -17906,7 +18082,7 @@ const AngularWorkflow = (defaultprops) => {
cy.removeListener("cxttap");
}
setupGraph(revision)
setupGraph(newrevision)
// Re-adding cytoscape triggers
if (cy !== undefined && cy !== null) {
@@ -17932,8 +18108,20 @@ const AngularWorkflow = (defaultprops) => {
cy.on("free", "node", (e) => onNodeDragStop(e, selectedAction));
cy.on("cxttap", "node", (e) => onCtxTap(e));
if (selectedAction.id !== undefined && selectedAction.id !== null && selectedAction.id !== "") {
setTimeout(() => {
const foundaction = cy.$id(selectedAction.id)
if (foundaction !== undefined && foundaction !== null) {
foundaction.select()
}
}, 250)
}
}
// Need to run through graph setup with this one
}}>
<div style={{display: "flex", }}>
+15 -6
View File
@@ -96,7 +96,8 @@ const useStyles = makeStyles({
const UsecaseListComponent = (props) => {
const { keys, userdata, isCloud, globalUrl, frameworkData, isLoggedIn, workflows, setWorkflows, } = props
const { keys, userdata, isCloud, globalUrl, frameworkData, isLoggedIn, workflows, setWorkflows, getFramework, setFrameworkData, } = props
const [expandedIndex, setExpandedIndex] = useState(-1);
const [expandedItem, setExpandedItem] = useState(-1);
@@ -114,11 +115,13 @@ const UsecaseListComponent = (props) => {
const [firstLoad, setFirstLoad] = useState(true)
const [apps, setApps] = useState([])
const classes = useStyles();
let navigate = useNavigate();
const [mitreTags, setMitreTags] = useState([]);
const parseUsecase = (subcase) => {
const srcdata = findSpecificApp(frameworkData, subcase.type)
const dstdata = findSpecificApp(frameworkData, subcase.last)
@@ -137,13 +140,11 @@ const UsecaseListComponent = (props) => {
}
useEffect(() => {
console.log("In frameworkData useEffect: frameworkData: ", frameworkData)
//console.log("Frameworkdata changed. Use to set inputUsecase: ", frameworkData, prevSubcase)
if (frameworkData === undefined || prevSubcase === undefined) {
return
}
console.log("PAST!")
var parsedUsecase = inputUsecase
const subcase = parseUsecase(prevSubcase)
@@ -917,6 +918,9 @@ const UsecaseListComponent = (props) => {
description={inputUsecase.description}
apps={apps}
getAppFramework={getFramework}
//appSetupDone={appSetupDone}
//setAppSetupDone={setAppSetupDone}
/>
: null}
</span>
@@ -990,13 +994,15 @@ const UsecaseListComponent = (props) => {
}}>
<AppFramework
inputUsecase={inputUsecase}
frameworkData={frameworkData}
selectedOption={"Draw"}
showOptions={false}
isLoaded={true}
isLoggedIn={true}
globalUrl={globalUrl}
size={0.6}
frameworkData={frameworkData}
setFrameworkData={setFrameworkData}
/>
</div>
</div>
@@ -1713,12 +1719,15 @@ const Dashboard = (props) => {
<UsecaseListComponent
userdata={userdata}
isLoggedIn={isLoggedIn}
frameworkData={frameworkData}
keys={selectedUsecases}
isCloud={isCloud}
globalUrl={globalUrl}
workflows={workflows}
setWorkflows={setWorkflows}
frameworkData={frameworkData}
setFrameworkData={setFrameworkData}
getFramework={getFramework}
/>
{treeKeys.length > 0 ?