Merge branch 'nightly' of https://github.com/Shuffle/Shuffle into automation
This commit is contained in:
@@ -96,7 +96,7 @@ const AdminNavBar = (props) => {
|
||||
return (
|
||||
<Wrapper>
|
||||
<div style={{ flexDirection: 'column', width: 220, }}>
|
||||
<nav style={{ padding: '25px 25px 3px 25px', height: "calc(100% - 30px)", fontSize: '16px', borderTopLeftRadius: 8, borderBottomLeftRadius: 8, background: '#212121', color: '#9CA3AF' }}>
|
||||
<nav style={{ padding: '25px 25px 3px 25px', height: isCloud ? "calc(100% - 60px)" : "calc(100% - 30px)" , fontSize: '16px', borderTopLeftRadius: 8, borderBottomLeftRadius: 8, background: '#212121', color: '#9CA3AF' }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', }}>
|
||||
<img loading="lazy" src={imageData} alt="Logo" style={{ width: '30px', borderRadius: 8, height: '30px', marginRight: '8px' }} />
|
||||
<div style={{
|
||||
|
||||
@@ -1,275 +1,278 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import Switch from '@mui/material/Switch';
|
||||
import { Typography, Button } from '@mui/material';
|
||||
import { useNavigate, Link, useParams } from "react-router-dom";
|
||||
import { Bar } from 'react-chartjs-2';
|
||||
import Grid from '@mui/material/Grid';
|
||||
import SearchIcon from '@mui/icons-material/Search';
|
||||
import NewReleasesIcon from '@mui/icons-material/NewReleases';
|
||||
import MailOutlineIcon from '@mui/icons-material/MailOutline';
|
||||
// import React, { useEffect, useState } from 'react';
|
||||
// import Switch from '@mui/material/Switch';
|
||||
// import { Typography, Button } from '@mui/material';
|
||||
// import { useNavigate, Link, useParams } from "react-router-dom";
|
||||
// import { Bar } from 'react-chartjs-2';
|
||||
// import Grid from '@mui/material/Grid';
|
||||
// import SearchIcon from '@mui/icons-material/Search';
|
||||
// import NewReleasesIcon from '@mui/icons-material/NewReleases';
|
||||
// import MailOutlineIcon from '@mui/icons-material/MailOutline';
|
||||
|
||||
const AnalyticsTab = (props) => {
|
||||
const { userdata, globalUrl, serverside } = props;
|
||||
const [checked, setChecked] = useState(false);
|
||||
const [selectedOption, setSelectedOption] = useState('all');
|
||||
const [expand, setExpand] = useState(false)
|
||||
const isCloud = (window.location.host === "localhost:3002" || window.location.host === "shuffler.io") ? true : (process.env.IS_SSR === "true");
|
||||
|
||||
console.log("if you need this, work without react-rechartjs-2")
|
||||
|
||||
// const [checked, setChecked] = useState(false);
|
||||
// const [selectedOption, setSelectedOption] = useState('all');
|
||||
// const [expand, setExpand] = useState(false)
|
||||
// const isCloud = (window.location.host === "localhost:3002" || window.location.host === "shuffler.io") ? true : (process.env.IS_SSR === "true");
|
||||
|
||||
const handleOptionChange = (option) => {
|
||||
setSelectedOption(option);
|
||||
// You can perform actions based on the selected option, such as filtering data
|
||||
};
|
||||
// const handleOptionChange = (option) => {
|
||||
// setSelectedOption(option);
|
||||
// // You can perform actions based on the selected option, such as filtering data
|
||||
// };
|
||||
|
||||
const handleChange = (event) => {
|
||||
setChecked(event.target.checked);
|
||||
};
|
||||
// const handleChange = (event) => {
|
||||
// setChecked(event.target.checked);
|
||||
// };
|
||||
|
||||
const allData = {
|
||||
labels: ['Email analysis', 'Email Management', 'EDR to Ticket', 'Ticket Analysis'],
|
||||
datasets: [
|
||||
{
|
||||
label: 'Revisions',
|
||||
data: [12, 19, 3, 5], // Data for revisions
|
||||
backgroundColor: '#FF8444',
|
||||
borderWidth: 1,
|
||||
// borderRadius: 60,
|
||||
barPercentage: 0.7,
|
||||
categoryPercentage: 0.5,
|
||||
},
|
||||
{
|
||||
label: 'Runs',
|
||||
data: [8, 15, 5, 8], // Data for runs
|
||||
backgroundColor: '#9747FF',
|
||||
borderWidth: 1,
|
||||
// borderRadius: 60,
|
||||
barPercentage: 0.7,
|
||||
categoryPercentage: 0.5
|
||||
}
|
||||
]
|
||||
};
|
||||
// const allData = {
|
||||
// labels: ['Email analysis', 'Email Management', 'EDR to Ticket', 'Ticket Analysis'],
|
||||
// datasets: [
|
||||
// {
|
||||
// label: 'Revisions',
|
||||
// data: [12, 19, 3, 5], // Data for revisions
|
||||
// backgroundColor: '#FF8444',
|
||||
// borderWidth: 1,
|
||||
// // borderRadius: 60,
|
||||
// barPercentage: 0.7,
|
||||
// categoryPercentage: 0.5,
|
||||
// },
|
||||
// {
|
||||
// label: 'Runs',
|
||||
// data: [8, 15, 5, 8], // Data for runs
|
||||
// backgroundColor: '#9747FF',
|
||||
// borderWidth: 1,
|
||||
// // borderRadius: 60,
|
||||
// barPercentage: 0.7,
|
||||
// categoryPercentage: 0.5
|
||||
// }
|
||||
// ]
|
||||
// };
|
||||
|
||||
let data;
|
||||
if (selectedOption === 'all') {
|
||||
data = allData;
|
||||
} else if (selectedOption === 'revisions') {
|
||||
data = {
|
||||
labels: allData.labels,
|
||||
datasets: [allData.datasets[0]] // Show only revisions data
|
||||
};
|
||||
} else if (selectedOption === 'run') {
|
||||
data = {
|
||||
labels: allData.labels,
|
||||
datasets: [allData.datasets[1]] // Show only runs data
|
||||
};
|
||||
}
|
||||
// let data;
|
||||
// if (selectedOption === 'all') {
|
||||
// data = allData;
|
||||
// } else if (selectedOption === 'revisions') {
|
||||
// data = {
|
||||
// labels: allData.labels,
|
||||
// datasets: [allData.datasets[0]] // Show only revisions data
|
||||
// };
|
||||
// } else if (selectedOption === 'run') {
|
||||
// data = {
|
||||
// labels: allData.labels,
|
||||
// datasets: [allData.datasets[1]] // Show only runs data
|
||||
// };
|
||||
// }
|
||||
|
||||
// Options for the chart
|
||||
const options = {
|
||||
scales: {
|
||||
yAxes: [
|
||||
{
|
||||
ticks: {
|
||||
beginAtZero: true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
};
|
||||
return (
|
||||
<div style={{ width: 1030, marginLeft: 20, marginTop:10, paddingRight: 17, paddingLeft: 17}}>
|
||||
<div style={{ width: 985, display: 'flex', alignItems: 'start', paddingTop: 16, paddingBottom: '48px', fontSize: '16px', color: '#ffffff', backgroundColor: '#1A1A1A', borderRadius: '16px', }}>
|
||||
<div style={{ marginLeft: 18 }}>Timeline</div>
|
||||
</div>
|
||||
<div style={{ display: "flex", width: "100%", marginTop: 16 }}>
|
||||
<div>
|
||||
<div style={{ width: 595, alignItems: 'start', paddingTop: 16, paddingBottom: checked ? 28 : 20, marginRight: 20, fontSize: '16px', color: '#ffffff', backgroundColor: '#1A1A1A', borderRadius: '16px', }}>
|
||||
<div style={{ display: "flex", alignItems: "center" }}>
|
||||
<div style={{ marginLeft: 18, marginRight: 310 }}>Apps</div>
|
||||
<Switch checked={checked}
|
||||
onChange={handleChange} /> Category
|
||||
<div style={{ marginLeft: 16, borderLeft: "1px solid #D9D9D9", width: 10, height: 15 }} />
|
||||
<Link onClick={() => { setExpand(prevExpand => !prevExpand); }} style={{ color: "#FF8444" }}>Expand</Link>
|
||||
</div>
|
||||
{expand ? null :
|
||||
<div style={{ marginTop: 8, display: "flex" }}>
|
||||
<div style={{ marginLeft: 19, }}>
|
||||
<Typography style={{ fontSize: 13, color: "#9E9E9E", textAlign: "start" }}>Onboarding</Typography>
|
||||
<Grid container spacing={2} style={{ marginTop: 1 }} >
|
||||
<Grid item xs={4}>
|
||||
<div style={{ position: 'relative' }}>
|
||||
<img src="/images/adminpage/app1.svg" style={{ margin: 'auto' }} />
|
||||
{checked ?
|
||||
<div style={{
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
left: '50%',
|
||||
top: 30,
|
||||
transform: 'translateX(-50%)',
|
||||
backgroundColor: '#2f2f2f',
|
||||
borderRadius: '50%',
|
||||
height: 24,
|
||||
width: 24,
|
||||
transition: 'transform 0.5s ease',
|
||||
}}><SearchIcon style={{ width: 16, height: 16, marginTop: 5 }} /></div> :
|
||||
null
|
||||
}
|
||||
</div>
|
||||
</Grid>
|
||||
<Grid item xs={4}>
|
||||
<div style={{ position: 'relative' }}>
|
||||
<img src="/images/adminpage/app1.svg" style={{ margin: 'auto' }} />
|
||||
{checked ?
|
||||
<div style={{
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
left: '50%',
|
||||
top: 30,
|
||||
transform: 'translateX(-50%)',
|
||||
backgroundColor: '#2f2f2f',
|
||||
borderRadius: '50%',
|
||||
height: 24,
|
||||
width: 24,
|
||||
transition: 'transform 0.5s ease',
|
||||
}}><MailOutlineIcon style={{ width: 16, height: 16, marginTop: 5 }} /></div> :
|
||||
null
|
||||
}
|
||||
</div>
|
||||
</Grid>
|
||||
<Grid item xs={4}>
|
||||
<div style={{ position: 'relative' }}>
|
||||
<img src="/images/adminpage/app1.svg" style={{ margin: 'auto' }} />
|
||||
{checked ?
|
||||
<div style={{
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
left: '50%',
|
||||
top: 30,
|
||||
transform: 'translateX(-50%)',
|
||||
backgroundColor: '#2f2f2f',
|
||||
borderRadius: '50%',
|
||||
height: 24,
|
||||
width: 24,
|
||||
transition: 'transform 0.5s ease',
|
||||
}}><NewReleasesIcon style={{ width: 16, height: 16, marginTop: 5 }} /></div> :
|
||||
null
|
||||
}
|
||||
</div>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</div>
|
||||
<div style={{ borderLeft: "1px solid #494949", justifyContent: "center", alignItems: "center", marginTop: 40, marginLeft: 20, marginRight: 20, height: 40 }}></div>
|
||||
<div style={{}}>
|
||||
<Typography style={{ fontSize: 13, color: "#9E9E9E", textAlign: "start" }}>Other</Typography>
|
||||
<Grid container spacing={2} style={{ marginTop: 1 }} >
|
||||
<Grid item xs={4}>
|
||||
<div style={{ position: 'relative' }}>
|
||||
<img src="/images/adminpage/app1.svg" style={{ margin: 'auto' }} />
|
||||
{checked ?
|
||||
<div style={{
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
left: '50%',
|
||||
top: 30,
|
||||
transform: 'translateX(-50%)',
|
||||
backgroundColor: '#2f2f2f',
|
||||
borderRadius: '50%',
|
||||
height: 24,
|
||||
width: 24,
|
||||
transition: 'transform 0.5s ease',
|
||||
}}><SearchIcon style={{ width: 16, height: 16, marginTop: 5 }} /></div> :
|
||||
null
|
||||
}
|
||||
</div>
|
||||
</Grid>
|
||||
<Grid item xs={4}>
|
||||
<div style={{ position: 'relative' }}>
|
||||
<img src="/images/adminpage/app1.svg" style={{ margin: 'auto' }} />
|
||||
{checked ?
|
||||
<div style={{
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
left: '50%',
|
||||
top: 30,
|
||||
transform: 'translateX(-50%)',
|
||||
backgroundColor: '#2f2f2f',
|
||||
borderRadius: '50%',
|
||||
height: 24,
|
||||
width: 24,
|
||||
transition: 'transform 10s ease-in-out',
|
||||
}}><NewReleasesIcon style={{ width: 16, height: 16, marginTop: 5 }} /></div> :
|
||||
null
|
||||
}
|
||||
</div>
|
||||
</Grid>
|
||||
<Grid item xs={4}>
|
||||
<div style={{ position: 'relative' }}>
|
||||
<img src="/images/adminpage/app1.svg" style={{ margin: 'auto' }} />
|
||||
{checked ?
|
||||
<div style={{
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
left: '50%',
|
||||
top: 30,
|
||||
transform: 'translateX(-50%)',
|
||||
backgroundColor: '#2f2f2f',
|
||||
borderRadius: '50%',
|
||||
height: 24,
|
||||
width: 24,
|
||||
transition: 'transform 10s ease-in-out',
|
||||
}}><MailOutlineIcon style={{ width: 16, height: 16, marginTop: 5 }} /></div> :
|
||||
null
|
||||
}
|
||||
</div>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</div>
|
||||
</div>}
|
||||
</div>
|
||||
<div style={{ width: 595, height: 322, marginTop: 16, paddingTop: 16, paddingBottom: '48px', fontSize: '16px', color: '#ffffff', backgroundColor: '#1A1A1A', borderRadius: '16px', }}>
|
||||
<div style={{ marginLeft: 18, textAlign: "start" }}>Workflows</div>
|
||||
<div style={{textAlign:"center"}}>
|
||||
<Button style={{ textTransform: "capitalize", background: selectedOption === 'all' ? "#494949" : "#1A1A1A", borderRadius: selectedOption === 'all' ? 15 : null, color: "#FFFFFF" }} onClick={() => handleOptionChange('all')}>All</Button>
|
||||
<Button style={{ textTransform: "capitalize", background: selectedOption === 'revisions' ? "#494949" : "#1A1A1A", borderRadius: selectedOption === 'revisions' ? 15 : null, color: "#FFFFFF" }} onClick={() => handleOptionChange('revisions')}>Revisions</Button>
|
||||
<Button style={{ textTransform: "capitalize", background: selectedOption === 'run' ? "#494949" : "#1A1A1A", borderRadius: selectedOption === 'run' ? 15 : null, color: "#FFFFFF" }} onClick={() => handleOptionChange('run')}>Runs</Button>
|
||||
</div>
|
||||
<Bar data={data} options={options} style={{ width: 400, marginLeft: 25, padding:20,marginTop: 10 }} />
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ width: 375, height: 440, display: 'flex', alignItems: 'start', paddingTop: '16px', paddingBottom: '48px', fontSize: '16px', color: '#ffffff', backgroundColor: '#1A1A1A', borderRadius: '16px', }}>
|
||||
<div style={{ marginLeft: 18 }}>Insights</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ width: 985, paddingTop: 16, marginTop: 16, paddingBottom: '48px', fontSize: '16px', color: '#ffffff', backgroundColor: '#1A1A1A', borderRadius: '16px', }}>
|
||||
<div style={{ marginLeft: 18, textAlign: 'start', marginBottom: 16 }}>Sessions Overview</div>
|
||||
<div style={{ display: "flex", width: "100%", justifyContent: "center" }}>
|
||||
<div style={{ fontSize: '16px',width: "30%", borderRadius: 8, background: '#212121', color: '#9CA3AF' }}>
|
||||
<div style={{ marginTop: 21, color: "#ffffff", marginLeft:20,fontSize: 16, fontWeight: "bold", }}>
|
||||
2.8 Hours
|
||||
</div>
|
||||
<div style={{ marginTop: 13, marginBottom: 16, marginLeft:20, }}>
|
||||
Avg. Activity per session
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ marginLeft: 16, fontSize: '16px', width: "30%", borderRadius: 8, background: '#212121', color: '#9CA3AF' }}>
|
||||
<div style={{ marginTop: 21, marginLeft:20, color: "#ffffff", fontSize: 16, fontWeight: "bold", }}>
|
||||
/usercases/edr to ticket
|
||||
</div>
|
||||
<div style={{ marginTop: 13, marginLeft:20, marginBottom: 16, }}>
|
||||
Last visited page
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ marginLeft: 16, fontSize: '16px', width: "30%", borderRadius: 8, background: '#212121', color: '#9CA3AF' }}>
|
||||
<div style={{ marginTop: 21, marginLeft:20,color: "#ffffff", fontSize: 16, fontWeight: "bold", }}>
|
||||
/workflow/email management
|
||||
</div>
|
||||
<div style={{ marginTop: 13, marginLeft:20, marginBottom: 16, }}>
|
||||
Most visited page
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
// // Options for the chart
|
||||
// const options = {
|
||||
// scales: {
|
||||
// yAxes: [
|
||||
// {
|
||||
// ticks: {
|
||||
// beginAtZero: true
|
||||
// }
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
// };
|
||||
// return (
|
||||
// <div style={{ width: 1030, marginLeft: 20, marginTop:10, paddingRight: 17, paddingLeft: 17}}>
|
||||
// <div style={{ width: 985, display: 'flex', alignItems: 'start', paddingTop: 16, paddingBottom: '48px', fontSize: '16px', color: '#ffffff', backgroundColor: '#1A1A1A', borderRadius: '16px', }}>
|
||||
// <div style={{ marginLeft: 18 }}>Timeline</div>
|
||||
// </div>
|
||||
// <div style={{ display: "flex", width: "100%", marginTop: 16 }}>
|
||||
// <div>
|
||||
// <div style={{ width: 595, alignItems: 'start', paddingTop: 16, paddingBottom: checked ? 28 : 20, marginRight: 20, fontSize: '16px', color: '#ffffff', backgroundColor: '#1A1A1A', borderRadius: '16px', }}>
|
||||
// <div style={{ display: "flex", alignItems: "center" }}>
|
||||
// <div style={{ marginLeft: 18, marginRight: 310 }}>Apps</div>
|
||||
// <Switch checked={checked}
|
||||
// onChange={handleChange} /> Category
|
||||
// <div style={{ marginLeft: 16, borderLeft: "1px solid #D9D9D9", width: 10, height: 15 }} />
|
||||
// <Link onClick={() => { setExpand(prevExpand => !prevExpand); }} style={{ color: "#FF8444" }}>Expand</Link>
|
||||
// </div>
|
||||
// {expand ? null :
|
||||
// <div style={{ marginTop: 8, display: "flex" }}>
|
||||
// <div style={{ marginLeft: 19, }}>
|
||||
// <Typography style={{ fontSize: 13, color: "#9E9E9E", textAlign: "start" }}>Onboarding</Typography>
|
||||
// <Grid container spacing={2} style={{ marginTop: 1 }} >
|
||||
// <Grid item xs={4}>
|
||||
// <div style={{ position: 'relative' }}>
|
||||
// <img src="/images/adminpage/app1.svg" style={{ margin: 'auto' }} />
|
||||
// {checked ?
|
||||
// <div style={{
|
||||
// position: 'absolute',
|
||||
// bottom: 0,
|
||||
// left: '50%',
|
||||
// top: 30,
|
||||
// transform: 'translateX(-50%)',
|
||||
// backgroundColor: '#2f2f2f',
|
||||
// borderRadius: '50%',
|
||||
// height: 24,
|
||||
// width: 24,
|
||||
// transition: 'transform 0.5s ease',
|
||||
// }}><SearchIcon style={{ width: 16, height: 16, marginTop: 5 }} /></div> :
|
||||
// null
|
||||
// }
|
||||
// </div>
|
||||
// </Grid>
|
||||
// <Grid item xs={4}>
|
||||
// <div style={{ position: 'relative' }}>
|
||||
// <img src="/images/adminpage/app1.svg" style={{ margin: 'auto' }} />
|
||||
// {checked ?
|
||||
// <div style={{
|
||||
// position: 'absolute',
|
||||
// bottom: 0,
|
||||
// left: '50%',
|
||||
// top: 30,
|
||||
// transform: 'translateX(-50%)',
|
||||
// backgroundColor: '#2f2f2f',
|
||||
// borderRadius: '50%',
|
||||
// height: 24,
|
||||
// width: 24,
|
||||
// transition: 'transform 0.5s ease',
|
||||
// }}><MailOutlineIcon style={{ width: 16, height: 16, marginTop: 5 }} /></div> :
|
||||
// null
|
||||
// }
|
||||
// </div>
|
||||
// </Grid>
|
||||
// <Grid item xs={4}>
|
||||
// <div style={{ position: 'relative' }}>
|
||||
// <img src="/images/adminpage/app1.svg" style={{ margin: 'auto' }} />
|
||||
// {checked ?
|
||||
// <div style={{
|
||||
// position: 'absolute',
|
||||
// bottom: 0,
|
||||
// left: '50%',
|
||||
// top: 30,
|
||||
// transform: 'translateX(-50%)',
|
||||
// backgroundColor: '#2f2f2f',
|
||||
// borderRadius: '50%',
|
||||
// height: 24,
|
||||
// width: 24,
|
||||
// transition: 'transform 0.5s ease',
|
||||
// }}><NewReleasesIcon style={{ width: 16, height: 16, marginTop: 5 }} /></div> :
|
||||
// null
|
||||
// }
|
||||
// </div>
|
||||
// </Grid>
|
||||
// </Grid>
|
||||
// </div>
|
||||
// <div style={{ borderLeft: "1px solid #494949", justifyContent: "center", alignItems: "center", marginTop: 40, marginLeft: 20, marginRight: 20, height: 40 }}></div>
|
||||
// <div style={{}}>
|
||||
// <Typography style={{ fontSize: 13, color: "#9E9E9E", textAlign: "start" }}>Other</Typography>
|
||||
// <Grid container spacing={2} style={{ marginTop: 1 }} >
|
||||
// <Grid item xs={4}>
|
||||
// <div style={{ position: 'relative' }}>
|
||||
// <img src="/images/adminpage/app1.svg" style={{ margin: 'auto' }} />
|
||||
// {checked ?
|
||||
// <div style={{
|
||||
// position: 'absolute',
|
||||
// bottom: 0,
|
||||
// left: '50%',
|
||||
// top: 30,
|
||||
// transform: 'translateX(-50%)',
|
||||
// backgroundColor: '#2f2f2f',
|
||||
// borderRadius: '50%',
|
||||
// height: 24,
|
||||
// width: 24,
|
||||
// transition: 'transform 0.5s ease',
|
||||
// }}><SearchIcon style={{ width: 16, height: 16, marginTop: 5 }} /></div> :
|
||||
// null
|
||||
// }
|
||||
// </div>
|
||||
// </Grid>
|
||||
// <Grid item xs={4}>
|
||||
// <div style={{ position: 'relative' }}>
|
||||
// <img src="/images/adminpage/app1.svg" style={{ margin: 'auto' }} />
|
||||
// {checked ?
|
||||
// <div style={{
|
||||
// position: 'absolute',
|
||||
// bottom: 0,
|
||||
// left: '50%',
|
||||
// top: 30,
|
||||
// transform: 'translateX(-50%)',
|
||||
// backgroundColor: '#2f2f2f',
|
||||
// borderRadius: '50%',
|
||||
// height: 24,
|
||||
// width: 24,
|
||||
// transition: 'transform 10s ease-in-out',
|
||||
// }}><NewReleasesIcon style={{ width: 16, height: 16, marginTop: 5 }} /></div> :
|
||||
// null
|
||||
// }
|
||||
// </div>
|
||||
// </Grid>
|
||||
// <Grid item xs={4}>
|
||||
// <div style={{ position: 'relative' }}>
|
||||
// <img src="/images/adminpage/app1.svg" style={{ margin: 'auto' }} />
|
||||
// {checked ?
|
||||
// <div style={{
|
||||
// position: 'absolute',
|
||||
// bottom: 0,
|
||||
// left: '50%',
|
||||
// top: 30,
|
||||
// transform: 'translateX(-50%)',
|
||||
// backgroundColor: '#2f2f2f',
|
||||
// borderRadius: '50%',
|
||||
// height: 24,
|
||||
// width: 24,
|
||||
// transition: 'transform 10s ease-in-out',
|
||||
// }}><MailOutlineIcon style={{ width: 16, height: 16, marginTop: 5 }} /></div> :
|
||||
// null
|
||||
// }
|
||||
// </div>
|
||||
// </Grid>
|
||||
// </Grid>
|
||||
// </div>
|
||||
// </div>}
|
||||
// </div>
|
||||
// <div style={{ width: 595, height: 322, marginTop: 16, paddingTop: 16, paddingBottom: '48px', fontSize: '16px', color: '#ffffff', backgroundColor: '#1A1A1A', borderRadius: '16px', }}>
|
||||
// <div style={{ marginLeft: 18, textAlign: "start" }}>Workflows</div>
|
||||
// <div style={{textAlign:"center"}}>
|
||||
// <Button style={{ textTransform: "capitalize", background: selectedOption === 'all' ? "#494949" : "#1A1A1A", borderRadius: selectedOption === 'all' ? 15 : null, color: "#FFFFFF" }} onClick={() => handleOptionChange('all')}>All</Button>
|
||||
// <Button style={{ textTransform: "capitalize", background: selectedOption === 'revisions' ? "#494949" : "#1A1A1A", borderRadius: selectedOption === 'revisions' ? 15 : null, color: "#FFFFFF" }} onClick={() => handleOptionChange('revisions')}>Revisions</Button>
|
||||
// <Button style={{ textTransform: "capitalize", background: selectedOption === 'run' ? "#494949" : "#1A1A1A", borderRadius: selectedOption === 'run' ? 15 : null, color: "#FFFFFF" }} onClick={() => handleOptionChange('run')}>Runs</Button>
|
||||
// </div>
|
||||
// <Bar data={data} options={options} style={{ width: 400, marginLeft: 25, padding:20,marginTop: 10 }} />
|
||||
// </div>
|
||||
// </div>
|
||||
// <div style={{ width: 375, height: 440, display: 'flex', alignItems: 'start', paddingTop: '16px', paddingBottom: '48px', fontSize: '16px', color: '#ffffff', backgroundColor: '#1A1A1A', borderRadius: '16px', }}>
|
||||
// <div style={{ marginLeft: 18 }}>Insights</div>
|
||||
// </div>
|
||||
// </div>
|
||||
// <div style={{ width: 985, paddingTop: 16, marginTop: 16, paddingBottom: '48px', fontSize: '16px', color: '#ffffff', backgroundColor: '#1A1A1A', borderRadius: '16px', }}>
|
||||
// <div style={{ marginLeft: 18, textAlign: 'start', marginBottom: 16 }}>Sessions Overview</div>
|
||||
// <div style={{ display: "flex", width: "100%", justifyContent: "center" }}>
|
||||
// <div style={{ fontSize: '16px',width: "30%", borderRadius: 8, background: '#212121', color: '#9CA3AF' }}>
|
||||
// <div style={{ marginTop: 21, color: "#ffffff", marginLeft:20,fontSize: 16, fontWeight: "bold", }}>
|
||||
// 2.8 Hours
|
||||
// </div>
|
||||
// <div style={{ marginTop: 13, marginBottom: 16, marginLeft:20, }}>
|
||||
// Avg. Activity per session
|
||||
// </div>
|
||||
// </div>
|
||||
// <div style={{ marginLeft: 16, fontSize: '16px', width: "30%", borderRadius: 8, background: '#212121', color: '#9CA3AF' }}>
|
||||
// <div style={{ marginTop: 21, marginLeft:20, color: "#ffffff", fontSize: 16, fontWeight: "bold", }}>
|
||||
// /usercases/edr to ticket
|
||||
// </div>
|
||||
// <div style={{ marginTop: 13, marginLeft:20, marginBottom: 16, }}>
|
||||
// Last visited page
|
||||
// </div>
|
||||
// </div>
|
||||
// <div style={{ marginLeft: 16, fontSize: '16px', width: "30%", borderRadius: 8, background: '#212121', color: '#9CA3AF' }}>
|
||||
// <div style={{ marginTop: 21, marginLeft:20,color: "#ffffff", fontSize: 16, fontWeight: "bold", }}>
|
||||
// /workflow/email management
|
||||
// </div>
|
||||
// <div style={{ marginTop: 13, marginLeft:20, marginBottom: 16, }}>
|
||||
// Most visited page
|
||||
// </div>
|
||||
// </div>
|
||||
// </div>
|
||||
// </div>
|
||||
// </div>
|
||||
// );
|
||||
};
|
||||
|
||||
export default AnalyticsTab;
|
||||
|
||||
@@ -842,7 +842,7 @@ const AppAuthTab = memo((props) => {
|
||||
hitsPerPage={5}
|
||||
searchQuery={searchQuery}
|
||||
globalUrl={globalUrl}
|
||||
isCloud={isCloud}
|
||||
isCloud={isCloud !== true}
|
||||
userdata={userdata}
|
||||
getAppAuthentication={getAppAuthentication}
|
||||
/>
|
||||
@@ -878,6 +878,7 @@ const AppAuthTab = memo((props) => {
|
||||
style={{ color: '#1a1a1a', textTransform: 'none', backgroundColor: "#FF8444", marginLeft:"auto", borderRadius: 4,fontSize: 16, minWidth: 162, height: 40, boxShadow:'none', }}
|
||||
variant="contained"
|
||||
color="primary"
|
||||
disabled={!isCloud}
|
||||
onClick={() => setShowAppModal(true)}
|
||||
>
|
||||
Add App Auth
|
||||
|
||||
@@ -198,7 +198,7 @@ export const findSpecificApp = (framework, inputcategory) => {
|
||||
id: "",
|
||||
}
|
||||
} else {
|
||||
console.log("findSpecificApp: unknown category: ", category)
|
||||
//console.log("findSpecificApp: unknown category: ", category)
|
||||
}
|
||||
|
||||
return null
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import React, { memo, useCallback, useEffect, useState } from 'react';
|
||||
import { useNavigate } from 'react-router';
|
||||
|
||||
import {
|
||||
@@ -29,8 +29,15 @@ import theme from "../theme.jsx";
|
||||
import YAML from 'yaml';
|
||||
import { toast } from 'react-toastify';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { InstantSearch, connectHits, connectSearchBox } from 'react-instantsearch-dom';
|
||||
import algoliasearch from "algoliasearch/lite";
|
||||
|
||||
const AppModal = ({ open, onClose, app, globalUrl, getApps }) => {
|
||||
const searchClient = algoliasearch(
|
||||
"JNSS5CFDZZ",
|
||||
"db08e40265e2941b9a7d8f644b6e5240"
|
||||
);;
|
||||
|
||||
const AppModal = ({ open, onClose, app, globalUrl, getApps}) => {
|
||||
|
||||
const [frameworkData, setFrameworkData] = useState({})
|
||||
const [userdata, setUserdata] = useState({})
|
||||
@@ -79,8 +86,7 @@ const AppModal = ({ open, onClose, app, globalUrl, getApps }) => {
|
||||
});
|
||||
}, [app]);
|
||||
|
||||
|
||||
const getFramework = () => {
|
||||
const getFramework = () => {
|
||||
fetch(globalUrl + "/api/v1/apps/frameworkConfiguration", {
|
||||
method: "GET",
|
||||
headers: {
|
||||
@@ -295,8 +301,6 @@ const AppModal = ({ open, onClose, app, globalUrl, getApps }) => {
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
setUsecaseLoading(true)
|
||||
getAvailableWorkflows()
|
||||
@@ -329,6 +333,7 @@ const AppModal = ({ open, onClose, app, globalUrl, getApps }) => {
|
||||
//delete apps from local storage
|
||||
localStorage.removeItem("apps");
|
||||
getApps();
|
||||
onClose();
|
||||
}, 1000);
|
||||
} else {
|
||||
toast("Failed deleting app. Does it still exist?");
|
||||
@@ -720,18 +725,7 @@ const AppModal = ({ open, onClose, app, globalUrl, getApps }) => {
|
||||
textAlign: "start",
|
||||
flex: 1,
|
||||
}}>
|
||||
<Typography
|
||||
variant="h6"
|
||||
sx={{
|
||||
fontFamily: theme?.typography?.fontFamily,
|
||||
fontSize: '24px',
|
||||
fontWeight: 600,
|
||||
mb: 0.3,
|
||||
color: '#fff'
|
||||
}}
|
||||
>
|
||||
20
|
||||
</Typography>
|
||||
<WorkflowCard app={app}/>
|
||||
<Typography
|
||||
variant="body2"
|
||||
sx={{
|
||||
@@ -930,3 +924,55 @@ const AppModal = ({ open, onClose, app, globalUrl, getApps }) => {
|
||||
};
|
||||
|
||||
export default AppModal;
|
||||
|
||||
|
||||
const WorkflowCard = memo(({ app }) => {
|
||||
const [name, setName] = useState("");
|
||||
const [relatedWorkflows, setRelatedWorkflows] = useState(0);
|
||||
|
||||
const WorkflowHits = ({ hits }) => {
|
||||
useEffect(() => {
|
||||
setRelatedWorkflows(hits?.length || 0);
|
||||
}, [hits]);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const CustomWorkflowHits = connectHits(WorkflowHits);
|
||||
|
||||
const SearchBox = ({ refine, currentRefinement }) => {
|
||||
useEffect(() => {
|
||||
if (name.length > 0 && currentRefinement !== name) {
|
||||
refine(name?.split(" ")[0]);
|
||||
}
|
||||
}, [name, refine, currentRefinement]);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const CustomSearchBox = connectSearchBox(SearchBox);
|
||||
|
||||
useEffect(() => {
|
||||
if (app?.name && app.name.trim().length > 0 && name !== app.name) {
|
||||
const formattedName = app.name
|
||||
.charAt(0)
|
||||
.toUpperCase() + app.name.substring(1)
|
||||
.replaceAll("_", " ");
|
||||
setName(formattedName);
|
||||
}
|
||||
}, [app?.name]);
|
||||
|
||||
return (
|
||||
<Typography variant="h4">
|
||||
{name.length > 0 ? (
|
||||
<InstantSearch key={name} searchClient={searchClient} indexName="workflows">
|
||||
<CustomSearchBox defaultRefinement={name?.split(" ")[0]}/>
|
||||
<CustomWorkflowHits />
|
||||
{relatedWorkflows}
|
||||
</InstantSearch>
|
||||
) : (
|
||||
relatedWorkflows
|
||||
)}
|
||||
</Typography>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -88,7 +88,7 @@ const AppSearchButtons = (props) => {
|
||||
|
||||
const foundApp = findSpecificApp(appFramework, appType)
|
||||
if (foundApp === undefined || foundApp === null) {
|
||||
console.log("AppSearchButtons: App not found in appFramework: " + appType)
|
||||
//console.log("AppSearchButtons: App not found in appFramework: " + appType)
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@ const CacheView = memo((props) => {
|
||||
|
||||
|
||||
const listOrgCache = (orgId, category) => {
|
||||
const url = `${globalUrl}/api/v1/orgs/${orgId}/list_cache${category !== undefined ? `?category=${category.replaceAll(" ", "_")}` : ""}`
|
||||
const url = `${globalUrl}/api/v1/orgs/${orgId}/list_cache${category !== undefined ? `?category=${category.replaceAll(" ", "%20")}` : ""}`
|
||||
fetch(url, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
|
||||
@@ -65,80 +65,83 @@ export const LoadStats = (globalUrl, cachekey) => {
|
||||
}
|
||||
|
||||
const DashboardBarchart = (props) => {
|
||||
const { timelineData, title, height, } = props;
|
||||
var inputHeight = 15
|
||||
if (height !== undefined && height !== null) {
|
||||
inputHeight = height
|
||||
}
|
||||
// this is clearly unfinished and not worth my time.
|
||||
// refer to health page to see how i made it work there w/o using chartjs
|
||||
|
||||
const barOptions = {
|
||||
plugins: {
|
||||
tooltip: {
|
||||
enabled: true, // Ensure tooltips are enabled
|
||||
},
|
||||
},
|
||||
tooltips: {
|
||||
mode: 'index',
|
||||
intersect: false,
|
||||
},
|
||||
legend: {
|
||||
display: false
|
||||
},
|
||||
layout: {
|
||||
padding: {
|
||||
top: 0, // Adjust the top padding as needed
|
||||
bottom: -10, // Adjust the bottom padding as needed
|
||||
left: 0, // Adjust the left padding as needed
|
||||
right: 0, // Adjust the right padding as needed
|
||||
},
|
||||
},
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: false,
|
||||
},
|
||||
yAxes: [{
|
||||
ticks: {
|
||||
display: false
|
||||
},
|
||||
beginAtZero: false,
|
||||
}],
|
||||
xAxes: [{
|
||||
ticks: {
|
||||
display: false
|
||||
},
|
||||
beginAtZero: false,
|
||||
}]
|
||||
},
|
||||
tooltips: {
|
||||
callbacks: {
|
||||
label: function (tooltipItem, data) {
|
||||
const label = data.labels[tooltipItem.index]
|
||||
return label.split('\n')[0]
|
||||
},
|
||||
afterLabel: function (tooltipItem, data) {
|
||||
const amount = tooltipItem.value === undefined || tooltipItem.value === null ? 0 : tooltipItem.value
|
||||
return `Amount: ${amount}`
|
||||
},
|
||||
title: function () {
|
||||
return title === undefined ? '' : title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// const { timelineData, title, height, } = props;
|
||||
// var inputHeight = 15
|
||||
// if (height !== undefined && height !== null) {
|
||||
// inputHeight = height
|
||||
// }
|
||||
|
||||
return (
|
||||
<Bar
|
||||
data={timelineData}
|
||||
options={barOptions}
|
||||
height={inputHeight}
|
||||
getElementAtEvent={(elements) => {
|
||||
if (elements && elements.length > 0) {
|
||||
//toast("Click event")
|
||||
console.log("Clicked: ", elements)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
// const barOptions = {
|
||||
// plugins: {
|
||||
// tooltip: {
|
||||
// enabled: true, // Ensure tooltips are enabled
|
||||
// },
|
||||
// },
|
||||
// tooltips: {
|
||||
// mode: 'index',
|
||||
// intersect: false,
|
||||
// },
|
||||
// legend: {
|
||||
// display: false
|
||||
// },
|
||||
// layout: {
|
||||
// padding: {
|
||||
// top: 0, // Adjust the top padding as needed
|
||||
// bottom: -10, // Adjust the bottom padding as needed
|
||||
// left: 0, // Adjust the left padding as needed
|
||||
// right: 0, // Adjust the right padding as needed
|
||||
// },
|
||||
// },
|
||||
// scales: {
|
||||
// y: {
|
||||
// beginAtZero: false,
|
||||
// },
|
||||
// yAxes: [{
|
||||
// ticks: {
|
||||
// display: false
|
||||
// },
|
||||
// beginAtZero: false,
|
||||
// }],
|
||||
// xAxes: [{
|
||||
// ticks: {
|
||||
// display: false
|
||||
// },
|
||||
// beginAtZero: false,
|
||||
// }]
|
||||
// },
|
||||
// tooltips: {
|
||||
// callbacks: {
|
||||
// label: function (tooltipItem, data) {
|
||||
// const label = data.labels[tooltipItem.index]
|
||||
// return label.split('\n')[0]
|
||||
// },
|
||||
// afterLabel: function (tooltipItem, data) {
|
||||
// const amount = tooltipItem.value === undefined || tooltipItem.value === null ? 0 : tooltipItem.value
|
||||
// return `Amount: ${amount}`
|
||||
// },
|
||||
// title: function () {
|
||||
// return title === undefined ? '' : title
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// return (
|
||||
// <Bar
|
||||
// data={timelineData}
|
||||
// options={barOptions}
|
||||
// height={inputHeight}
|
||||
// getElementAtEvent={(elements) => {
|
||||
// if (elements && elements.length > 0) {
|
||||
// //toast("Click event")
|
||||
// console.log("Clicked: ", elements)
|
||||
// }
|
||||
// }}
|
||||
// />
|
||||
// )
|
||||
}
|
||||
|
||||
export default DashboardBarchart;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import React, { useEffect, useState, useContext } from 'react';
|
||||
import OrgHeaderexpanded from "./OrgHeaderexpandedNew.jsx";
|
||||
import OrgHeader from './OrgHeaderNew.jsx';
|
||||
import OrgHeaderexpanded from "../components/OrgHeaderexpandedNew.jsx";
|
||||
import OrgHeader from '../components/OrgHeaderNew.jsx';
|
||||
import { toast } from "react-toastify";
|
||||
import CloudSyncTab from './CloudSyncTab.jsx';
|
||||
import CloudSyncTab from '../components/CloudSyncTab.jsx';
|
||||
import {
|
||||
FileCopy as FileCopyIcon,
|
||||
} from "@mui/icons-material";
|
||||
@@ -443,4 +443,4 @@ If you're interested, please let me know a time that works for you, or set up a
|
||||
)
|
||||
}
|
||||
|
||||
export default EditOrgTab;
|
||||
export default EditOrgTab;
|
||||
|
||||
@@ -581,7 +581,7 @@ const EditWorkflow = (props) => {
|
||||
</Typography>
|
||||
|
||||
<Typography variant="body2" color="textSecondary" style={{ marginTop: 30, marginBottom: 10, }}>
|
||||
Multi-Tenant Workflows. Make one workflow, and keep a separate, synced copy in all your tenants. Control distributed auth, runtime locations, files, datastore keys etc. (<b>late beta</b> - contact support@shuffler.io if you want a demo. Please try it!)
|
||||
Multi-Tenant Workflows. Make one workflow, and keep a separate, synced copy in all your tenants. Control distributed auth, runtime locations, files, datastore keys etc. (contact support@shuffler.io if you want a demo. Please try it!)
|
||||
</Typography>
|
||||
|
||||
{userdata !== undefined && userdata !== null && userdata.orgs !== undefined && userdata.orgs !== null && userdata.orgs.length > 0 ?
|
||||
|
||||
@@ -421,7 +421,7 @@ const EnvironmentTab = memo((props) => {
|
||||
-e AUTH="${auth}" \\
|
||||
-e ENVIRONMENT_NAME="${environment.Name}" \\
|
||||
-e ORG="${environment.org_id}" \\
|
||||
-e SHUFFLE_WORKER_IMAGE="ghcr.io/shuffle/shuffle-worker:nightly" \\
|
||||
-e SHUFFLE_WORKER_IMAGE="ghcr.io/shuffle/shuffle-worker:latest" \\
|
||||
-e SHUFFLE_SWARM_CONFIG=run \\
|
||||
-e SHUFFLE_LOGS_DISABLED=true \\
|
||||
-e BASE_URL="${newUrl}" \\${addProxy ? `
|
||||
|
||||
@@ -525,7 +525,7 @@ useEffect(() => {
|
||||
<Divider style={{ marginBottom: 10, }} />
|
||||
|
||||
<Typography color="textSecondary" align="center" style={{ marginTop: 5, marginBottom: 5, fontSize: 18 }}>
|
||||
Version: 2.0.0-rc7
|
||||
Version: 2.0.0
|
||||
</Typography>
|
||||
</Menu>
|
||||
</span>
|
||||
|
||||
@@ -549,7 +549,7 @@ const OrgHeaderexpandedNew = (props) => {
|
||||
|
||||
{isCloud ? (
|
||||
<div style={{ marginLeft: 13, fontSize: 16, color: "#9E9E9E" }} >
|
||||
Region
|
||||
Change Region
|
||||
<RegionChangeModal selectedOrganization={selectedOrganization} setSelectedRegion={setSelectedRegion} userdata={userdata} handleSendChangeRegionMail={handleSendChangeRegionMail} />
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
@@ -3,7 +3,6 @@ import { Link, useNavigate, useLocation } from "react-router-dom";
|
||||
import Billing from "../components/Billing.jsx";
|
||||
import Priorities from "../components/Priorities.jsx";
|
||||
import Branding from "../components/Branding.jsx";
|
||||
import AnalyticsTab from '../components/AnalyticsTab.jsx';
|
||||
import EditOrgTab from '../components/EditOrgTab.jsx';
|
||||
import CloudSyncTab from '../components/CloudSyncTab.jsx';
|
||||
import SSOTab from "../components/ssoTab.jsx"
|
||||
|
||||
@@ -361,7 +361,7 @@ const ParsedAction = (props) => {
|
||||
}
|
||||
|
||||
if (keyorder.join(",") !== newkeyorder.join(",")) {
|
||||
console.log("KEYORDER CHANGED! DID ACTION AS WELL?", keyorder, newkeyorder)
|
||||
//console.log("KEYORDER CHANGED! DID ACTION AS WELL?", keyorder, newkeyorder)
|
||||
|
||||
setSelectedActionParameters(newparams)
|
||||
selectedAction.parameters = newparams
|
||||
@@ -1160,6 +1160,12 @@ const ParsedAction = (props) => {
|
||||
|
||||
selectedActionParameters[1].value = splitparsed[1]
|
||||
selectedAction.parameters[1].value = splitparsed[1]
|
||||
|
||||
if (splitparsed.length > 2) {
|
||||
toast.warn("Filter list only supports filtering at the first level. If you want multi-level filtering, please use the 'execute python' action with the 'filter a list' function in the code editor.")
|
||||
} else if (selectedAction.parameters[1].value.includes(".#")) {
|
||||
toast.warn("This filter may not work due to using .# indexing. Please use the 'execute python' action and try the 'filter a list' function in the code editor.")
|
||||
}
|
||||
} else {
|
||||
// Remove .# and after
|
||||
const splitparsed = parsedvalue.split(".#")
|
||||
@@ -3658,6 +3664,12 @@ const ParsedAction = (props) => {
|
||||
</Box>
|
||||
);
|
||||
|
||||
if (selectedApp.name === "email") {
|
||||
//hideBody = false
|
||||
showButtonField = false
|
||||
hideBodyButtonValue = null
|
||||
}
|
||||
|
||||
|
||||
if ((multiline === undefined || multiline === false) && ((data?.autocompleted === true || data?.field_active === true) || data.name.startsWith("${") && data.name.endsWith("}"))) {
|
||||
multiline = true
|
||||
|
||||
@@ -89,6 +89,7 @@ const liquidFilters = [
|
||||
const pythonFilters = [
|
||||
{ "name": "Hello World", "value": `print("hello world")`, "example": `` },
|
||||
{ "name": "Using Shuffle variables", "value": `import json\nnodevalue = r\"\"\"$exec\"\"\"\nif not nodevalue:\n nodevalue = r\"\"\"{\"sample\": \"string\", \"int\": 1}\"\"\"\n \njsondata = json.loads(nodevalue)\nprint(jsondata)`, "example": `` },
|
||||
{ "name": "Filter a list", "value": `import json\nnodevalue = r\"\"\"$exec\"\"\"\nif not nodevalue:\n nodevalue = r\"\"\"[{\"sample\": \"string\", \"int\": 1, "malicious": "no"}, {\"sample\": \"string2\", \"int\": 1, "malicious": "yes"}]\"\"\"\n \njsondata = json.loads(nodevalue)\nfiltered = []\nfor item in jsondata:\n try:\n if item[\"malicious\"] == \"yes\":\n filtered.append(item)\n except:\n pass\nprint(json.dumps(filtered))`, "example": `` },
|
||||
{ "name": "Print Execution ID", "value": `print(self.current_execution_id)`, "example": `` },
|
||||
{ "name": "Get full execution details", "value": `print(self.full_execution)`, "example": `` },
|
||||
{ "name": "Use files", "value": `# Create a sample file\nfiles = [{\n \"filename\": \"test.txt\",\n \"data\": \"Testdata\"\n}]\nret = self.set_files(files)\n\n# Get the content of the file from Shuffle storage\n# Originally a byte string in the \"data\" key\nfile_content = (self.get_file(ret[0])[\"data\"]).decode()\nprint(file_content)`, "example": `` },
|
||||
@@ -657,6 +658,7 @@ const CodeEditor = (props) => {
|
||||
}
|
||||
|
||||
if (!inputvariable.includes(".")) {
|
||||
inputvariable = inputvariable.toLowerCase()
|
||||
return inputvariable
|
||||
}
|
||||
|
||||
@@ -665,6 +667,9 @@ const CodeEditor = (props) => {
|
||||
var removedIndexes = 0
|
||||
for (var key in itemsplit) {
|
||||
var tmpitem = itemsplit[key]
|
||||
if (key == 0) {
|
||||
tmpitem = tmpitem.toLowerCase()
|
||||
}
|
||||
|
||||
// Makes sure #0 and # are same, as we only visualize first one anyway
|
||||
if (tmpitem.startsWith("#")) {
|
||||
@@ -695,20 +700,24 @@ const CodeEditor = (props) => {
|
||||
var variable_occurence = current_code_line.match(/[\\]{0,1}[$]{1}([a-zA-Z0-9_@-]+\.?){1}([a-zA-Z0-9#_@-]+\.?){0,}/g)
|
||||
|
||||
if (!variable_occurence) {
|
||||
continue;
|
||||
continue
|
||||
}
|
||||
|
||||
var new_occurences = variable_occurence.filter((occurrence) => occurrence[0]);
|
||||
variable_occurence = new_occurences
|
||||
//var new_occurences = variable_occurence.filter((occurrence) => occurrence[0]);
|
||||
//variable_occurence = new_occurences
|
||||
|
||||
variable_occurence = variable_occurence.filter((occurrence) => occurrence[0]);
|
||||
|
||||
// Checks code lines, not variable occurences. Then remaps later
|
||||
var dollar_occurence = [];
|
||||
for (let ch = 0; ch < current_code_line.length; ch++) {
|
||||
//if (current_code_line[ch] === '$' && (ch === 0)) {
|
||||
if (current_code_line[ch] === '$') {
|
||||
dollar_occurence.push(ch);
|
||||
dollar_occurence.push(ch)
|
||||
}
|
||||
}
|
||||
|
||||
// Lowercase anything between the $ and first .
|
||||
var dollar_occurence_len = []
|
||||
try {
|
||||
for (let occ = 0; occ < variable_occurence.length; occ++) {
|
||||
@@ -1005,7 +1014,6 @@ const CodeEditor = (props) => {
|
||||
|
||||
// Replace quotes with nothing
|
||||
} else {
|
||||
console.log("NO TYPE? ", typeof new_input)
|
||||
try {
|
||||
new_input = new_input.toString()
|
||||
} catch (e) {
|
||||
@@ -1897,7 +1905,7 @@ const CodeEditor = (props) => {
|
||||
overflow: "hidden",
|
||||
}}
|
||||
onClick={() => {
|
||||
console.log(innerdata.example)
|
||||
//console.log(innerdata.example)
|
||||
|
||||
//const handleClick = (item) => {
|
||||
handleItemClick([innerdata]);
|
||||
|
||||
@@ -299,7 +299,7 @@ const WorkflowValidationTimeline = (props) => {
|
||||
var scheduleNotStarted = false
|
||||
|
||||
if (workflow.validation !== undefined && workflow.validation !== null && workflow.validation.validation_ran === false) {
|
||||
console.log("Validation didn't run or get set for workflow. Why?")
|
||||
//console.log("Validation didn't run or get set for workflow. Why?")
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user