Merged in all UI fixes

This commit is contained in:
Frikky
2024-07-18 14:41:05 +02:00
parent 0dd5913072
commit 5875745056
12 changed files with 737 additions and 354 deletions
+3 -2
View File
@@ -36,6 +36,7 @@ import edgehandles from "cytoscape-edgehandles";
import cytoscape from "cytoscape";
import { toast } from 'react-toastify';
import { isMobile } from 'react-device-detect';
cytoscape.use(edgehandles)
@@ -2152,7 +2153,7 @@ const AppFramework = (props) => {
{
Object.getOwnPropertyNames(discoveryData).length > 0 ?
<Paper style={{width: 300, maxHeight: 400, overflow: "hidden", zIndex: 12500, padding: 25, paddingRight: 25, backgroundColor: theme.palette.surfaceColor, border: "1px solid rgba(255,255,255,0.2)", position: "absolute", top: -50, left: 50, }}>
<Paper style={{width: 300, maxHeight: 400, overflow: "hidden", zIndex: 12500, padding: 25, paddingRight: 25, backgroundColor: theme.palette.surfaceColor, border: "1px solid rgba(255,255,255,0.2)", position: "absolute", top: -50, left: isMobile?-50: 50, }}>
{paperTitle.length > 0 ?
<span>
<Typography variant="h6" style={{textAlign: "center"}}>
@@ -2321,7 +2322,7 @@ const AppFramework = (props) => {
elements={elements}
minZoom={0.35}
maxZoom={2.00}
style={{width: 560*scale, height: 560*scale, backgroundColor: theme.palette.backgroundColor, margin: "auto",}}
style={{width: isMobile?null:560*scale, height: 560*scale, backgroundColor: theme.palette.backgroundColor, margin: isMobile?null:"auto",}}
stylesheet={frameworkStyle}
boxSelectionEnabled={false}
panningEnabled={false}
+2 -2
View File
@@ -2,7 +2,7 @@ import React, { useState, useEffect, useRef } from "react";
import theme from '../theme.jsx';
import ReactGA from 'react-ga4';
import { useNavigate, Link } from 'react-router-dom';
import { isMobile } from 'react-device-detect';
import { Search as Searchicon, CloudQueue as CloudQueueicon, Code as Codeicon, Close as Closeicon, Folder as Foldericon, LibraryBooks as LibraryBooksicon, Delete as DeleteIcon, Close as CloseIcon, } from '@mui/icons-material';
import aa from 'search-insights'
import Deleteicon from '@mui/icons-material/Delete';
@@ -181,7 +181,7 @@ const AppSearchButtons = (props) => {
width: 319,
height: 395,
flexShrink: 0,
marginLeft: 70,
marginLeft: isMobile? null:70,
marginTop: 68,
position: "absolute",
zIndex: 100,
+358 -62
View File
@@ -41,11 +41,12 @@ import {
Close as CloseIcon,
Delete,
RestaurantRounded,
Cloud,
} from "@mui/icons-material";
//import { useAlert
import { typecost, typecost_single, } from "../views/HandlePaymentNew.jsx";
import BillingStats from "../components/BillingStats.jsx";
import BillingStats from "./BillingStats.jsx";
import { handlePayasyougo } from "../views/HandlePaymentNew.jsx"
import DeleteIcon from '@mui/icons-material/Delete';
@@ -173,10 +174,10 @@ const Billing = (props) => {
const paperStyle = {
padding: 20,
height: "100%",
minHeight: 280,
maxWidth: 400,
width: "100%",
// maxWidth: 400,
width: 340,
height: 480,
// width: "100%",
backgroundColor: theme.palette.platformColor,
borderRadius: theme.palette.borderRadius * 2,
border: "1px solid rgba(255,255,255,0.3)",
@@ -470,9 +471,11 @@ const Billing = (props) => {
style: {
pointerEvents: "auto",
color: "white",
minWidth: 750,
// minWidth: 750,
width: 340,
padding: 30,
maxHeight: 700,
// maxHeight: 700,
height: 480,
overflowY: "auto",
overflowX: "hidden",
zIndex: 10012,
@@ -546,7 +549,7 @@ const Billing = (props) => {
</div>
</DialogContent>
</Dialog>
<div style={{ display: "flex" }}>
<div style={{ display: "flex", width: 340 }}>
{top_text === "Base Cloud Access" && userdata.has_card_available === true ?
<Chip
style={{
@@ -715,14 +718,14 @@ const Billing = (props) => {
userdata.has_card_available === true ?
"While you have a card attached to your account, Shuffle will no longer prevent workflows from running. Billing will occur at the start of each month."
:
isCloud ?
isCloud ?
`You are not subscribed to any plan and are using the free plan with max 10,000 app runs per month. Upgrade to deactivate this limit.`
:
`You are not subscribed to any plan and are using the free, open source plan. This plan has no enforced limits, but scale issues may occur due to CPU congestion.`
`You are not subscribed to any plan and are using the free, open source plan. This plan has no enforced limits, but scale issues may occur due to CPU congestion.`
}
</Typography>
<div style={{ display: 'flex', flexDirection: 'row' }}>
<Typography variant="body2" style={{}}>
<Typography variant="body2" style={{ marginTop: !userdata.has_card_available ? 5 : 0 }}>
Billing email: {BillingEmail}
</Typography>
{userdata.has_card_available === true && (
@@ -741,7 +744,7 @@ const Billing = (props) => {
boxShadow: 'none',
border: 'none',
cursor: 'pointer',
transition: 'background-color 0.3s, color 0.3s'
transition: 'background-color 0.3s, color 0.3s',
}}
>
Change
@@ -813,12 +816,13 @@ const Billing = (props) => {
variant="outlined"
color="primary"
style={{
marginTop: 10,
marginTop: !userdata.has_card_available ? 20 : 10,
borderRadius: 25,
height: 40,
fontSize: 14,
fontSize: 16,
color: "white",
backgroundImage: userdata.has_card_available ? null : "linear-gradient(to right, #f86a3e, #f34079)",
textTransform: "none",
}}
onClick={() => {
@@ -847,9 +851,10 @@ const Billing = (props) => {
marginTop: 10,
borderRadius: 25,
height: 40,
fontSize: 14,
fontSize: 16,
color: "white",
backgroundImage: "linear-gradient(to right, #f86a3e, #f34079)",
textTransform: 'none'
}}
onClick={() => {
if (isCloud) {
@@ -904,9 +909,11 @@ const Billing = (props) => {
const [editConsultation, setEditConsultation] = React.useState(false);
const [openUpgradePlan, setOpenUpgradePlan] = React.useState(false);
const [consultationHours, setConsultationHours] = React.useState(5);
const [consultationHours, setConsultationHours] = React.useState(1);
const [message, setMessage] = React.useState("");
const [hovered, setHovered] = React.useState(false)
const [getProfessionalServices, setGetProfessionalServices] = React.useState(false)
const [clickOnBuy, setClickOnBuy] = React.useState(false)
const formatedHours = String(inputHour).padStart(2, "0")
const formatedMinutes = String(inputMinutes).padStart(2, "0")
@@ -959,13 +966,17 @@ const Billing = (props) => {
return response.json();
})
.then((responseJson) => {
console.log("Response from consultation save: ", responseJson);
if (responseJson.success === true) {
toast.success("Consultation hours saved successfully");
setEditConsultation(false);
} else {
toast.error("Failed saving consultation hours.");
}
if (inputHour > 0 || inputMinutes > 0) {
setGetProfessionalServices(true)
} else {
setGetProfessionalServices(false)
}
})
.catch((error) => {
console.log("Error: ", error);
@@ -1001,7 +1012,6 @@ const Billing = (props) => {
return response.json();
})
.then((responseJson) => {
console.log("Response from consultation save: ", responseJson);
if (responseJson.success === true) {
toast.success("Thank you for your request. We will get back to you soon.");
setOpenUpgradePlan(false);
@@ -1015,18 +1025,23 @@ const Billing = (props) => {
});
}
var newPaperstyle = JSON.parse(JSON.stringify(paperStyle))
useEffect(() => {
if (inputHour !== undefined && inputMinutes !== undefined && inputHour > 0 || inputMinutes > 0) {
setGetProfessionalServices(true)
} else {
setGetProfessionalServices(false)
}
})
return (
<Paper style={{
padding: 20,
height: "100%",
minHeight: 280,
maxWidth: 400,
width: "100%",
// maxWidth: 400,
minWidth: 340,
height: 480,
backgroundColor: hovered ? "#232427" : theme.palette.platformColor,
borderRadius: theme.palette.borderRadius * 2,
border: "1px solid rgba(255,255,255,0.3)",
border: "1px solid #f85a3e",
marginRight: 10,
marginTop: 15,
}}
@@ -1041,9 +1056,9 @@ const Billing = (props) => {
</Typography>
<div>
<Typography variant="body2" color="textSecondary" style={{ marginTop: 10, }}>
Current Plan includes total {inputHour} hours and {inputMinutes} minutes of consultation and management by our experts.
You currently have a total of {inputHour} hours and {inputMinutes} minutes of professional services available by our experts.
</Typography>
<div style={{ display: "flex", width: 'auto', justifyContent: 'center', marginTop: 10 }}>
<div style={{ display: "flex", minWidth: 340, justifyContent: 'center', marginTop: userdata.support ? 0 : 10 }}>
{editConsultation ?
<>
<TextField
@@ -1074,6 +1089,7 @@ const Billing = (props) => {
variant="contained"
color="primary"
onClick={handleCancel}
style={{ textTransform: 'none' }}
>
Cancel
</Button>
@@ -1082,48 +1098,113 @@ const Billing = (props) => {
variant="contained"
color="primary"
onClick={toggleEditMode}
style={{ textTransform: 'none' }}
>
Edit
</Button>
)}
{editConsultation && <Button variant="contained" color="primary" style={{ marginLeft: 5 }} onClick={handleSave}>Save</Button>}
{editConsultation && <Button variant="contained" color="primary" style={{ marginLeft: 5, textTransform: 'none' }} onClick={handleSave}>Save</Button>}
</div>
: null}
<Typography variant="body2" color="textSecondary" style={{ marginTop: 10, }}>
<Typography variant="body2" color="textSecondary" style={{ marginTop: userdata.support ? 5 : 10, }}>
Features
</Typography>
<ul>
<li>
<Typography variant="body2" color="textPrimary" style={{}}>
Debug/Create workflows with our experts
Build custom apps, integrations, and worklows for your specific use cases or applications
</Typography>
</li>
<li>
<Typography variant="body2" color="textPrimary" style={{}}>
Ask questions and get help with your workflows and integrations by our experts
Help solve / debug / update / add features and capabilities of the platform
</Typography>
</li>
</ul>
</div>
<Button
fullWidth
disabled={false}
variant="outlined"
color="primary"
style={{
marginTop: 10,
borderRadius: 25,
height: 40,
fontSize: 14,
color: "white",
backgroundImage: "linear-gradient(to right, #f86a3e, #f34079)",
}}
onClick={() => {
setOpenUpgradePlan(true)
}}
>
Upgrade plan
</Button>
<div style={{ display: 'flex', flexDirection: 'column', justifyContent: 'space-between', marginTop: 20 }}>
<Button
fullWidth
disabled={false}
variant="outlined"
color="primary"
style={{
marginTop: userdata.support ? 0 : 10,
borderRadius: 25,
height: 40,
fontSize: 16,
color: "white",
backgroundImage: "linear-gradient(to right, #f86a3e, #f34079)",
textTransform: 'none'
}}
onClick={() => {
if (Cloud) {
ReactGA.event({
category: "Billing",
action: "Buy_consultation_hours",
});
}
setClickOnBuy(true)
}}
>
Buy
</Button>
<Dialog open={clickOnBuy} onClose={() => { setClickOnBuy(false) }}>
<Typography variant="body1" style={{ marginTop: 10, textAlign: 'center', padding: 20, fontSize: 18 }}>
You will be taken to Stripe to book professional service hours. You can adjust the number of hours on the left side of the Stripe page.
</Typography>
<DialogContent>
<Button
variant="contained"
color="primary"
style={{ display: 'block', marginLeft: 'auto', marginRight: 'auto', padding: '12px 24px', textTransform: 'none', fontSize: 16 }}
onClick={() => {
if (Cloud) {
ReactGA.event({
category: "Billing",
action: "Buy_consultation_hours",
});
}
const url = userdata.licensed === true
? "https://book.stripe.com/6oEeY23fw2T84M06oq"
: "https://book.stripe.com/00g6rw3fw9hwguI289";
window.open(url, "_blank");
}}
>
Book Professional Service Hours
</Button>
</DialogContent>
</Dialog>
<Tooltip title={!getProfessionalServices ? "Please buy the consultation hours to get this professional service" : ""}>
<span>
<Button
fullWidth
disabled={!getProfessionalServices}
variant="outlined"
color="primary"
style={{
marginTop: userdata.support ? 5 : 10,
borderRadius: 25,
height: 40,
fontSize: 16,
color: "white",
backgroundImage: "linear-gradient(to right, #f86a3e, #f34079)",
textTransform: 'none',
cursor: getProfessionalServices ? 'pointer' : 'not-allowed',
opacity: getProfessionalServices ? 1 : 0.6,
}}
onClick={() => {
if (getProfessionalServices) {
setOpenUpgradePlan(true);
}
}}
>
Get Professional Service
</Button>
</span>
</Tooltip>
</div>
<Dialog open={openUpgradePlan}
onClose={() => setOpenUpgradePlan(false)}
fullWidth
@@ -1140,20 +1221,21 @@ const Billing = (props) => {
</DialogTitle>
<DialogContent style={{ padding: '24px', }}>
<Typography variant="body1" color="textSecondary" style={{ marginBottom: '16px', textAlign: 'left' }}>
Enter the total hours of consultation you want to include in your plan.
Enter the total hours of consultation you want.
</Typography>
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', marginTop: '16px' }}>
<Slider
value={consultationHours}
onChange={(e, val) => setConsultationHours(val)}
aria-labelledby="continuous-slider"
step={5}
min={5}
max={50}
style={{ width: '80%', color: theme.palette.primary.main }} // Adding primary color for better visibility
step={1}
min={1}
max={(inputHour === "0" && inputMinutes > 0) ? 1 : inputHour}
style={{ width: '80%', color: theme.palette.primary.main }}
marks
valueLabelDisplay="auto"
/>
</div>
<Typography variant="body1" color="textSecondary" style={{ marginTop: '24px', textAlign: 'left' }}>
If you have any additional requirements or questions, please leave a message below.
@@ -1163,17 +1245,17 @@ const Billing = (props) => {
fullWidth
multiline
rows={4}
placeholder="Your message"
placeholder="What kind of services are you looking for?"
style={{ marginTop: '16px', borderRadius: '8px' }}
onChange={(e) => setMessage(e.target.value)}
/>
<Button
variant="contained"
color="primary"
style={{ marginTop: '24px', display: 'block', marginLeft: 'auto', marginRight: 'auto', padding: '12px 24px' }}
style={{ marginTop: '24px', display: 'block', marginLeft: 'auto', marginRight: 'auto', padding: '12px 24px', textTransform: 'none' }}
onClick={handleUpgradeConsultation}
>
Submit Request
Submit Request for {consultationHours} hours
</Button>
</DialogContent>
</Dialog>
@@ -1181,6 +1263,217 @@ const Billing = (props) => {
)
}
const TrainingService = () => {
const [hovered, setHovered] = React.useState(false)
const [openPrivateTraining, setOpenPrivateTraining] = React.useState(false)
const [PrivateTrainingMember, setPrivateTrainingMember] = React.useState(5)
const [message, setMessage] = React.useState("");
const handlePrivateTraining = () => {
toast("Submitting your request for private training. Please wait...")
const data = {
org_id: selectedOrganization.id,
trainingMembers: String(PrivateTrainingMember),
message: message
}
const url = `${globalUrl}/api/v1/orgs/${selectedOrganization.id}/privateTraining`
fetch(url, {
body: JSON.stringify(data),
mode: "cors",
method: "POST",
credentials: "include",
crossDomain: true,
withCredentials: true,
headers: {
"Content-Type": "application/json; charset=utf-8",
},
}).then((response) => {
if (response.status !== 200) {
console.log("Error in response");
}
return response.json();
}).then((responseJson) => {
if (responseJson.success === true) {
toast.success("Your request for private training has been submitted successfully. We will get back to you soon.")
setOpenPrivateTraining(false)
} else {
toast.error("Failed sending request for private training. Please try again later or contact support@shuffler.io for help.")
}
})
}
return (
<Paper
style={{
padding: 20,
height: 480,
// maxWidth: 400,
width: 340,
backgroundColor: hovered ? "#232427" : theme.palette.platformColor,
borderRadius: theme.palette.borderRadius * 2,
border: "1px solid #f85a3e",
marginRight: 10,
marginTop: 15,
}}
onMouseEnter={() => setHovered(true)}
onMouseLeave={() => setHovered(false)}
>
<Typography variant="h6" style={{ marginTop: 10, marginBottom: 10, }}>
Training
</Typography>
<Divider />
<Typography variant="body1" style={{ marginTop: 10, }}>
Become a Shuffle Expert
</Typography>
<div>
<Typography variant="body2" color="textSecondary" style={{ marginTop: 10, }}>
Public Training
</Typography>
<ul>
<li>
<Typography variant="body2" color="textPrimary">
Public course on Automation for Security Professionals
</Typography>
</li>
<li>
<Typography variant="body2" color="textPrimary">
Covers Shuffle Platform, Apps, Workflows, Usecases, JSON, Liquid Formatting, and more.
</Typography>
</li>
</ul>
<Typography variant="body2" color="textSecondary" style={{ marginTop: 10, }}>
Private Training
</Typography>
<ul>
<li>
<Typography variant="body2" color="textPrimary">
Everything from Public Training
</Typography>
</li>
<li>
<Typography variant="body2" color="textPrimary" >
Customized for your teams usecases, date and time, location, and more.
</Typography>
</li>
</ul>
</div>
<div style={{ display: 'flex', flexDirection: 'column', justifyContent: 'space-between', marginTop: 30, width: 340 }}>
<Button
fullWidth
disabled={false}
variant="outlined"
color="primary"
style={{
marginTop: 10,
borderRadius: 25,
height: 40,
fontSize: 16,
color: "white",
backgroundImage: "linear-gradient(to right, #f86a3e, #f34079)",
textTransform: 'none'
}}
onClick={() => {
if (Cloud) {
ReactGA.event({
category: "Billing",
action: "click_public_training_button",
});
}
navigate("/training")
}}
>
Public Training
</Button>
<Button
fullWidth
disabled={false}
variant="outlined"
color="primary"
style={{
marginTop: 10,
borderRadius: 25,
height: 40,
fontSize: 16,
color: "white",
backgroundImage: "linear-gradient(to right, #f86a3e, #f34079)",
textTransform: 'none'
}}
onClick={() => {
if (Cloud) {
ReactGA.event({
category: "Billing",
action: "click_public_training_button",
});
}
setOpenPrivateTraining(true)
}}
>
Private Training
</Button>
<Dialog open={openPrivateTraining}
onClose={() => setOpenPrivateTraining(false)}
fullWidth
style={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}
PaperProps={{
style: {
width: 500,
margin: 0,
}
}}
>
<DialogTitle style={{ marginTop: 10, textAlign: 'center', fontWeight: 'bold' }}>
Private Training
</DialogTitle>
<DialogContent style={{ padding: '24px', }}>
<Typography variant="body1" color="textSecondary" style={{ marginBottom: '16px', textAlign: 'left' }}>
Enter the total members for private training. Minimum 5 members required.
</Typography>
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', marginTop: '16px' }}>
<Slider
value={PrivateTrainingMember}
onChange={(e, val) => setPrivateTrainingMember(val)}
aria-labelledby="continuous-slider"
step={1}
min={5}
max={50}
style={{ width: '80%', color: theme.palette.primary.main }}
marks
valueLabelDisplay="auto"
/>
</div>
<Typography variant="body1" color="textSecondary" style={{ marginTop: '24px', textAlign: 'left' }}>
If you have any additional requirements or questions, please leave a message below.
</Typography>
<TextField
variant="outlined"
fullWidth
multiline
rows={4}
placeholder="Your message"
style={{ marginTop: '16px', borderRadius: '8px' }}
onChange={(e) => setMessage(e.target.value)}
/>
<Button
variant="contained"
color="primary"
style={{ marginTop: '24px', display: 'block', marginLeft: 'auto', marginRight: 'auto', padding: '12px 24px', textTransform: 'none' }}
onClick={handlePrivateTraining}
>
Submit Request
</Button>
</DialogContent>
</Dialog>
</div>
</Paper>
)
}
const addDealModal = (
<Dialog
open={selectedDealModalOpen}
@@ -1623,11 +1916,11 @@ const Billing = (props) => {
{userdata.support === true ?
<div style={{ marginBottom: 10, marginTop: clickedFromOrgTab ? 16 : null, color: clickedFromOrgTab ? "#F1F1F1" : null }}>
For sales: Create&nbsp;
<a href={"https://docs.google.com/document/d/1N-ZJNn8lWaqiXITrqYcnTt53oXGLNYFEzc5PU-tdAps/copy" + selectedOrganization.id} target="_blank" rel="noopener noreferrer" style={{ textDecoration: "none", color: "#f85a3e" }}>
<a href={"https://docs.google.com/document/d/1N-ZJNn8lWaqiXITrqYcnTt53oXGLNYFEzc5PU-tdAps/copy"} target="_blank" rel="noopener noreferrer" style={{ textDecoration: "none", color: "#f85a3e" }}>
EU contract
</a>
&nbsp;or&nbsp;
<a href={"https://docs.google.com/document/d/1cF-Cwxt1TcahlLrpl1GH2hFZO4gxppLeYjHW6QB0EzQ/copy" + selectedOrganization.id} target="_blank" rel="noopener noreferrer" style={{ textDecoration: "none", color: "#f85a3e" }}>
<a href={"https://docs.google.com/document/d/1cF-Cwxt1TcahlLrpl1GH2hFZO4gxppLeYjHW6QB0EzQ/copy"} target="_blank" rel="noopener noreferrer" style={{ textDecoration: "none", color: "#f85a3e" }}>
NOT EU contract
</a>
&nbsp; - &nbsp;
@@ -1650,7 +1943,7 @@ const Billing = (props) => {
</Typography>
: null}
<div style={{ display: "flex", maxWidth: 768, minWidth: 768, }}>
<div style={{ display: "flex", width: 1180, overflowX: 'auto', overflowY: 'hidden', scrollbarWidth: 'thin', scrollbarColor: '#494949 #2f2f2f', height: 580 }} >
{isCloud && billingInfo.subscription !== undefined && billingInfo.subscription !== null ? isChildOrg ? null :
<SubscriptionObject
index={0}
@@ -1712,6 +2005,9 @@ const Billing = (props) => {
selectedOrganization={selectedOrganization}
/> : null}
<TrainingService />
{isCloud &&
selectedOrganization.subscriptions !== undefined &&
selectedOrganization.subscriptions !== null &&
@@ -1966,9 +2262,9 @@ const Billing = (props) => {
</div>
) : null*/}
<div style={{ marginTop: 50, marginLeft: 10 }}>
<div style={{ marginTop: 20, marginLeft: 10 }}>
<Typography
style={{ marginTop: 40, marginBottom: 5 }}
style={{ marginBottom: 5 }}
variant="h4"
>
Manage Billing
+1 -1
View File
@@ -690,7 +690,7 @@ const LicencePopup = (props) => {
const priceItem = window.location.origin === "https://shuffler.io" ?
shuffleVariant === 0 ? "app_executions" : "cores"
:
shuffleVariant === 0 ? "price_1PWI5zDzMUgUjxHSKkz0fGdN" : "price_1NXjQqDzMUgUjxHSg690R4FP"
shuffleVariant === 0 ? "price_1PbO0cEJjT17t98NsfEMUlMn" : "price_1PbNnaEJjT17t98NLadq6Lhq"
const successUrl = `${window.location.origin}/admin?admin_tab=billing&payment=success`
const failUrl = `${window.location.origin}/pricing?admin_tab=billing&payment=failure`
+283 -235
View File
@@ -25,9 +25,10 @@ import {
Divider,
LinearProgress,
AppBar,
Dialog,
DialogTitle,
Dialog,
DialogTitle,
} from "@mui/material";
import { makeStyles } from '@mui/styles';
import {
Close as CloseIcon,
@@ -45,10 +46,80 @@ import {
Analytics as AnalyticsIcon,
Lightbulb as LightbulbIcon,
ExpandMore as ExpandMoreIcon,
KeyboardArrowDown as KeyboardArrowDownIcon
} from "@mui/icons-material";
import zIndex from "@mui/material/styles/zIndex.js";
const hoverColor = "#f85a3e";
const hoverOutColor = "#e8eaf6";
const useStyles = makeStyles((theme) => ({
menuButton: {
textTransform: "none !important",
fontStyle: "normal",
color: "#333",
textAlign: "center",
fontSize: "16px !important",
fontWeight: "500 !important",
display: "flex",
alignItems: "center",
'&:hover': {
backgroundColor: "transparent",
},
},
dropdownMenu: {
marginTop: theme.spacing(1),
borderRadius: "12px !important",
zIndex: 10,
"& .MuiPaper-root": {
border: "1px solid #f85a3e",
boxShadow: "0 4px 6px rgba(0, 0, 0, 0.1)",
borderRadius: "12px !important",
top: -10,
overflow: "visible",
background: "#1A1A1A",
"&::before": {
content: '""',
display: "block",
position: "absolute",
top: -10,
left: "82%",
borderLeft: "10px solid transparent",
borderRight: "10px solid transparent",
borderBottom: "10px solid #f85a3e",
},
},
},
dropdownMenuItem: {
padding: theme.spacing(2, 3),
fontSize: "16px",
fontWeight: 400,
color: "#fff",
background: "#1A1A1A",
borderRadius: 16, // Ensure the border radius matches the container
transition: "background-color 0.3s, color 0.3s",
'&:hover': {
color: "#1A73E8",
background: "#3c3c3c",
},
},
menuList: {
display: "flex",
flexDirection: "row",
alignItems: "center",
padding: 0,
margin: 0,
listStyle: "none",
textTransform: "none",
},
cssStcg3yMenuList: {
borderRadius: "12px !important",
},
divider: {
width: "80%",
border: "0.5px solid #494949",
backgroundColor: "#fff",
alignItems: "center",
marginLeft: 17
},
}));
const Header = (props) => {
const {
@@ -64,35 +135,62 @@ const Header = (props) => {
serverside,
billingInfo,
} = props;
const [HomeHoverColor, setHomeHoverColor] = useState(hoverOutColor);
const [SoarHoverColor, setSoarHoverColor] = useState(hoverOutColor);
const [LoginHoverColor, setLoginHoverColor] = useState(hoverOutColor);
const [DocsHoverColor, setDocsHoverColor] = useState(hoverOutColor);
const [HelpHoverColor, setHelpHoverColor] = useState(hoverOutColor);
const [isHeader, setIsHeader] = React.useState(false);
const [modalOpen, setModalOpen] = useState(false);
const [tooltipOpen, setTooltipOpen] = useState(false);
const [anchorEl, setAnchorEl] = React.useState(null);
const [anchorElAvatar, setAnchorElAvatar] = React.useState(null);
const [subAnchorEl, setSubAnchorEl] = React.useState(null);
const [upgradeHovered, setUpgradeHovered] = React.useState(false);
const [showTopbar, setShowTopbar] = useState(false)
const stripeKey = typeof window === 'undefined' || window.location === undefined ? "" : window.location.origin === "https://shuffler.io" ? "pk_live_XAxwE2Fp9DEbEcNYw4UKmyby00vIlIPPRp" : "pk_test_EdxgKfqmQGXY5JLjdBqtuhCw00BHbiKJDB"
const stripeKey = typeof window === 'undefined' || window.location === undefined ? "" : window.location.origin === "https://shuffler.io" ? "pk_live_XAxwE2Fp9DEbEcNYw4UKmyby00vIlIPPRp" : "pk_test_51PXYYMEJjT17t98NbDkojZ3DRvsFUQBs35LGMx3i436BXwEBVFKB9nCvHt0Q3M4MG3dz4mHheuWvfoYvpaL3GmsG00k1Rb2ksO"
let navigate = useNavigate();
const classes = useStyles();
const handleClick = (event) => {
setAnchorEl(event.currentTarget);
};
const handleMenuOpen = (event) => {
setAnchorEl(event.currentTarget);
};
const handleMenuClose = () => {
setAnchorEl(null);
};
const handleMenuItemClick = (path) => {
navigate(path);
handleMenuClose();
};
const handleTooltipClose = () => {
setTooltipOpen(false);
};
const handleTooltipOpen = () => {
setTooltipOpen(true);
};
useEffect(() => {
const topbar = localStorage.getItem("topbar_closed")
if (topbar === "true") {
setShowTopbar(false)
} else {
setShowTopbar(true)
}
const topbar = localStorage.getItem("topbar_closed")
if (topbar === "true") {
setShowTopbar(false)
} else {
setShowTopbar(true)
}
}, [])
const hoverColor = "#f85a3e";
const hoverOutColor = "#e8eaf6";
const handleHover = (event) => {
event.target.style.color = hoverColor;
};
const handleHoverOut = (event) => {
event.target.style.color = hoverOutColor;
};
const handleClose = () => {
setAnchorEl(null);
setAnchorElAvatar(null);
@@ -103,6 +201,10 @@ const Header = (props) => {
const hrefStyle = {
color: hoverOutColor,
textDecoration: "none",
textTransform: "none",
fontStyle: "normal",
width: "100%",
fontSize: "16px",
};
const menuText = {
@@ -229,47 +331,6 @@ const Header = (props) => {
});
};
// Rofl this is weird
const handleDocsHover = () => {
setDocsHoverColor(hoverColor);
};
const handleDocsHoverOut = () => {
setDocsHoverColor(hoverOutColor);
};
const handleHomeHover = () => {
setHomeHoverColor(hoverColor);
};
const handleHelpHover = () => {
setHelpHoverColor(hoverColor);
};
const handleHelpHoverOut = () => {
setHelpHoverColor(hoverOutColor);
};
const handleSoarHover = () => {
setSoarHoverColor(hoverColor);
};
const handleSoarHoverOut = () => {
setSoarHoverColor(hoverOutColor);
};
const handleHomeHoverOut = () => {
setHomeHoverColor(hoverOutColor);
};
const handleLoginHover = () => {
setLoginHoverColor(hoverColor);
};
const handleLoginHoverOut = () => {
setLoginHoverColor(hoverOutColor);
};
const notificationWidth = 335
const imagesize = 22;
const boxColor = "#86c142";
@@ -553,8 +614,8 @@ const Header = (props) => {
aria-haspopup="true"
onClick={(event) => { }}
>
<svg viewBox="0 0 256 199" width="256" height="199" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid" style={{height: 30, width: 30, }}><path d="M216.856 16.597A208.502 208.502 0 0 0 164.042 0c-2.275 4.113-4.933 9.645-6.766 14.046-19.692-2.961-39.203-2.961-58.533 0-1.832-4.4-4.55-9.933-6.846-14.046a207.809 207.809 0 0 0-52.855 16.638C5.618 67.147-3.443 116.4 1.087 164.956c22.169 16.555 43.653 26.612 64.775 33.193A161.094 161.094 0 0 0 79.735 175.3a136.413 136.413 0 0 1-21.846-10.632 108.636 108.636 0 0 0 5.356-4.237c42.122 19.702 87.89 19.702 129.51 0a131.66 131.66 0 0 0 5.355 4.237 136.07 136.07 0 0 1-21.886 10.653c4.006 8.02 8.638 15.67 13.873 22.848 21.142-6.58 42.646-16.637 64.815-33.213 5.316-56.288-9.08-105.09-38.056-148.36ZM85.474 135.095c-12.645 0-23.015-11.805-23.015-26.18s10.149-26.2 23.015-26.2c12.867 0 23.236 11.804 23.015 26.2.02 14.375-10.148 26.18-23.015 26.18Zm85.051 0c-12.645 0-23.014-11.805-23.014-26.18s10.148-26.2 23.014-26.2c12.867 0 23.236 11.804 23.015 26.2 0 14.375-10.148 26.18-23.015 26.18Z" fill="#dadae1"/></svg>
{/*#f865f2*/}
<svg viewBox="0 0 256 199" width="256" height="199" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid" style={{ height: 30, width: 30, }}><path d="M216.856 16.597A208.502 208.502 0 0 0 164.042 0c-2.275 4.113-4.933 9.645-6.766 14.046-19.692-2.961-39.203-2.961-58.533 0-1.832-4.4-4.55-9.933-6.846-14.046a207.809 207.809 0 0 0-52.855 16.638C5.618 67.147-3.443 116.4 1.087 164.956c22.169 16.555 43.653 26.612 64.775 33.193A161.094 161.094 0 0 0 79.735 175.3a136.413 136.413 0 0 1-21.846-10.632 108.636 108.636 0 0 0 5.356-4.237c42.122 19.702 87.89 19.702 129.51 0a131.66 131.66 0 0 0 5.355 4.237 136.07 136.07 0 0 1-21.886 10.653c4.006 8.02 8.638 15.67 13.873 22.848 21.142-6.58 42.646-16.637 64.815-33.213 5.316-56.288-9.08-105.09-38.056-148.36ZM85.474 135.095c-12.645 0-23.015-11.805-23.015-26.18s10.149-26.2 23.015-26.2c12.867 0 23.236 11.804 23.015 26.2.02 14.375-10.148 26.18-23.015 26.18Zm85.051 0c-12.645 0-23.014-11.805-23.014-26.18s10.148-26.2 23.014-26.2c12.867 0 23.236 11.804 23.015 26.2 0 14.375-10.148 26.18-23.015 26.18Z" fill="#dadae1" /></svg>
{/*#f865f2*/}
</IconButton>
</Tooltip>
</a>
@@ -690,67 +751,68 @@ const Header = (props) => {
textAlign: "center",
marginTop: "auto",
marginBottom: "auto",
marginRight: 10,
// marginRight: 10,
};
const modalView =
<Dialog
open={modalOpen}
onClose={() => {
setModalOpen(false);
}}
PaperProps={{
style: {
color: "white",
minWidth: 850,
minHeight: 370,
padding: 20,
backgroundColor: "rgba(0, 0, 0, 1)",
borderRadius: theme.palette.borderRadius,
},
}}
>
<DialogTitle style={{ display: "flex" }}>
<span style={{ color: "white", fontSize: 24 }}>
Upgrade your plan
</span>
<IconButton
onClick={() => {
if (isCloud) {
const modalView =
<Dialog
open={modalOpen}
onClose={() => {
setModalOpen(false);
}}
PaperProps={{
style: {
color: "white",
minWidth: 850,
minHeight: 370,
padding: 20,
backgroundColor: "rgba(0, 0, 0, 1)",
borderRadius: theme.palette.borderRadius,
},
}}
>
<DialogTitle style={{ display: "flex" }}>
<span style={{ color: "white", fontSize: 24 }}>
Upgrade your plan
</span>
<IconButton
onClick={() => {
if (isCloud) {
ReactGA.event({
category: "header",
action: "close_Upgread_popup",
label: "",
})};
setModalOpen(false);
}}
style={{
marginLeft: "auto",
position: "absolute",
top: 20,
right: 20,
}}
>
<CloseIcon />
</IconButton>
</DialogTitle>
<div style={{ paddingLeft: "30px", paddingRight: "30px" }}>
<LicencePopup
serverside={serverside}
removeCookie={removeCookie}
isLoaded={isLoaded}
isLoggedIn={isLoggedIn}
globalUrl={globalUrl}
})
};
setModalOpen(false);
}}
style={{
marginLeft: "auto",
position: "absolute",
top: 20,
right: 20,
}}
>
<CloseIcon />
</IconButton>
</DialogTitle>
<div style={{ paddingLeft: "30px", paddingRight: "30px" }}>
<LicencePopup
serverside={serverside}
removeCookie={removeCookie}
isLoaded={isLoaded}
isLoggedIn={isLoggedIn}
globalUrl={globalUrl}
billingInfo={billingInfo}
billingInfo={billingInfo}
userdata={userdata}
stripeKey={stripeKey}
setModalOpen={setModalOpen}
{...props}
/>
</div>
</Dialog>
userdata={userdata}
stripeKey={stripeKey}
setModalOpen={setModalOpen}
{...props}
/>
</div>
</Dialog>
// Handle top bar or something
const defaultTop = -2
@@ -792,13 +854,13 @@ const Header = (props) => {
</Link>
</ListItem>
</List>
<List style={{ flex: 1.5, display: "flex", flexDirect: "row", marginTop: 10, itemAlign: "center", padding: 0 }} component="nav">
<List className={classes.menuList} component="nav">
<ListItem style={{ textAlign: "center", marginLeft: "0px" }}>
<Link to="/usecases" style={hrefStyle}>
<Button
variant="text"
color="secondary"
style={menuText}
className={classes.menuButton}
onClick={() => {
if (isCloud) {
ReactGA.event({
@@ -813,44 +875,12 @@ const Header = (props) => {
</Button>
</Link>
</ListItem>
{isCloud ? (
<ListItem
style={{
textAlign: "center",
marginLeft: "0px",
paddingRight: 0,
}}
>
<Link to="/pricing" style={hrefStyle}>
<Button
variant="text"
color="secondary"
style={menuText}
onClick={() => {
ReactGA.event({
category: "header",
action: "pricing_click",
label: "",
});
}}
>
Pricing
</Button>
</Link>
</ListItem>
) : null}
<ListItem
style={{
textAlign: "center",
marginLeft: 0,
paddingRight: 0,
}}
>
<ListItem style={{ textAlign: "center", marginLeft: 0, paddingRight: 0 }}>
<Link rel="noopener noreferrer" to="/docs" style={hrefStyle}>
<Button
variant="text"
color="secondary"
style={menuText}
className={classes.menuButton}
onClick={() => { }}
>
Docs
@@ -858,23 +888,62 @@ const Header = (props) => {
</Link>
</ListItem>
<ListItem
style={{
textAlign: "center",
marginLeft: 0,
paddingRight: 0,
}}
style={{ textAlign: "center", marginLeft: "0px", paddingRight: 0 }}
// onMouseEnter={handleMenuOpen}
// onMouseLeave={handleMenuClose}
>
<Button
variant="text"
color="secondary"
className={classes.menuButton}
style={{width:200}}
onClick={handleMenuOpen}
>
Pricing & Services
<KeyboardArrowDownIcon style={{ marginLeft: 4 }} />
</Button>
<Menu
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleMenuClose}
className={classes.dropdownMenu}
classes={{ paper: classes.dropdownMenu }}
MenuListProps={{ className: classes.cssStcg3yMenuList }}
>
{isCloud && (
<MenuItem className={classes.dropdownMenuItem} onClick={() => handleMenuItemClick('/pricing')}>
<Link to="/pricing" style={hrefStyle}>
Pricing
</Link>
</MenuItem>
)}
<div className={classes.divider} />
<MenuItem className={classes.dropdownMenuItem} onClick={() => handleMenuItemClick('/professional-support')}>
<Link to="/professional-support" style={hrefStyle}>
Professional Services
</Link>
</MenuItem>
<div className={classes.divider} />
<MenuItem className={classes.dropdownMenuItem} onClick={() => handleMenuItemClick('/training')}>
<Link to="/training" style={hrefStyle}>
Training Courses
</Link>
</MenuItem>
</Menu>
</ListItem>
{/* <ListItem style={{ textAlign: "center", marginLeft: 0, paddingRight: 0 }}>
<Link rel="noopener noreferrer" to="/training" style={hrefStyle}>
<Button
variant="text"
color="secondary"
style={menuText}
className={classes.menuButton}
onClick={() => { }}
>
Training
</Button>
</Link>
</ListItem>
</ListItem> */}
</List>
<List
style={{ flex: 2, display: "flex", alignItems: "flex-start", padding: 0, }}
@@ -950,7 +1019,7 @@ const Header = (props) => {
margin: "auto",
}}
>
<div style={{ flexDirection: "row" }}>
<div style={{ flexDirection: "row", marginLeft: 0}}>
<List
style={{
height: 56,
@@ -966,9 +1035,9 @@ const Header = (props) => {
<ListItem style={{ textAlign: "center", justifyContent: "center" }}>
<Link to="/" style={hrefStyle}>
<div
onMouseOver={handleHomeHover}
onMouseOut={handleHomeHoverOut}
style={{ color: HomeHoverColor, cursor: "pointer" }}
onMouseOver={handleHover}
onMouseOut={handleHoverOut}
style={{ cursor: "pointer" }}
>
<Grid container direction="row" alignItems="center">
<Grid item style={{}}>
@@ -984,10 +1053,9 @@ const Header = (props) => {
<ListItem style={listItemStyle}>
<Link to="/workflows" style={hrefStyle}>
<div
onMouseOver={handleSoarHover}
onMouseOut={handleSoarHoverOut}
onMouseOver={handleHover}
onMouseOut={handleHoverOut}
style={{
color: SoarHoverColor,
cursor: "pointer",
display: "flex",
marginLeft: 25,
@@ -1005,10 +1073,9 @@ const Header = (props) => {
<ListItem style={listItemStyle}>
<Link to="/apps" style={hrefStyle}>
<div
onMouseOver={handleHelpHover}
onMouseOut={handleHelpHoverOut}
onMouseOver={handleHover}
onMouseOut={handleHoverOut}
style={{
color: HelpHoverColor,
cursor: "pointer",
display: "flex",
}}
@@ -1032,10 +1099,9 @@ const Header = (props) => {
<ListItem style={listItemStyle}>
<Link to="/docs" style={hrefStyle}>
<div
onMouseOver={handleDocsHover}
onMouseOut={handleDocsHoverOut}
onMouseOver={handleHover}
onMouseOut={handleHoverOut}
style={{
color: DocsHoverColor,
cursor: "pointer",
display: "flex",
}}
@@ -1049,6 +1115,25 @@ const Header = (props) => {
</div>
</Link>
</ListItem>
{/*
<ListItem style={listItemStyle}>
<Link to="/admin?admin_tab=billing" style={hrefStyle}>
<div
onMouseOver={handleHover}
onMouseOut={handleHoverOut}
style={{
cursor: "pointer",
display: "flex",
width:170
}}
>
<Typography style={{ marginTop: defaultTop }}>
Pricing & Services
</Typography>
</div>
</Link>
</ListItem>
*/}
</ListItem>
</List>
</div>
@@ -1260,7 +1345,7 @@ const Header = (props) => {
title={""}
placement="left"
>
<div style={{ display: "flex", marginLeft: 50, marginRight: 50, }}>
<div style={{ display: "flex", marginLeft: 50, marginRight: 50, }}>
<AddIcon />
<span style={{ marginLeft: 8 }}>
Add suborgs
@@ -1285,14 +1370,17 @@ const Header = (props) => {
marginRight: 7,
marginTop: 0,
}}
title={upgradeHovered ? "Upgrade License" : ""}
open={tooltipOpen}
onClose={handleTooltipClose}
>
<Link style={hrefStyle}>
<Button
variant="contained"
color="primary"
style={{ textTransform: "none" }}
onMouseOver={() => { setUpgradeHovered(true) }}
onMouseOut={() => { setUpgradeHovered(false) }}
onMouseOver={() => { setUpgradeHovered(true); handleTooltipOpen(); }}
onMouseOut={() => { setUpgradeHovered(false); handleTooltipClose(); }}
onClick={() => {
if (isCloud) {
ReactGA.event({
@@ -1304,11 +1392,11 @@ const Header = (props) => {
setModalOpen(true)
}}
>
{upgradeHovered ?
{/* {upgradeHovered ?
"Upgrade License"
:
"Upgrade"
}
: */}
Upgrade
{/* } */}
</Button>
</Link>
@@ -1397,9 +1485,9 @@ const Header = (props) => {
<ListItem style={{ textAlign: "center" }}>
<Link to="/" style={hrefStyle}>
<div
onMouseOver={handleHomeHover}
onMouseOut={handleHomeHoverOut}
style={{ color: HomeHoverColor, cursor: "pointer" }}
onMouseOver={handleHover}
onMouseOut={handleHoverOut}
style={{ cursor: "pointer" }}
>
<Grid container direction="row" alignItems="center">
<Grid item>
@@ -1421,9 +1509,9 @@ const Header = (props) => {
<ListItem style={{ textAlign: "center" }}>
<Link to="/docs" style={hrefStyle}>
<div
onMouseOver={handleSoarHover}
onMouseOut={handleSoarHoverOut}
style={{ color: SoarHoverColor, cursor: "pointer" }}
onMouseOver={handleHover}
onMouseOut={handleHoverOut}
style={{ cursor: "pointer" }}
>
About
</div>
@@ -1465,9 +1553,7 @@ const Header = (props) => {
<ListItem style={{ textAlign: "center" }}>
<Link to="/" style={hrefStyle}>
<div
onMouseOver={handleHomeHover}
onMouseOut={handleHomeHoverOut}
style={{ color: HomeHoverColor, cursor: "pointer" }}
style={{ cursor: "pointer" }}
>
<Grid container direction="row" alignItems="center">
<Grid item>
@@ -1512,10 +1598,10 @@ const Header = (props) => {
>
<ListItem style={{ flex: "1", textAlign: "center" }}>
<div
onMouseOver={handleLoginHover}
onMouseOut={handleLoginHoverOut}
onMouseOver={handleHover}
onMouseOut={handleHoverOut}
onClick={handleClickLogout}
style={{ color: LoginHoverColor, cursor: "pointer" }}
style={{ cursor: "pointer" }}
>
Logout
</div>
@@ -1541,50 +1627,12 @@ const Header = (props) => {
const topbarHeight = showTopbar ? 40 : 0
const topbar = !isCloud || !showTopbar ? null :
curpath === "/" || curpath.includes("/docs") || curpath === "/pricing" || curpath === "/contact" || curpath === "/search" || curpath === "/usecases" || curpath === "/training" ?
curpath === "/" || curpath.includes("/docs") || curpath === "/pricing" || curpath === "/contact" || curpath === "/search" || curpath === "/usecases" || curpath === "/training" || curpath === "/professional-support" ?
<span style={{ zIndex: 50001, }}>
<div style={{ position: "relative", height: topbarHeight, backgroundImage: "linear-gradient(to right, #f86a3e, #f34079)", overflow: "hidden", }}>
<Typography variant="body1" style={{ paddingTop: 7, margin: "auto", textAlign: "center", color: "white", }}>
{/* Shuffle 1.4.0 is out! Read more about&nbsp; */}
Early Success! More&nbsp;
{/* <u>
<a href="https://github.com/Shuffle/Shuffle/releases/tag/v1.4.0" target="_blank" style={{ color: "inherit", }} onClick={() => {
ReactGA.event({
category: "landingpage",
action: "click_header_features",
label: "",
})
//if (window.drift !== undefined) {
// window.drift.api.startInteraction({ interactionId: 341911 })
//} else {
// console.log("Couldn't find drift in window.drift and not .drift-open-chat with querySelector: ", window.drift)
//}
}} style={{ cursor: "pointer", textDecoration: "none", color: "rgba(255,255,255,0.8)" }}>
Features
</a>
</u>
,&nbsp;
<u>
<span onClick={() => {
ReactGA.event({
category: "landingpage",
action: "click_header_pricing",
label: "",
})
navigate("/pricing")
//if (window.drift !== undefined) {
// window.drift.api.startInteraction({ interactionId: 341911 })
//} else {
// console.log("Couldn't find drift in window.drift and not .drift-open-chat with querySelector: ", window.drift)
//}
}} style={{ cursor: "pointer", textDecoration: "none", color: "rgba(255,255,255,0.8)" }}>
Pricing
</span>
</u>
&nbsp;and&nbsp; */}
New Public&nbsp;
<u>
<span onClick={() => {
ReactGA.event({
@@ -1595,18 +1643,18 @@ const Header = (props) => {
navigate("/training")
}} style={{ cursor: "pointer", textDecoration: "none", fontWeight:600, color: "rgba(255,255,255,0.8)" }}>
Public Trainings
}} style={{ cursor: "pointer", textDecoration: "none", fontWeight: 600, color: "rgba(255,255,255,0.8)" }}>
Training Dates Released
</span>
</u>
&nbsp;Ahead!
</Typography>
<IconButton color="secondary" style={{ position: "absolute", top: -3, right: 20, }} onClick={(event) => {
setShowTopbar(false)
<IconButton color="secondary" style={{ position: "absolute", top: -3, right: 20, }} onClick={(event) => {
setShowTopbar(false)
// Set storage that it's clicked
localStorage.setItem("topbar_closed", "true")
}}>
// Set storage that it's clicked
localStorage.setItem("topbar_closed", "true")
}}>
<CloseIcon />
</IconButton>
</div>
+1 -1
View File
@@ -356,7 +356,7 @@ const Priorities = (props) => {
dismissNotification(data.id);
}}
>
Dismiss
Dismiss
</Button>
) : null}
<Tooltip title="Disabling a notification makes it so similar notifications to this one will NOT be re-opened. It will NOT forward notifications to your notification workflow, but WILL still keep counting." placement="top">
+21
View File
@@ -27,6 +27,13 @@ const Priority = (props) => {
const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io";
let navigate = useNavigate();
if (window.location.pathname === "/workflows") {
const hidePriorities = localStorage.getItem("hidePriorities", "true")
if (hidePriorities === "true") {
return null
}
}
var realignedSrc = false
var realignedDst = false
let newdescription = priority.description
@@ -176,6 +183,20 @@ const Priority = (props) => {
<Button style={{borderRadius: 25, fontSize:16, boxShadow: clickedFromOrgTab ? "none":null,textTransform: clickedFromOrgTab ? 'capitalize':null, width: 100, height: 50, marginTop: 8, }} variant="text" color="secondary" onClick={() => {
// dismiss -> get envs
changeRecommendation(priority, "dismiss")
// Check window location if it's /workflows
if (window.location.pathname === "/workflows") {
// Set local storage to hide priorities for now
localStorage.setItem("hidePriorities", "true")
}
if (isCloud) {
ReactGA.event({
category: "recommendation",
action: `dismiss_${priority.name}`,
label: "",
})
}
}}>
Dismiss
</Button>
+1 -1
View File
@@ -124,7 +124,7 @@ const SearchField = props => {
);
return (
<div style={{ marginTop: "auto", marginLeft: !isLoggedIn ? 0 : 130 }}>
<div style={{ marginTop: "auto", marginLeft: !isLoggedIn ? 0: "auto", marginRight: !isLoggedIn ? 0 : "auto", width: !isLoggedIn ? "auto" : 300, }}>
{modalView}
<TextField
style={{ backgroundColor: "#212121", height: 48, borderRadius: rounded === true ? 25 : theme.palette.borderRadius, minWidth: fieldWidth, maxWidth: fieldWidth, }}
@@ -153,7 +153,11 @@ const WorkflowValidationTimeline = (props) => {
// 1. Find startnode
// 2. Map childnodes from it
const startnodeId = workflow.start
var startnodeId = workflow.start
if (execution !== undefined && execution !== null) {
startnodeId = execution.start
}
// Find parent of startnodeId and if it's a webhook
var relevantactions = []
@@ -177,32 +181,38 @@ const WorkflowValidationTimeline = (props) => {
}
}
for (var key in workflow.actions) {
const action = workflow.actions[key]
if (action.id === startnodeId) {
action.order = 0
relevantactions.push(action)
continue
}
var parents = []
if (getParents !== undefined) {
parents = getParents(action)
} else {
parents = getParentNodes(workflow, action)
}
//const parents = getParentNodes(workflow, action)
//console.log("PARENTS", key, parents)
if (parents !== undefined && parents !== null && parents.length > 0) {
const parentfound = parents.find((element) => element.id === startnodeId)
if (parentfound !== undefined) {
// FIXME: add order here based on how many steps away from the startnode
// This just has the parent count
action.order = parents.length
if (getParents !== undefined) {
for (var key in workflow.actions) {
const action = workflow.actions[key]
if (action.id === startnodeId) {
action.order = 0
relevantactions.push(action)
continue
}
const parents = getParents(action)
//const parents = getParentNodes(workflow, action)
//console.log("PARENTS", key, parents)
if (parents !== undefined && parents !== null) {
const parentfound = parents.find((element) => element.id === startnodeId)
if (parentfound !== undefined) {
// FIXME: add order here based on how many steps away from the startnode
// This just has the parent count
action.order = parents.length
relevantactions.push(action)
}
}
}
} else {
}
if (getParents === undefined) {
var newactions = []
for (var key in workflow.triggers) {
const trigger = workflow.triggers[key]
if (trigger.trigger_type !== "SUBFLOW" && trigger.trigger_type !== "USERINPUT") {
@@ -210,11 +220,12 @@ const WorkflowValidationTimeline = (props) => {
}
if (workflow.actions.find((element) => element.id === trigger.id) === undefined) {
workflow.actions.push(trigger)
newactions.push(trigger)
//workflow.actions.push(trigger)
}
}
relevantactions = workflow.actions
relevantactions.push(...newactions)
}
// Sort according to how many parents a node has. MAY be wrong~
@@ -279,7 +290,10 @@ const WorkflowValidationTimeline = (props) => {
}
previousTools = true
return null
if (startnodeId !== action.id) {
return null
}
} else {
if (action.status === "SUCCESS") {
nodecolor = green
@@ -405,7 +419,7 @@ const WorkflowValidationTimeline = (props) => {
:
<Tooltip title={
<Typography variant="body1" style={{margin: 5, color: "white", }}>
{founderror.length > 0 ? founderror : ``}
{founderror.length > 0 ? founderror : `${action.app_name.replaceAll('_', ' ')}`}
</Typography>
} placement="top">
+2 -7
View File
@@ -7514,7 +7514,6 @@ const releaseToConnectLabel = "Release to Connect"
}
} else if (action.app_name === "Integration Framework") {
const iconInfo = GetIconInfo(action)
console.log("FOUND INTEGRATION: iconInfo: ", iconInfo)
if (iconInfo !== undefined && iconInfo !== null) {
action.fillGradient = iconInfo.fillGradient
action.iconBackground = iconInfo.iconBackgroundColor
@@ -12462,7 +12461,6 @@ const releaseToConnectLabel = "Release to Connect"
//setWorkflow(workflow);
}
console.log("STARTNODE: ", startnode);
} else {
console.log("WORKFLOW: ", workflow);
}
@@ -16581,6 +16579,7 @@ const releaseToConnectLabel = "Release to Connect"
}
}
/*
if (( event.ctrlKey || event.metaKey ) && event.shiftKey) {
console.log("Shift key pressed")
if (!workflow.public && executionModalOpen) {
@@ -16592,6 +16591,7 @@ const releaseToConnectLabel = "Release to Connect"
setExecutionModalView(0);
}
}
*/
};
document.addEventListener('keydown', handleKeyDown);
@@ -21829,17 +21829,12 @@ const releaseToConnectLabel = "Release to Connect"
}
}
console.log("2 - SELECTED ACTION: ", selectedAction)
console.log("2 - DATA: ", data)
if (selectedAction.app_name === "Shuffle Tools" && selectedAction.name === "filter_list" && count === 0) {
const parsedvalue = data
console.log("Parsed value: ", parsedvalue)
if (parsedvalue.includes("#")) {
const splitparsed = parsedvalue.split(".#.")
//console.log("Cant contain #: ", splitparsed)
if (splitparsed.length > 1) {
console.log("IN HERE AY")
//data.value = splitparsed[0]
selectedAction.parameters[0].value = splitparsed[0]
+15 -12
View File
@@ -62,6 +62,7 @@ import {
TreeMapLabel,
TreeMapRect,
} from 'reaviz';
import { isMobile } from "react-device-detect"
const useStyles = makeStyles({
notchedOutline: {
@@ -381,7 +382,7 @@ const UsecaseListComponent = (props) => {
<Typography variant="h6">
{usecase.name}
</Typography>
<Grid container spacing={3} style={{marginTop: 25}}>
<Grid container spacing={3} style={{marginTop: isMobile ? null:25, padding: isMobile?20:null}}>
{usecase.list.map((subcase, subindex) => {
const selectedItem = subindex === expandedItem && index === expandedIndex
@@ -426,7 +427,7 @@ const UsecaseListComponent = (props) => {
const fixedName = subcase.name.toLowerCase().replace("_", " ")
return (
<Grid id={fixedName} item xs={selectedItem ? 12 : 4} key={subindex} style={{minHeight: 110,}} onClick={() => {
<Grid id={fixedName} item xs={isMobile ? 12 : selectedItem ? 12 : 4} key={subindex} style={{minHeight: 110,}} onClick={() => {
if (fixedName === "reporting") {
getUsecase(subcase, index, subindex)
return
@@ -443,7 +444,7 @@ const UsecaseListComponent = (props) => {
}}>
{!selectedItem ?
<div style={{textAlign: "left", position: "relative",}}>
<Typography variant="h6" style={{maxWidth: 215}}>
<Typography variant="h6" style={{maxWidth: isMobile? null:215}}>
<b>{subcase.name}</b>
</Typography>
{finished ?
@@ -478,7 +479,7 @@ const UsecaseListComponent = (props) => {
<IconButton
style={{
position: "absolute",
bottom: -25,
bottom: isMobile ? 11 :-20,
right: -15,
}}
onClick={(e) => {
@@ -503,7 +504,7 @@ const UsecaseListComponent = (props) => {
<IconButton
style={{
position: "absolute",
bottom: -65,
bottom: isMobile ? -22 : 10,
right: -15,
}}
onClick={(e) => {
@@ -618,7 +619,7 @@ const UsecaseListComponent = (props) => {
</IconButton>
</Tooltip>
</div>
<div style={{marginTop: 25, display: "flex", minHeight: 400, maxHeight: 400, marginRight: 15, }}>
<div style={{marginTop: isMobile? null:25, padding: isMobile?20:null, width: isMobile?"100%":null, display: isMobile ? null:"flex", minHeight: isMobile ? "auto":400, maxHeight: isMobile ? null:400, marginRight: isMobile?null:15 }}>
{editing ?
<div style={{flex: 1, marginRight: 50, }}>
<TextField
@@ -979,7 +980,8 @@ const UsecaseListComponent = (props) => {
}
<div style={{
height: 350,
width: 350,
width: isMobile? null:350,
marginTop: isMobile ? 50:null,
borderRadius: theme.palette.borderRadius,
border: "1px solid rgba(255,255,255,0.3)",
padding: 5,
@@ -1066,8 +1068,8 @@ const RadialChart = ({keys, setSelectedCategory}) => {
}}>
<RadialAreaChart
id="workflow_categories"
height={500}
width={500}
height={isMobile ? 400:500}
width={isMobile ? null:500}
data={keys}
axis={<RadialAxis type="category" />}
series={
@@ -1675,15 +1677,15 @@ const Dashboard = (props) => {
console.log("USECASES: ", usecases)
const data =
<div className="content" style={{width: 1000, margin: "auto", paddingBottom: 200, textAlign: "center",}}>
<div style={{width: 500, margin: "auto"}}>
<div className="content" style={{width: isMobile ? "100%": 1000, margin: "auto", paddingBottom: 200, textAlign: "center",}}>
<div style={{width: isMobile ? null:500, margin: "auto"}}>
{keys.length > 0 ?
<RadialChart keys={keys} setSelectedCategory={setSelectedUsecaseCategory} />
: null}
</div>
{usecases !== null && usecases !== undefined && usecases.length > 0 ?
<div style={{ display: "flex", marginLeft: 180, }}>
<div style={{ display: isMobile ? null:"flex", marginLeft: isMobile? null :180, }}>
{usecases.map((usecase, index) => {
return (
<Chip
@@ -1693,6 +1695,7 @@ const Dashboard = (props) => {
marginRight: 10,
paddingLeft: 5,
paddingRight: 5,
marginTop: isMobile? 10:null,
height: 28,
cursor: "pointer",
border: `1px solid ${usecase.color}`,
+9 -4
View File
@@ -513,10 +513,15 @@ export const validateJson = (showResult) => {
try {
for (const [key, value] of Object.entries(result)) {
if (typeof value === "string" && (value.startsWith("{") || value.startsWith("["))) {
//console.log("CHECKING STRING: ", value)
const inside_result = validateJson(value)
if (inside_result.valid) {
//console.log("INSIDE RESULT: ", inside_result.result)
if (typeof inside_result.result === "string") {
const newres = JSON.parse(inside_result.result)
const newres = JSON.parse(inside_result.result)
result[key] = newres
} else {
result[key] = inside_result.result
@@ -1037,9 +1042,9 @@ const Workflows = (props) => {
data.default_return_value,
{},
false,
[],
"",
data.status,
[],
"",
data.status,
)
.then((response) => {
if (response !== undefined) {