Fixed public workflow loading bug

This commit is contained in:
frikky
2022-02-06 04:28:22 +01:00
parent c11051c7eb
commit 6886f9e585
11 changed files with 100 additions and 47 deletions
+2 -2
View File
@@ -2,7 +2,7 @@ module main
go 1.16 go 1.16
//replace github.com/shuffle/shuffle-shared => ../../../shuffle-shared replace github.com/shuffle/shuffle-shared => ../../../shuffle-shared
//replace github.com/frikky/kin-openapi => ../../../../git/kin-openapi //replace github.com/frikky/kin-openapi => ../../../../git/kin-openapi
//replace github.com/frikky/go-elasticsearch => ../../../../git/go-elasticsearch //replace github.com/frikky/go-elasticsearch => ../../../../git/go-elasticsearch
@@ -24,7 +24,7 @@ require (
github.com/h2non/filetype v1.1.3 github.com/h2non/filetype v1.1.3
github.com/nirasan/go-oauth-pkce-code-verifier v0.0.0-20170819232839-0fbfe93532da // indirect github.com/nirasan/go-oauth-pkce-code-verifier v0.0.0-20170819232839-0fbfe93532da // indirect
github.com/satori/go.uuid v1.2.0 github.com/satori/go.uuid v1.2.0
github.com/shuffle/shuffle-shared v0.1.94 github.com/shuffle/shuffle-shared v0.1.95
go4.org v0.0.0-20201209231011-d4a079459e60 // indirect go4.org v0.0.0-20201209231011-d4a079459e60 // indirect
golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce
google.golang.org/api v0.65.0 google.golang.org/api v0.65.0
+9 -2
View File
@@ -1235,7 +1235,14 @@ func checkAdminLogin(resp http.ResponseWriter, request *http.Request) {
//log.Printf("[DEBUG] Got challenge value %s (pre state)", codeChallenge) //log.Printf("[DEBUG] Got challenge value %s (pre state)", codeChallenge)
redirectUrl := url.QueryEscape("http://localhost:5001/api/v1/login_openid") // https://192.168.55.222:3443/api/v1/login_openid
//location := strings.Split(request.URL.String(), "/")
//redirectUrl := url.QueryEscape("http://localhost:5001/api/v1/login_openid")
redirectUrl := url.QueryEscape(fmt.Sprintf("http://%s/api/v1/login_openid", request.Host))
if strings.Contains(request.Host, "shuffle-backend") && !strings.Contains(os.Getenv("BASE_URL"), "shuffle-backend") {
redirectUrl = url.QueryEscape(fmt.Sprintf("%s/api/v1/login_openid", os.Getenv("BASE_URL")))
}
state := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("org=%s&challenge=%s&redirect=%s", org.Id, codeChallenge, redirectUrl))) state := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("org=%s&challenge=%s&redirect=%s", org.Id, codeChallenge, redirectUrl)))
// has to happen after initial value is stored // has to happen after initial value is stored
@@ -1256,7 +1263,7 @@ func checkAdminLogin(resp http.ResponseWriter, request *http.Request) {
} }
} }
log.Printf("[DEBUG] URL: %s", baseSSOUrl) //log.Printf("[DEBUG] OpenID URL: %s", baseSSOUrl)
resp.WriteHeader(200) resp.WriteHeader(200)
resp.Write([]byte(fmt.Sprintf(`{"success": true, "reason": "redirect", "sso_url": "%s"}`, baseSSOUrl))) resp.Write([]byte(fmt.Sprintf(`{"success": true, "reason": "redirect", "sso_url": "%s"}`, baseSSOUrl)))
} }
+1 -1
View File
@@ -16,7 +16,7 @@ services:
depends_on: depends_on:
- backend - backend
backend: backend:
#build: ./backend build: ./backend
image: ghcr.io/frikky/shuffle-backend:nightly image: ghcr.io/frikky/shuffle-backend:nightly
container_name: shuffle-backend container_name: shuffle-backend
hostname: ${BACKEND_HOSTNAME} hostname: ${BACKEND_HOSTNAME}
@@ -1499,7 +1499,7 @@ const Framework = (props) => {
/> />
: :
<div> <div>
TBD: Coming in 1.0.0. Coming in 1.0.0. <a style={{ textDecoration: "none", color: "#f85a3e" }} href="https://shuffler.io/register" target="_blank">Register for Shuffle cloud</a> to try an early version now.
</div> </div>
: null} : null}
</div> </div>
+3 -1
View File
@@ -517,6 +517,8 @@ const AuthenticationOauth2 = (props) => {
backgroundColor: theme.palette.inputColor, backgroundColor: theme.palette.inputColor,
color: "white", color: "white",
padding: 5, padding: 5,
minWidth: 300,
maxWidth: 300,
}} }}
onChange={(e) => { onChange={(e) => {
handleScopeChange(e) handleScopeChange(e)
@@ -542,7 +544,7 @@ const AuthenticationOauth2 = (props) => {
title={"Automatic Refresh (default: true)"} title={"Automatic Refresh (default: true)"}
placement="top" placement="top"
> >
<Checkbox style={{paddingTop: 10}} color="secondary" checked={offlineAccess} onClick={() => { <Checkbox style={{paddingTop: 20}} color="secondary" checked={offlineAccess} onClick={() => {
setOfflineAccess(!offlineAccess) setOfflineAccess(!offlineAccess)
}}/> }}/>
</Tooltip> </Tooltip>
+1 -1
View File
@@ -119,7 +119,7 @@ const OrgHeader = (props) => {
: selectedOrganization.sso_config.openid_token === undefined || : selectedOrganization.sso_config.openid_token === undefined ||
selectedOrganization.sso_config.openid_token.length === 0 selectedOrganization.sso_config.openid_token.length === 0
? "" ? ""
: selectedOrganization.sso_config.openidtoken_ : selectedOrganization.sso_config.openid_token
) )
const [file, setFile] = React.useState(""); const [file, setFile] = React.useState("");
+4 -4
View File
@@ -1154,7 +1154,7 @@ const Admin = (props) => {
}) })
.then((respdata) => { .then((respdata) => {
if (respdata.length === 0) { if (respdata.length === 0) {
alert.error("Failed getting file"); alert.error("Failed getting file. Is it deleted?");
return; return;
} }
@@ -3101,12 +3101,12 @@ const Admin = (props) => {
{fileNamespaces !== undefined && {fileNamespaces !== undefined &&
fileNamespaces !== null && fileNamespaces !== null &&
fileNamespaces.length > 1 ? ( fileNamespaces.length > 1 ? (
<FormControl> <FormControl style={{minWidth: 150, maxWidth: 150,}}>
<InputLabel id="input-namespace-label">Namespace</InputLabel> <InputLabel id="input-namespace-label">File Category</InputLabel>
<Select <Select
labelId="input-namespace-select-label" labelId="input-namespace-select-label"
id="input-namespace-select-id" id="input-namespace-select-id"
style={{ color: "white", minWidth: 100, float: "right" }} style={{ color: "white", minWidth: 150, maxWidth: 150, float: "right" }}
value={selectedNamespace} value={selectedNamespace}
onChange={(event) => { onChange={(event) => {
console.log("CHANGE NAMESPACE: ", event.target); console.log("CHANGE NAMESPACE: ", event.target);
+20 -9
View File
@@ -342,6 +342,7 @@ const AngularWorkflow = (defaultprops) => {
const [executionModalOpen, setExecutionModalOpen] = React.useState(false); const [executionModalOpen, setExecutionModalOpen] = React.useState(false);
const [executionModalView, setExecutionModalView] = React.useState(0); const [executionModalView, setExecutionModalView] = React.useState(0);
const [executionData, setExecutionData] = React.useState({}); const [executionData, setExecutionData] = React.useState({});
const [appsLoaded, setAppsLoaded] = React.useState(false);
const [lastSaved, setLastSaved] = React.useState(true); const [lastSaved, setLastSaved] = React.useState(true);
@@ -552,13 +553,17 @@ const AngularWorkflow = (defaultprops) => {
}) })
.then((responseJson) => { .then((responseJson) => {
if ( if (
responseJson.apikey === undefined || responseJson.success === true &&
(responseJson.apikey === undefined ||
responseJson.apikey.length === 0 || responseJson.apikey.length === 0 ||
responseJson.apikey === null responseJson.apikey === null)
) { ) {
generateApikey(); generateApikey();
} }
setUserSettings(responseJson);
if (responseJson.success === true) {
setUserSettings(responseJson)
}
}) })
.catch((error) => { .catch((error) => {
console.log(error); console.log(error);
@@ -1462,6 +1467,7 @@ const AngularWorkflow = (defaultprops) => {
credentials: "include", credentials: "include",
}) })
.then((response) => { .then((response) => {
setAppsLoaded(true)
if (response.status !== 200) { if (response.status !== 200) {
console.log("Status not 200 for apps :O!"); console.log("Status not 200 for apps :O!");
} }
@@ -1508,6 +1514,7 @@ const AngularWorkflow = (defaultprops) => {
} }
}) })
.catch((error) => { .catch((error) => {
setAppsLoaded(true)
alert.error("App loading error: ", error.toString()); alert.error("App loading error: ", error.toString());
}); });
}; };
@@ -3561,19 +3568,23 @@ const AngularWorkflow = (defaultprops) => {
!graphSetup && !graphSetup &&
Object.getOwnPropertyNames(workflow).length > 0 Object.getOwnPropertyNames(workflow).length > 0
) { ) {
setGraphSetup(true); setGraphSetup(true);
setupGraph(); setupGraph();
console.log("In graph setup")
} else if ( } else if (
// 2nd load - configures cytoscape // 2nd load - configures cytoscape
// //
!established && !established &&
cy !== undefined && cy !== undefined &&
apps !== null && ((apps !== null &&
apps !== undefined && apps !== undefined &&
apps.length > 0 && apps.length > 0) || workflow.public === true) &&
Object.getOwnPropertyNames(workflow).length > 0 && Object.getOwnPropertyNames(workflow).length > 0 &&
authLoaded authLoaded
) { ) {
console.log("In POST graph setup!")
//This part has to load LAST, as it's kind of not async. //This part has to load LAST, as it's kind of not async.
//This means we need everything else to happen first. //This means we need everything else to happen first.
@@ -4203,6 +4214,8 @@ const AngularWorkflow = (defaultprops) => {
'control-point-distance': edgeCurve.distance, 'control-point-distance': edgeCurve.distance,
'control-point-weight': edgeCurve.weight, 'control-point-weight': edgeCurve.weight,
} }
} else {
console.log("FAILED node curve handling")
} }
return edge; return edge;
@@ -10591,7 +10604,6 @@ const AngularWorkflow = (defaultprops) => {
return response.json(); return response.json();
}) })
.then((responseJson) => { .then((responseJson) => {
console.log("FOUND USER FOR: ", username, responseJson)
if (responseJson.success !== false) { if (responseJson.success !== false) {
setCreatorProfile(responseJson) setCreatorProfile(responseJson)
} }
@@ -10668,7 +10680,7 @@ const AngularWorkflow = (defaultprops) => {
<AvatarGroup max={6} style={{marginLeft: 10, }}> <AvatarGroup max={6} style={{marginLeft: 10, }}>
{appGroup.map((data, index) => { {appGroup.map((data, index) => {
return ( return (
<Link to={`/apps/${data.app_id}`}> <Link key={index} to={`/apps/${data.app_id}`}>
<Avatar alt={data.app_name} src={data.large_image} style={{width: 30, height: 30}}/> <Avatar alt={data.app_name} src={data.large_image} style={{width: 30, height: 30}}/>
</Link> </Link>
) )
@@ -12302,8 +12314,7 @@ const parsedExecutionArgument = () => {
{leftView} {leftView}
{workflow.id === undefined || {workflow.id === undefined ||
workflow.id === null || workflow.id === null ||
apps.length === 0 ? ( appsLoaded === false ? (
<div <div
style={{ style={{
width: bodyWidth - leftBarSize - 15, width: bodyWidth - leftBarSize - 15,
+1
View File
@@ -5036,6 +5036,7 @@ const AppCreator = (defaultprops) => {
marginTop: "5px", marginTop: "5px",
marginRight: "15px", marginRight: "15px",
backgroundColor: inputColor, backgroundColor: inputColor,
maxHeight: 200,
}} }}
fullWidth={true} fullWidth={true}
type="name" type="name"
+9 -4
View File
@@ -32,9 +32,6 @@ const useStyles = makeStyles({
}); });
const LoginDialog = (props) => { const LoginDialog = (props) => {
const theme = useTheme();
let navigate = useNavigate();
const { const {
globalUrl, globalUrl,
isLoaded, isLoaded,
@@ -45,6 +42,10 @@ const LoginDialog = (props) => {
checkLogin, checkLogin,
} = props; } = props;
const theme = useTheme();
let navigate = useNavigate();
const classes = useStyles();
const [username, setUsername] = useState(""); const [username, setUsername] = useState("");
const [password, setPassword] = useState(""); const [password, setPassword] = useState("");
const [firstRequest, setFirstRequest] = useState(true); const [firstRequest, setFirstRequest] = useState(true);
@@ -58,7 +59,10 @@ const LoginDialog = (props) => {
// Used to swap from login to register. True = login, false = register // Used to swap from login to register. True = login, false = register
const classes = useStyles(); useEffect(() => {
checkAdmin()
}, [loginViewLoading])
// Error messages etc // Error messages etc
const [loginInfo, setLoginInfo] = useState(""); const [loginInfo, setLoginInfo] = useState("");
@@ -267,6 +271,7 @@ const LoginDialog = (props) => {
}} }}
/> />
</div> </div>
{loginViewLoading ? ( {loginViewLoading ? (
<div style={{ textAlign: "center", marginTop: 50 }}> <div style={{ textAlign: "center", marginTop: 50 }}>
<Typography <Typography
+31 -4
View File
@@ -1596,6 +1596,7 @@ const Workflows = (props) => {
{appGroup.map((data, index) => { {appGroup.map((data, index) => {
return ( return (
<div <div
key={index}
style={{ style={{
height: 24, height: 24,
width: 24, width: 24,
@@ -1734,6 +1735,8 @@ const Workflows = (props) => {
justifyContent: "left", justifyContent: "left",
overflow: "hidden", overflow: "hidden",
marginTop: 5, marginTop: 5,
maxHeight: 28,
overflow: "hidden",
}} }}
> >
{data.tags !== undefined && data.tags !== null {data.tags !== undefined && data.tags !== null
@@ -2055,15 +2058,38 @@ const Workflows = (props) => {
const data = params.row.record; const data = params.row.record;
const actions = data.actions !== null ? data.actions.length : 0; const actions = data.actions !== null ? data.actions.length : 0;
let [triggers, subflows] = getWorkflowMeta(data); let [triggers, subflows] = getWorkflowMeta(data);
const appGroup = getWorkflowAppgroup(data)
return ( return (
<Grid item> <Grid item>
<div style={{ display: "flex" }}> <div style={{ display: "flex" }}>
<Tooltip {appGroup.length > 0 ?
color="primary" <div style={{display: "flex", marginTop: 3, }}>
title="Action amount" <AvatarGroup max={4} style={{marginLeft: 5, maxHeight: 24,}}>
placement="bottom" {appGroup.map((data, index) => {
return (
<div
key={index}
style={{
height: 24,
width: 24,
filter: "brightness(0.6)",
cursor: "pointer",
}}
onClick={() => {
addFilter(data.app_name);
}}
> >
<Tooltip color="primary" title={data.app_name} placement="bottom">
<Avatar alt={data.app_name} src={data.large_image} style={{width: 24, height: 24}}/>
</Tooltip>
</div>
)
})}
</AvatarGroup>
</div>
:
<Tooltip color="primary" title="Action amount" placement="bottom">
<span style={{ color: "#979797", display: "flex" }}> <span style={{ color: "#979797", display: "flex" }}>
<BubbleChartIcon <BubbleChartIcon
style={{ marginTop: "auto", marginBottom: "auto" }} style={{ marginTop: "auto", marginBottom: "auto" }}
@@ -2079,6 +2105,7 @@ const Workflows = (props) => {
</Typography> </Typography>
</span> </span>
</Tooltip> </Tooltip>
}
<Tooltip <Tooltip
color="primary" color="primary"
title="Trigger amount" title="Trigger amount"