Revert "Multiple diff fixes for multi tenant workflows"

This reverts commit f0c2dfa3d2.
This commit is contained in:
yashsinghcodes
2025-03-17 18:12:23 +05:30
parent 02801ecd78
commit b6512897e8
11 changed files with 106 additions and 247 deletions
+1 -1
View File
@@ -18,7 +18,7 @@ require (
github.com/gorilla/mux v1.8.1 github.com/gorilla/mux v1.8.1
github.com/h2non/filetype v1.1.3 github.com/h2non/filetype v1.1.3
github.com/satori/go.uuid v1.2.0 github.com/satori/go.uuid v1.2.0
github.com/shuffle/shuffle-shared v0.8.12 github.com/shuffle/shuffle-shared v0.8.7
golang.org/x/crypto v0.32.0 golang.org/x/crypto v0.32.0
google.golang.org/api v0.176.1 google.golang.org/api v0.176.1
google.golang.org/grpc v1.68.1 google.golang.org/grpc v1.68.1
-2
View File
@@ -356,8 +356,6 @@ github.com/shuffle/shuffle-shared v0.8.5 h1:c98AMOzIrDXmgQrKyf1HJ9wZwAwB02LPRvf9
github.com/shuffle/shuffle-shared v0.8.5/go.mod h1:bBXhEsPKjxln0mFnSeri7gIJ3tL/636Sh5NyTyNrvIQ= github.com/shuffle/shuffle-shared v0.8.5/go.mod h1:bBXhEsPKjxln0mFnSeri7gIJ3tL/636Sh5NyTyNrvIQ=
github.com/shuffle/shuffle-shared v0.8.6 h1:chnGJRKsO1gR5Vt/8hp5SQg1yP8/DmiK8sRhWVaTgEg= github.com/shuffle/shuffle-shared v0.8.6 h1:chnGJRKsO1gR5Vt/8hp5SQg1yP8/DmiK8sRhWVaTgEg=
github.com/shuffle/shuffle-shared v0.8.6/go.mod h1:bBXhEsPKjxln0mFnSeri7gIJ3tL/636Sh5NyTyNrvIQ= github.com/shuffle/shuffle-shared v0.8.6/go.mod h1:bBXhEsPKjxln0mFnSeri7gIJ3tL/636Sh5NyTyNrvIQ=
github.com/shuffle/shuffle-shared v0.8.12 h1:fg6jGAuevOGLgR7kpoZDJh//tzFjrEqj/bpxRFzxUTw=
github.com/shuffle/shuffle-shared v0.8.12/go.mod h1:bBXhEsPKjxln0mFnSeri7gIJ3tL/636Sh5NyTyNrvIQ=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
+2 -6
View File
@@ -1032,14 +1032,10 @@ func deleteWorkflow(resp http.ResponseWriter, request *http.Request) {
log.Printf("[INFO] Should have deleted workflow %s (%s)", workflow.Name, fileId) log.Printf("[INFO] Should have deleted workflow %s (%s)", workflow.Name, fileId)
shuffle.DeleteCache(ctx, fmt.Sprintf("%s_workflows", user.Id)) cacheKey := fmt.Sprintf("%s_workflows", user.Id)
shuffle.DeleteCache(ctx, cacheKey)
shuffle.DeleteCache(ctx, fmt.Sprintf("%s_workflows", user.ActiveOrg.Id)) shuffle.DeleteCache(ctx, fmt.Sprintf("%s_workflows", user.ActiveOrg.Id))
shuffle.DeleteCache(ctx, fmt.Sprintf("%s_%s", user.Username, fileId))
log.Printf("[DEBUG] Cleared workflow cache for %s (%s)", user.Username, user.Id) log.Printf("[DEBUG] Cleared workflow cache for %s (%s)", user.Username, user.Id)
shuffle.DeleteCache(ctx, fmt.Sprintf("workflow_%s_childworkflows", workflow.ID))
if len(workflow.ParentWorkflowId) > 0 {
shuffle.DeleteCache(ctx, fmt.Sprintf("workflow_%s_childworkflows", workflow.ParentWorkflowId))
}
resp.WriteHeader(200) resp.WriteHeader(200)
resp.Write([]byte(`{"success": true}`)) resp.Write([]byte(`{"success": true}`))
+36 -45
View File
@@ -77,8 +77,6 @@ const Billing = memo((props) => {
const [currentIndex, setCurrentIndex] = useState(0); const [currentIndex, setCurrentIndex] = useState(0);
const [deleteAlertIndex, setDeleteAlertIndex] = useState(-1); const [deleteAlertIndex, setDeleteAlertIndex] = useState(-1);
const [deleteAlertVerification, setDeleteAlertVerification] = useState(false); const [deleteAlertVerification, setDeleteAlertVerification] = useState(false);
const [isScale, setIsScale] = useState(false);
useEffect(() => { useEffect(() => {
if (userdata.app_execution_limit !== undefined && userdata.app_execution_usage !== undefined) { if (userdata.app_execution_limit !== undefined && userdata.app_execution_usage !== undefined) {
const percentage = (userdata.app_execution_usage / userdata.app_execution_limit) * 100; const percentage = (userdata.app_execution_usage / userdata.app_execution_limit) * 100;
@@ -178,10 +176,11 @@ const Billing = memo((props) => {
padding: 20, padding: 20,
// maxWidth: 400, // maxWidth: 400,
width: 340, width: 340,
height: 'auto', height: 480,
// width: "100%", // width: "100%",
backgroundColor: "#1e1e1e", backgroundColor: theme.palette.backgroundColor,
borderRadius: 10, borderRadius: theme.palette?.borderRadius * 2,
border: "1px solid rgba(255,255,255,0.3)",
marginRight: 10, marginRight: 10,
marginTop: 15, marginTop: 15,
} }
@@ -362,7 +361,7 @@ const Billing = memo((props) => {
var showSupport = false var showSupport = false
if (subscription.name.includes("default")) { if (subscription.name.includes("default")) {
top_text = "Custom Contract" top_text = "Custom Contract"
// newPaperstyle.border = "1px solid rgba(255,255,255,0.3)" newPaperstyle.border = "1px solid rgba(255,255,255,0.3)"
showSupport = true showSupport = true
} }
@@ -378,17 +377,16 @@ const Billing = memo((props) => {
if (subscription.name.includes("Scale")) { if (subscription.name.includes("Scale")) {
top_text = "Scale access" top_text = "Scale access"
setIsScale(true)
} }
if (highlight === true) { if (highlight === true) {
// Add an "Upgrade now" button // Add an "Upgrade now" button
// newPaperstyle.border = "1px solid rgba(255,255,255,0.3)" newPaperstyle.border = "1px solid rgba(255,255,255,0.3)"
} }
// if (hovered) { if (hovered) {
// newPaperstyle.backgroundColor = "#2b2b2b" newPaperstyle.backgroundColor = "#2b2b2b"
// } }
const handleClickOpen = () => { const handleClickOpen = () => {
setOpenChangeEmailBox(true); setOpenChangeEmailBox(true);
@@ -558,7 +556,6 @@ const Billing = memo((props) => {
</div> </div>
</DialogContent> </DialogContent>
</Dialog> </Dialog>
<Button style={{ backgroundColor: '#2F2F2F', color: "white", textTransform: "capitalize", borderRadius: 200, boxShadow: 'none', width: 144, height: 40 }}>Current Plan</Button>
<div style={{ display: "flex", width: 340 }}> <div style={{ display: "flex", width: 340 }}>
{top_text === "Base Cloud Access" && userdata.has_card_available === true ? {top_text === "Base Cloud Access" && userdata.has_card_available === true ?
<Chip <Chip
@@ -662,8 +659,8 @@ const Billing = memo((props) => {
<TextField <TextField
value={feature.split("Worker License: ")[1]} value={feature.split("Worker License: ")[1]}
style={{ style={{
backgroundColor: theme.palette.textFieldStyle.backgroundColor, backgroundColor: theme.palette.inputColor,
borderRadius: theme.palette?.textFieldStyle.borderRadius, borderRadius: theme.palette?.borderRadius,
}} }}
id={fieldId} id={fieldId}
onClick={() => { }} onClick={() => { }}
@@ -2016,33 +2013,7 @@ const Billing = memo((props) => {
</Typography> </Typography>
: null} : null}
<div style={{ display: "flex", width: clickedFromOrgTab ? "100%" : "auto", overflowX: 'auto', overflowY: 'hidden', scrollbarWidth: 'thin', scrollbarColor: '#494949 #2f2f2f', height: isChildOrg ? 0 : "100%", marginTop: 20}} > <div style={{ display: "flex", width: clickedFromOrgTab ? "100%" : "auto", overflowX: 'auto', overflowY: 'hidden', scrollbarWidth: 'thin', scrollbarColor: '#494949 #2f2f2f', height: isChildOrg ? 0 : "100%", maxWidth: 860, marginTop: 20}} >
<div style={{ display: "flex", flexDirection: "column", width: "100%", }}>
{isCloud &&
selectedOrganization.subscriptions !== undefined &&
selectedOrganization.subscriptions !== null &&
selectedOrganization.subscriptions.length > 0 &&
!isChildOrg ?
selectedOrganization.subscriptions
.reverse()
.map((sub, index) => {
return (
<SubscriptionObject
index={index + 1}
globalUrl={globalUrl}
userdata={userdata}
serverside={serverside}
billingInfo={billingInfo}
stripeKey={stripeKey}
selectedOrganization={selectedOrganization}
subscription={sub}
highlight={true}
/>
)
})
: null}
<div style={{ display: "flex", flexDirection: "row", width: "100%", marginTop: 20, marginBottom: 20, maxWidth: 860, }}>
{isCloud && billingInfo.subscription !== undefined && billingInfo.subscription !== null ? isChildOrg ? null : {isCloud && billingInfo.subscription !== undefined && billingInfo.subscription !== null ? isChildOrg ? null :
<LicencePopup <LicencePopup
serverside={serverside} serverside={serverside}
@@ -2055,7 +2026,6 @@ const Billing = memo((props) => {
isCloud={isCloud} isCloud={isCloud}
userdata={userdata} userdata={userdata}
stripeKey={stripeKey} stripeKey={stripeKey}
isScale={isScale}
{...props} {...props}
/> />
: !isCloud ? : !isCloud ?
@@ -2091,7 +2061,6 @@ const Billing = memo((props) => {
isCloud={isCloud} isCloud={isCloud}
userdata={userdata} userdata={userdata}
stripeKey={stripeKey} stripeKey={stripeKey}
isScale={isScale}
/> />
{/* <SubscriptionObject {/* <SubscriptionObject
@@ -2115,9 +2084,30 @@ const Billing = memo((props) => {
/> */} /> */}
</span> </span>
: null} : null}
</div>
</div>
{isCloud &&
selectedOrganization.subscriptions !== undefined &&
selectedOrganization.subscriptions !== null &&
selectedOrganization.subscriptions.length > 0 &&
!isChildOrg ?
selectedOrganization.subscriptions
.reverse()
.map((sub, index) => {
return (
<SubscriptionObject
index={index + 1}
globalUrl={globalUrl}
userdata={userdata}
serverside={serverside}
billingInfo={billingInfo}
stripeKey={stripeKey}
selectedOrganization={selectedOrganization}
subscription={sub}
highlight={true}
/>
)
})
: null}
{/* {/*
<Grid item key={index} xs={12/selectedOrganization.subscriptions.length}> <Grid item key={index} xs={12/selectedOrganization.subscriptions.length}>
<Card <Card
@@ -2163,6 +2153,7 @@ const Billing = memo((props) => {
*/} */}
</div> </div>
{/*isCloud && {/*isCloud &&
selectedOrganization.partner_info !== undefined && selectedOrganization.partner_info !== undefined &&
selectedOrganization.partner_info.reseller === true ? ( selectedOrganization.partner_info.reseller === true ? (
+3 -12
View File
@@ -577,20 +577,12 @@ const EditWorkflow = (props) => {
<Typography variant="h4" style={{ marginTop: 50, }}> <Typography variant="h4" style={{ marginTop: 50, }}>
Multi-Tenancy, Backups & Security Multi-Tenancy, Backups & Security
</Typography> </Typography>
<Typography variant="body2" color="textSecondary" style={{ marginTop: 30, marginBottom: 10, }}> <Typography variant="body2" color="textSecondary" style={{ marginTop: 30, marginBottom: 10, }}>
Control mechanisms for multi-tenancy, backups, and security. Multi-Tenant Workflows. Make one workflow, and keep a separate, synced copy in all your tenants. Control distributed auth, runtime locations, files, datastore keys etc. (contact support@shuffler.io if you want a demo. Please try it!)
</Typography> </Typography>
<Typography variant="h6" style={{ marginTop: 50, }}> {userdata !== undefined && userdata !== null && userdata.orgs !== undefined && userdata.orgs !== null && userdata.orgs.length > 0 ?
Multi-Tenant Workflows
</Typography>
<Typography variant="body2" color="textSecondary" style={{ marginTop: 10, marginBottom: 10, }}>
Make one workflow, and keep a separate, synced copy in your other tenants. Control distributed auth, runtime locations, files, datastore keys etc. Can only distribute from parent org to child org. Need help trying it? <a href="https://shuffler.io/contact" target="_blank" style={{color: "#f85a3e", textDecoration: "none",}}>Contact us for a demo</a>
</Typography>
{userdata !== undefined && userdata !== null && userdata.orgs !== undefined && userdata.orgs !== null && userdata.orgs.length > 0 ?
userdata.orgs.filter(org => org.creator_org === userdata.active_org.id).length === 0 ? userdata.orgs.filter(org => org.creator_org === userdata.active_org.id).length === 0 ?
userdata.active_org.creator_org === undefined || userdata.active_org.creator_org === null || userdata.active_org.creator_org === "" ? userdata.active_org.creator_org === undefined || userdata.active_org.creator_org === null || userdata.active_org.creator_org === "" ?
<Typography variant="body2" style={{ marginTop: 10, color: "rgba(255,255,255,0.7)" }}> <Typography variant="body2" style={{ marginTop: 10, color: "rgba(255,255,255,0.7)" }}>
@@ -608,7 +600,6 @@ const EditWorkflow = (props) => {
multiple multiple
style={{ marginTop: 10, }} style={{ marginTop: 10, }}
value={innerWorkflow.suborg_distribution === undefined || innerWorkflow.suborg_distribution === null ? ["none"] : innerWorkflow.suborg_distribution} value={innerWorkflow.suborg_distribution === undefined || innerWorkflow.suborg_distribution === null ? ["none"] : innerWorkflow.suborg_distribution}
disabled={workflow?.parentorg_workflow !== undefined && workflow?.parentorg_workflow !== null && workflow?.parentorg_workflow.length > 0}
onChange={(e) => { onChange={(e) => {
var newvalue = e.target.value var newvalue = e.target.value
if (newvalue.length > 1 && newvalue[0] === "none") { if (newvalue.length > 1 && newvalue[0] === "none") {
+14 -56
View File
@@ -46,7 +46,7 @@ import { handlePayasyougo } from "../views/HandlePaymentNew.jsx"
import Billing from "./Billing.jsx"; import Billing from "./Billing.jsx";
const LicencePopup = (props) => { const LicencePopup = (props) => {
const { globalUrl, userdata, serverside, billingInfo, stripeKey, setModalOpen, isScale, isLoggedIn, isMobile, selectedOrganization, isCloud } = props; const { globalUrl, userdata, serverside, billingInfo, stripeKey, setModalOpen, isLoggedIn, isMobile, selectedOrganization, isCloud } = props;
//const alert = useAlert(); //const alert = useAlert();
let navigate = useNavigate(); let navigate = useNavigate();
const [selectedDealModalOpen, setSelectedDealModalOpen] = React.useState(false); const [selectedDealModalOpen, setSelectedDealModalOpen] = React.useState(false);
@@ -165,25 +165,11 @@ const LicencePopup = (props) => {
] ]
} }
if (userdata?.app_execution_limit >= 300000) {
subscription.name = "Enterprise"
subscription.currency_text = "$"
subscription.price = typecost_single
subscription.limit = userdata?.app_execution_limit
subscription.interval = "app run / month"
subscription.features = [
"Includes " + (userdata?.app_execution_limit/1000) + "K app runs/month. ",
"Multi-Tenancy and Region-Selection",
"And all other features from /pricing",
]
}
var newPaperstyle = JSON.parse(JSON.stringify(paperStyle)) var newPaperstyle = JSON.parse(JSON.stringify(paperStyle))
if (subscription.name === "Enterprise" && subscription.active === true) { if (subscription.name === "Enterprise" && subscription.active === true) {
top_text = "Enterprise Plan" top_text = "Current Plan"
// newPaperstyle.border = "1px solid #f85a3e" newPaperstyle.border = "1px solid #f85a3e"
} }
var showSupport = false var showSupport = false
@@ -269,7 +255,7 @@ const LicencePopup = (props) => {
style={{ borderRadius: theme.palette?.borderRadius, }} style={{ borderRadius: theme.palette?.borderRadius, }}
placement="bottom" placement="bottom"
> >
<div style={{ backgroundColor: "#1e1e1e"}}> <div style={{}}>
<Paper <Paper
style={newPaperstyle} style={newPaperstyle}
// onMouseEnter={() => setHovered(true)} // onMouseEnter={() => setHovered(true)}
@@ -357,9 +343,9 @@ const LicencePopup = (props) => {
</div> </div>
</DialogContent> </DialogContent>
</Dialog> </Dialog>
{subscription.active === true && !isScale && <Button style={{ backgroundColor: '#2F2F2F', color: "white", textTransform: "capitalize", borderRadius: 200, boxShadow: 'none', width: 144, height: 40 }}>Current Plan</Button> } <Button style={{ backgroundColor: '#2F2F2F', color: "white", textTransform: "capitalize", borderRadius: 200, boxShadow: 'none', width: 144, height: 40 }}>Current Plan</Button>
<div style={{ display: "flex" }}> <div style={{ display: "flex" }}>
{top_text === "Base Cloud Access" && userdata.has_card_available === true && !isScale ? {top_text === "Base Cloud Access" && userdata.has_card_available === true ?
<Chip <Chip
style={{ style={{
backgroundColor: "#f86a3e", backgroundColor: "#f86a3e",
@@ -525,10 +511,7 @@ const LicencePopup = (props) => {
"While you have a card attached to your account, Shuffle will no longer prevent workflows from running. Billing will occur at the start of each month." "While you have a card attached to your account, Shuffle will no longer prevent workflows from running. Billing will occur at the start of each month."
: :
isCloud ? isCloud ?
userdata?.app_execution_limit && userdata?.app_execution_limit >= 300000 ? `You are not subscribed to any plan and are using the free plan with max 10,000 app runs per month. Upgrade to deactivate this limit.`
"You have subscribed to the Enterprise plan, which includes " + (userdata?.app_execution_limit/1000) + "K app runs/month. You can increase the limit by upgrading current plan. Contact support@shuffler.io for more information." :
`You are not subscribed to any plan and are using the free plan with max 10,000 app runs per month. Upgrade to deactivate this limit.`
: :
`You are not subscribed to any plan and are using the free, open source plan. This plan has no enforced limits, but scale issues may occur due to CPU congestion.` `You are not subscribed to any plan and are using the free, open source plan. This plan has no enforced limits, but scale issues may occur due to CPU congestion.`
} }
@@ -716,33 +699,8 @@ const LicencePopup = (props) => {
setCalculatedCost("$960") setCalculatedCost("$960")
setSelectedValue(8) setSelectedValue(8)
} else { } else {
if (userdata && userdata?.app_execution_limit) { setCalculatedCost("$960")
if (userdata.app_execution_limit >= 300000 && userdata.app_execution_limit < 400000) { setSelectedValue(300)
setSelectedValue(400)
setCalculatedCost("$1280")
}else if (userdata?.app_execution_limit >= 400000 && userdata?.app_execution_limit < 500000) {
setSelectedValue(500)
setCalculatedCost("$1600")
} else if (userdata?.app_execution_limit >= 500000 && userdata?.app_execution_limit < 600000) {
setSelectedValue(600)
setCalculatedCost("$1920")
} else if (userdata?.app_execution_limit >= 600000 && userdata?.app_execution_limit < 700000) {
setSelectedValue(700)
setCalculatedCost("$2240")
} else if (userdata?.app_execution_limit >= 700000 && userdata?.app_execution_limit < 800000) {
setSelectedValue(800)
setCalculatedCost("$2560")
} else if (userdata?.app_execution_limit >= 800000 && userdata?.app_execution_limit < 900000) {
setSelectedValue(900)
setCalculatedCost("$2880")
}else {
setCalculatedCost("$960")
setSelectedValue(300)
}
}else {
setCalculatedCost("$960")
setSelectedValue(300)
}
} }
}, [shuffleVariant]) }, [shuffleVariant])
@@ -1019,7 +977,7 @@ const LicencePopup = (props) => {
</span> </span>
: null} : null}
{/* {isCloud && {isCloud &&
selectedOrganization.subscriptions !== undefined && selectedOrganization.subscriptions !== undefined &&
selectedOrganization.subscriptions !== null && selectedOrganization.subscriptions !== null &&
selectedOrganization.subscriptions.length > 0 ? selectedOrganization.subscriptions.length > 0 ?
@@ -1040,7 +998,7 @@ const LicencePopup = (props) => {
/> />
) )
}) })
: null} */} : null}
</Grid> </Grid>
<Grid item xs={8}> <Grid item xs={8}>
<Grid style={{}}> <Grid style={{}}>
@@ -1048,12 +1006,12 @@ const LicencePopup = (props) => {
<Card style={{ <Card style={{
padding: 20, padding: 20,
borderRadius: theme.palette?.borderRadius, borderRadius: theme.palette?.borderRadius,
border: !isScale ? "1px solid #f85a3e" : 'none', border: "1px solid #f85a3e",
}}> }}>
<div> <div>
{ !isScale && <Button style={{ backgroundColor: 'rgba(255, 132, 68, 0.2)', color: "#FF8444", textTransform: "capitalize", borderRadius: 200, boxShadow: 'none', }} <Button style={{ backgroundColor: 'rgba(255, 132, 68, 0.2)', color: "#FF8444", textTransform: "capitalize", borderRadius: 200, boxShadow: 'none', }}
variant="contained" variant="contained"
color="primary">Recommended </Button> } color="primary">Recommended </Button>
</div> </div>
<Typography variant="h6" style={{ marginTop: 10, marginBottom: 10, flex: 5, }}>{shuffleVariant === 1 ? "Scale" : "Enterprise"}</Typography> <Typography variant="h6" style={{ marginTop: 10, marginBottom: 10, flex: 5, }}>{shuffleVariant === 1 ? "Scale" : "Enterprise"}</Typography>
+1 -1
View File
@@ -47,7 +47,7 @@ const menuData = {
title: "Shuffle", title: "Shuffle",
description: description:
"The most versatile automation engine with focus on security.", "The most versatile automation engine with focus on security.",
icon: "images/icons/shuffleLogo.svg", icon: "images/logos/orange_logo.svg",
path: "/docs/about", path: "/docs/about",
gaData: { gaData: {
category: "navbar", category: "navbar",
+33 -101
View File
@@ -575,17 +575,11 @@ const AngularWorkflow = (defaultprops) => {
}, [editWorkflowModalOpen]) }, [editWorkflowModalOpen])
useEffect(() => { useEffect(() => {
// Check if selectedTriggerIndex is a number >= 0 if(selectedTrigger?.trigger_type === "SUBFLOW"){
if (isNaN(selectedTriggerIndex) || selectedTriggerIndex < 0) {
return
}
if (selectedTrigger?.trigger_type === "SUBFLOW" && selectedTriggerIndex !== undefined && selectedTriggerIndex !== null && workflow?.triggers[selectedTriggerIndex].parameters.length > 1) {
setSelectedTriggerValue(workflow.triggers[selectedTriggerIndex].parameters[1].value || "") setSelectedTriggerValue(workflow.triggers[selectedTriggerIndex].parameters[1].value || "")
} else if (selectedTrigger?.trigger_type === "USERINPUT" && selectedTriggerIndex !== undefined && selectedTriggerIndex !== null && workflow?.triggers[selectedTriggerIndex].parameters.length > 0) { } else if(selectedTrigger?.trigger_type === "USERINPUT"){
setSelectedTriggerValue(workflow.triggers[selectedTriggerIndex].parameters[0].value || "Do you want to continue the workflow? Start parameters: $exec") setSelectedTriggerValue(workflow.triggers[selectedTriggerIndex].parameters[0].value || "Do you want to continue the workflow? Start parameters: $exec")
} }
}, [selectedTriggerIndex, selectedTrigger, workflow]) }, [selectedTriggerIndex, selectedTrigger, workflow])
useEffect(() => { useEffect(() => {
@@ -954,15 +948,11 @@ const AngularWorkflow = (defaultprops) => {
} }
useEffect(() => { useEffect(() => {
if (workflow?.actions?.length == 1) { if (workflow.actions?.length == 1) {
if (workflow?.actions[0].app_id == "3e320a20966d33c9b7e6790b2705f0bf") { if (workflow.actions[0].app_id == "3e320a20966d33c9b7e6790b2705f0bf") {
setWorkflowAsCode(true); setWorkflowAsCode(true);
} }
} }
if (workflow?.suborg_distribution !== undefined && workflow?.suborg_distribution !== null && workflow?.suborg_distribution.length > 0) {
getChildWorkflows(workflow.id)
}
}, [workflow]); }, [workflow]);
// Event for making sure app is correct // Event for making sure app is correct
@@ -1505,8 +1495,6 @@ const AngularWorkflow = (defaultprops) => {
if (workflow.org_id !== undefined && workflow.org_id !== null && workflow.org_id.length > 0) { if (workflow.org_id !== undefined && workflow.org_id !== null && workflow.org_id.length > 0) {
headers["Org-Id"] = workflow.org_id headers["Org-Id"] = workflow.org_id
} }
setWorkflows([])
fetch(globalUrl + "/api/v1/workflows?subflow=true", { fetch(globalUrl + "/api/v1/workflows?subflow=true", {
method: "GET", method: "GET",
@@ -1524,7 +1512,7 @@ const AngularWorkflow = (defaultprops) => {
if (responseJson !== undefined) { if (responseJson !== undefined) {
// Sets up subflow trigger with the right info // Sets up subflow trigger with the right info
if (isNaN(trigger_index) === false && trigger_index > -1) { if (trigger_index > -1) {
var baseSubflow = {} var baseSubflow = {}
const trigger = workflow.triggers[trigger_index]; const trigger = workflow.triggers[trigger_index];
@@ -2506,19 +2494,15 @@ const AngularWorkflow = (defaultprops) => {
if (cy !== undefined && cy !== null) { if (cy !== undefined && cy !== null) {
// scale: 0.3, // scale: 0.3,
// bg: "#27292d", // bg: "#27292d",
if (cy?.png !== undefined && cy?.png !== null) { if (cy.png !== undefined && cy.png !== null) {
try { const cyImageData = cy.png({
const cyImageData = cy.png({ output: "base64uri",
output: "base64uri", maxWidth: 480,
maxWidth: 480, maxHeight: 270,
maxHeight: 270, })
})
if (cyImageData !== undefined && cyImageData !== null && cyImageData.length > 0) { if (cyImageData !== undefined && cyImageData !== null && cyImageData.length > 0) {
useworkflow.image = cyImageData useworkflow.image = cyImageData
}
} catch (e) {
console.log("Failed to get image data: ", e)
} }
} }
} }
@@ -3930,10 +3914,6 @@ const AngularWorkflow = (defaultprops) => {
} }
const findWorkflowDiff = (parentWorkflow, childWorkflow) => { const findWorkflowDiff = (parentWorkflow, childWorkflow) => {
// Ensures new memory is used
parentWorkflow = JSON.parse(JSON.stringify(parentWorkflow))
childWorkflow = JSON.parse(JSON.stringify(childWorkflow))
var diff = { var diff = {
"different": false, "different": false,
"environment": false, "environment": false,
@@ -3951,13 +3931,9 @@ const AngularWorkflow = (defaultprops) => {
return diff return diff
} }
var parentEnvironment = "" var parentEnvironment = ""
var childEnvironment = "" var childEnvironment = ""
if (parentWorkflow.triggers !== undefined && parentWorkflow.triggers !== null && parentWorkflow.triggers.length > 0) {
parentWorkflow.actions = parentWorkflow.actions.concat(parentWorkflow.triggers)
}
for (var parentKey in parentWorkflow.actions) { for (var parentKey in parentWorkflow.actions) {
const parentAction = parentWorkflow.actions[parentKey] const parentAction = parentWorkflow.actions[parentKey]
if (parentAction.environment !== undefined && parentAction.environment !== null && parentAction.environment !== "") { if (parentAction.environment !== undefined && parentAction.environment !== null && parentAction.environment !== "") {
@@ -3969,19 +3945,6 @@ const AngularWorkflow = (defaultprops) => {
} }
var found = false var found = false
if (childWorkflow.triggers !== undefined && childWorkflow.triggers !== null && childWorkflow.triggers.length > 0) {
for (var triggerKey in childWorkflow.triggers) {
if (childWorkflow.triggers[triggerKey].replacement_for_trigger !== parentAction.id) {
continue
}
// Rewrapping the ID just in case
childWorkflow.triggers[triggerKey].id = childWorkflow.triggers[triggerKey].replacement_for_trigger
childWorkflow.actions.push(childWorkflow.triggers[triggerKey])
break
}
}
for (var childKey in childWorkflow.actions) { for (var childKey in childWorkflow.actions) {
const childAction = childWorkflow.actions[childKey] const childAction = childWorkflow.actions[childKey]
if (childAction.environment !== undefined && childAction.environment !== null && childAction.environment !== "") { if (childAction.environment !== undefined && childAction.environment !== null && childAction.environment !== "") {
@@ -4028,10 +3991,6 @@ const AngularWorkflow = (defaultprops) => {
continue continue
} }
var parentworkflow = ""
var parentstartnode = ""
var childworkflow = ""
var childstartnode = ""
for (var parentParamIndex in parentAction.parameters) { for (var parentParamIndex in parentAction.parameters) {
const parentParam = parentAction.parameters[parentParamIndex] const parentParam = parentAction.parameters[parentParamIndex]
for (var childParamIndex in childAction.parameters) { for (var childParamIndex in childAction.parameters) {
@@ -4040,38 +3999,20 @@ const AngularWorkflow = (defaultprops) => {
continue continue
} }
if (childParam.name === "workflow" || childParam.name === "subflow") {
parentworkflow = parentParam.value
childworkflow = childParam.value
continue
}
if (childParam.name == "startnode") {
parentstartnode = parentParam.value
childstartnode = childParam.value
continue
}
if (childParam.value !== parentParam.value) { if (childParam.value !== parentParam.value) {
actionDiff.parameters.push(childParam.name) actionDiff.parameters.push(childParam.name)
} }
} }
} }
if (parentworkflow !== childworkflow && parentstartnode !== childstartnode) {
actionDiff.parameters.push("subflow")
}
} }
if (actionDiff.parameters.length > 0) { if (actionDiff.parameters.length > 0) {
actionDiff.params = true actionDiff.params = true
} }
/*
if (!found) { if (!found) {
actionDiff.new = true actionDiff.new = true
} }
*/
if (actionDiff !== undefined && actionDiff !== null && Object.keys(actionDiff).length > 1) { if (actionDiff !== undefined && actionDiff !== null && Object.keys(actionDiff).length > 1) {
actionDiff.label = parentAction.label.replaceAll("_", " ") actionDiff.label = parentAction.label.replaceAll("_", " ")
@@ -6364,15 +6305,11 @@ const AngularWorkflow = (defaultprops) => {
if (workflow.org_id !== undefined && workflow.org_id !== null && workflow.org_id.length > 0 && originalWorkflow.org_id !== undefined && originalWorkflow.org_id !== null && originalWorkflow.org_id.length > 0 && workflow.org_id === originalWorkflow.org_id) { if (workflow.org_id !== undefined && workflow.org_id !== null && workflow.org_id.length > 0 && originalWorkflow.org_id !== undefined && originalWorkflow.org_id !== null && originalWorkflow.org_id.length > 0 && workflow.org_id === originalWorkflow.org_id) {
// Allows a parent workflow to control the schedule // Allows a parent workflow to control the schedule
} else if (data.replacement_for_trigger !== undefined && data.replacement_for_trigger !== null && data.replacement_for_trigger.length > 0) { } else if (data.replacement_for_trigger !== undefined && data.replacement_for_trigger !== null && data.replacement_for_trigger.length > 0) {
toast.warning("This schedule is controlled by the parent workflow. If you want additional schedule control, please add a custom schedule to this workflow.", {
// No custom control on cloud autoClose: 30000,
if (isCloud) { })
toast.warning("This schedule is controlled by the parent workflow. If you want additional schedule control, please add a custom schedule to this workflow.", { event.target.unselect()
autoClose: 30000, return
})
event.target.unselect()
return
}
} }
} else if (data.app_name === "Webhook" && trigger_index >= 0) { } else if (data.app_name === "Webhook" && trigger_index >= 0) {
@@ -6948,7 +6885,7 @@ const AngularWorkflow = (defaultprops) => {
) )
if (targetnode !== -1) { if (targetnode !== -1) {
if (workflow.triggers[targetnode].app_name === "User Input" || workflow.triggers[targetnode].app_name === "Shuffle Workflow" || workflow.triggers[targetnode].app_name === "Shuffle Subflow") { if (workflow.triggers[targetnode].app_name === "User Input" || workflow.triggers[targetnode].app_name === "Shuffle Workflow" || workflow.triggers[targetnode].app_name === "Shuffle Subflow") {
//console.log("User Input or Shuffle Workflow") console.log("User Input or Shuffle Workflow")
} else { } else {
toast("Can't have triggers as target of branch") toast("Can't have triggers as target of branch")
event.target.remove() event.target.remove()
@@ -9280,15 +9217,11 @@ const AngularWorkflow = (defaultprops) => {
} }
insertedNodes = insertedNodes.concat(newedges); insertedNodes = insertedNodes.concat(newedges);
setWorkflow(inputworkflow) setWorkflow(inputworkflow);
// Reset view for cytoscape // Reset view for cytoscape
if (cy !== undefined && cy !== null) { if (cy !== undefined && cy !== null) {
try { cy.add(insertedNodes)
cy.add(insertedNodes)
} catch (error) {
console.log("Error adding nodes to cytoscape (6): ", error)
}
try { try {
cy.fit(null, 250) cy.fit(null, 250)
@@ -9367,6 +9300,12 @@ const AngularWorkflow = (defaultprops) => {
} }
} }
//if (selectedNode.data("id") === selectedAction.id) {
// setSelectedApp({});
// setSelectedAction({});
//setSelectedTrigger({});
//setSelectedTriggerIndex({});
//}
const parsedSelection = cy.$(":selected"); const parsedSelection = cy.$(":selected");
if (selectedNode.data().decorator === true && selectedNode.data("type") !== "COMMENT") { if (selectedNode.data().decorator === true && selectedNode.data("type") !== "COMMENT") {
toast("This node can't be deleted."); toast("This node can't be deleted.");
@@ -9566,6 +9505,7 @@ const AngularWorkflow = (defaultprops) => {
if (firstrequest) { if (firstrequest) {
setFirstrequest(false) setFirstrequest(false)
getWorkflow(props.match.params.key, {}) getWorkflow(props.match.params.key, {})
getChildWorkflows(props.match.params.key)
getRevisionHistory(props.match.params.key) getRevisionHistory(props.match.params.key)
loadTriggers() loadTriggers()
getApps() getApps()
@@ -14951,15 +14891,12 @@ const AngularWorkflow = (defaultprops) => {
}} }}
> >
<div style={{ flex: "10" }}> <div style={{ flex: "10" }}>
<b>Select a workflow to run</b> <b>Select a workflow to execute </b>
</div> </div>
</div> </div>
{workflow.triggers[selectedTriggerIndex].parameters[0].value {workflow.triggers[selectedTriggerIndex].parameters[0].value
.length === 0 ? null : workflow.triggers[selectedTriggerIndex] .length === 0 ? null : workflow.triggers[selectedTriggerIndex]
.parameters[0].value === props.match.params.key ? .parameters[0].value === props.match.params.key ? null : (
null
: (
<div style={{ marginLeft: 5, flex: 1 }}> <div style={{ marginLeft: 5, flex: 1 }}>
<a <a
rel="noopener noreferrer" rel="noopener noreferrer"
@@ -14980,9 +14917,8 @@ const AngularWorkflow = (defaultprops) => {
{workflows === undefined || {workflows === undefined ||
workflows === null || workflows === null ||
workflows.length === 0 ? workflows.length === 0 ? null : (
<CircularProgress color="secondary" style={{ margin: "auto", marginTop: 10, width: 25, height: 25, }} />
: (
<Autocomplete <Autocomplete
id="subflow_search" id="subflow_search"
autoHighlight autoHighlight
@@ -18239,10 +18175,6 @@ const AngularWorkflow = (defaultprops) => {
value={workflow.org_id} value={workflow.org_id}
disabled={savingState !== 0 || suborgWorkflows?.length === 0 || allTriggers === undefined} disabled={savingState !== 0 || suborgWorkflows?.length === 0 || allTriggers === undefined}
onChange={(e) => { onChange={(e) => {
if (cy !== undefined && cy !== null) {
cy.nodes().unselect()
}
if (lastSaved === false && originalWorkflow.id === workflow.id) { if (lastSaved === false && originalWorkflow.id === workflow.id) {
setSuborgWorkflows([]) setSuborgWorkflows([])
+10 -10
View File
@@ -427,14 +427,14 @@ const LoginPage = props => {
window.location.pathname = "/workflows" window.location.pathname = "/workflows"
} }
const checkAdmin = () => { const checkAdmin = () => {
const url = globalUrl + "/api/v1/checkusers"; const url = globalUrl + "/api/v1/checkusers";
fetch(url, { fetch(url, {
method: "GET", method: "GET",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
}, },
}) })
.then((response) => .then((response) =>
response.json().then((responseJson) => { response.json().then((responseJson) => {
if (responseJson["success"] === false) { if (responseJson["success"] === false) {
@@ -459,7 +459,7 @@ const LoginPage = props => {
navigate("/adminsetup") navigate("/adminsetup")
}, 2500) }, 2500)
}) })
} };
const onSubmit = (e) => { const onSubmit = (e) => {
@@ -952,7 +952,7 @@ const LoginPage = props => {
</div> </div>
return ( return (
<div style={{zoom: 0.8, paddingTop: 75, paddingBottom: 90 }}> <div style={{zoom: 0.8, paddingTop: 150, paddingBottom: 90 }}>
{loadedCheck} {loadedCheck}
</div> </div>
) )
+1 -4
View File
@@ -1946,10 +1946,7 @@ const Workflows = (props) => {
.then((response) => { .then((response) => {
if (response.status !== 200) { if (response.status !== 200) {
console.log("Status not 200 for setting workflows :O!"); console.log("Status not 200 for setting workflows :O!");
toast("Failed deleting workflow. Do you have access?");
if (bulk !== true) {
toast(`Failed deleting workflow ${id}. Do you have access?`);
}
} else { } else {
if (bulk !== true) { if (bulk !== true) {
toast(`Deleted workflow ${id}. Child Workflows in Suborgs were also removed.`) toast(`Deleted workflow ${id}. Child Workflows in Suborgs were also removed.`)
+5 -9
View File
@@ -2043,10 +2043,7 @@ const Workflows2 = (props) => {
.then((response) => { .then((response) => {
if (response.status !== 200) { if (response.status !== 200) {
console.log("Status not 200 for setting workflows :O!"); console.log("Status not 200 for setting workflows :O!");
toast("Failed deleting workflow. Do you have access?");
if (bulk !== true) {
toast("Failed deleting workflow. Do you have access?");
}
} else { } else {
if (bulk !== true) { if (bulk !== true) {
toast(`Deleted workflow ${id}. Child Workflows in Suborgs were also removed.`) toast(`Deleted workflow ${id}. Child Workflows in Suborgs were also removed.`)
@@ -2824,7 +2821,7 @@ const Workflows2 = (props) => {
{(data.sharing !== undefined && data.sharing !== null && data.sharing === "form") || (data?.form_control?.input_markdown !== undefined && data?.form_control?.input_markdown !== null && data?.form_control?.input_markdown !== "") && type !== "public" ? {(data.sharing !== undefined && data.sharing !== null && data.sharing === "form") || (data?.form_control?.input_markdown !== undefined && data?.form_control?.input_markdown !== null && data?.form_control?.input_markdown !== "") && type !== "public" ?
<Tooltip title="Edit Form" placement="top"> <Tooltip title="Edit Form" placement="top">
<div style={{ position: "absolute", top: 50, right: 8, }}> <div style={{ position: "absolute", top: 45, right: 8, }}>
<IconButton <IconButton
aria-label="more" aria-label="more"
aria-controls="long-menu" aria-controls="long-menu"
@@ -2841,8 +2838,8 @@ const Workflows2 = (props) => {
: null} : null}
{(data?.validation?.validation_ran === true && data?.validation?.valid === false && data?.validation?.errors?.length > 0 ) ? {(data?.validation?.validation_ran === true && data?.validation?.valid === false && data?.validation?.errors?.length > 0 ) ?
<Tooltip title={`Explore more than ${data?.validation?.errors?.length} notifications. When the last execution finishes without errors AND notifications stop occuring, this icon disappears.`} placement="top"> <Tooltip title={`Explore more than ${data?.validation?.errors?.length} errors. When the last execution finishes without errors AND notifications stop occuring, this icon disappears.`} placement="top">
<div style={{ position: "absolute", top: 85, right: 8, }}> <div style={{ position: "absolute", top: 45, right: 8, }}>
<IconButton <IconButton
aria-label="more" aria-label="more"
aria-controls="long-menu" aria-controls="long-menu"
@@ -2861,8 +2858,8 @@ const Workflows2 = (props) => {
</IconButton> </IconButton>
</div> </div>
</Tooltip> </Tooltip>
: null}
: null}
</Grid> </Grid>
</Paper> </Paper>
</div> </div>
@@ -3238,7 +3235,6 @@ const Workflows2 = (props) => {
</span> </span>
</Tooltip> </Tooltip>
} }
<Tooltip <Tooltip
color="primary" color="primary"
title="Amount of triggers" title="Amount of triggers"