-
-
- Notification Workflow
-
-
- The notification workflow triggers when an error occurs in one of your workflows. Each individual one will only start a workflow once every 2 minutes. You can point child org notifications into the parent org notification by choosing it in the list.
-
-
-
+
+
+
+
+ Notification Workflow
+
+
+ The notification workflow triggers when an error occurs in one of your workflows. Each individual one will only start a workflow once every 2 minutes. You can point child org notifications into the parent org notification by choosing it in the list.
+
- {workflows !== undefined && workflows !== null && workflows.length > 0 ?
-
{
- setOpenNotification(true);
- }}
- onClose={() => {
- setOpenNotification(false);
- }}
- freeSolo
- //autoSelect
- value={workflows?.find(w => w.id === notificationWorkflow) || null}
- classes={{ inputRoot: classes.inputRoot }}
- ListboxProps={{
- style: {
- backgroundColor: theme.palette.surfaceColor,
- color: theme.palette.text.primary,
- borderRadius: theme.palette.borderRadius,
- },
- }}
- getOptionLabel={(option) => {
- if (
- option === undefined ||
- option === null ||
- option.name === undefined ||
- option.name === null
- ) {
- return "No Workflow Selected";
- }
+ {modalView}
+ {/*{testWorkflowModal} */}
+
+ {renderChips()}
+
- const newname = (
- option.name.charAt(0).toUpperCase() + option.name.substring(1)
- ).replaceAll("_", " ");
- return newname;
- }}
- options={workflows}
- fullWidth
- style={{
- backgroundColor: theme.palette.textFieldStyle.backgroundColor,
- borderRadius: theme.palette.textFieldStyle.borderRadius,
- color: theme.palette.textFieldStyle.color,
- height: 35,
- marginBottom: 40,
- }}
- onChange={(event, newValue) => {
- console.log("Found value: ", newValue)
+
- var parsedinput = { target: { value: newValue } }
-
- // For variables
- if (typeof newValue === 'string' && newValue.startsWith("$")) {
- parsedinput = {
- target: {
- value: {
- "name": newValue,
- "id": newValue,
- "actions": [],
- "triggers": [],
- }
- }
- }
- }
-
- handleWorkflowSelectionUpdate(parsedinput)
- }}
- renderOption={(props, data, state) => {
- if (data.id === workflow.id) {
- data = workflow;
- }
-
- return (
-
- {data.image !== undefined && data.image !== null && data.image.length > 0 ?
-
- : null}
-
- Choose {data.name}
-
-
- } placement="bottom">
-
-
- )
- }}
- renderInput={(params) => {
- return (
-
{
+ if (
+ option === undefined ||
+ option === null ||
+ option.name === undefined ||
+ option.name === null
+ ) {
+ return "No Workflow Selected";
+ }
+
+ const newname = (
+ option.name.charAt(0).toUpperCase() + option.name.substring(1)
+ ).replaceAll("_", " ");
+ return newname;
+ }}
+ options={workflows}
+ fullWidth
style={{
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
- color: theme.palette.textFieldStyle.color,
borderRadius: theme.palette.textFieldStyle.borderRadius,
+ color: theme.palette.textFieldStyle.color,
height: 35,
- fontSize: 16,
- marginTop: "16px"
+ marginBottom: 40,
}}
+ onChange={(event, newValue) => {
+ console.log("Found value: ", newValue)
+
+ var parsedinput = { target: { value: newValue } }
+
+ // For variables
+ if (typeof newValue === 'string' && newValue.startsWith("$")) {
+ parsedinput = {
+ target: {
+ value: {
+ "name": newValue,
+ "id": newValue,
+ "actions": [],
+ "triggers": [],
+ }
+ }
+ }
+ }
+
+ handleWorkflowSelectionUpdate(parsedinput)
+ }}
+ renderOption={(props, data, state) => {
+ if (data.id === workflow.id) {
+ data = workflow;
+ }
+
+ return (
+
+ {data.image !== undefined && data.image !== null && data.image.length > 0 ?
+
+ : null}
+
+ Choose {data.name}
+
+
+ } placement="bottom">
+
+
+ )
+ }}
+ renderInput={(params) => {
+ return (
+
+ );
+ }}
+ />
+ :
+ {
borderRadius: 4,
},
inputProps: {
- ...params.inputProps,
style: {
height: "100%",
boxSizing: "border-box",
@@ -499,198 +1673,171 @@ const Priorities = memo((props) => {
}
}}
- // label="Find a notification workflow"
- variant="outlined"
- placeholder="Select a notification workflow"
+ style={{
+ backgroundColor: theme.palette.textFieldStyle.backgroundColor,
+ color: theme.palette.textFieldStyle.color,
+ borderRadius: 4,
+ height: 35,
+ fontSize: 16,
+ marginBottom: 30
+ }}
+ fullWidth={true}
+ type="name"
+ id="outlined-with-placeholder"
+ margin="normal"
+ variant="outlined"
+ placeholder="ID of the workflow to receive notifications"
+ value={notificationWorkflow}
+ onChange={(e) => {
+ setNotificationWorkflow(e.target.value);
+ }}
/>
- );
- }}
- />
- :
- {
- setNotificationWorkflow(e.target.value);
- }}
- />
- }
- {/*
+ {/*
{orgSaveButton}
*/}
-
+
- {notificationWorkflow === undefined || notificationWorkflow === null || notificationWorkflow.length === 0 ? null :
-
-
-
{
- if (notificationWorkflow === "parent") {
- toast.error("Can't open parent org's notification workflow from here.")
- return
- }
-
- window.open(`/workflows/${notificationWorkflow}?view=executions`, "_blank")
- }}
- >
-
-
-
- }
-
- Notifications ({
- notifications?.filter((notification) => showRead === true || notification.read === false).length
- })
-
-
- Notifications help you find potential problems with your workflows and apps.
-
- Learn more
-
-
-
-
- {
- setShowRead(!showRead);
- }}
- /> Show read
- {notifications !== undefined && notifications !== null && notifications.length > 1 ? (
- !data.read).length === 0}
- onClick={() => {
- clearNotifications()
- }}
- style={{marginLeft: 50, textTransform: "none", fontSize: 16}}
- >
- Mark all as read
-
- ) : null}
-
-
-
-
- {clickedFromOrgTab? null : }
-
- Suggestions
-
- Suggestions are tasks identified by Shuffle to help you discover ways to protect your and customers' company.
These range from simple configurations in Shuffle to Usecases you may have missed.
-
- Learn more
-
-
-
- {
- setShowDismissed(!showDismissed);
- }}
- /> Show dismissed
- {userdata.priorities === null || userdata.priorities === undefined || userdata.priorities.length === 0 ?
-
- No Suggestions found
-
- :
- userdata.priorities.map((priority, index) => {
- if (showDismissed === false && priority.active === false) {
- return null
}
-
- return (
-
- )
- })
- }
-
-
+
+
)
})
@@ -699,15 +1846,15 @@ export default Priorities;
const NotificationItem = memo((props) => {
- const {data, selectedExecutionId, selectedWorkflow, highlightKMS, userdata, imagesize, boxColor, clickedFromOrgTab, notificationWidth, dismissNotification} = props
+ const { data, selectedExecutionId, selectedWorkflow, highlightKMS, userdata, imagesize, boxColor, clickedFromOrgTab, notificationWidth, dismissNotification } = props
var image = "";
var orgName = "";
var orgId = "";
const { themeMode, brandColor } = useContext(Context);
- const theme = getTheme(themeMode, brandColor);
-
- var highlighted = selectedExecutionId === "" && selectedWorkflow === "" ? false : data.reference_url === undefined || data.reference_url === null || data.reference_url.length === 0 ? false : data.reference_url.includes(selectedExecutionId) || data.reference_url.includes(selectedWorkflow)
+ const theme = getTheme(themeMode, brandColor);
+
+ var highlighted = selectedExecutionId === "" && selectedWorkflow === "" ? false : data.reference_url === undefined || data.reference_url === null || data.reference_url.length === 0 ? false : data.reference_url.includes(selectedExecutionId) || data.reference_url.includes(selectedWorkflow)
if (!highlighted && highlightKMS) {
if (data.title !== undefined && data.title !== null && data.title.toLowerCase().includes("kms")) {
@@ -719,45 +1866,45 @@ const NotificationItem = memo((props) => {
}
if (userdata.orgs !== undefined) {
- const foundOrg = userdata.orgs.find((org) => org.id === data["org_id"]);
- if (foundOrg !== undefined && foundOrg !== null) {
- //position: "absolute", bottom: 5, right: -5,
- const imageStyle = {
- width: imagesize,
- height: imagesize,
- pointerEvents: "none",
- marginLeft:
- data.creator_org !== undefined && data.creator_org.length > 0
- ? 20
- : 0,
- borderRadius: 10,
- border:
- foundOrg.id === userdata.active_org.id
- ? `3px solid ${boxColor}`
- : null,
- cursor: "pointer",
- marginRight: 10,
- };
+ const foundOrg = userdata.orgs.find((org) => org.id === data["org_id"]);
+ if (foundOrg !== undefined && foundOrg !== null) {
+ //position: "absolute", bottom: 5, right: -5,
+ const imageStyle = {
+ width: imagesize,
+ height: imagesize,
+ pointerEvents: "none",
+ marginLeft:
+ data.creator_org !== undefined && data.creator_org.length > 0
+ ? 20
+ : 0,
+ borderRadius: 10,
+ border:
+ foundOrg.id === userdata.active_org.id
+ ? `3px solid ${boxColor}`
+ : null,
+ cursor: "pointer",
+ marginRight: 10,
+ };
- image =
- foundOrg.image === "" ? (
-

- ) : (
-

{}}
- />
- );
+ image =
+ foundOrg.image === "" ? (
+

+ ) : (
+

{ }}
+ />
+ );
- orgName = foundOrg.name;
- orgId = foundOrg.id;
- }
+ orgName = foundOrg.name;
+ orgId = foundOrg.id;
+ }
}
return (
@@ -776,185 +1923,185 @@ const NotificationItem = memo((props) => {
backgroundColor: theme.palette.cardHoverColor,
},
}}
- >
-
- {data.amount === 1 && data.read === false ?
-
- : null}
- {data.ignored === true ?
-
- : null}
- {data.read === false ?
-
- :
-
- }
-
- {data.title}
-
-
-
- {data.image !== undefined && data.image !== null && data.image.length > 0 ?
-

- :
- null
- }
-
- {data.description}
-
-
-
- {
- window.open(data.reference_url, "_blank");
- }}
- >
- Explore
-
-
- {data.read === false ? (
- {
- dismissNotification(data.id);
- }}
- >
- Mark as Read
-
- ) : null}
-
-
- {
- if (data.ignored) {
- dismissNotification(data.id, false);
- } else {
- dismissNotification(data.id, true);
- }
- }}
>
- {data.ignored ? "Re-enable" : "Disable"}
-
-
-
+
+ {data.amount === 1 && data.read === false ?
+
+ : null}
+ {data.ignored === true ?
+
+ : null}
+ {data.read === false ?
+
+ :
+
+ }
+
+ {data.title}
+
+
-
0 ?
+
+ :
+ null
+ }
+
+ {data.description}
+
+
+
+ {
+ window.open(data.reference_url, "_blank");
+ }}
+ >
+ Explore
+
- }}
- >
- First seen:{" "}
- {new Date(data.created_at * 1000).toISOString().slice(0, 19)}
-
+ {data.read === false ? (
+ {
+ dismissNotification(data.id);
+ }}
+ >
+ Mark as Read
+
+ ) : null}
-
- Last seen:{" "}
- {new Date(data.updated_at * 1000).toISOString().slice(0, 19)}
-
+
+ {
+ if (data.ignored) {
+ dismissNotification(data.id, false);
+ } else {
+ dismissNotification(data.id, true);
+ }
+ }}
+ >
+ {data.ignored ? "Re-enable" : "Disable"}
+
+
+
-
- Times seen: {data.amount}
-
-
+
+ }}
+ >
+ First seen:{" "}
+ {new Date(data.created_at * 1000).toISOString().slice(0, 19)}
+
+
+
+ Last seen:{" "}
+ {new Date(data.updated_at * 1000).toISOString().slice(0, 19)}
+
+
+
+ Times seen: {data.amount}
+
+
+
+
);
})
-const NotificationComponent = memo(({notifications, showRead, selectedExecutionId, selectedWorkflow, highlightKMS, userdata, imagesize, boxColor, clickedFromOrgTab, notificationWidth, dismissNotification}) => {
+const NotificationComponent = memo(({ notifications, showRead, selectedExecutionId, selectedWorkflow, highlightKMS, userdata, imagesize, boxColor, clickedFromOrgTab, notificationWidth, dismissNotification }) => {
- return(
+ return (
{notifications === null || notifications === undefined || notifications?.length === 0 ? (
- null
- ) :
-
- {notifications?.map((notification, index) => {
- if (showRead === false && notification.read === true) {
- return null
- }
+ null
+ ) :
+
+ {notifications?.map((notification, index) => {
+ if (showRead === false && notification.read === true) {
+ return null
+ }
- return (
-
- )
- })}
-
- }
+ return (
+
+ )
+ })}
+
+ }
)
})
diff --git a/frontend/src/components/ShuffleCodeEditor1.jsx b/frontend/src/components/ShuffleCodeEditor1.jsx
index 33b37483..3132034f 100644
--- a/frontend/src/components/ShuffleCodeEditor1.jsx
+++ b/frontend/src/components/ShuffleCodeEditor1.jsx
@@ -132,7 +132,7 @@ const CodeEditor = (props) => {
fieldname,
contentLoading,
editorData,
- handleSubflowParamChange,
+ handleTriggerParamChange,
setAiQueryModalOpen,
fullScreenMode,
environment,
@@ -212,7 +212,7 @@ const CodeEditor = (props) => {
const triggerField = searchParams.get('trigger_field');
const triggerName = searchParams.get('trigger_name');
const conditionId = searchParams.get('condition_id');
- const conditionField = searchParams.get('field');
+ const conditionField = searchParams.get('condition_field');
useEffect(() => {
if (actionId === undefined || actionId === null) {
@@ -251,7 +251,7 @@ const CodeEditor = (props) => {
setSelectedCondition(condition);
// Update available variables when condition changes
updateAvailableVariables(actionlist);
- }, [conditionId, fieldName])
+ }, [conditionId, conditionField])
// Extract variable updating logic into a separate function
const updateAvailableVariables = (actionlist) => {
@@ -2588,7 +2588,7 @@ const CodeEditor = (props) => {
// Handle condition fields
if (conditionField !== null && handleConditionFieldChange !== undefined) {
- handleConditionFieldChange(conditionField, fieldName, fixedcodedata);
+ handleConditionFieldChange(conditionField, fixedcodedata);
}
// Handle action fields
else if (actionId !== undefined && actionId !== null && actionId.length > 0) {
@@ -2596,7 +2596,7 @@ const CodeEditor = (props) => {
}
// Handle trigger fields
else if (triggerId !== undefined && triggerId !== null && triggerId.length > 0) {
- handleSubflowParamChange(triggerId, triggerField, fixedcodedata)
+ handleTriggerParamChange(triggerId, triggerField, fixedcodedata)
}
setExpansionModalOpen(false)
diff --git a/frontend/src/views/AngularWorkflow.jsx b/frontend/src/views/AngularWorkflow.jsx
index db5111bd..95b3e462 100755
--- a/frontend/src/views/AngularWorkflow.jsx
+++ b/frontend/src/views/AngularWorkflow.jsx
@@ -13032,7 +13032,7 @@ const AngularWorkflow = (defaultprops) => {
event.preventDefault()
setExpansionModalOpen(true)
setActiveDialog("codeeditor")
- navigate(`?condition_id=${data.id}&field=${data.name}`)
+ navigate(`?condition_id=${data.id}&condition_field=${data.name}`)
setEditorData({
"name": data.name,
"value": data.value || "",
@@ -13117,9 +13117,9 @@ const AngularWorkflow = (defaultprops) => {
// Update the field value based on type
if (type === "source") {
- handleConditionFieldChange("source", "value", toComplete);
+ handleConditionFieldChange("source", toComplete);
} else if (type === "destination") {
- handleConditionFieldChange("destination", "value", toComplete);
+ handleConditionFieldChange("destination", toComplete);
}
handleMenuClose();
@@ -13996,7 +13996,7 @@ const AngularWorkflow = (defaultprops) => {
/>
- const handleConditionFieldChange = (fieldType, fieldName, value) => {
+ const handleConditionFieldChange = (fieldType, value) => {
if (fieldType === "source") {
setSourceValue({
...sourceValue,
@@ -15197,7 +15197,7 @@ const AngularWorkflow = (defaultprops) => {
}
]
- const handleSubflowParamChange = (triggerId, triggerField, newData) => {
+ const handleTriggerParamChange = (triggerId, triggerField, newData) => {
var updateFail = ""
if (workflow !== undefined && workflow !== null) {
@@ -17336,9 +17336,13 @@ const AngularWorkflow = (defaultprops) => {
fullWidth
rows="4"
multiline
- defaultValue={selectedTrigger.parameters[0]?.value}
+ value={selectedTriggerValue || ""}
color="primary"
placeholder=""
+ onChange={(e) => {
+ setLastSaved(false)
+ setSelectedTriggerValue(e.target.value)
+ }}
onBlur={(e) => {
setLastSaved(false)
setTriggerTextInformationWrapper(e.target.value);
@@ -25472,7 +25476,7 @@ const AngularWorkflow = (defaultprops) => {
// selectedTrigger={selectedTrigger}
aiSubmit={aiSubmit}
toolsAppId={toolsApp.id}
- handleSubflowParamChange={handleSubflowParamChange}
+ handleTriggerParamChange={handleTriggerParamChange}
codedata={editorData.value}
setcodedata={setcodedata}
selectedEdge={selectedEdge}
diff --git a/frontend/src/views/LoginPage.jsx b/frontend/src/views/LoginPage.jsx
index 26bf6782..b2cb9426 100755
--- a/frontend/src/views/LoginPage.jsx
+++ b/frontend/src/views/LoginPage.jsx
@@ -314,12 +314,15 @@ const LoginPage = props => {
},
})
- if (serverside !== true) {
- const tmpMessage = new URLSearchParams(window.location.search).get("message")
- if (tmpMessage !== undefined && tmpMessage !== null && message !== tmpMessage) {
- setMessage(tmpMessage)
+ useEffect(() => {
+ if (serverside !== true) {
+ const tmpMessage = new URLSearchParams(window.location.search).get("message")
+ if (tmpMessage !== undefined && tmpMessage !== null && message !== tmpMessage) {
+ setMessage(tmpMessage)
+ toast(tmpMessage)
+ }
}
- }
+ }, [])
if (document !== undefined) {
if (register) {
@@ -444,13 +447,17 @@ const LoginPage = props => {
}
if (isLoggedIn === true && serverside !== true) {
- const tmpView = new URLSearchParams(window.location.search).get("view")
- if (tmpView !== undefined && tmpView !== null && tmpView === "pricing") {
- window.location.pathname = "/pricing"
- return
- } else if (tmpView !== undefined && tmpView !== null) {
- window.location.pathname = tmpView
- return
+ const tmpView = new URLSearchParams(window.location.search).get("view");
+ if (tmpView !== undefined && tmpView !== null) {
+ let pathOnly = tmpView.split("?")[0];
+ if (!pathOnly.startsWith("/")) pathOnly = "/" + pathOnly;
+
+ if (pathOnly === "/pricing" || pathOnly === "admin") {
+ window.location.replace(pathOnly + window.location.search);
+ } else {
+ window.location.replace(pathOnly);
+ }
+ return;
}
window.location.pathname = "/workflows"
@@ -575,20 +582,17 @@ const LoginPage = props => {
setCookie(responseJson["cookies"][key].key, responseJson["cookies"][key].value, { path: "/" })
}
- const tmpView = new URLSearchParams(window.location.search).get("view")
+ const tmpView = new URLSearchParams(window.location.search).get("view");
if (tmpView !== undefined && tmpView !== null) {
- //const newUrl = `/${tmpView}${decodeURIComponent(window.location.search)}`
- // Check if slash in the url
+ let pathOnly = tmpView.split("?")[0];
+ if (!pathOnly.startsWith("/")) pathOnly = "/" + pathOnly;
- var newUrl = `/${tmpView}`
- if (tmpView.startsWith("/")) {
- newUrl = `${tmpView}`
+ if (pathOnly === "/pricing" || pathOnly === "admin") {
+ window.location.replace(pathOnly + window.location.search);
+ } else {
+ window.location.replace(pathOnly);
}
-
- console.log("Found url: ", newUrl)
-
- window.location.pathname = newUrl
- return
+ return;
}
console.log("LOGIN DATA: ", responseJson)
@@ -647,9 +651,14 @@ const LoginPage = props => {
const tmpView = new URLSearchParams(window.location.search).get("view")
if (tmpView !== undefined && tmpView !== null) {
- //const newUrl = `/${tmpView}${decodeURIComponent(window.location.search)}`
- const newUrl = `/${tmpView}`
- window.location.pathname = newUrl
+ let pathOnly = tmpView.split("?")[0];
+ if (!pathOnly.startsWith("/")) pathOnly = "/" + pathOnly;
+
+ if (pathOnly === "/pricing" || pathOnly === "admin") {
+ window.location.replace(pathOnly + window.location.search);
+ } else {
+ window.location.replace(pathOnly);
+ }
return
}
diff --git a/frontend/src/views/SettingsPage.jsx b/frontend/src/views/SettingsPage.jsx
index f10dbfb7..ec5ba658 100755
--- a/frontend/src/views/SettingsPage.jsx
+++ b/frontend/src/views/SettingsPage.jsx
@@ -458,7 +458,12 @@ const Settings = (props) => {
if (responseJson["success"] === false) {
setPasswordFormMessage(responseJson["reason"]);
} else {
- toast("Changed password!");
+ var reason = ""
+ if (responseJson.reason !== undefined && responseJson.reason !== null && responseJson.reason.length > 0) {
+ reason += responseJson.reason
+ }
+
+ toast.success("Changed password! " + reason);
setPasswordFormMessage("");
}
})
diff --git a/frontend/src/views/Workflows2.jsx b/frontend/src/views/Workflows2.jsx
index 1655c901..c059f991 100644
--- a/frontend/src/views/Workflows2.jsx
+++ b/frontend/src/views/Workflows2.jsx
@@ -5071,7 +5071,7 @@ const Workflows2 = (props) => {
//isLoaded && isLoggedIn && workflowDone ? (
const loadedCheck =
- workflowDone ? (
+ workflowDone && isLoaded ? (
{/*
@@ -5134,7 +5134,9 @@ const Workflows2 = (props) => {
}}
>
- Loading Workflows
+
+ Loading Workflows and Apps
+
);