Fixed public workflow loading bug
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -116,10 +116,10 @@ const OrgHeader = (props) => {
|
|||||||
const [openidToken, setOpenidToken] = React.useState(
|
const [openidToken, setOpenidToken] = React.useState(
|
||||||
selectedOrganization.sso_config === undefined
|
selectedOrganization.sso_config === undefined
|
||||||
? ""
|
? ""
|
||||||
: 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("");
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
Reference in New Issue
Block a user