Merge branch 'Shuffle:1.4.0' into 1.4.0
This commit is contained in:
@@ -5,8 +5,6 @@ import { makeStyles } from "@mui/styles";
|
||||
|
||||
import { useNavigate, Link } from "react-router-dom";
|
||||
import countries from "../components/Countries.jsx";
|
||||
import CodeEditor from "../components/ShuffleCodeEditor.jsx";
|
||||
import getLocalCodeData from "../components/ShuffleCodeEditor.jsx";
|
||||
import CacheView from "../components/CacheView.jsx";
|
||||
|
||||
import {
|
||||
@@ -1867,16 +1865,24 @@ If you're interested, please let me know a time that works for you, or set up a
|
||||
{selectedAuthentication.type === "oauth" || selectedAuthentication.type === "oauth2" || selectedAuthentication.type === "oauth2-app" ?
|
||||
<div>
|
||||
<Typography variant="body1" color="textSecondary" style={{ marginBottom: 0, marginTop: 10 }}>
|
||||
Only the name of the auth can be modified for Oauth2. Please remake the authentication to change the fields like Client ID, Secret, Scopes etc.
|
||||
Only the name and url can be modified for Oauth2/OpenID connect. Please remake the authentication if you want to change the other fields like Client ID, Secret, Scopes etc.
|
||||
</Typography>
|
||||
</div>
|
||||
:
|
||||
selectedAuthentication.fields.map((data, index) => {
|
||||
: null }
|
||||
|
||||
{selectedAuthentication.fields.map((data, index) => {
|
||||
var fieldname = data.key.replaceAll("_", " ")
|
||||
if (fieldname.endsWith(" basic")) {
|
||||
fieldname = fieldname.substring(0, fieldname.length - 6)
|
||||
}
|
||||
|
||||
if (selectedAuthentication.type === "oauth" || selectedAuthentication.type === "oauth2" || selectedAuthentication.type === "oauth2-app") {
|
||||
if (selectedAuthentication.fields[index].key !== "url") {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//console.log("DATA: ", data, selectedAuthentication)
|
||||
return (
|
||||
<div key={index}>
|
||||
@@ -3415,24 +3421,26 @@ If you're interested, please let me know a time that works for you, or set up a
|
||||
// using request id or trace id
|
||||
<ListItem key={index} style={{ backgroundColor: index % 2 === 0 ? "#1f2023" : "#27292d" }}>
|
||||
<ListItemText
|
||||
primary={new Date(data.start_time.seconds * 1000).toISOString().slice(0, 10)}
|
||||
primary={new Date(data.start_time.seconds * 1000).toLocaleString('en-US', {
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
second: '2-digit',
|
||||
hour12: false,
|
||||
})}
|
||||
style={{
|
||||
minWidth: 150,
|
||||
maxWidth: 150,
|
||||
minWidth: 200,
|
||||
maxWidth: 200,
|
||||
}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary={data.status}
|
||||
primary={data.referrer}
|
||||
style={{
|
||||
minWidth: 70,
|
||||
maxWidth: 70,
|
||||
}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary={data.method}
|
||||
style={{
|
||||
minWidth: 150,
|
||||
maxWidth: 150,
|
||||
minWidth: 300,
|
||||
maxWidth: 300,
|
||||
overflow: "hidden",
|
||||
}}
|
||||
/>
|
||||
<ListItemText
|
||||
@@ -3441,6 +3449,7 @@ If you're interested, please let me know a time that works for you, or set up a
|
||||
minWidth: 700,
|
||||
maxWidth: 700,
|
||||
overflow: "hidden",
|
||||
marginLeft: 10,
|
||||
}}
|
||||
/>
|
||||
</ListItem>
|
||||
@@ -4406,7 +4415,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 +4559,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 +4568,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"
|
||||
>
|
||||
|
||||
@@ -121,7 +121,7 @@ import * as edgehandles from "cytoscape-edgehandles";
|
||||
import CytoscapeComponent from "react-cytoscapejs";
|
||||
import Draggable from "react-draggable";
|
||||
import cytoscapestyle from "../defaultCytoscapeStyle.jsx";
|
||||
import ShuffleCodeEditor from "../components/ShuffleCodeEditor.jsx";
|
||||
import ShuffleCodeEditor from "../components/ShuffleCodeEditor1.jsx";
|
||||
|
||||
import { validateJson, GetIconInfo } from "../views/Workflows.jsx";
|
||||
import { GetParsedPaths, internalIds, } from "../views/Apps.jsx";
|
||||
@@ -13366,6 +13366,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) => {
|
||||
@@ -13744,9 +13805,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={{
|
||||
@@ -13802,7 +13918,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={
|
||||
@@ -14000,7 +14116,7 @@ const AngularWorkflow = (defaultprops) => {
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
color="secondary"
|
||||
title={`Show executions (${workflowExecutions.length})`}
|
||||
title={`Show executions (${workflowExecutions.length}) (Ctrl + ')`}
|
||||
placement="top-start"
|
||||
>
|
||||
<span>
|
||||
@@ -14069,7 +14185,7 @@ const AngularWorkflow = (defaultprops) => {
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
color="secondary"
|
||||
title="Show Workflow Revision History (Beta)"
|
||||
title="Show Workflow Revision History (Beta) (Ctrl + ])"
|
||||
placement="top"
|
||||
>
|
||||
<span>
|
||||
@@ -14080,8 +14196,8 @@ const AngularWorkflow = (defaultprops) => {
|
||||
variant={"outlined"}
|
||||
onClick={() => {
|
||||
setShowWorkflowRevisions(true)
|
||||
setSelectedRevision(workflow)
|
||||
//setOriginalWorkflow(workflow)
|
||||
setSelectedRevision(workflow)
|
||||
//setOriginalWorkflow(workflow)
|
||||
}}
|
||||
>
|
||||
<RestoreIcon />
|
||||
@@ -14283,6 +14399,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={() => {
|
||||
@@ -14538,8 +14700,8 @@ const AngularWorkflow = (defaultprops) => {
|
||||
</Button>
|
||||
<Button
|
||||
color="secondary"
|
||||
disabled
|
||||
variant="outlined"
|
||||
disabled={workflow.public !== true}
|
||||
fullWidth
|
||||
style={{ marginTop: 15, }}
|
||||
onClick={() => {
|
||||
@@ -14547,6 +14709,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
|
||||
@@ -15112,6 +15276,7 @@ const AngularWorkflow = (defaultprops) => {
|
||||
</a>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<Tooltip title="Refresh runs (Ctrl + ;)" arrow>
|
||||
<Button
|
||||
style={{ borderRadius: "0px" }}
|
||||
variant="outlined"
|
||||
@@ -15124,6 +15289,7 @@ const AngularWorkflow = (defaultprops) => {
|
||||
<CachedIcon style={{ marginRight: 10 }} />
|
||||
Refresh Runs
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Divider
|
||||
style={{
|
||||
backgroundColor: "rgba(255,255,255,0.5)",
|
||||
@@ -15351,48 +15517,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)",
|
||||
@@ -15456,15 +15625,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" />
|
||||
@@ -17855,42 +18028,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({})
|
||||
|
||||
@@ -17910,7 +18086,7 @@ const AngularWorkflow = (defaultprops) => {
|
||||
cy.removeListener("cxttap");
|
||||
}
|
||||
|
||||
setupGraph(revision)
|
||||
setupGraph(newrevision)
|
||||
|
||||
// Re-adding cytoscape triggers
|
||||
if (cy !== undefined && cy !== null) {
|
||||
@@ -17936,8 +18112,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", }}>
|
||||
|
||||
@@ -1,16 +1,11 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { useInterval } from "react-powerhooks";
|
||||
import AppFramework from "../components/AppFramework.jsx";
|
||||
import { makeStyles, } from "@mui/styles";
|
||||
// nodejs library that concatenates classes
|
||||
import classNames from "classnames";
|
||||
import theme from '../theme.jsx';
|
||||
import { useNavigate, Link, useParams } from "react-router-dom";
|
||||
import WorkflowTemplatePopup from "../components/WorkflowTemplatePopup.jsx";
|
||||
|
||||
// react plugin used to create charts
|
||||
//import { Line, Bar } from "react-chartjs-2";
|
||||
//import { useAlert
|
||||
import React, { useState, useEffect } from "react"
|
||||
import { useInterval } from "react-powerhooks"
|
||||
import AppFramework from "../components/AppFramework.jsx"
|
||||
import { makeStyles, } from "@mui/styles"
|
||||
import classNames from "classnames"
|
||||
import theme from '../theme.jsx'
|
||||
import { useNavigate, Link, useParams } from "react-router-dom"
|
||||
import WorkflowTemplatePopup from "../components/WorkflowTemplatePopup.jsx"
|
||||
import { ToastContainer, toast } from "react-toastify"
|
||||
import { parsedDatatypeImages } from "../components/AppFramework.jsx"
|
||||
import { findSpecificApp } from "../components/AppFramework.jsx"
|
||||
@@ -96,7 +91,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 +110,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 +135,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 +913,9 @@ const UsecaseListComponent = (props) => {
|
||||
description={inputUsecase.description}
|
||||
|
||||
apps={apps}
|
||||
getAppFramework={getFramework}
|
||||
//appSetupDone={appSetupDone}
|
||||
//setAppSetupDone={setAppSetupDone}
|
||||
/>
|
||||
: null}
|
||||
</span>
|
||||
@@ -990,13 +989,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 +1714,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 ?
|
||||
|
||||
@@ -13,6 +13,11 @@ import {
|
||||
//import { useAlert
|
||||
import { ToastContainer, toast } from "react-toastify"
|
||||
|
||||
import { FileCopy, Visibility, VisibilityOff } from "@mui/icons-material";
|
||||
import IconButton from "@mui/material/IconButton";
|
||||
import { Tooltip } from "@mui/material";
|
||||
|
||||
|
||||
const Settings = (props) => {
|
||||
const { globalUrl, isLoaded, userdata, setUserData } = props;
|
||||
//const alert = useAlert();
|
||||
@@ -44,6 +49,17 @@ const Settings = (props) => {
|
||||
|
||||
const [userSettings, setUserSettings] = useState({});
|
||||
|
||||
const [showApiKey, setShowApiKey] = useState(false);
|
||||
const [apiKeyCopied, setApiKeyCopied] = useState(false);
|
||||
|
||||
const handleCopyApiKey = () => {
|
||||
navigator.clipboard.writeText(userSettings.apikey);
|
||||
setApiKeyCopied(true);
|
||||
setTimeout(() => {
|
||||
setApiKeyCopied(false);
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
/*
|
||||
const [userdata.eth_info, setEthInfo] = useState(userdata.eth_info !== undefined && userdata.eth_info.account !== undefined && userdata.eth_info.account.length > 0 ? userdata.eth_info : {
|
||||
"account": "",
|
||||
@@ -467,7 +483,7 @@ const Settings = (props) => {
|
||||
>
|
||||
What is the API key used for?
|
||||
</a>
|
||||
<TextField
|
||||
{/* <TextField
|
||||
style={{ backgroundColor: theme.palette.inputColor, flex: "1" }}
|
||||
InputProps={{
|
||||
style: {
|
||||
@@ -484,7 +500,43 @@ const Settings = (props) => {
|
||||
id="standard-required"
|
||||
margin="normal"
|
||||
variant="outlined"
|
||||
/>
|
||||
/> */}
|
||||
<TextField
|
||||
style={{ backgroundColor: theme.palette.inputColor, flex: "1" }}
|
||||
InputProps={{
|
||||
style: {
|
||||
height: "50px",
|
||||
color: "white",
|
||||
},
|
||||
endAdornment: (
|
||||
<>
|
||||
<Tooltip title={showApiKey ? "Hide API Key" : "Show API Key"}>
|
||||
<IconButton
|
||||
onClick={() => setShowApiKey(!showApiKey)}
|
||||
>
|
||||
{showApiKey ? <VisibilityOff /> : <Visibility />}
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Tooltip title={apiKeyCopied ? "API Key copied!" : "Copy API Key"}>
|
||||
<IconButton
|
||||
onClick={handleCopyApiKey}
|
||||
>
|
||||
<FileCopy />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</>
|
||||
),
|
||||
}}
|
||||
color="primary"
|
||||
value={showApiKey ? userSettings.apikey : '*'.repeat(36)} // Show API key if showApiKey is true, else show asterisks
|
||||
required
|
||||
disabled
|
||||
fullWidth
|
||||
placeholder="APIKEY"
|
||||
id="standard-required"
|
||||
margin="normal"
|
||||
variant="outlined"
|
||||
/>
|
||||
<Button
|
||||
style={{ width: "100%", height: "40px", marginTop: "10px" }}
|
||||
variant="outlined"
|
||||
@@ -676,8 +728,13 @@ const Settings = (props) => {
|
||||
Submit password change
|
||||
</Button>
|
||||
<h3>{passwordFormMessage}</h3>
|
||||
<Divider style={{ marginTop: "40px" }} />
|
||||
<h2>Creator Incentive Program</h2>
|
||||
{isCloud && (
|
||||
<>
|
||||
<Divider style={{ marginTop: "40px" }} />
|
||||
<h2>Creator Incentive Program</h2>
|
||||
</>
|
||||
)}
|
||||
|
||||
<div style={{ display: runFlex ? "flex" : "", width: "100%" }}>
|
||||
<div>
|
||||
{isCloud ?
|
||||
|
||||
@@ -551,9 +551,7 @@ const Workflows = (props) => {
|
||||
|
||||
const [field1, setField1] = React.useState("");
|
||||
const [field2, setField2] = React.useState("");
|
||||
const [downloadUrl, setDownloadUrl] = React.useState(
|
||||
"https://github.com/frikky/shuffle-workflows"
|
||||
);
|
||||
const [downloadUrl, setDownloadUrl] = React.useState("https://github.com/shuffle/workflows")
|
||||
const [downloadBranch, setDownloadBranch] = React.useState("master");
|
||||
const [loadWorkflowsModalOpen, setLoadWorkflowsModalOpen] =
|
||||
React.useState(false);
|
||||
@@ -924,7 +922,7 @@ const Workflows = (props) => {
|
||||
>
|
||||
<DialogTitle>
|
||||
<div style={{ textAlign: "center", color: "rgba(255,255,255,0.9)" }}>
|
||||
Are you sure you want to delete {selectedWorkflowId.length > 0 ? filteredWorkflows.find((w) => w.id === selectedWorkflowId).name : `${selectedWorkflowIndexes.length} workflow${selectedWorkflowIndexes.length === 1 ? '' : 's'}`}? <div />
|
||||
Are you sure you want to delete {selectedWorkflowId.length > 0 ? filteredWorkflows.find((w) => w.id === selectedWorkflowId)?.name : `${selectedWorkflowIndexes.length} workflow${selectedWorkflowIndexes.length === 1 ? '' : 's'}`}? <div />
|
||||
|
||||
Other workflows relying on {selectedWorkflowIndexes.length > 0 ? "them" : "it"} one will stop working
|
||||
</div>
|
||||
@@ -3630,7 +3628,7 @@ const Workflows = (props) => {
|
||||
const handleGithubValidation = () => {
|
||||
importWorkflowsFromUrl(downloadUrl);
|
||||
setLoadWorkflowsModalOpen(false);
|
||||
};
|
||||
}
|
||||
|
||||
const workflowDownloadModalOpen = loadWorkflowsModalOpen ? (
|
||||
<Dialog
|
||||
@@ -3677,11 +3675,11 @@ const Workflows = (props) => {
|
||||
},
|
||||
}}
|
||||
onChange={(e) => setDownloadUrl(e.target.value)}
|
||||
placeholder="https://github.com/frikky/shuffle-apps"
|
||||
placeholder="https://github.com/shuffle/workflows"
|
||||
fullWidth
|
||||
/>
|
||||
<span style={{ marginTop: 10 }}>
|
||||
Branch (default value is "master"):
|
||||
Branch (default value is "main"):
|
||||
</span>
|
||||
<div style={{ display: "flex" }}>
|
||||
<TextField
|
||||
|
||||
Reference in New Issue
Block a user