Fixed a bunch of form deploy systems

This commit is contained in:
Frikky
2024-10-18 10:24:40 +02:00
parent 691af569fa
commit 01a23bff41
16 changed files with 730 additions and 410 deletions
@@ -344,12 +344,13 @@ const AuthenticationData = (props) => {
onClick={() => {
setAuthenticationModalOpen(false);
}}
color="primary"
color="secondary"
>
Cancel
</Button>
<Button
style={{ borderRadius: "0px" }}
variant="outlined"
onClick={() => {
setAuthenticationOptions(authenticationOption);
handleSubmitCheck();
@@ -104,14 +104,19 @@ const AuthenticationData = (props) => {
toast("Failed to set app auth: " + responseJson.reason);
}
} else {
setSubmitSuccessful(true)
if (getAppAuthentication !== undefined) {
getAppAuthentication(true, false);
}
setSubmitSuccessful(true)
if (getAppAuthentication !== undefined) {
if (setAuthenticationModalOpen !== undefined) {
setAuthenticationModalOpen(false)
}
if (workflow !== undefined && workflow !== null && workflow.org_id !== undefined && workflow.org_id !== null && workflow.org_id.length > 0) {
getAppAuthentication(true, false, undefined, workflow.org_id)
} else {
getAppAuthentication(true, false)
}
}
if (setAuthenticationModalOpen !== undefined) {
setAuthenticationModalOpen(false)
}
}
})
.catch((error) => {
+4 -8
View File
@@ -1097,7 +1097,7 @@ const Billing = (props) => {
</Button>
) : (
<Button
variant="contained"
variant="outlined"
color="primary"
onClick={toggleEditMode}
style={{ textTransform: 'none' }}
@@ -1191,7 +1191,6 @@ const Billing = (props) => {
height: 40,
fontSize: 16,
color: "white",
backgroundColor: "#f86743",
textTransform: 'none',
cursor: getProfessionalServices ? 'pointer' : 'not-allowed',
opacity: getProfessionalServices ? 1 : 0.6,
@@ -1202,7 +1201,7 @@ const Billing = (props) => {
}
}}
>
Get Professional Service
Use Professional Service Hours
</Button>
</span>
</Tooltip>
@@ -1368,7 +1367,7 @@ const Billing = (props) => {
<Button
fullWidth
disabled={false}
variant="outlined"
variant="contained"
color="primary"
style={{
marginTop: 10,
@@ -1376,7 +1375,6 @@ const Billing = (props) => {
height: 40,
fontSize: 16,
color: "white",
backgroundColor: "#f86743",
textTransform: 'none'
}}
onClick={() => {
@@ -1403,8 +1401,6 @@ const Billing = (props) => {
borderRadius: 25,
height: 40,
fontSize: 16,
color: "white",
backgroundColor: "#f86743",
textTransform: 'none'
}}
onClick={() => {
@@ -2446,4 +2442,4 @@ const Billing = (props) => {
)
}
export default Billing;
export default Billing;
+13 -14
View File
@@ -626,13 +626,13 @@ const EditWorkflow = (props) => {
<Typography variant="body1" style={{marginTop: 50, }}>
MSSP Suborg Distribution (beta - contact support@shuffler.io for more info)
MSSP Suborg Distribution (<b>beta</b> - contact support@shuffler.io for more info)
</Typography>
{userdata !== undefined && userdata !== null && userdata.orgs !== undefined && userdata.orgs !== null && userdata.orgs.length > 0 ?
userdata.orgs.filter(org => org.creator_org === userdata.active_org.id).length === 0 ?
userdata.active_org.creator_org === undefined || userdata.active_org.creator_org === null || userdata.active_org.creator_org === "" ?
<Typography variant="body2" style={{marginTop: 10, color: "rgba(255,255,255,0.7)"}}>
Your organization does not have any suborgs yet, OR you may not have access to any suborgs directly.. Please <a href="/admin?tab=suborgs" style={{textDecoration: "none", color: "#f86a3e"}} target="_blank">make one</a> or get access to suborgs by admin, then try again.
Your organization does not have any suborgs yet OR your user may not have access to available suborgs. Please <a href="/admin?tab=suborgs" style={{textDecoration: "none", color: "#f86a3e"}} target="_blank">make one</a> or get access to suborgs by another admin, then try again.
</Typography>
:
<Typography variant="body2" style={{marginTop: 10, color: "rgba(255,255,255,0.7)"}}>
@@ -738,9 +738,7 @@ const EditWorkflow = (props) => {
Git Backup Repository
</Typography>
<Typography variant="body2" style={{ textAlign: "left", marginTop: 5, }} color="textSecondary">
Decide where this workflow is backed up in a Git repository. Will create logs and notifications if upload fails. <b>The repository and branch must already have been initialized</b>. Files will show up in the root folder in the format 'orgid/workflow status/workflow id.json' without images. Overrides the <a href="/admin?admin_tab=organization" style={{textDecoration: "none", color: "#f86a3e"}} target="_blank">default backup repository</a> your org has chosen. All fields must be filled in for the backup to work.
<br />
PS: This is a beta feature, and might not work as expected. Credentials are NOT encrypted.
Decide where this workflow is backed up in a Git repository. Will create logs and notifications if upload fails. <b>The repository and branch must already have been initialized</b>. Files will show up in the root folder in the format 'orgid/workflow status/workflow id.json' without images. Overrides your <a href="/admin?admin_tab=organization" style={{textDecoration: "none", color: "#f86a3e"}} target="_blank">default backup repository</a>. <a href="/docs/configuration#environment-variables" style={{textDecoration: "none", color: "#f86a3e"}} target="_blank">Credentials are encrypted.</a> Creates <a href="/admin?admin_tab=priorities" style={{textDecoration: "none", color: "#f86a3e"}} target="_blank">notifications</a> if it fails.
</Typography>
<Grid container style={{ marginTop: 10, }} spacing={2}>
<Grid item xs={6} style={{}}>
@@ -782,7 +780,6 @@ const EditWorkflow = (props) => {
<span>
<Typography>Branch</Typography>
<TextField
required
style={{
flex: "1",
marginTop: "5px",
@@ -795,7 +792,7 @@ const EditWorkflow = (props) => {
variant="outlined"
multiline={true}
rows={1}
placeholder="The branch to use"
placeholder="The branch to use (default: master)"
defaultValue={innerWorkflow.backup_config === undefined || innerWorkflow.backup_config.upload_branch === undefined || innerWorkflow.backup_config.upload_branch === null || innerWorkflow.backup_config.upload_branch === "" ? "" : innerWorkflow.backup_config.upload_branch}
onChange={(e) => {
innerWorkflow.backup_config.upload_branch = e.target.value
@@ -818,7 +815,6 @@ const EditWorkflow = (props) => {
<span>
<Typography>Username</Typography>
<TextField
required
style={{
flex: "1",
marginTop: "5px",
@@ -831,7 +827,7 @@ const EditWorkflow = (props) => {
id="outlined-with-placeholder"
margin="normal"
variant="outlined"
placeholder="The username to use"
placeholder="Username to use"
defaultValue={innerWorkflow.backup_config === undefined || innerWorkflow.backup_config.upload_username === undefined || innerWorkflow.backup_config.upload_username === null || innerWorkflow.backup_config.upload_username === "" ? "" : innerWorkflow.backup_config.upload_username}
onChange={(e) => {
innerWorkflow.backup_config.upload_username = e.target.value
@@ -864,7 +860,7 @@ const EditWorkflow = (props) => {
variant="outlined"
multiline={true}
rows={1}
placeholder="The API token to use"
placeholder="Your API token. Required."
defaultValue={innerWorkflow.backup_config === undefined || innerWorkflow.backup_config.upload_token === undefined || innerWorkflow.backup_config.upload_token === null || innerWorkflow.backup_config.upload_token === "" ? "" : innerWorkflow.backup_config.upload_token}
onChange={(e) => {
innerWorkflow.backup_config.upload_token = e.target.value
@@ -1032,7 +1028,7 @@ const EditWorkflow = (props) => {
Input Markdown
</Typography>
<Typography variant="body2" color="textSecondary" style={{marginBottom: 20, }}>
Markdown will be shown on the <a href={`/forms/${workflow.id}`} rel="noopener noreferrer" target="_blank" style={{ textDecoration: "none", color: "#f86a3e" }}>Form page</a>. Output for a Workflow is also shown in Markdown, and is controlled by the LAST action that runs.
Markdown will be shown on the <a href={`/forms/${workflow.id}`} rel="noopener noreferrer" target="_blank" style={{ textDecoration: "none", color: "#f86a3e" }}>Form page</a>. The first image added will be used in your Form Toolbox list. Output for a Workflow is shown in Markdown, and is controlled by the LAST action that runs. Supports HTML.
</Typography>
<TextField
multiline
@@ -1098,7 +1094,7 @@ const EditWorkflow = (props) => {
<MenuItem value="none">
<em>None</em>
</MenuItem>
{workflow.actions.map((action, actionIndex) => {
{workflow?.actions?.map((action, actionIndex) => {
return (
<MenuItem
key={actionIndex}
@@ -1121,14 +1117,17 @@ const EditWorkflow = (props) => {
<Tooltip color="primary" title={"Add more details"} placement="top">
<Button
style={{ margin: "auto", marginTop: 50, textAlign: "center", }}
style={{ margin: "auto", marginTop: 50, textAlign: "center", textTransform: "none", }}
variant="outlined"
disabled={newWorkflow === true}
color="secondary"
onClick={() => {
setShowMoreClicked(!showMoreClicked);
}}
>
{showMoreClicked ? <ExpandLessIcon /> : <ExpandMoreIcon/>}
{showMoreClicked ? <ExpandLessIcon style={{marginRight: 10, }}/> : <ExpandMoreIcon style={{marginRight: 10, }}/>}
{showMoreClicked ? "Less Options": "More Options"}
</Button>
</Tooltip>
</div>
+17 -41
View File
@@ -142,7 +142,7 @@ const Header = (props) => {
const [anchorElAvatar, setAnchorElAvatar] = React.useState(null);
const [subAnchorEl, setSubAnchorEl] = React.useState(null);
const [upgradeHovered, setUpgradeHovered] = React.useState(false);
const [showTopbar, setShowTopbar] = useState(false)
const [showTopbar, setShowTopbar] = useState(false) // Set to true to show top bar
const stripeKey = typeof window === 'undefined' || window.location === undefined ? "" : window.location.origin === "https://shuffler.io" ? "pk_live_51PXYYMEJjT17t98N20qEqItyt1fLQjrnn41lPeG2PjnSlZHTDNKHuisAbW00s4KAn86nGuqB9uSVU4ds8MutbnMU00DPXpZ8ZD" : "pk_test_51PXYYMEJjT17t98NbDkojZ3DRvsFUQBs35LGMx3i436BXwEBVFKB9nCvHt0Q3M4MG3dz4mHheuWvfoYvpaL3GmsG00k1Rb2ksO"
let navigate = useNavigate();
const classes = useStyles();
@@ -171,15 +171,13 @@ const Header = (props) => {
setTooltipOpen(true);
};
const topbar_var = "topbar_closed4"
const topbar_var = "topbar_closed5"
useEffect(() => {
// Manually setShowTopbar(true) to show topbar by default
const topbar = localStorage.getItem(topbar_var)
if (topbar === "true") {
setShowTopbar(false)
} else {
setShowTopbar(true)
}
}
}, [])
const hoverColor = "#f85a3e";
@@ -433,29 +431,18 @@ const Header = (props) => {
</Link>
<Divider style={{ marginTop: 10, marginBottom: 10, }} />
<Link to="/admin?admin_tab=priorities" style={hrefStyle}>
<MenuItem
onClick={(event) => {
handleClose();
}}
>
<NotificationsIcon style={{ marginRight: 5 }} /> Notifications ({
notifications === undefined || notifications === null ? 0 :
notifications?.filter((notification) => notification.read === false).length
})
</MenuItem>
</Link>
{/*
<Link to="/getting-started" style={hrefStyle}>
<MenuItem
onClick={(event) => {
handleClose();
}}
>
<AnalyticsIcon style={{marginRight: 5 }}/> Get Started
</MenuItem>
</Link>
*/}
<Link to="/admin?admin_tab=priorities" style={hrefStyle}>
<MenuItem
onClick={(event) => {
handleClose();
}}
>
<NotificationsIcon style={{ marginRight: 5 }} /> Notifications ({
notifications === undefined || notifications === null ? 0 :
notifications?.filter((notification) => notification.read === false).length
})
</MenuItem>
</Link>
<Link to="/usecases2" style={hrefStyle}>
<MenuItem
onClick={(event) => {
@@ -466,19 +453,8 @@ const Header = (props) => {
</MenuItem>
</Link>
{/*userdata?.public_username === undefined || userdata?.public_username === null || userdata?.public_username.length <= 0 ? null :
<Link to={`/creators/${userdata.public_username}`} style={hrefStyle}>
<MenuItem
onClick={(event) => {
handleClose();
}}
>
<EmojiObjectsIcon style={{ marginRight: 5 }} /> Creator page
</MenuItem>
</Link>
*/}
<Divider style={{ marginTop: 10, marginBottom: 10, }} />
<Link to="/docs" style={hrefStyle}>
<MenuItem
onClick={(event) => {
+13 -8
View File
@@ -460,16 +460,16 @@ const AuthenticationOauth2 = (props) => {
}
if (
authenticationType.refresh_uri !== undefined &&
authenticationType.refresh_uri !== null &&
authenticationType.refresh_uri.length > 0
) {
state += `%26refresh_uri%3d${authenticationType.refresh_uri}`;
if (authenticationType.refresh_uri !== undefined && authenticationType.refresh_uri !== null && authenticationType.refresh_uri.length > 0) {
state += `%26refresh_uri%3d${authenticationType.refresh_uri}`
} else {
state += `%26refresh_uri%3d${authentication_url}`;
state += `%26refresh_uri%3d${authentication_url}`
}
if (workflow.org_id !== undefined && workflow.org_id !== null && workflow.org_id.length > 0) {
state += `%26org_id%3d${workflow.org_id}`
}
// FIXME: Should this be =consent?
var defaultPrompt = "login"
if (prompt !== undefined && prompt !== null && prompt.length > 0) {
@@ -524,7 +524,12 @@ const AuthenticationOauth2 = (props) => {
//alert('"Secure Payment" window closed!');
if (getAppAuthentication !== undefined) {
getAppAuthentication(true, true, true, selectedAction.id)
// This should be orgId, not action Id as to load auth properly
if (workflow !== undefined && workflow !== null && workflow.org_id !== undefined && workflow.org_id !== null && workflow.org_id.length > 0) {
getAppAuthentication(true, true, true, workflow.org_id)
} else {
getAppAuthentication(true, true, true)
}
}
toast("Authentication successful!")
+2 -40
View File
@@ -382,46 +382,8 @@ const OrgHeaderexpanded = (props) => {
})
.catch((err) => {
console.log("error for sso test is: ", err);
});
};
const HandleTestSSO = () => {
const url = `${globalUrl}/api/v1/orgs/${selectedOrganization?.id}/change`;
const data = {
org_id: selectedOrganization?.id,
sso_test: true,
}
fetch(url, {
mode: "cors",
credentials: "include",
crossDomain: true,
method: "POST",
body: JSON.stringify(data),
withCredentials: true,
headers: {
"Content-Type": "application/json; charset=utf-8",
},
}).then((response) => {
if (response.status !== 200) {
toast.error("Failed to test sso. Please try again later or contact support@shuffler.io if issue persist.")
return
}
return response.json();
}).then((responjson) => {
if (responjson["reason"] === "SSO_REDIRECT") {
setTimeout(() => {
toast.info("Redirecting to SSO login page as SSO is required for this organization.")
window.location.href = responjson["url"];
return
}, 2000)
} else {
toast.error("No SSO found for this org. Please set up sso for this org.")
}
}).catch((err) => {
console.log("error for sso test is: ", err)
})
}
})
}
return (
<div style={{ textAlign: "center" }}>
+4 -34
View File
@@ -207,7 +207,6 @@ const ParsedAction = (props) => {
}
}, [expansionModalOpen])
useEffect(() => {
if (selectedActionEnvironment === undefined || selectedActionEnvironment === null || Object.keys(selectedActionEnvironment).length === 0) {
@@ -224,20 +223,6 @@ const ParsedAction = (props) => {
}
}, [])
/*
useEffect(() => {
setParamValues(selectedAction.parameters.map((param) => {
return {
name: param.name,
value: param.value,
}
}))
},[
selectedAction, selectedApp,setNewSelectedAction, workflow,
])
*/
useEffect(() => {
if (selectedAction.parameters === null || selectedAction.parameters === undefined) {
return
@@ -1855,6 +1840,7 @@ const ParsedAction = (props) => {
</div>
</span>
)}
{selectedApp.name !== undefined &&
selectedAction.authentication !== null &&
selectedAction.authentication !== undefined &&
@@ -1937,8 +1923,8 @@ const ParsedAction = (props) => {
selectedAction.parameters[key].value = ""
}
}
setSelectedAction(selectedAction);
setUpdate(Math.random());
setSelectedAction(selectedAction)
setUpdate(Math.random())
} else if (e.target.value === "authgroups") {
if (authGroups !== undefined && authGroups !== null && authGroups.length === 0) {
@@ -2051,14 +2037,6 @@ const ParsedAction = (props) => {
</Select>
{/*
<Button fullWidth style={{margin: "auto", marginTop: "10px",}} color="primary" variant="contained" onClick={() => setAuthenticationModalOpen(true)}>
AUTHENTICATE
</Button>
curaction.authentication = authenticationOptions
if (curaction.selectedAuthentication === null || curaction.selectedAuthentication === undefined || curaction.selectedAuthentication.length === "")
*/}
<Tooltip
color="primary"
title={"Add authentication option"}
@@ -4163,20 +4141,12 @@ const ParsedAction = (props) => {
/*<div style={{width: 17, height: 17, borderRadius: 17 / 2, backgroundColor: itemColor, marginRight: 10, marginTop: 2, marginTop: "auto", marginBottom: "auto",}}/>*/
}
const buttonTitle = `Authenticate ${selectedApp.name.replaceAll("_", " ")}`
const buttonTitle = `Authenticate API ${selectedApp.name.replaceAll("_", " ")}`
const hasAutocomplete = data?.autocompleted === true
if (data.variant === undefined || data.variant === null) {
data.variant = "STATIC_VALUE"
}
/*
if (data?.configuration === true) {
if (data?.name === "url" && authenticationType?.type === "oauth2-app") {
data.configuration = false
}
}
*/
return (
<div key={data.name}>
{/* {hideBodyButton} */}
+7 -7
View File
@@ -47,7 +47,7 @@ const chipStyle = {
const searchClient = algoliasearch("JNSS5CFDZZ", "db08e40265e2941b9a7d8f644b6e5240")
const SearchData = props => {
const { serverside, globalUrl, userdata, setModalOpen, modalOpen } = props
const { serverside, globalUrl, userdata, searchBarModalOpen, setSearchBarModalOpen } = props
let navigate = useNavigate();
const borderRadius = 3
const node = useRef()
@@ -56,8 +56,8 @@ const SearchData = props => {
const [value, setValue] = useState("");
const handleLinkClick = () => {
if (modalOpen) {
setModalOpen(false); // Assuming setModalOpen is defined correctly
if (searchBarModalOpen) {
setSearchBarModalOpen(false); // Assuming setModalOpen is defined correctly
} else {
console.log("Condition not met, staying on the same page");
}
@@ -95,7 +95,7 @@ const SearchData = props => {
const trimmedValue = inputValue.trim();
if (trimmedValue !== '') {
navigate(`/search?q=${trimmedValue}`, { state: trimmedValue, replace: true });
setModalOpen(false);
setSearchBarModalOpen(false);
}
}
};
@@ -249,7 +249,7 @@ const SearchData = props => {
<Link key={hit.objectID} to={parsedUrl} rel="noopener noreferrer" style={{ textDecoration: "none", color: "white", }} onClick={(event) => {
//console.log("CLICK")
setSearchOpen(true)
setModalOpen(false)
setSearchBarModalOpen(false)
aa('init', {
appId: searchClient.appId,
apiKey: searchClient.transporter.queryParameters["x-algolia-api-key"]
@@ -498,7 +498,7 @@ const SearchData = props => {
return (
<Link key={hit.objectID} to={parsedUrl} style={{ textDecoration: "none", color: "white", }} onClick={(event) => {
setSearchOpen(true)
setModalOpen(false)
setSearchBarModalOpen(false)
aa('init', {
appId: searchClient.appId,
apiKey: searchClient.transporter.queryParameters["x-algolia-api-key"]
@@ -702,7 +702,7 @@ const SearchData = props => {
console.log("CLICK")
setSearchOpen(true)
setModalOpen(false)
setSearchBarModalOpen(false)
}}>
<ListItem key={hit.objectID} style={innerlistitemStyle} onMouseOver={() => {
setMouseHoverIndex(index)
+13 -9
View File
@@ -1,9 +1,11 @@
import React, { useState, useEffect, useRef } from 'react';
import React, { useState, useEffect, useRef, useContext } from 'react';
import theme from '../theme.jsx';
import { useNavigate, Link, useParams } from "react-router-dom";
import SearchBox from "../components/SearchData.jsx";
import { Context } from '../Context/contextApi.js';
import {
Chip,
IconButton,
@@ -45,20 +47,22 @@ const chipStyle = {
const SearchField = props => {
const { serverside, userdata, isMobile, isLoaded, globalUrl, isHeader, isLoggedIn, small, rounded } = props
const {searchBarModalOpen, setSearchBarModalOpen} = useContext(Context);
let navigate = useNavigate();
const borderRadius = 3
const node = useRef()
const [searchOpen, setSearchOpen] = useState(false)
const [modalOpen, setModalOpen] = React.useState(false);
// const [modalOpen, setModalOpen] = React.useState(false);
const [oldPath, setOldPath] = useState("")
const [value, setValue] = useState("");
useEffect(() => {
Mousetrap.bind(['command+k', 'ctrl+k'], () => {
setModalOpen(true);
setSearchBarModalOpen(true);
return false; // Prevent the default action
});
Mousetrap.bind(['esc'], () => {
setModalOpen(false);
setSearchBarModalOpen(false);
return false; // Prevent the default action
});
@@ -72,9 +76,9 @@ const SearchField = props => {
// console.log("key:", dataValue.key),
//console.log("value:",dataValue.value),
<Dialog
open={modalOpen}
open={searchBarModalOpen}
onClose={() => {
setModalOpen(false);
setSearchBarModalOpen(false);
}}
PaperProps={{
style: {
@@ -92,12 +96,12 @@ const SearchField = props => {
{isHeader ? <div style={{ display: "flex"}}>
<DialogTitle style={{ marginTop: 15, marginLeft: 5, color: "var(--Paragraph-text, #C8C8C8)" }} >Search for Docs, Apps, Workflows and more</DialogTitle>
<Button color="secondary" fullWidth style={{ marginLeft:180, }} onClick={() => {
setModalOpen(false);
setSearchBarModalOpen(false);
}}><CloseIcon /></Button>
</div>
: null}
<DialogContent className='dialog-content' style={{}}>
<SearchBox globalUrl={globalUrl} setModalOpen={setModalOpen} modalOpen={modalOpen} serverside={serverside} userdata={userdata} />
<SearchBox globalUrl={globalUrl} setSearchBarModalOpen={setSearchBarModalOpen} modalOpen={searchBarModalOpen} serverside={serverside} userdata={userdata} />
</DialogContent>
<Divider style={{overflow: "hidden"}}/>
<span style={{display:"flex", width:"100%", height:30}}>
@@ -155,7 +159,7 @@ const SearchField = props => {
color="primary"
placeholder="Search Apps, Workflows, Docs..."
onClick={(event) => {
setModalOpen(true)
setSearchBarModalOpen(true)
}}
limit={5}
/>
@@ -261,8 +261,6 @@ const WorkflowValidationTimeline = (props) => {
relevantactions.push(...newactions)
}
console.log("Relevant actions (return null if 0-1): ", relevantactions)
if (relevantactions.length <= 1) {
return null
}