Minor sdk update

This commit is contained in:
Frikky
2023-11-30 11:14:55 +01:00
parent 1373bac875
commit ff7ca90936
12 changed files with 274 additions and 54 deletions
+1 -1
View File
@@ -70,7 +70,7 @@ SHUFFLE_SWARM_BRIDGE_DEFAULT_MTU=1500 # 1500 by default
# Used for auto-cleanup of containers. REALLY important at scale. Set to false to see all container info. # Used for auto-cleanup of containers. REALLY important at scale. Set to false to see all container info.
SHUFFLE_MEMCACHED= SHUFFLE_MEMCACHED=
SHUFFLE_CONTAINER_AUTO_CLEANUP=true SHUFFLE_CONTAINER_AUTO_CLEANUP=true
SHUFFLE_ORBORUS_EXECUTION_CONCURRENCY=3 # The amount of concurrent executions Orborus can handle. This is a soft limit, but it's recommended to keep it low. SHUFFLE_ORBORUS_EXECUTION_CONCURRENCY=7 # The amount of concurrent executions Orborus can handle. This is a soft limit, but it's recommended to keep it low.
SHUFFLE_HEALTHCHECK_DISABLED=false SHUFFLE_HEALTHCHECK_DISABLED=false
SHUFFLE_ELASTIC=true SHUFFLE_ELASTIC=true
SHUFFLE_LOGS_DISABLED=false SHUFFLE_LOGS_DISABLED=false
+1
View File
@@ -3619,6 +3619,7 @@ class AppBase:
timeout_env = os.getenv("SHUFFLE_APP_SDK_TIMEOUT", timeout) timeout_env = os.getenv("SHUFFLE_APP_SDK_TIMEOUT", timeout)
try: try:
timeout = int(timeout_env) timeout = int(timeout_env)
self.logger.info(f"[DEBUG] Timeout set to {timeout} seconds")
except Exception as e: except Exception as e:
self.logger.info(f"[WARNING] Failed parsing timeout to int: {e}") self.logger.info(f"[WARNING] Failed parsing timeout to int: {e}")
+36 -36
View File
@@ -216,44 +216,44 @@ const { globalUrl, setNotifications, notifications, isLoggedIn, removeCookie, ho
const NotificationItem = (props) => { const NotificationItem = (props) => {
const {data} = props const {data} = props
var image = ""; var image = "";
var orgName = ""; var orgName = "";
var orgId = ""; var orgId = "";
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"]);
if (foundOrg !== undefined && foundOrg !== null) { if (foundOrg !== undefined && foundOrg !== null) {
//position: "absolute", bottom: 5, right: -5, //position: "absolute", bottom: 5, right: -5,
const imageStyle = { const imageStyle = {
width: imagesize, width: imagesize,
height: imagesize, height: imagesize,
pointerEvents: "none", pointerEvents: "none",
marginLeft: data.creator_org !== undefined && data.creator_org.length > 0 ? 20 : 0, marginLeft: data.creator_org !== undefined && data.creator_org.length > 0 ? 20 : 0,
borderRadius: 10, borderRadius: 10,
border: foundOrg.id === userdata.active_org.id ? `3px solid ${boxColor}` : null, border: foundOrg.id === userdata.active_org.id ? `3px solid ${boxColor}` : null,
cursor: "pointer", cursor: "pointer",
marginRight: 10, marginRight: 10,
}; };
image = image =
foundOrg.image === "" ? ( foundOrg.image === "" ? (
<img <img
alt={foundOrg.name} alt={foundOrg.name}
src={theme.palette.defaultImage} src={theme.palette.defaultImage}
style={imageStyle} style={imageStyle}
/> />
) : ( ) : (
<img <img
alt={foundOrg.name} alt={foundOrg.name}
src={foundOrg.image} src={foundOrg.image}
style={imageStyle} style={imageStyle}
onClick={() => {}} onClick={() => {}}
/> />
); );
orgName = foundOrg.name; orgName = foundOrg.name;
orgId = foundOrg.id; orgId = foundOrg.id;
} }
} }
return ( return (
<Paper style={{backgroundColor: theme.palette.surfaceColor, width: notificationWidth, padding: 25, borderBottom: "1px solid rgba(255,255,255,0.4)"}}> <Paper style={{backgroundColor: theme.palette.surfaceColor, width: notificationWidth, padding: 25, borderBottom: "1px solid rgba(255,255,255,0.4)"}}>
+9 -3
View File
@@ -106,6 +106,8 @@ const Header = (props) => {
const clearNotifications = () => { const clearNotifications = () => {
// Don't really care about the logout // Don't really care about the logout
toast("Clearing notifications")
fetch(`${globalUrl}/api/v1/notifications/clear`, { fetch(`${globalUrl}/api/v1/notifications/clear`, {
credentials: "include", credentials: "include",
method: "GET", method: "GET",
@@ -351,7 +353,7 @@ const Header = (props) => {
setAnchorEl(event.currentTarget); setAnchorEl(event.currentTarget);
}} }}
> >
<Badge badgeContent={notifications.length} color="primary"> <Badge badgeContent={notifications.filter((n) => n.read === false).length} color="primary">
<NotificationsIcon <NotificationsIcon
color="secondary" color="secondary"
style={{ height: 30, width: 30 }} style={{ height: 30, width: 30 }}
@@ -390,7 +392,7 @@ const Header = (props) => {
> >
<div style={{ display: "flex", marginBottom: 5 }}> <div style={{ display: "flex", marginBottom: 5 }}>
<Typography variant="body1"> <Typography variant="body1">
Your Notifications ({notifications.length}) Your Notifications ({notifications.filter((data) => !data.read).length})
</Typography> </Typography>
{notifications.length > 1 ? ( {notifications.length > 1 ? (
<Button <Button
@@ -412,7 +414,11 @@ const Header = (props) => {
</Typography> </Typography>
</Paper> </Paper>
{notifications.map((data, index) => { {notifications.map((data, index) => {
return <NotificationItem data={data} key={index} />; if (data.read) {
return null
}
return <NotificationItem data={data} key={index} />;
})} })}
</Menu> </Menu>
</span> </span>
+9 -2
View File
@@ -375,7 +375,11 @@ const AuthenticationOauth2 = (props) => {
"reference_workflow": workflowId, "reference_workflow": workflowId,
} }
setNewAppAuth(appAuthData, true) if (setNewAppAuth !== undefined) {
setNewAppAuth(appAuthData, true)
} else {
console.log("setNewAppAuth is undefined")
}
// Wait 1 second, then get app auth with update // Wait 1 second, then get app auth with update
//if (getAppAuthentication !== undefined) { //if (getAppAuthentication !== undefined) {
@@ -602,7 +606,10 @@ const AuthenticationOauth2 = (props) => {
console.log("FIELDS: ", newFields); console.log("FIELDS: ", newFields);
newAuthOption.fields = newFields; newAuthOption.fields = newFields;
setNewAppAuth(newAuthOption);
if (setNewAppAuth !== undefined) {
setNewAppAuth(newAuthOption);
}
//appAuthentication.push(newAuthOption) //appAuthentication.push(newAuthOption)
//setAppAuthentication(appAuthentication) //setAppAuthentication(appAuthentication)
// //
+199 -3
View File
@@ -1,24 +1,30 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import { toast } from "react-toastify";
import theme from "../theme.jsx"; import theme from "../theme.jsx";
import { import {
Paper, Paper,
Typography, Tooltip,
Typography,
Divider, Divider,
Button, Button,
ButtonGroup,
Grid, Grid,
Card, Card,
Switch, Chip,
Switch,
} from "@mui/material"; } from "@mui/material";
import { useNavigate, Link } from "react-router-dom";
import Priority from "../components/Priority.jsx"; import Priority from "../components/Priority.jsx";
//import { useAlert //import { useAlert
const Priorities = (props) => { const Priorities = (props) => {
const { globalUrl, userdata, serverside, billingInfo, stripeKey, checkLogin, setAdminTab, setCurTab, } = props; const { globalUrl, userdata, serverside, billingInfo, stripeKey, checkLogin, setAdminTab, setCurTab, notifications, setNotifications, } = 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({});
let navigate = useNavigate();
useEffect(() => { useEffect(() => {
getFramework() getFramework()
@@ -61,6 +67,182 @@ const Priorities = (props) => {
}) })
} }
const dismissNotification = (alert_id) => {
// Don't really care about the logout
fetch(`${globalUrl}/api/v1/notifications/${alert_id}/markasread`, {
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) {
const newNotifications = notifications.filter(
(data) => data.id !== alert_id
);
console.log("NEW NOTIFICATIONS: ", newNotifications);
if (setNotifications !== undefined) {
setNotifications(newNotifications)
}
} else {
toast("Failed dismissing notification. Please try again later.");
}
})
.catch((error) => {
console.log("error in notification dismissal: ", error);
//removeCookie("session_token", {path: "/"})
})
}
const notificationWidth = "100%"
const imagesize = 22
const boxColor = "#86c142"
const NotificationItem = (props) => {
const {data} = props
var image = "";
var orgName = "";
var orgId = "";
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,
};
image =
foundOrg.image === "" ? (
<img
alt={foundOrg.name}
src={theme.palette.defaultImage}
style={imageStyle}
/>
) : (
<img
alt={foundOrg.name}
src={foundOrg.image}
style={imageStyle}
onClick={() => {}}
/>
);
orgName = foundOrg.name;
orgId = foundOrg.id;
}
}
return (
<Paper
style={{
backgroundColor: theme.palette.platformColor,
width: notificationWidth,
padding: 30,
borderBottom: "1px solid rgba(255,255,255,0.4)",
marginBottom: 20,
}}
>
<div style={{display: "flex", }}>
{data.amount === 1 && data.read === false ?
<Chip
label={"First seen"}
variant="contained"
color="primary"
style={{marginRight: 15, height: 25, }}
/>
: null}
{data.read === false ?
<Chip
label={"Unread"}
variant="outlined"
color="primary"
style={{marginRight: 15, height: 25, }}
/>
:
<Chip
label={"Read"}
variant="outlined"
color="secondary"
style={{marginRight: 15, height: 25, }}
/>
}
<Typography variant="body1" color="textPrimary">
{data.title}
</Typography >
</div>
{data.image !== undefined && data.image !== null && data.image.length > 0 ?
<img alt={data.title} src={data.image} style={{height: 100, width: 100, }} />
:
null
}
<Typography variant="body2" color="textSecondary" style={{marginTop: 10, maxHeight: 200, overflowX: "hidden", overflowY: "auto", }}>
{data.description}
</Typography >
<div style={{ display: "flex" }}>
<ButtonGroup>
<Button
color="secondary"
variant="outlined"
style={{ marginTop: 15 }}
disabled={data.reference_url === undefined || data.reference_url === null || data.reference_url.length === 0}
onClick={() => {
window.open(data.reference_url, "_blank")
}}
>
Explore
</Button>
{data.read === false ? (
<Button
color="secondary"
variant="outlined"
style={{ marginTop: 15 }}
onClick={() => {
dismissNotification(data.id);
}}
>
Dismiss
</Button>
) : null}
</ButtonGroup>
<Typography variant="body2" color="textSecondary" style={{marginLeft: 20, marginTop: 20, }}>
<b>First seen</b>: {new Date(data.created_at * 1000).toISOString().slice(0, 19)}
</Typography >
<Typography variant="body2" color="textSecondary" style={{marginLeft: 20, marginTop: 20, }}>
<b>Last seen</b>: {new Date(data.updated_at * 1000).toISOString().slice(0, 19)}
</Typography >
<Typography variant="body2" color="textSecondary" style={{marginLeft: 20, marginTop: 20, }}>
<b>Times seen</b>: {data.amount}
</Typography >
</div>
</Paper>
);
}
return ( return (
<div style={{maxWidth: 1000, }}> <div style={{maxWidth: 1000, }}>
<h2 style={{ display: "inline" }}>Suggestions</h2> <h2 style={{ display: "inline" }}>Suggestions</h2>
@@ -125,6 +307,20 @@ const Priorities = (props) => {
setShowRead(!showRead); setShowRead(!showRead);
}} }}
/>&nbsp; Show read />&nbsp; Show read
{notifications === null || notifications === undefined || notifications.length === 0 ? null :
<div>
{notifications.map((notification, index) => {
if (showRead === false && notification.read === true) {
return null
}
return (
<NotificationItem data={notification} key={index} />
)
})}
</div>
}
</div> </div>
) )
} }
+3 -1
View File
@@ -181,6 +181,7 @@ const RuntimeDebugger = (props) => {
}, []) }, [])
const imageSize = 30 const imageSize = 30
const timenowUnix = Math.floor(Date.now() / 1000)
const columns: GridColDef[] = [ const columns: GridColDef[] = [
{ {
field: 'execution_source', field: 'execution_source',
@@ -319,7 +320,8 @@ const RuntimeDebugger = (props) => {
}, },
{ field: 'startTimestamp', headerName: 'Start time (UTC)', width: 160, { field: 'startTimestamp', headerName: 'Start time (UTC)', width: 160,
renderCell: (params) => { renderCell: (params) => {
const hasError = params.row.completed_at-params.row.started_at > 300 const comparisonTimestamp = params.row.completed_at === 0 ? timenowUnix : params.row.completed_at
const hasError = comparisonTimestamp-params.row.started_at > 300
return ( return (
<Tooltip title={hasError ? "More than 5 minutes from start to finish" : ""} placement="top"> <Tooltip title={hasError ? "More than 5 minutes from start to finish" : ""} placement="top">
+3 -1
View File
@@ -134,7 +134,7 @@ const FileCategoryInput = (props) => {
const Admin = (props) => { const Admin = (props) => {
const { globalUrl, userdata, serverside, checkLogin } = props; const { globalUrl, userdata, serverside, checkLogin, notifications, setNotifications, } = props;
var to_be_copied = ""; var to_be_copied = "";
const classes = useStyles(); const classes = useStyles();
@@ -2836,6 +2836,8 @@ If you're interested, please let me know a time that works for you, or set up a
checkLogin={checkLogin} checkLogin={checkLogin}
setAdminTab={setAdminTab} setAdminTab={setAdminTab}
setCurTab={setCurTab} setCurTab={setCurTab}
notifications={notifications}
setNotifications={setNotifications}
/> />
: adminTab === 3 ? : adminTab === 3 ?
<Billing <Billing
+1 -1
View File
@@ -15628,7 +15628,7 @@ const AngularWorkflow = (defaultprops) => {
marginBottom: "auto", marginBottom: "auto",
}} }}
> >
<b>{data.action.label}</b> <b>{data.action.label.replaceAll("_", " ")}</b>
</div> </div>
<div style={{ fontSize: 14 }}> <div style={{ fontSize: 14 }}>
<Typography variant="body2" color="textSecondary"> <Typography variant="body2" color="textSecondary">
+8 -2
View File
@@ -2511,10 +2511,16 @@ const AppCreator = (defaultprops) => {
scheme: "basic", scheme: "basic",
}; };
} else if (authenticationOption === "Oauth2") { } else if (authenticationOption === "Oauth2") {
console.log("oauth2: ", parameterName) console.log("oauth2: ", parameterName)
var newparamName = parameterName.replaceAll('"', ""); var newparamName = parameterName.replaceAll('"', "");
newparamName = newparamName.replaceAll("'", ""); newparamName = newparamName.replaceAll("'", "");
// FIXME - this is a hack to get around the fact that the oauth2
// flow is not properly defined
if (oauth2Type === "application") {
newparamName = ""
}
//parameterName, parameterValue, revocationUrl //parameterName, parameterValue, revocationUrl
data.components.securitySchemes["Oauth2"] = { data.components.securitySchemes["Oauth2"] = {
type: "oauth2", type: "oauth2",
@@ -2945,7 +2951,7 @@ const AppCreator = (defaultprops) => {
color="textSecondary" color="textSecondary"
style={{ marginTop: 10 }} style={{ marginTop: 10 }}
> >
Base Authorization URL for Oauth2 Authorization URL for Oauth2
</Typography> </Typography>
<TextField <TextField
required required
+1 -1
View File
@@ -403,7 +403,7 @@ const Apps = (props) => {
return response.json(); return response.json();
}) })
.then((responseJson) => { .then((responseJson) => {
//console.log("Apps: ", responseJson) console.log("Apps: ", responseJson)
//responseJson = sortByKey(responseJson, "large_image") //responseJson = sortByKey(responseJson, "large_image")
//responseJson = sortByKey(responseJson, "is_valid") //responseJson = sortByKey(responseJson, "is_valid")
//setFilteredApps(responseJson.filter(app => !internalIds.includes(app.name) && !(!app.activated && app.generated))) //setFilteredApps(responseJson.filter(app => !internalIds.includes(app.name) && !(!app.activated && app.generated)))
+2 -2
View File
@@ -805,7 +805,7 @@ func deployWorker(image string, identifier string, env []string, executionReques
log.Printf("[ERROR] Failed to start worker container in environment %s: %s", environment, err) log.Printf("[ERROR] Failed to start worker container in environment %s: %s", environment, err)
return err return err
} else { } else {
log.Printf("[INFO] Worker Container %s was created under environment %s for execution %s: docker logs %s", cont.ID, environment, executionRequest.ExecutionId, cont.ID) log.Printf("[INFO][%s] Worker Container created. Environment %s: docker logs %s", executionRequest.ExecutionId, environment, cont.ID)
} }
//stats, err := cli.ContainerInspect(context.Background(), containerName) //stats, err := cli.ContainerInspect(context.Background(), containerName)
@@ -830,7 +830,7 @@ func deployWorker(image string, identifier string, env []string, executionReques
// } // }
//} //}
} else { } else {
log.Printf("[INFO] Worker Container %s was created under environment %s: docker logs %s", cont.ID, environment, cont.ID) log.Printf("[INFO][%s] New Worker created. Environment %s: docker logs %s", executionRequest.ExecutionId, environment, cont.ID)
} }
return nil return nil