Multiple minor fixes for 2.0.1 release to improve general usability

This commit is contained in:
Frikky
2025-03-21 02:03:19 +01:00
parent f3d547b875
commit 373e5bc909
12 changed files with 145 additions and 76 deletions
+7 -3
View File
@@ -526,7 +526,7 @@ const LeftSideBar = ({ userdata, serverside, globalUrl, notifications, }) => {
<Divider style={{ marginBottom: 10, }} /> <Divider style={{ marginBottom: 10, }} />
<Typography color="textSecondary" align="center" style={{ marginTop: 5, marginBottom: 5, fontSize: 18 }}> <Typography color="textSecondary" align="center" style={{ marginTop: 5, marginBottom: 5, fontSize: 18 }}>
Version: 2.0.0 Version: 2.0.1
</Typography> </Typography>
</Menu> </Menu>
</span> </span>
@@ -773,6 +773,9 @@ const LeftSideBar = ({ userdata, serverside, globalUrl, notifications, }) => {
}, [window?.location?.pathname]); }, [window?.location?.pathname]);
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
return ( return (
<div <div
style={{ style={{
@@ -785,8 +788,9 @@ const LeftSideBar = ({ userdata, serverside, globalUrl, notifications, }) => {
transition: "width 0.3s ease", transition: "width 0.3s ease",
boxShadow: "0px 4px 12px rgba(0, 0, 0, 0.2)" , boxShadow: "0px 4px 12px rgba(0, 0, 0, 0.2)" ,
resize: 'both', resize: 'both',
zoom: isSafari ? undefined : 0.8,
zoom: 0.8, transform: isSafari ? "scale(0.8)" : undefined,
transformOrigin: isSafari ? "top left" : undefined,
height: "calc((100vh - 32px)*1.2)", height: "calc((100vh - 32px)*1.2)",
}} }}
> >
+7 -4
View File
@@ -909,21 +909,23 @@ const LicencePopup = (props) => {
const priceItem = const priceItem =
window.location.origin === "https://shuffler.io/" || "https://sandbox.shuffler.io/" window.location.origin === "https://shuffler.io/" || "https://sandbox.shuffler.io/"
? shuffleVariant === 0 ? shuffleVariant === 0
? "app_executions" ? "price_1PWI3uDzMUgUjxHSffUBwWCy"
: "cores" : "price_1PWI8EDzMUgUjxHSfEhUB7oL"
: shuffleVariant === 0 : shuffleVariant === 0
? "price_1PZPSSEJjT17t98NLJoTMYja" ? "price_1PZPSSEJjT17t98NLJoTMYja"
: "price_1PZPQuEJjT17t98N3yORUtd9"; : "price_1PZPQuEJjT17t98N3yORUtd9";
const successUrl = `${window.location.origin}/admin?admin_tab=billingstats&payment=success` const successUrl = `${window.location.origin}/admin?admin_tab=billingstats&payment=success`
const failUrl = `${window.location.origin}/admin?admin_tab=billingstats&payment=failure` const failUrl = `${window.location.origin}/admin?admin_tab=billingstats&payment=failure`
const quantity = shuffleVariant === 0 ? selectedValue / 100 : selectedValue
console.log("Priceitem: ", priceItem, shuffleVariant) console.log("Priceitem: ", priceItem, quantity, shuffleVariant)
var checkoutObject = { var checkoutObject = {
lineItems: [ lineItems: [
{ {
price: priceItem, price: priceItem,
quantity: shuffleVariant === 0 ? selectedValue / 100 : selectedValue, quantity: quantity,
}, },
], ],
mode: "subscription", mode: "subscription",
@@ -1141,6 +1143,7 @@ const LicencePopup = (props) => {
> >
View all plans View all plans
</Button> </Button>
<Button <Button
variant="contained" variant="contained"
style={{ borderRadius: 4, textTransform: "capitalize", color: "#1a1a1a", backgroundColor: "#ff8544", width: "100%", fontSize: 16}} style={{ borderRadius: 4, textTransform: "capitalize", color: "#1a1a1a", backgroundColor: "#ff8544", width: "100%", fontSize: 16}}
+1 -1
View File
@@ -48,7 +48,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/icons/shuffleLogo.svg",
path: "/docs/about", path: "/docs/about",
gaData: { gaData: {
category: "navbar", category: "navbar",
@@ -307,17 +307,16 @@ const OrgHeaderexpandedNew = (props) => {
const setSelectedRegion = (region) => { const setSelectedRegion = (region) => {
// send a POST request to /api/v1/orgs/{org_id}/region with the region as the body // send a POST request to /api/v1/orgs/{org_id}/region with the region as the body
if (region === "US") { const regionMap = {
region = "us-west2" "US": "us-west2",
} else if (region === "EU") { "EU": "europe-west2",
region = "europe-west2" "CA": "northamerica-northeast1",
} else if (region === "CA") { "UK": "europe-west2",
region = "northamerica-northeast1" "EU-2": "europe-west3",
} else if (region === "UK") { "AUS": "australia-southeast1"
region = "europe-west2" };
} else if (region === "EU-2") {
region = "europe-west3" region = regionMap[region] || region;
}
var data = { var data = {
dst_region: region dst_region: region
@@ -336,7 +335,11 @@ const OrgHeaderexpandedNew = (props) => {
timeOut: 1000 timeOut: 1000
}).then((response) => { }).then((response) => {
if (response.status !== 200) { if (response.status !== 200) {
toast("Failed to change region!") response.json().then((reason) => {
toast.error("Failed to change region: " + reason.reason)
}).catch((err) => {
toast.error("Failed to change region")
});
} }
else { else {
toast("Region changed successfully! Reloading in 5 seconds..") toast("Region changed successfully! Reloading in 5 seconds..")
@@ -347,7 +350,7 @@ const OrgHeaderexpandedNew = (props) => {
} }
return response.json(); // return responseJson
}) })
} }
@@ -1091,6 +1094,7 @@ const RegionChangeModal = memo(({ selectedOrganization, setSelectedRegion, userd
"EU-2": "eu", "EU-2": "eu",
"CA": "ca", "CA": "ca",
"UK": "gb", "UK": "gb",
"AUS": "au",
}; };
//let regiontag = "UK"; //let regiontag = "UK";
@@ -1112,6 +1116,9 @@ const RegionChangeModal = memo(({ selectedOrganization, setSelectedRegion, userd
} else if (regiontag === "ca") { } else if (regiontag === "ca") {
regiontag = "CA"; regiontag = "CA";
regionCode = "ca"; regionCode = "ca";
} else if (regiontag === "austrailia") {
regiontag = "AUS";
regionCode = "au"
} }
} }
@@ -1124,11 +1131,12 @@ const RegionChangeModal = memo(({ selectedOrganization, setSelectedRegion, userd
value={regiontag} value={regiontag}
style={{ minWidth: 120, height: 35, borderRadius: 4 }} style={{ minWidth: 120, height: 35, borderRadius: 4 }}
onChange={(e) => { onChange={(e) => {
if (userdata?.support) { // if (userdata?.support) {
setSelectedRegion(e.target.value) // setSelectedRegion(e.target.value)
} else { // } else {
handleSendChangeRegionMail(e.target.value) // handleSendChangeRegionMail(e.target.value)
} // }
setSelectedRegion(e.target.value)
}} }}
> >
{Object.keys(regionMapping).map((region, index) => { {Object.keys(regionMapping).map((region, index) => {
@@ -1138,6 +1146,10 @@ const RegionChangeModal = memo(({ selectedOrganization, setSelectedRegion, userd
selectedOrganization.region = "europe-west2"; selectedOrganization.region = "europe-west2";
} }
if (region === "AUS") {
region = "AUS (test)"
}
// Check if the current region matches the selected region // Check if the current region matches the selected region
if (region === selectedOrganization.region) { if (region === selectedOrganization.region) {
// If the region matches, set the MenuItem as selected // If the region matches, set the MenuItem as selected
+1 -1
View File
@@ -2551,7 +2551,7 @@ const ParsedAction = (props) => {
{workflow.execution_variables !== undefined && workflow.execution_variables !== null && workflow.execution_variables.length > 0 ? ( {workflow.execution_variables !== undefined && workflow.execution_variables !== null && workflow.execution_variables.length > 0 ? (
<div style={{ marginTop: "20px" }}> <div style={{ marginTop: "20px" }}>
<Typography>Execution variable (optional)</Typography> <Typography color="textSecondary">Runtime variable (optional)</Typography>
<Select <Select
MenuProps={{ MenuProps={{
disableScrollLock: true, disableScrollLock: true,
@@ -2476,7 +2476,8 @@ const CodeEditor = (props) => {
var fixedcodedata = localcodedata var fixedcodedata = localcodedata
const valid = validateJson(localcodedata, true) const valid = validateJson(localcodedata, true)
if (valid.valid) { if (valid.valid) {
fixedcodedata = JSON.stringify(valid.result, null, 2) //fixedcodedata = JSON.stringify(valid.result, null, 2)
fixedcodedata = JSON.stringify(valid.result)
} }
// console.log(codedata) // console.log(codedata)
@@ -398,8 +398,9 @@ const WorkflowValidationTimeline = (props) => {
nodecolor = green nodecolor = green
branchcolor = green branchcolor = green
} else { } else {
nodecolor = grey // Green by default
branchcolor = grey nodecolor = green
branchcolor = green
} }
} else { } else {
nodecolor = green nodecolor = green
@@ -562,8 +563,6 @@ const WorkflowValidationTimeline = (props) => {
branchcolor = green branchcolor = green
} }
var flex = index !== 0 && index !== relevantactions.length - 1 ? 1 : 3 var flex = index !== 0 && index !== relevantactions.length - 1 ? 1 : 3
if (nodecolor === green) { if (nodecolor === green) {
branchcolor = green branchcolor = green
@@ -609,6 +608,8 @@ const WorkflowValidationTimeline = (props) => {
const ballsize = 8 const ballsize = 8
const topMargin = 20 const topMargin = 20
console.log("CHIP: ", index, chipColor, chipBackground)
const chipStyle = { const chipStyle = {
height: 40, height: 40,
minWidth: 125, minWidth: 125,
@@ -676,7 +677,6 @@ const WorkflowValidationTimeline = (props) => {
{founderror.length > 0 ? founderror : `App: ${appname} - Action: ${action.label}`} {founderror.length > 0 ? founderror : `App: ${appname} - Action: ${action.label}`}
</Typography> </Typography>
} placement="top"> } placement="top">
<Chip label={`${appname}`} style={chipStyle} icon={ <Chip label={`${appname}`} style={chipStyle} icon={
<Avatar <Avatar
variant="round" variant="round"
+1 -1
View File
@@ -81,7 +81,7 @@ const theme = createTheme(adaptV4Theme({
singulBlackWhite: "/images/singul_black_white.png", singulBlackWhite: "/images/singul_black_white.png",
}, },
typography: { typography: {
fontFamily: `"Roboto", "Helvetica", "Arial", "inter", sans-serif`, fontFamily: `"inter", "Roboto", "Helvetica", "Arial", sans-serif`,
useNextVariants: true, useNextVariants: true,
fontWeightLight: 300, fontWeightLight: 300,
fontWeightRegular: 400, fontWeightRegular: 400,
+72 -35
View File
@@ -386,6 +386,8 @@ const useStyles = makeStyles({
const splitter = "|~|"; const splitter = "|~|";
const svgSize = 24; const svgSize = 24;
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
//const referenceUrl = "https://shuffler.io/functions/webhooks/" //const referenceUrl = "https://shuffler.io/functions/webhooks/"
//const referenceUrl = window.location.origin+"/api/v1/hooks/" //const referenceUrl = window.location.origin+"/api/v1/hooks/"
@@ -1320,33 +1322,45 @@ const AngularWorkflow = (defaultprops) => {
const allTriggersInOne = useTriggers.pipelines.concat(useTriggers.schedules).concat(useTriggers.webhooks) const allTriggersInOne = useTriggers.pipelines.concat(useTriggers.schedules).concat(useTriggers.webhooks)
for (let triggerkey in allTriggersInOne) { for (let triggerkey in allTriggersInOne) {
const curtrigger = allTriggersInOne[triggerkey] const curtrigger = allTriggersInOne[triggerkey]
if (curtrigger.id === selectedTrigger.id) { if (curtrigger.id !== selectedTrigger.id) {
if (curtrigger.status === undefined || curtrigger.status === null) { continue
continue
}
if (curtrigger.running === undefined || curtrigger.running === null) {
continue
}
var changed = false
if (curtrigger.status !== selectedTrigger.status) {
changed = true
selectedTrigger.status = curtrigger.status
}
if (curtrigger.running !== selectedTrigger.running) {
changed = true
selectedTrigger.running = curtrigger.running
}
if (changed) {
//console.log("TRIGGER FIX: ", selectedTrigger)
setSelectedTrigger(selectedTrigger)
}
break
} }
if (curtrigger.status === undefined || curtrigger.status === null) {
continue
}
var changed = false
if (selectedTrigger?.parameters === undefined || selectedTrigger?.parameters === null) {
changed = true
if (selectedTrigger?.trigger_type === "SCHEDULE" && curtrigger?.frequency !== undefined && curtrigger?.frequency !== null) {
selectedTrigger.parameters = [{
name: "cron",
value: curtrigger.frequency,
},
{
name: "execution_argument",
value: curtrigger.argument,
}]
}
}
if (curtrigger.status !== selectedTrigger.status) {
changed = true
selectedTrigger.status = curtrigger.status
}
if (curtrigger.running !== selectedTrigger.running) {
changed = true
selectedTrigger.running = curtrigger.running
}
if (changed) {
setSelectedTrigger(selectedTrigger)
}
break
} }
} }
} }
@@ -2799,11 +2813,11 @@ const AngularWorkflow = (defaultprops) => {
// FIXME: Check if any node contains $exec in a param // FIXME: Check if any node contains $exec in a param
// If they do, show a popup asking if they want to execute it without an execution argument, or to use a previous one // If they do, show a popup asking if they want to execute it without an execution argument, or to use a previous one
if (skip_popup !== true && executionArgument === undefined || executionArgument === null || executionArgument.length === 0) if (skip_popup !== true && executionArgument === undefined || executionArgument === null || executionArgument?.length === 0)
if (workflow.actions !== undefined && workflow.actions !== null && workflow.actions.length > 0) { if (workflow?.actions !== undefined && workflow?.actions !== null && workflow?.actions?.length > 0) {
var foundmissing = false var foundmissing = false
for (let actionkey in workflow.actions) { for (let actionkey in workflow?.actions) {
if (workflow.actions[actionkey].parameters === undefined || workflow.actions[actionkey].parameters === null || workflow.actions[actionkey].parameters.length === 0) { if (workflow.actions[actionkey].parameters === undefined || workflow.actions[actionkey].parameters === null || workflow.actions[actionkey].parameters.length === 0) {
continue continue
} }
@@ -12236,7 +12250,9 @@ const AngularWorkflow = (defaultprops) => {
overflowAnchor: "none", overflowAnchor: "none",
minWidth: minSize, minWidth: minSize,
width: isMobile ? "100%" : minSize, width: isMobile ? "100%" : minSize,
zoom: 0.9, zoom: isSafari ? undefined : 0.9,
transform: isSafari ? "scale(0.9)" : undefined,
transformOrigin: isSafari ? "top right" : undefined,
}; };
const setTriggerFolderWrapperMulti = (event) => { const setTriggerFolderWrapperMulti = (event) => {
@@ -18011,10 +18027,10 @@ const AngularWorkflow = (defaultprops) => {
const topBarStyle = { const topBarStyle = {
position: "absolute", position: "absolute",
top: isMobile ? 30 : 25, top: isMobile ? 30 : isSafari ? 15 : 25,
transform: isMobile ? "translateX(20px)" : `translateX(${leftBarSize}px)`, transform: isMobile ? "translateX(20px)" : `translateX(${leftBarSize}px)`,
transition: "all 0.3s ease", transition: "all 0.3s ease",
zoom: 0.9, zoom: isSafari ? undefined : 0.9,
} }
const TopCytoscapeBar = (props) => { const TopCytoscapeBar = (props) => {
@@ -21834,13 +21850,23 @@ const AngularWorkflow = (defaultprops) => {
const cursearch = typeof window === "undefined" || window.location === undefined ? "" : window.location.search; const cursearch = typeof window === "undefined" || window.location === undefined ? "" : window.location.search;
const chosenNodeId = new URLSearchParams(cursearch).get("node"); const chosenNodeId = new URLSearchParams(cursearch).get("node");
const highlightNode = chosenNodeId !== null && chosenNodeId !== undefined && chosenNodeId !== "" && chosenNodeId === data.action.id const highlightNode = chosenNodeId !== null && chosenNodeId !== undefined && chosenNodeId !== "" && chosenNodeId === data.action.id
var relevant_errors = []
if (data?.action?.parameters !== undefined && data?.action?.parameters !== null && data?.action?.parameters.length > 0) {
for (var i = 0; i < data.action.parameters.length; i++) {
// Specific error patterns in params
const param = data.action.parameters[i]
if (param?.name?.endsWith("_error") && (param?.name?.startsWith("shuffle_") || param?.name?.startsWith("liquid_"))) {
relevant_errors.push(param)
}
}
}
return ( return (
<div <div
key={index} key={index}
style={{ style={{
marginBottom: 20, marginBottom: 20,
border: highlightNode ? "2px solid red" border: highlightNode ? `2px solid ${red}`
: :
data.action.sub_action === true data.action.sub_action === true
? "1px solid rgba(255,255,255,0.3)" ? "1px solid rgba(255,255,255,0.3)"
@@ -21913,11 +21939,17 @@ const AngularWorkflow = (defaultprops) => {
> >
<Tooltip <Tooltip
color="primary" color="primary"
title="Expand result window" title={
<Typography variant="body1">
Expand result window. Errors: {relevant_errors.length}
</Typography>
}
placement="top" placement="top"
style={{ zIndex: 50000 }} style={{ zIndex: 50000 }}
> >
<ArrowLeftIcon style={{ color: "white" }} /> <ArrowLeftIcon style={{
color: relevant_errors.length > 0 ? yellow : "rgba(255,255,255,0.7)",
}} />
</Tooltip> </Tooltip>
</IconButton> </IconButton>
{actionimg} {actionimg}
@@ -22087,6 +22119,11 @@ const AngularWorkflow = (defaultprops) => {
const checked = validateJson(data.value.trim()) const checked = validateJson(data.value.trim())
if (data.name === "shuffle_action_logs" && data.value !== undefined && data.value !== null && data.value.length > 0 && data.value.includes("add env SHUFFLE_LOGS_DISABLED")) { if (data.name === "shuffle_action_logs" && data.value !== undefined && data.value !== null && data.value.length > 0 && data.value.includes("add env SHUFFLE_LOGS_DISABLED")) {
if (isCloud) {
return null
}
return ( return (
<div style={{ maxWidth: 600, marginTop: 75, overflowX: "hidden", }}> <div style={{ maxWidth: 600, marginTop: 75, overflowX: "hidden", }}>
<Typography <Typography
+4 -3
View File
@@ -166,12 +166,13 @@ export const OuterLink = (props) => {
export const Img = (props) => { export const Img = (props) => {
// Find parent container and check width // Find parent container and check width
const isArticlePage = window.location.pathname.includes("/articles/"); const isArticlePage = window.location.pathname.includes("/articles/")
const isFormPage = window.location.pathname.includes("/forms/")
var height = "auto" var height = "auto"
var width = isArticlePage ? 1000 : 750 var width = isArticlePage ? 1000 : isFormPage ? 400: 750
const docsImageStyle = { const docsImageStyle = {
border: "1px solid rgba(255,255,255,0.3)", border: isFormPage ? null : "1px solid rgba(255,255,255,0.3)",
borderRadius: theme.palette?.borderRadius, borderRadius: theme.palette?.borderRadius,
width: width, width: width,
maxWidth: width, maxWidth: width,
+2
View File
@@ -1197,6 +1197,7 @@ const RunWorkflow = (defaultprops) => {
<form onSubmit={(e) => {onSubmit(e)}} style={{margin: "25px 0px 15px 0px",}}> <form onSubmit={(e) => {onSubmit(e)}} style={{margin: "25px 0px 15px 0px",}}>
{workflowQuestion !== "" || (workflow.form_control.input_markdown !== undefined && workflow.form_control.input_markdown !== null && workflow.form_control.input_markdown.length > 0) ? null : {workflowQuestion !== "" || (workflow.form_control.input_markdown !== undefined && workflow.form_control.input_markdown !== null && workflow.form_control.input_markdown.length > 0) ? null :
<div> <div>
{/*
<img <img
alt={workflow.name} alt={workflow.name}
src={image} src={image}
@@ -1211,6 +1212,7 @@ const RunWorkflow = (defaultprops) => {
left: 200, left: 200,
}} }}
/> />
*/}
<Typography variant="h6" style={{marginBottom: 10, marginTop: 50, textAlign: "center", }}> <Typography variant="h6" style={{marginBottom: 10, marginTop: 50, textAlign: "center", }}>
{organization} {organization}
+13 -4
View File
@@ -724,6 +724,8 @@ const Workflows2 = (props) => {
const [apps, setApps] = React.useState([]); const [apps, setApps] = React.useState([]);
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
document.title = "Shuffle - Workflows"; document.title = "Shuffle - Workflows";
useEffect(() => { useEffect(() => {
@@ -2327,7 +2329,7 @@ const Workflows2 = (props) => {
key={"explore forms"} key={"explore forms"}
> >
<EditNoteIcon style={{ marginLeft: 0, marginRight: 8 }} /> <EditNoteIcon style={{ marginLeft: 0, marginRight: 8 }} />
{"Create Form"} {"Edit Form"}
</MenuItem> </MenuItem>
<Divider /> <Divider />
@@ -4289,7 +4291,7 @@ const Workflows2 = (props) => {
display: "flex", display: "flex",
flexDirection: "column", flexDirection: "column",
width: "100%", width: "100%",
maxWidth: "70%", maxWidth: isSafari ? "100%" : "70%",
margin: "auto", margin: "auto",
}}> }}>
<Typography variant="h4" style={{ marginBottom: 20, paddingLeft: 15, textTransform: 'none', fontFamily: theme?.typography?.fontFamily }}> <Typography variant="h4" style={{ marginBottom: 20, paddingLeft: 15, textTransform: 'none', fontFamily: theme?.typography?.fontFamily }}>
@@ -5061,8 +5063,9 @@ const Workflows2 = (props) => {
</iframe> </iframe>
</Dialog> </Dialog>
//isLoaded && isLoggedIn && workflowDone ? (
const loadedCheck = const loadedCheck =
isLoaded && isLoggedIn && workflowDone ? ( workflowDone ? (
<div> <div>
{/* {/*
<ShepherdTour steps={newSteps} tourOptions={tourOptions}> <ShepherdTour steps={newSteps} tourOptions={tourOptions}>
@@ -5129,8 +5132,14 @@ const Workflows2 = (props) => {
</div> </div>
); );
const safariStyle = {
transform: 'scale(0.7)',
transformOrigin: 'top',
width: '100%',
height: '100%',
}
// Maybe use gridview or something, idk // Maybe use gridview or something, idk
return <div style={{zoom: 0.7, }}>{loadedCheck}</div>; return <div style={isSafari ? safariStyle : {zoom: 0.7, minHeight: "80vh",}}>{loadedCheck}</div>;
}; };