Added integration framework properly

This commit is contained in:
Frikky
2024-05-21 16:53:37 +02:00
parent d52b024716
commit b5ee9863e2
12 changed files with 1000 additions and 872 deletions
+79 -13
View File
@@ -187,7 +187,7 @@ const ConfigureWorkflow = (props) => {
console.log("No apps loaded: ", apps); console.log("No apps loaded: ", apps);
if (setConfigureWorkflowModalOpen !== undefined) { if (setConfigureWorkflowModalOpen !== undefined) {
setConfigureWorkflowModalOpen(false); setConfigureWorkflowModalOpen(false)
} }
return null; return null;
@@ -198,7 +198,7 @@ const ConfigureWorkflow = (props) => {
const newactions = []; const newactions = [];
for (let [key, keyval] in Object.entries(workflow.actions)) { for (let [key, keyval] in Object.entries(workflow.actions)) {
const action = workflow.actions[key]; var action = JSON.parse(JSON.stringify(workflow.actions[key]))
var newaction = { var newaction = {
large_image: action.large_image, large_image: action.large_image,
app_name: action.app_name, app_name: action.app_name,
@@ -220,17 +220,67 @@ const ConfigureWorkflow = (props) => {
} }
if (action.app_name === "Integration Framework") { if (action.app_name === "Integration Framework") {
console.log("Skipping integration framework: ", action) var selected_app = ""
for (var paramkey in action.parameters) {
const param = action.parameters[paramkey]
if (param.name === "app_name") {
selected_app = param.value
break
}
}
for (var appauth in appAuthentication) {
if (appAuthentication[appauth].app.name.toLowerCase() === selected_app.toLowerCase()) {
newaction.auth_done = true
break
}
}
if (newaction.auth_done) {
continue continue
} }
for (var appkey in apps) {
if (apps[appkey].name.toLowerCase() === selected_app.toLowerCase()) {
newaction.app_name = apps[appkey].name
newaction.app_version = apps[appkey].app_version
newaction.app = apps[appkey]
newaction.app_id = apps[appkey].id
newaction.must_activate = false
newaction.must_authenticate = true
newaction.steps.push({
"title": "Authenticate app",
"type": "authenticate",
"required": true,
})
action.app_id = apps[appkey].id
action.authentication_id = ""
action.authentication = {
"required": true,
}
break
}
}
if (newaction.app.id === undefined) {
console.log("Failed to find app: ", selected_app)
continue
}
newaction.update_version = "1.1.0"
}
// ID match OR name match + version match // ID match OR name match + version match
//const app = apps.find((app) => app.id === action.app_id || (app.name === action.app_name && (app.app_version === action.app_version || (app.loop_versions !== null && app.loop_versions.includes(action.app_version))))) //const app = apps.find((app) => app.id === action.app_id || (app.name === action.app_name && (app.app_version === action.app_version || (app.loop_versions !== null && app.loop_versions.includes(action.app_version)))))
//
// without version match // without version match
const newappname = action.app_name.toLowerCase().replaceAll(" ", "_") const newappname = action.app_name.toLowerCase().replaceAll(" ", "_")
const app = apps.find((app) => app.id === action.app_id || app.name.toLowerCase().replaceAll(" ", "_") === newappname) var app = apps.find((app) => app.id === action.app_id || app.name.toLowerCase().replaceAll(" ", "_") === newappname)
if (app === undefined || app === null) { if (app === undefined || app === null) {
@@ -246,6 +296,19 @@ const ConfigureWorkflow = (props) => {
"required": true, "required": true,
}) })
} else { } else {
if (action.authentication_id !== "" && app.authentication.required === true) {
var authFound = false
for (var authkey in appAuthentication) {
if (appAuthentication[authkey].id === action.authentication_id) {
authFound = true
break
}
}
if (!authFound) {
action.authentication_id = ""
}
}
if (action.authentication_id === "" && app.authentication.required === true && action.parameters !== undefined && action.parameters !== null) { if (action.authentication_id === "" && app.authentication.required === true && action.parameters !== undefined && action.parameters !== null) {
// Check if configuration is filled or not // Check if configuration is filled or not
@@ -292,9 +355,11 @@ const ConfigureWorkflow = (props) => {
//console.log(newaction.app_name,"AUTH: ", newaction.must_authenticate, " ACTIVATE: ", newaction.must_activate) //console.log(newaction.app_name,"AUTH: ", newaction.must_authenticate, " ACTIVATE: ", newaction.must_activate)
if (newaction.must_authenticate) { if (newaction.must_authenticate) {
var authenticationOptions = [];
var authenticationOptions = []
for (let [key,keyval] in Object.entries(appAuthentication)) { for (let [key,keyval] in Object.entries(appAuthentication)) {
const auth = appAuthentication[key]; const auth = appAuthentication[key]
if (auth.app.name === app.name && auth.active) { if (auth.app.name === app.name && auth.active) {
//console.log("Found auth: ", auth) //console.log("Found auth: ", auth)
authenticationOptions.push(auth); authenticationOptions.push(auth);
@@ -403,17 +468,18 @@ const ConfigureWorkflow = (props) => {
continue; continue;
} }
requiredTriggers.push(trigger); requiredTriggers.push(trigger)
} }
} }
if (requiredTriggers.length === 0 && requiredVariables.length === 0 && newactions.length === 0 && setConfigureWorkflowModalOpen !== undefined) { if (setConfigureWorkflowModalOpen !== undefined && requiredTriggers.length === 0 && requiredVariables.length === 0 && newactions.length === 0 ) {
setConfigureWorkflowModalOpen(false); console.log("No required triggers, variables or actions. Closing modal.")
setConfigureWorkflowModalOpen(false)
} }
setRequiredTriggers(requiredTriggers); setRequiredTriggers(requiredTriggers)
setRequiredVariables(requiredVariables); setRequiredVariables(requiredVariables)
setRequiredActions(newactions); setRequiredActions(newactions)
} }
if (appAuthentication !== undefined && previousAuth !== undefined && appAuthentication.length !== previousAuth.length) { if (appAuthentication !== undefined && previousAuth !== undefined && appAuthentication.length !== previousAuth.length) {
+9 -5
View File
@@ -411,10 +411,10 @@ const Header = (props) => {
}} }}
> >
<div style={{ display: "flex", marginBottom: 5 }}> <div style={{ display: "flex", marginBottom: 5 }}>
<Typography variant="body1" style={{flex: 1, }}> <Typography variant="body1" style={{ flex: 1, }}>
Notifications ({notifications.filter((data) => !data.read).length}) Notifications ({notifications.filter((data) => !data.read).length})
</Typography> </Typography>
<ButtonGroup style={{height: 40, flex: 1, }}> <ButtonGroup style={{ height: 40, flex: 1, }}>
{notifications.length > 1 ? ( {notifications.length > 1 ? (
<Button <Button
color="primary" color="primary"
@@ -496,6 +496,10 @@ const Header = (props) => {
localStorage.setItem("globalUrl", responseJson.region_url); localStorage.setItem("globalUrl", responseJson.region_url);
//globalUrl = responseJson.region_url //globalUrl = responseJson.region_url
} }
if (responseJson["reason"] === "SSO_REDIRECT") {
window.location.href = responseJson["url"]
return
}
setTimeout(() => { setTimeout(() => {
window.location.reload(); window.location.reload();
@@ -567,7 +571,7 @@ const Header = (props) => {
alt="Your username here" alt="Your username here"
src={parsedAvatar} src={parsedAvatar}
/> />
<ExpandMoreIcon style={{color: "rgba(255,255,255,0.4)", }}/> <ExpandMoreIcon style={{ color: "rgba(255,255,255,0.4)", }} />
</IconButton> </IconButton>
<Menu <Menu
id="simple-menu" id="simple-menu"
@@ -1518,7 +1522,7 @@ const Header = (props) => {
null null
return !isMobile ? return !isMobile ?
<div style={{marginTop: 0, }}> <div style={{ marginTop: 0, }}>
<AppBar <AppBar
color="transparent" color="transparent"
elevation={0} elevation={0}
@@ -1533,7 +1537,7 @@ const Header = (props) => {
{topbar} {topbar}
<div style={{position: "sticky", top: 0, }}> <div style={{ position: "sticky", top: 0, }}>
{loginTextBrowser} {loginTextBrowser}
</div> </div>
</AppBar> </AppBar>
+36 -178
View File
@@ -113,6 +113,11 @@ const OrgHeaderexpanded = (props) => {
? "" ? ""
: selectedOrganization.sso_config.sso_certificate : selectedOrganization.sso_config.sso_certificate
); );
const [SSORequired, setSSORequired] = React.useState(selectedOrganization.sso_config === undefined
? false
: selectedOrganization.sso_config.SSORequired === undefined
? false
: selectedOrganization.sso_config.SSORequired);
const [notificationWorkflow, setNotificationWorkflow] = React.useState( const [notificationWorkflow, setNotificationWorkflow] = React.useState(
selectedOrganization.defaults === undefined selectedOrganization.defaults === undefined
@@ -121,7 +126,7 @@ const OrgHeaderexpanded = (props) => {
selectedOrganization.defaults.notification_workflow.length === 0 selectedOrganization.defaults.notification_workflow.length === 0
? "" ? ""
: selectedOrganization.defaults.notification_workflow : selectedOrganization.defaults.notification_workflow
) );
const [documentationReference, setDocumentationReference] = React.useState( const [documentationReference, setDocumentationReference] = React.useState(
selectedOrganization.defaults === undefined selectedOrganization.defaults === undefined
@@ -304,171 +309,9 @@ const OrgHeaderexpanded = (props) => {
</Tooltip> </Tooltip>
); );
const getAppIDs = async (appList) => { const toggleBetweenRequiredOrOptional = (event) => {
fetch(globalUrl + "/api/v1/apps", { setSSORequired(event.target.checked);
method: "GET", };
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
credentials: "include",
}).then((response) => {
if (response.status !== 200) {
toast("Failed getting app ids: ", response.reason);
console.log("Status not 200 for app ids :O!");
return;
}
return response.json();
}).then((responseJson) => {
if (responseJson !== undefined) {
// console.log("App ids: ", responseJson)
// console.log("App list: ", appList)
const filteredApps = responseJson.filter(app => appList.includes(app.name));
const appDetails = filteredApps.map(app => ({ name: app.name, id: app.id }));
return appDetails
// console.log("App IDs: ", appDetails)
}
}).catch((error) => {
console.log("Error getting app ids: " + error);
})
}
const generateNotificationWorkflow = async (appname,appImage,appAuthId,projectId,issuetype) => {
//currently only supports JIRA figure out a way to support more apps
var workflowName = `[GENERATED] ${appname} notification workflow`
var workflowDescription = "Generated by Shuffle for sending info/error notifications."
var data = {
"name": workflowName,
"description": workflowDescription,
}
fetch(globalUrl + "/api/v1/workflows", {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify(data),
credentials: "include",
})
.then((response) => {
if (response.status !== 200) {
toast("Failed setting notification workflow: ", response.reason);
console.log("Status not 200 for workflows :O!");
return;
}
return response.json();
}).then((responseJson)=>{
if (responseJson !== undefined) {
console.log("Notification workflow created successfully")
var workflow_id = responseJson.id
if (appname.toLowerCase() === "jira"){
console.log("updating workflow for JIRA")
var workflowBody = {
"name": workflowName,
"Description": workflowDescription,
"id": workflow_id,
"actions": [
{
"app_name": "Jira",
"name": "post_create_issue",
"authentication_id":appAuthId,
"large_image":appImage,
"isStartNode": true,
"label": "create_issue",
"app_version": "1.1.0",
"parameters": [
{
"name": "body",
"value": `{"fields": { "project": {"key": "${projectId}"},"summary": "$exec.title","issuetype": {"name": "${issuetype}"},"description": {"content": [{"content":[{"type":"text","text":"$exec.description"}],"type": "paragraph"}],"type": "doc","version": 1}}}`
},
{
"name": "username_basic",
"value": ""
},
{
"name": "password_basic",
"value": ""
},
{
"name": "url",
"value": ""
},
{
"name": "headers",
"value": "Content-type=application/json \nAccept=application/json"
},
{
"name": "queries",
"value": ""
},
{
"name": "ssl_verify",
"value": "False"
}
]
}
]
}
}
fetch(globalUrl + `/api/v1/workflows/${workflow_id}`, {
method: "PUT",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify(workflowBody),
credentials: "include",
})
.then((response) => {
if (response.status !== 200) {
toast("Failed setting notification workflow: ", response.reason);
console.log("Status not 200 for workflows :O!");
return;
}
return response.json();
}).then((responseJson)=>{
if (responseJson !== undefined) {
handleEditOrg(
orgName,
orgDescription,
selectedOrganization.id,
selectedOrganization.image,
{
app_download_repo: appDownloadUrl,
app_download_branch: appDownloadBranch,
workflow_download_repo: workflowDownloadUrl,
workflow_download_branch: workflowDownloadBranch,
notification_workflow: workflow_id,
documentation_reference: documentationReference,
},
{
sso_entrypoint: ssoEntrypoint,
sso_certificate: ssoCertificate,
client_id: openidClientId,
client_secret: openidClientSecret,
openid_authorization: openidAuthorization,
openid_token: openidToken,
}
)
console.log("Notification workflow updated successfully")
toast("Notification workflow updated successfully")
}
})
}
}).catch((error) => {
console.log("Error setting workflows: " + error);
})
}
return ( return (
<div style={{ textAlign: "center" }}> <div style={{ textAlign: "center" }}>
@@ -488,7 +331,7 @@ const generateNotificationWorkflow = async (appname,appImage,appAuthId,projectId
*/} */}
<div style={{display: "flex", flexDirection: "row", alignItems: "center"}}> <div style={{ display: "flex", flexDirection: "row", alignItems: "center" }}>
{workflows !== undefined && workflows !== null && workflows.length > 0 ? {workflows !== undefined && workflows !== null && workflows.length > 0 ?
<Autocomplete <Autocomplete
id="notification_workflow_search" id="notification_workflow_search"
@@ -621,7 +464,7 @@ const generateNotificationWorkflow = async (appname,appImage,appAuthId,projectId
}} }}
/> />
} }
<div style={{minWidth: 150, maxWidth: 150, marginTop: 5, marginLeft: 10, }}> <div style={{ minWidth: 150, maxWidth: 150, marginTop: 5, marginLeft: 10, }}>
{orgSaveButton} {orgSaveButton}
</div> </div>
</div> </div>
@@ -659,10 +502,25 @@ const generateNotificationWorkflow = async (appname,appImage,appAuthId,projectId
/> />
</span> </span>
</Grid> </Grid>
{isCloud ? null : {/* {isCloud ? null : */}
<Grid item xs={12} style={{marginTop: 50 }}> <div style={{ display: 'flex', flexDirection: 'column', marginTop: 20, marginLeft: 10, width: '100%', borderBottom: '1px solid #414347' }}>
<Typography variant="h4" style={{textAlign: "center",}}>OpenID connect</Typography> <div>
<Grid container style={{marginTop: 10, }}> <Switch
checked={SSORequired}
onChange={toggleBetweenRequiredOrOptional}
name="onOffSwitch"
color="primary"
title="Make SAML SSO or OpenID Authentication Required or Optional for Your Organization"
/>
{SSORequired ? 'Required' : 'Optional'}
</div>
<Typography variant="body2" style={{ margin: '5px 0px 5px 10px' }}>Make SAML SSO or OpenID Authentication Required or Optional for Your Organization.</Typography>
</div>
<div>
</div>
<Grid item xs={12} style={{}}>
<Typography variant="h4" style={{ textAlign: "center", }}>OpenID connect</Typography>
<Grid container style={{ marginTop: 10, }}>
<Grid item xs={6} style={{}}> <Grid item xs={6} style={{}}>
<span> <span>
<Typography>Client ID</Typography> <Typography>Client ID</Typography>
@@ -742,7 +600,7 @@ const generateNotificationWorkflow = async (appname,appImage,appAuthId,projectId
</span> </span>
</Grid> </Grid>
</Grid> </Grid>
<Grid container style={{marginTop: 10, }}> <Grid container style={{ marginTop: 10, }}>
<Grid item xs={6} style={{}}> <Grid item xs={6} style={{}}>
<span> <span>
<Typography>Authorization URL</Typography> <Typography>Authorization URL</Typography>
@@ -813,11 +671,11 @@ const generateNotificationWorkflow = async (appname,appImage,appAuthId,projectId
</Grid> </Grid>
</Grid> </Grid>
</Grid> </Grid>
} {/* } */}
{/*isCloud ? null : */} {/*isCloud ? null : */}
<Grid item xs={12} style={{marginTop: 50,}}> <Grid item xs={12} style={{ marginTop: 50, }}>
<Typography variant="h4" style={{textAlign: "center",}}>SAML SSO (v1.1)</Typography> <Typography variant="h4" style={{ textAlign: "center", }}>SAML SSO (v1.1)</Typography>
<Grid container style={{marginTop: 20, }}> <Grid container style={{ marginTop: 20, }}>
<Grid item xs={6} style={{}}> <Grid item xs={6} style={{}}>
<span> <span>
<Typography>SSO Entrypoint (IdP)</Typography> <Typography>SSO Entrypoint (IdP)</Typography>
@@ -893,7 +751,7 @@ const generateNotificationWorkflow = async (appname,appImage,appAuthId,projectId
</Grid> </Grid>
</Grid> </Grid>
{isCloud ? {isCloud ?
<Typography variant="body2" style={{textAlign: "left",}} color="textSecondary"> <Typography variant="body2" style={{ textAlign: "left", }} color="textSecondary">
IdP URL for Shuffle: https://shuffler.io/api/v1/login_sso IdP URL for Shuffle: https://shuffler.io/api/v1/login_sso
</Typography> </Typography>
: null} : null}
+32 -5
View File
@@ -1558,6 +1558,17 @@ const ParsedAction = (props) => {
*/ */
} }
if (selectedAction.name === "custom_action" && data.name === "body") {
for (var key in selectedActionParameters) {
const param = selectedActionParameters[key]
if (param.name === "method") {
if (param.value === "GET") {
return null
}
}
}
}
if (data.name.startsWith("${") && data.name.endsWith("}")) { if (data.name.startsWith("${") && data.name.endsWith("}")) {
const paramcheck = selectedAction.parameters.find((param) => param.name === "body"); const paramcheck = selectedAction.parameters.find((param) => param.name === "body");
@@ -2678,8 +2689,6 @@ const ParsedAction = (props) => {
/*<div style={{width: 17, height: 17, borderRadius: 17 / 2, backgroundColor: itemColor, marginRight: 10, marginTop: 2, marginTop: "auto", marginBottom: "auto",}}/>*/ /*<div style={{width: 17, height: 17, borderRadius: 17 / 2, backgroundColor: itemColor, marginRight: 10, marginTop: 2, marginTop: "auto", marginBottom: "auto",}}/>*/
} }
//console.log(data.configuration)
const buttonTitle = `Authenticate ${selectedApp.name.replaceAll("_", " ")}` const buttonTitle = `Authenticate ${selectedApp.name.replaceAll("_", " ")}`
const hasAutocomplete = data.autocompleted === true const hasAutocomplete = data.autocompleted === true
return ( return (
@@ -3007,7 +3016,9 @@ const ParsedAction = (props) => {
a.category_label !== undefined && a.category_label !== null && a.category_label.length > 0).concat(sortByKey(selectedApp.actions, "label")) a.category_label !== undefined && a.category_label !== null && a.category_label.length > 0).concat(sortByKey(selectedApp.actions, "label"))
).sort(sortByCategoryLabel)) ).sort(sortByCategoryLabel))
var baselabel = selectedAction.label;
const selectedAppIcon = selectedAction.large_image
var baselabel = selectedAction.label
return ( return (
<div style={appApiViewStyle} id="parsed_action_view"> <div style={appApiViewStyle} id="parsed_action_view">
@@ -3015,13 +3026,29 @@ const ParsedAction = (props) => {
<span> <span>
<div style={{ display: "flex", minHeight: 40, marginBottom: 30 }}> <div style={{ display: "flex", minHeight: 40, marginBottom: 30 }}>
<div style={{ flex: 1 }}> <div style={{ flex: 1 }}>
<h3 style={{ marginBottom: 5 }}> <div style={{ display: "flex", }}
onClick={() => {
//window.open("/apps/${selectedAction.app_id}", "_blank")
}}
>
<Tooltip title={"App: "+selectedAction.app_name} placement="top">
<img src={selectedAppIcon} style={{
width: 30,
height: 30,
marginRight: 10,
borderRadius: 5,
marginTop: 13,
border: "2px solid rgba(255,255,255,0.3)",
}} />
</Tooltip>
<h3 style={{ }}>
{( {(
selectedAction.app_name.charAt(0).toUpperCase() + selectedAction.app_name.charAt(0).toUpperCase() +
selectedAction.app_name.substring(1) selectedAction.app_name.substring(1)
).replaceAll("_", " ")} ).replaceAll("_", " ")}
</h3> </h3>
<div style={{display: "flex", marginTop: 10, }}> </div>
<div style={{display: "flex", marginTop: 0, }}>
<IconButton <IconButton
style={{ style={{
marginTop: "auto", marginTop: "auto",
+58 -4
View File
@@ -24,8 +24,9 @@ const Priorities = (props) => {
const [showDismissed, setShowDismissed] = React.useState(false); const [showDismissed, setShowDismissed] = React.useState(false);
const [showRead, setShowRead] = React.useState(false); const [showRead, setShowRead] = React.useState(false);
const [appFramework, setAppFramework] = React.useState({}); const [appFramework, setAppFramework] = React.useState({});
const [selectedWorkflow, setSelectedWorkflow] = React.useState("");
const [selectedExecutionId, setSelectedExecutionId] = React.useState(""); const [selectedWorkflow, setSelectedWorkflow] = React.useState("NO HIGHLIGHT");
const [selectedExecutionId, setSelectedExecutionId] = React.useState("NO HIGHLIGHT");
let navigate = useNavigate(); let navigate = useNavigate();
useEffect(() => { useEffect(() => {
@@ -86,6 +87,44 @@ const Priorities = (props) => {
}) })
} }
const clearNotifications = () => {
// Don't really care about the logout
toast("Clearing notifications")
fetch(`${globalUrl}/api/v1/notifications/clear`, {
credentials: "include",
method: "GET",
headers: {
"Content-Type": "application/json",
},
})
.then(function (response) {
if (response.status !== 200) {
console.log("Error in response");
}
return response.json();
})
.then(function (responseJson) {
if (responseJson.success === true) {
// Reload the UI
const newNotifications = notifications.map((notification) => {
notification.read = true
return notification
})
setNotifications(newNotifications)
setShowRead(true)
} else {
toast("Failed dismissing notifications. Please try again later.");
}
})
.catch((error) => {
console.log("error in notification dismissal: ", error);
//removeCookie("session_token", {path: "/"})
});
};
const dismissNotification = (alert_id, disabled) => { const dismissNotification = (alert_id, disabled) => {
var notificationurl = `${globalUrl}/api/v1/notifications/${alert_id}/markasread` var notificationurl = `${globalUrl}/api/v1/notifications/${alert_id}/markasread`
if (disabled === true) { if (disabled === true) {
@@ -178,7 +217,7 @@ const Priorities = (props) => {
var orgId = ""; var orgId = "";
const highlighted = 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 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 (userdata.orgs !== undefined) { if (userdata.orgs !== undefined) {
const foundOrg = userdata.orgs.find((org) => org.id === data["org_id"]); const foundOrg = userdata.orgs.find((org) => org.id === data["org_id"]);
@@ -351,12 +390,27 @@ const Priorities = (props) => {
</a> </a>
</span> </span>
<div/> <div/>
<div style={{display: "flex", marginTop: 10, marginBottom: 10, }}>
<Switch <Switch
checked={showRead} checked={showRead}
onChange={() => { onChange={() => {
setShowRead(!showRead); setShowRead(!showRead);
}} }}
/>&nbsp; Show read /><span style={{marginTop: 5, }}>&nbsp; Show read </span>
{notifications !== undefined && notifications !== null && notifications.length > 1 ? (
<Button
color="primary"
variant="outlined"
disabled={notifications.filter((data) => !data.read).length === 0}
onClick={() => {
clearNotifications()
}}
style={{marginLeft: 50, }}
>
Mark all as read
</Button>
) : null}
</div>
{notifications === null || notifications === undefined || notifications.length === 0 ? null : {notifications === null || notifications === undefined || notifications.length === 0 ? null :
<div> <div>
{notifications.map((notification, index) => { {notifications.map((notification, index) => {
+1 -2
View File
@@ -23,6 +23,7 @@ import {
DialogTitle, DialogTitle,
DialogContent, DialogContent,
} from '@mui/material'; } from '@mui/material';
import Mousetrap from 'mousetrap'; import Mousetrap from 'mousetrap';
import { import {
@@ -31,7 +32,6 @@ import {
import { Search as SearchIcon, Close as CloseIcon, Folder as FolderIcon, Code as CodeIcon, LibraryBooks as LibraryBooksIcon } from '@mui/icons-material' import { Search as SearchIcon, Close as CloseIcon, Folder as FolderIcon, Code as CodeIcon, LibraryBooks as LibraryBooksIcon } from '@mui/icons-material'
import KeyboardCommandKeyIcon from '@mui/icons-material/KeyboardCommandKey'; import KeyboardCommandKeyIcon from '@mui/icons-material/KeyboardCommandKey';
import algoliasearch from 'algoliasearch/lite';
import aa from 'search-insights' import aa from 'search-insights'
import { InstantSearch, Configure, connectSearchBox, connectHits, Index } from 'react-instantsearch-dom'; import { InstantSearch, Configure, connectSearchBox, connectHits, Index } from 'react-instantsearch-dom';
//import { InstantSearch, SearchBox, Hits, connectSearchBox, connectHits, Index } from 'react-instantsearch-dom'; //import { InstantSearch, SearchBox, Hits, connectSearchBox, connectHits, Index } from 'react-instantsearch-dom';
@@ -42,7 +42,6 @@ const chipStyle = {
backgroundColor: "#3d3f43", height: 30, marginRight: 5, paddingLeft: 5, paddingRight: 5, height: 28, cursor: "pointer", borderColor: "#3d3f43", color: "white", backgroundColor: "#3d3f43", height: 30, marginRight: 5, paddingLeft: 5, paddingRight: 5, height: 28, cursor: "pointer", borderColor: "#3d3f43", color: "white",
} }
const searchClient = algoliasearch("JNSS5CFDZZ", "db08e40265e2941b9a7d8f644b6e5240")
const SearchField = props => { const SearchField = props => {
const { serverside, userdata, isMobile, isLoaded, globalUrl, isHeader, isLoggedIn, small, rounded } = props const { serverside, userdata, isMobile, isLoaded, globalUrl, isHeader, isLoggedIn, small, rounded } = props
+2 -2
View File
@@ -48,8 +48,8 @@ const data = [
css: { css: {
label: "data(label)", label: "data(label)",
shape: "roundrectangle", shape: "roundrectangle",
"height": "16px", "height": "18px",
"width": "120px", "width": "145px",
"background-color": "#212121", "background-color": "#212121",
"border-color": "#81c784", "border-color": "#81c784",
"z-index": 10000, "z-index": 10000,
+2 -2
View File
@@ -34,7 +34,7 @@ const theme = createTheme(adaptV4Theme({
//jsonTheme: "tomorrow", //jsonTheme: "tomorrow",
jsonIconStyle: "round", jsonIconStyle: "round",
jsonTheme: "summerfruit", jsonTheme: "summerfruit",
jsonCollapseStringsAfterLength: 75, jsonCollapseStringsAfterLength: 100,
reactJsonStyle: { reactJsonStyle: {
padding: 5, padding: 5,
@@ -65,7 +65,7 @@ const theme = createTheme(adaptV4Theme({
defaultImage: "/images/no_image.png", defaultImage: "/images/no_image.png",
}, },
typography: { typography: {
fontFamily: `"Roboto", "Helvetica", "Arial", sans-serif`, fontFamily: `"Roboto", "Helvetica", "Arial", "inter", sans-serif`,
useNextVariants: true, useNextVariants: true,
h1: { h1: {
fontSize: 40, fontSize: 40,
+7 -1
View File
@@ -1430,6 +1430,8 @@ If you're interested, please let me know a time that works for you, or set up a
} }
// Just use this one? // Just use this one?
localStorage.setItem("globalUrl", "");
localStorage.setItem("getting_started_sidebar", "open");
fetch(`${globalUrl}/api/v1/orgs/${orgId}`, { fetch(`${globalUrl}/api/v1/orgs/${orgId}`, {
method: "GET", method: "GET",
@@ -1440,6 +1442,10 @@ If you're interested, please let me know a time that works for you, or set up a
}) })
.then((response) => { .then((response) => {
if (response.status === 401) { if (response.status === 401) {
} else {
localStorage.removeItem("apps")
localStorage.removeItem("workflows")
localStorage.removeItem("userinfo")
} }
return response.json(); return response.json();
@@ -1728,7 +1734,7 @@ If you're interested, please let me know a time that works for you, or set up a
// Horrible frontend fix for environments // Horrible frontend fix for environments
const setDefaultEnvironment = (environment) => { const setDefaultEnvironment = (environment) => {
// FIXME - add more checks to this // FIXME - add more checks to this
toast("Setting default env to " + environment.name); toast("Changing default env")
var newEnv = []; var newEnv = [];
for (var key in environments) { for (var key in environments) {
if (environments[key].id == environment.id) { if (environments[key].id == environment.id) {
+164 -48
View File
@@ -9,7 +9,7 @@ import { makeStyles, } from "@mui/styles";
import WorkflowTemplatePopup from "../components/WorkflowTemplatePopup.jsx" import WorkflowTemplatePopup from "../components/WorkflowTemplatePopup.jsx"
import { v4 as uuidv4 } from "uuid"; import { v4 as uuidv4 } from "uuid";
import { useNavigate, Link, useParams } from "react-router-dom"; import { useNavigate, Link, useParams } from "react-router-dom";
import { useBeforeunload } from "react-beforeunload"; import { useBeforeunload } from "react-beforeunload"
import ReactJson from "react-json-view"; import ReactJson from "react-json-view";
import { NestedMenuItem } from 'mui-nested-menu'; import { NestedMenuItem } from 'mui-nested-menu';
import Markdown from "react-markdown"; import Markdown from "react-markdown";
@@ -642,22 +642,21 @@ const AngularWorkflow = (defaultprops) => {
"field_id": "", "field_id": "",
}) })
// Event for making sure app is correct const [loadedApps, setLoadedApps] = React.useState([])
useEffect(() => {
if (selectedApp === undefined || selectedApp === null && selectedApp.app_name === undefined) { const loadAppConfig = (appId, select) => {
if (appId === undefined || appId === null || appId.length === 0) {
return return
} }
if (apps === undefined || apps === null || apps.length === 0) { if (loadedApps.includes(appId)) {
return return
} }
// Handle the activation case, as they are NOT in the event management system yet loadedApps.push(appId)
if (selectedApp.actions === undefined || selectedApp.actions === null || selectedApp.actions.length > 1) { setLoadedApps(loadedApps)
return
} else { const appUrl = `${globalUrl}/api/v1/apps/${appId}/config?openapi=false`
if (selectedApp.id !== undefined && selectedApp.id !== null && selectedApp.id.length > 0) {
const appUrl = `${globalUrl}/api/v1/apps/${selectedApp.id}/config?openapi=false`
fetch(appUrl, { fetch(appUrl, {
headers: { headers: {
Accept: "application/json", Accept: "application/json",
@@ -668,11 +667,23 @@ const AngularWorkflow = (defaultprops) => {
return response.json() return response.json()
}) })
.then((responseJson) => { .then((responseJson) => {
console.log("Loaded app config: ", responseJson)
if (responseJson.success === true && responseJson.app !== undefined && responseJson.app !== null && responseJson.app.length > 0) { if (responseJson.success === true && responseJson.app !== undefined && responseJson.app !== null && responseJson.app.length > 0) {
// Base64 decode into json // Base64 decode into json
const foundapp = JSON.parse(atob(responseJson.app)) const foundapp = JSON.parse(atob(responseJson.app))
if (foundapp.actions !== undefined && foundapp.actions !== null && foundapp.actions.length > selectedApp.actions.length) { console.log("Checked app: ", foundapp)
const selectedAppActions = selectedApp.actions === undefined || selectedApp.actions === null ? [] : selectedApp.actions
if (foundapp.actions !== undefined && foundapp.actions !== null && foundapp.actions.length > selectedAppActions.length) {
if (select) {
setSelectedApp(foundapp) setSelectedApp(foundapp)
}
if (apps === undefined || apps === null || apps.length === 0) {
console.log("LOAD APPS!")
}
for (var i = 0; i < apps.length; i++) { for (var i = 0; i < apps.length; i++) {
if (apps[i].id !== foundapp.id) { if (apps[i].id !== foundapp.id) {
@@ -693,9 +704,26 @@ const AngularWorkflow = (defaultprops) => {
} }
}) })
.catch((error) => { .catch((error) => {
console.log(`Failed side-loading app ${selectedApp.name}`) console.log(`Failed side-loading app ${appId}: ${error}`)
}) })
}
// Event for making sure app is correct
useEffect(() => {
if (selectedApp === undefined || selectedApp === null && selectedApp.app_name === undefined) {
return
}
if (apps === undefined || apps === null || apps.length === 0) {
return
}
// Handle the activation case, as they are NOT in the event management system yet
if (selectedApp.actions === undefined || selectedApp.actions === null || selectedApp.actions.length > 1) {
return
} else {
if (selectedApp.id !== undefined && selectedApp.id !== null && selectedApp.id.length > 0) {
loadAppConfig(selectedApp.id, true)
} }
} }
@@ -705,7 +733,6 @@ const AngularWorkflow = (defaultprops) => {
continue continue
} }
console.log("Found app: ", curapp)
if (curapp.actions !== undefined && curapp.actions !== null && curapp.actions.length > selectedApp.actions.length) { if (curapp.actions !== undefined && curapp.actions !== null && curapp.actions.length > selectedApp.actions.length) {
var foundActionIndex = -1 var foundActionIndex = -1
for (let actionkey in curapp.actions) { for (let actionkey in curapp.actions) {
@@ -1128,6 +1155,8 @@ const AngularWorkflow = (defaultprops) => {
"autoClose": false, "autoClose": false,
}) })
} else { } else {
if (refresh === true) { if (refresh === true) {
getAppAuthentication(true, true, true) getAppAuthentication(true, true, true)
@@ -1138,6 +1167,13 @@ const AngularWorkflow = (defaultprops) => {
setAuthenticationModalOpen(false) setAuthenticationModalOpen(false)
// Needs a refresh with the new authentication.. // Needs a refresh with the new authentication..
//toast("Successfully saved new app auth") //toast("Successfully saved new app auth")
if (configureWorkflowModalOpen === true) {
setConfigureWorkflowModalOpen(false)
setTimeout(() => {
setConfigureWorkflowModalOpen(true)
}, 1000)
}
} }
}) })
.catch((error) => { .catch((error) => {
@@ -1179,7 +1215,6 @@ const AngularWorkflow = (defaultprops) => {
if (tmpView !== undefined && tmpView !== null && tmpView.length > 0) { if (tmpView !== undefined && tmpView !== null && tmpView.length > 0) {
// Don't clean up if it's already open // Don't clean up if it's already open
if (executionModalOpen === true) { if (executionModalOpen === true) {
console.log("Execution modal already open, not cleaning up")
return return
} }
@@ -3221,8 +3256,9 @@ const AngularWorkflow = (defaultprops) => {
responseJson.errors.length > 0 responseJson.errors.length > 0
) { ) {
console.log("Setting configure Modal to open") console.log("Setting configure Modal to open")
setConfigureWorkflowModalOpen(true);
} }
setConfigureWorkflowModalOpen(true)
} }
} }
}) })
@@ -3777,8 +3813,21 @@ const AngularWorkflow = (defaultprops) => {
if (data.buttonType == "ACTIONSUGGESTION") { if (data.buttonType == "ACTIONSUGGESTION") {
const attachedToId = data.attachedTo const attachedToId = data.attachedTo
const parentitem = cy.getElementById(data.attachedTo).data() const parentitemRaw = cy.getElementById(data.attachedTo)
const parentitem = parentitemRaw.data()
if (parentitem !== null && parentitem !== undefined) { if (parentitem !== null && parentitem !== undefined) {
setTimeout(() => {
parentitemRaw.select()
const allNodes = cy.nodes().jsons()
for (var _key in allNodes) {
const currentNode = allNodes[_key]
if (currentNode.data.buttonType === "ACTIONSUGGESTION") {
cy.getElementById(currentNode.data.id).remove()
}
}
}, 100)
const findaction = data.label const findaction = data.label
console.log("CLICKED: ", findaction, apps.length) console.log("CLICKED: ", findaction, apps.length)
@@ -4262,6 +4311,16 @@ const AngularWorkflow = (defaultprops) => {
curaction.app_id = curapp.id curaction.app_id = curapp.id
if (curapp.authentication === undefined || curapp.authentication === null) {
setAuthenticationType({
type: "",
})
curapp.authentication = {
type: "",
required: false,
}
} else {
setAuthenticationType( setAuthenticationType(
curapp.authentication.type === "oauth2-app" || (curapp.authentication.type === "oauth2" && curapp.authentication.redirect_uri !== undefined && curapp.authentication.redirect_uri !== null) ? { curapp.authentication.type === "oauth2-app" || (curapp.authentication.type === "oauth2" && curapp.authentication.redirect_uri !== undefined && curapp.authentication.redirect_uri !== null) ? {
type: curapp.authentication.type, type: curapp.authentication.type,
@@ -4276,6 +4335,7 @@ const AngularWorkflow = (defaultprops) => {
type: "", type: "",
} }
) )
}
const requiresAuth = curapp.authentication.required; //&& ((curapp.authentication.parameters !== undefined && curapp.authentication.parameters !== null) || (curapp.authentication.type === "oauth2" && curapp.authentication.redirect_uri !== undefined && curapp.authentication.redirect_uri !== null)) const requiresAuth = curapp.authentication.required; //&& ((curapp.authentication.parameters !== undefined && curapp.authentication.parameters !== null) || (curapp.authentication.type === "oauth2" && curapp.authentication.redirect_uri !== undefined && curapp.authentication.redirect_uri !== null))
setRequiresAuthentication(requiresAuth); setRequiresAuthentication(requiresAuth);
@@ -5855,15 +5915,15 @@ const AngularWorkflow = (defaultprops) => {
}; };
const addActionSuggestions = (nodedata, event) => { const addActionSuggestions = (nodedata, event) => {
console.log("App Action suggestions disabled for now") console.log("App Action suggestions being added")
return
if (nodedata.type !== "ACTION") { if (nodedata.type !== "ACTION") {
return return
} }
var parentNode = cy.$("#" + event.target.data("id")); var parentNode = cy.$("#" + event.target.data("id"))
if (parentNode.data("isButton") || parentNode.data("buttonId")) return; if (parentNode.data("isButton") || parentNode.data("buttonId")) {
return
}
const px = parentNode.position("x") + 0; const px = parentNode.position("x") + 0;
const py = parentNode.position("y") + 100; const py = parentNode.position("y") + 100;
@@ -5887,6 +5947,8 @@ const AngularWorkflow = (defaultprops) => {
// 1. Find the app // 1. Find the app
// 2. Loop the apps' actions // 2. Loop the apps' actions
// 3. Find actions based on category label IF it exists // 3. Find actions based on category label IF it exists
console.log("Fidning app match for: ", parentname)
var added = 0 var added = 0
for (let appKey in apps) { for (let appKey in apps) {
const curapp = apps[appKey] const curapp = apps[appKey]
@@ -5898,6 +5960,7 @@ const AngularWorkflow = (defaultprops) => {
continue continue
} }
console.log("Found matching: ", curapp.name, parentname, curapp.actions.length)
for (let actionKey in curapp.actions) { for (let actionKey in curapp.actions) {
const curaction = curapp.actions[actionKey] const curaction = curapp.actions[actionKey]
@@ -5907,6 +5970,7 @@ const AngularWorkflow = (defaultprops) => {
} }
if (curaction.category_label !== undefined && curaction.category_label !== null && curaction.category_label.length > 0) { if (curaction.category_label !== undefined && curaction.category_label !== null && curaction.category_label.length > 0) {
console.log("IN NODE ADD")
cy.add({ cy.add({
group: "nodes", group: "nodes",
@@ -5925,7 +5989,7 @@ const AngularWorkflow = (defaultprops) => {
}) })
added += 1 added += 1
if (added >= 2) { if (added >= 3) {
break break
} }
} }
@@ -6182,7 +6246,6 @@ const AngularWorkflow = (defaultprops) => {
cytoscapeElement.style.cursor = "pointer" cytoscapeElement.style.cursor = "pointer"
} }
sendStreamRequest({ sendStreamRequest({
"item": "node", "item": "node",
"type": "hover", "type": "hover",
@@ -6268,7 +6331,8 @@ const AngularWorkflow = (defaultprops) => {
for (var _key in allNodes) { for (var _key in allNodes) {
const currentNode = allNodes[_key]; const currentNode = allNodes[_key];
// console.log("CURRENT NODE: ", currentNode) // console.log("CURRENT NODE: ", currentNode)
if ((currentNode.data.isButton || currentNode.data.isSuggestion) && currentNode.data.attachedTo !== nodedata.id) {
if ((currentNode.data.buttonType === "ACTIONSUGGESTION" || currentNode.data.isButton || currentNode.data.isSuggestion) && currentNode.data.attachedTo !== nodedata.id) {
cy.getElementById(currentNode.data.id).remove(); cy.getElementById(currentNode.data.id).remove();
} }
@@ -6320,6 +6384,10 @@ const AngularWorkflow = (defaultprops) => {
//"cursor": "pointer", //"cursor": "pointer",
} }
if (nodedata.buttonType === "ACTIONSUGGESTION") {
parsedStyle["font-size"] = "18px"
}
const typeIds = cy.elements('node:selected').jsons(); const typeIds = cy.elements('node:selected').jsons();
for (var idkey in typeIds) { for (var idkey in typeIds) {
const item = typeIds[idkey] const item = typeIds[idkey]
@@ -7149,6 +7217,7 @@ const AngularWorkflow = (defaultprops) => {
cy.edgehandles({ cy.edgehandles({
handleNodes: (el) => { handleNodes: (el) => {
if (el.isNode() && if (el.isNode() &&
el.data("buttonType") != "ACTIONSUGGESTION" &&
!el.data("isButton") && !el.data("isButton") &&
!el.data("isDescriptor") && !el.data("isDescriptor") &&
!el.data("isSuggestion") && !el.data("isSuggestion") &&
@@ -8342,7 +8411,6 @@ const AngularWorkflow = (defaultprops) => {
newAppStyle.borderLeft = `${pixelSize} solid ${yellow}`; newAppStyle.borderLeft = `${pixelSize} solid ${yellow}`;
} }
return ( return (
<Draggable <Draggable
onDrag={(e) => { onDrag={(e) => {
@@ -8361,8 +8429,17 @@ const AngularWorkflow = (defaultprops) => {
<Paper <Paper
square square
style={newAppStyle} style={newAppStyle}
onMouseOver={() => { onMouseOver={(e) => {
setHover(true); e.preventDefault()
e.stopPropagation()
setHover(true)
if (app.actions !== undefined && app.actions !== null && app.actions.length === 1) {
console.log("HOVERING: ", app.id)
loadAppConfig(app.id, false)
}
}} }}
onMouseOut={() => { onMouseOut={() => {
setHover(false); setHover(false);
@@ -8784,6 +8861,7 @@ const AngularWorkflow = (defaultprops) => {
const CustomSearchBox = connectSearchBox(SearchBox) const CustomSearchBox = connectSearchBox(SearchBox)
const CustomAppHits = connectHits(AppHits) const CustomAppHits = connectHits(AppHits)
var viewedApps = []
return ( return (
<div style={appViewStyle}> <div style={appViewStyle}>
<div style={{ flex: "1" }}> <div style={{ flex: "1" }}>
@@ -8839,6 +8917,12 @@ const AngularWorkflow = (defaultprops) => {
return null return null
} }
if (viewedApps.includes(app.id)) {
return null
}
viewedApps.push(app.id)
var extraMessage = "" var extraMessage = ""
if (index == 2) { if (index == 2) {
extraMessage = <div style={{ marginTop: 5 }} /> extraMessage = <div style={{ marginTop: 5 }} />
@@ -14217,7 +14301,8 @@ const AngularWorkflow = (defaultprops) => {
right: 0, right: 0,
left: isMobile ? 20 : leftBarSize + 20, left: isMobile ? 20 : leftBarSize + 20,
top: isMobile ? 30 : appBarSize + 20, top: isMobile ? 30 : appBarSize + 20,
}; pointerEvents: "none",
}
@@ -14235,11 +14320,16 @@ const AngularWorkflow = (defaultprops) => {
return ( return (
<div style={topBarStyle}> <div style={topBarStyle}>
<div style={{ margin: "0px 10px 0px 10px" }}> <div style={{
margin: "0px 10px 0px 10px",
pointerEvents: "none",
}}>
<Breadcrumbs <Breadcrumbs
aria-label="breadcrumb" aria-label="breadcrumb"
separator="›" separator="›"
style={{ color: "white" }} style={{
color: "white"
}}
> >
<Link <Link
to="/workflows" to="/workflows"
@@ -14255,7 +14345,10 @@ const AngularWorkflow = (defaultprops) => {
Workflows Workflows
</h2> </h2>
</Link> </Link>
<h2 style={{ margin: 0 }}>{workflow.name}</h2> <h2 style={{
margin: 0,
pointerEvents: "none",
}}>{workflow.name}</h2>
</Breadcrumbs> </Breadcrumbs>
{isCorrectOrg ? null : {isCorrectOrg ? null :
@@ -14282,7 +14375,9 @@ const AngularWorkflow = (defaultprops) => {
if (response.status !== 200) { if (response.status !== 200) {
console.log("Error in response"); console.log("Error in response");
} else { } else {
localStorage.setItem("apps", []) localStorage.removeItem("apps")
localStorage.removeItem("workflows")
localStorage.removeItem("userinfo")
} }
return response.json(); return response.json();
@@ -15939,7 +16034,6 @@ const AngularWorkflow = (defaultprops) => {
}; };
const handleReactJsonClipboard = (copy) => { const handleReactJsonClipboard = (copy) => {
console.log("COPY: ", copy);
const elementName = "copy_element_shuffle"; const elementName = "copy_element_shuffle";
var copyText = document.getElementById(elementName); var copyText = document.getElementById(elementName);
@@ -17270,10 +17364,9 @@ const AngularWorkflow = (defaultprops) => {
? "red" ? "red"
: yellow; : yellow;
const validate = ! codeModalOpen? "" : validateJson(selectedResult.result.trim()); const validate = !codeModalOpen ? "" : validateJson(selectedResult.result.trim())
if (validate.valid && typeof validate.result === "string") { if (validate.valid && typeof validate.result === "string") {
validate.result = JSON.parse(validate.result); validate.result = JSON.parse(validate.result)
} }
const AppResultVariable = ({ data }) => { const AppResultVariable = ({ data }) => {
@@ -17381,7 +17474,6 @@ const AngularWorkflow = (defaultprops) => {
if (stringbody.length > 1000) { if (stringbody.length > 1000) {
return "Body looks to be big in a standard format. Consider using the 'To File' parameter to automatically make it into a file." return "Body looks to be big in a standard format. Consider using the 'To File' parameter to automatically make it into a file."
} }
} else {
} }
} }
@@ -17405,10 +17497,19 @@ const AngularWorkflow = (defaultprops) => {
return "Authorization failed (403). The API user most likely doesn't have the correct permissions. Check the body of the result for more information." return "Authorization failed (403). The API user most likely doesn't have the correct permissions. Check the body of the result for more information."
} }
if (result.status === 404) {
return "The URL, or content of the URL is incorrect. Check it and try again."
}
if (result.status === 400) { if (result.status === 400) {
return "The queries or data sent to the API is most likely wrong (400). Check the body of the result for more information." return "The queries or data sent to the API is most likely wrong (400). Check the body of the result for more information."
} }
if (result.status === 200 || result.status === 201 || result.status === 204) {
return "It looks like the result was successful! If it didn't work, make sure to check if the body you are sending was correct."
}
// Validate and check for newlines // Validate and check for newlines
if (result.success !== false) { if (result.success !== false) {
@@ -17425,7 +17526,7 @@ const AngularWorkflow = (defaultprops) => {
} }
} }
return "" //return ""
} }
@@ -17447,13 +17548,14 @@ const AngularWorkflow = (defaultprops) => {
return "Consider whether your Orborus environment can connect to a local IP or not." return "Consider whether your Orborus environment can connect to a local IP or not."
} }
if (stringjson.includes("invalidurl")) {
if (stringjson.includes("connectionerror")) { // IF count of "http" is more than one, 1, it's prolly invalid
if (stringjson.includes("kms")) { var additionalinfo = ""
return "KMS authentication failed. Check your notifications for more details." if (stringjson.includes("http") && stringjson.match(/http/g).length > 1) {
additionalinfo = "You may be using multiple 'http' in the URL. "
} }
return "Your URL is incorrect." return "The URL is invalid. Change the URL to a valid one, and try again. "+additionalinfo
} }
if (stringjson.includes("result too large to handle")) { if (stringjson.includes("result too large to handle")) {
@@ -17469,6 +17571,15 @@ const AngularWorkflow = (defaultprops) => {
} }
if (stringjson.includes("connectionerror")) {
if (stringjson.includes("kms")) {
return "KMS authentication failed. Check your notifications for more details."
}
return "The URL is incorrect, or Shuffle can't reach it. Set up a Shuffle Environment in the same VLAN, or whitelist Shuffle's IPs."
}
return "" return ""
} }
@@ -17706,7 +17817,7 @@ const AngularWorkflow = (defaultprops) => {
{currentSuggestion.length > 0 ? {currentSuggestion.length > 0 ?
<div style={{ marginBottom: 5 }}> <div style={{ marginBottom: 5 }}>
<b style={{color: "rgba(214,110,117)", }}>Debug Info:</b> {currentSuggestion} <b style={{color: "rgba(214,110,117)", }}>Debug:</b> {currentSuggestion}
</div> </div>
: :
<div style={{ marginBottom: 5 }}> <div style={{ marginBottom: 5 }}>
@@ -18381,9 +18492,14 @@ const AngularWorkflow = (defaultprops) => {
selectedAction.authentication === undefined || selectedAction.authentication === undefined ||
selectedAction.authentication === null selectedAction.authentication === null
) { ) {
selectedAction.authentication = [authenticationOption]; selectedAction.authentication = [authenticationOption]
} else { } else {
selectedAction.authentication.push(authenticationOption);
try {
selectedAction.authentication.push(authenticationOption)
} catch (e) {
//console.log("Error: ", e)
}
} }
setSelectedAction(selectedAction); setSelectedAction(selectedAction);
@@ -19647,7 +19763,7 @@ const AngularWorkflow = (defaultprops) => {
} }
} }
const foundusecase.name === undefined || foundusecase.name === null || foundusecase.name === "" ? null : const templatePopup = foundusecase.name === undefined || foundusecase.name === null || foundusecase.name === "" ? null :
<Slide direction="down" in={true} mountOnEnter unmountOnExit> <Slide direction="down" in={true} mountOnEnter unmountOnExit>
<div style={{position: "fixed", top: "10%", left: "37%", border: "1px solid rgba(255,255,255,0.3)", backgroundColor: theme.palette.inputColor, borderRadius: theme.palette.borderRadius, display: "flex", }}> <div style={{position: "fixed", top: "10%", left: "37%", border: "1px solid rgba(255,255,255,0.3)", backgroundColor: theme.palette.inputColor, borderRadius: theme.palette.borderRadius, display: "flex", }}>
<WorkflowTemplatePopup <WorkflowTemplatePopup
+3 -5
View File
@@ -427,7 +427,7 @@ const UsecaseListComponent = (props) => {
return ( return (
<Grid id={fixedName} item xs={selectedItem ? 12 : 4} key={subindex} style={{minHeight: 110,}} onClick={() => { <Grid id={fixedName} item xs={selectedItem ? 12 : 4} key={subindex} style={{minHeight: 110,}} onClick={() => {
if (fixedName === "increase authentication") { if (fixedName === "reporting") {
getUsecase(subcase, index, subindex) getUsecase(subcase, index, subindex)
return return
} }
@@ -1192,8 +1192,7 @@ const Dashboard = (props) => {
navigate(curpath + newitem) navigate(curpath + newitem)
} }
/* const baseItem = document.getElementById("reporting")
const baseItem = document.getElementById("increase authentication")
if (baseItem !== undefined && baseItem !== null) { if (baseItem !== undefined && baseItem !== null) {
baseItem.click() baseItem.click()
@@ -1206,7 +1205,6 @@ const Dashboard = (props) => {
// Scroll back to top // Scroll back to top
window.scrollTo(0, 0) window.scrollTo(0, 0)
} }
*/
const foundQuery2 = params["selected_object"] const foundQuery2 = params["selected_object"]
if (foundQuery2 !== null && foundQuery2 !== undefined) { if (foundQuery2 !== null && foundQuery2 !== undefined) {
@@ -1231,7 +1229,7 @@ const Dashboard = (props) => {
} else { } else {
//console.log("Couldn't find item with name ", queryName) //console.log("Couldn't find item with name ", queryName)
} }
}, 1000); }, 1000)
} }
} }
+1 -1
View File
@@ -1186,7 +1186,7 @@ const Workflows = (props) => {
} }
} }
if (newarray.length > 0 && storageWorkflows.length <= newarray.length) { if (newarray.length > 0) {
try { try {
localStorage.setItem("workflows", JSON.stringify(newarray)) localStorage.setItem("workflows", JSON.stringify(newarray))
} catch (e) { } catch (e) {