- const creatorname = data.creator_info !== undefined && data.creator_info !== null && data.creator_info.username !== undefined && data.creator_info.username !== null && data.creator_info.username.length > 0 ? data.creator_info.username : ""
- var orgName = "";
- var orgId = "";
- if ((data.objectID === undefined || data.objectID === null) && data.id !== undefined && data.id !== null) {
- data.objectID = data.id
- }
-
- //console.log("IMG: ", data)
- var parsedUrl = `/workflows/${data.objectID}`
- if (data.__queryID !== undefined && data.__queryID !== null) {
- parsedUrl += `?queryID=${data.__queryID}`
- }
-
- return (
-
-
-
-
-
-
- {
- if (data.creator_info !== undefined) {
- navigate("/creators/"+data.creator_info.username)
- }
- }}
- >
- {image}
-
-
-
-
-
- {parsedName}
-
-
-
-
-
- {appGroup.length > 0 ?
-
-
- {appGroup.map((app, index) => {
- return (
- {
- navigate("/apps/"+app.id)
- }}
- >
-
-
-
-
- )
- })}
-
-
- :
-
-
-
-
- {data.actions === undefined || data.actions === null ? 1 : data.actions.length}
-
-
-
- }
-
-
-
-
- {data.triggers === undefined || data.triggers === null ? 1 : data.triggers.length}
-
-
-
-
- {
- }}
- >
-
-
- {0}
-
-
-
-
-
- {data.tags !== undefined && data.tags !== null
- ? data.tags.map((tag, index) => {
- if (index >= 3) {
- return null;
- }
-
- return (
-
- );
- })
- : null}
-
-
-
-
- )
- }
-
-export default WorkflowPaper
diff --git a/frontend/src/views/AngularWorkflow.jsx b/frontend/src/views/AngularWorkflow.jsx
index bbbe9189..5378d297 100755
--- a/frontend/src/views/AngularWorkflow.jsx
+++ b/frontend/src/views/AngularWorkflow.jsx
@@ -369,7 +369,6 @@ const useStyles = makeStyles({
},
inputRoot: {
color: "white",
- // This matches the specificity of the default styles at https://github.com/mui-org/material-ui/blob/v4.11.3/packages/material-ui-lab/src/Autocomplete/Autocomplete.js#L90
"&:hover .MuiOutlinedInput-notchedOutline": {
borderColor: "#f86a3e",
},
diff --git a/frontend/src/views/AppExplorer.jsx b/frontend/src/views/AppExplorer.jsx
deleted file mode 100644
index 01fc4546..00000000
--- a/frontend/src/views/AppExplorer.jsx
+++ /dev/null
@@ -1,468 +0,0 @@
-
-import { Grid, Divider, List, ListItem, ListItemText } from "@mui/material";
-import { experimentalStyled as styled } from '@mui/material/styles';
-import Typography from "@material-ui/core/Typography";
-import Paper from "@material-ui/core/Paper";
-import Button from '@mui/material/Button';
-import Box from '@material-ui/core/Box';
-import React, { useState, useEffect } from "react";
-
-
-import algoliasearch from "algoliasearch";
-//import algoliarecommend from "algoliarecommend";
-
-const searchClient = algoliasearch(
- "JNSS5CFDZZ",
- "db08e40265e2941b9a7d8f644b6e5240"
-);
-
-// https://www.algolia.com/doc/api-client/getting-started/install/
-/*const algoliarecommend = require('@algolia/recommend');
-
-const client = algoliarecommend(
- "NSS5CFDZZ",
- "db08e40265e2941b9a7d8f644b6e5240"
-);*/
-
-
-const Item = styled(Paper)(({ theme }) => ({
- padding: theme.spacing(2),
- border: "0.0625rem solid #b2b2b2",
- borderRadius: "1.5625rem",
- boxSizing: "content-box",
- backgroundColor: "transparent",
- width: "200px",
- textAlign: 'center',
- color: theme.palette.text.secondary,
- marginTop: "20px",
- marginBottom: "20px",
- color: "textPrimary"
-}));
-const AppExplorer = (props) => {
- const [algoliaResult, setAlgoliaResult] = useState("");
-
- const runAlgoliaAppSearch = (query) => {
- const index = searchClient.initIndex("appsearch");
-
- index
- .search(`${query}`)
- .then(({ hits }) => {
- setAlgoliaResult(hits);
- })
- .catch((err) => {
- console.log(err);
- });
- };
-
- useEffect(() => {
-
- runAlgoliaAppSearch("wazuh")
-
- }, [])
-
-
- const brandApp = () => {
- const index = searchClient.initIndex("appsearch");
-
- const replicaIndex = searchClient.initIndex('appsearch');
- replicaIndex.setSettings({
- customRanking: [
- "asc(time_edited)"
- ]
- })
-
- .then(({ hits }) => {
- console.log(hits);
- })
- .catch((err) => {
- console.log(err);
- });
- };
-
- useEffect(() => {
-
- brandApp()
-
- }, [])
-
- /*const trandingApp = () => {
-
- const index = client.getTrendingGlobalItems([
- {
- indexName: "appsearch",
- threshold: 60
- },
- ])
- .then(({ results }) => {
- console.log(results);
- })
- .catch(err => {
- console.log(err);
- });
- };
-
- useEffect(() => {
-
- trandingApp();
-
- }, [])
- */
-
- const SideBar = {
- minWidth: 250,
-
- borderRight: "1px solid rgba(255,255,255,0.3)",
- left: 0,
- position: "sticky",
- minHeight: "90vh",
- maxHeight: "90vh",
- overflowX: "hidden",
- overflowY: "auto",
- zIndex: 1000,
- color: "white"
- };
- const contentbar = {
- padding: "40px",
-
- };
- const boxdata = {
- paddingLeft: "30px"
- }
- const link = {
- textDecoration: "none"
- }
- const catItems = (
-
-
-
-
- Categories
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- )
- return (
-
-
- );
-}
-export default AppExplorer;
diff --git a/frontend/src/views/AppHub.jsx b/frontend/src/views/AppHub.jsx
deleted file mode 100644
index 5a4db83a..00000000
--- a/frontend/src/views/AppHub.jsx
+++ /dev/null
@@ -1,789 +0,0 @@
-import React from "react";
-import { Grid, Container, Divider, CardMedia, List, ListItem, ListItemText } from "@mui/material";
-
-import { makeStyles } from "@material-ui/core/styles";
-import Card from "@material-ui/core/Card";
-import CardContent from "@material-ui/core/CardContent";
-
-import Table from "@material-ui/core/Table";
-import TableBody from "@material-ui/core/TableBody";
-import TableCell from "@material-ui/core/TableCell";
-import TableContainer from "@material-ui/core/TableContainer";
-import TableHead from "@material-ui/core/TableHead";
-import TableRow from "@material-ui/core/TableRow";
-import Paper from "@material-ui/core/Paper";
-
-import { LineChart, LineSeries, BarChart } from "reaviz";
-import { Gridline, GridStripe } from "reaviz";
-import { GridlineSeries } from "reaviz";
-
-import InputLabel from '@material-ui/core/InputLabel';
-import FormControl from '@material-ui/core/FormControl';
-import Select from '@material-ui/core/Select';
-
-import { styled, alpha } from '@mui/material/styles';
-import AppBar from '@mui/material/AppBar';
-import Box from '@mui/material/Box';
-import Toolbar from '@mui/material/Toolbar';
-import IconButton from '@mui/material/IconButton';
-import Typography from '@mui/material/Typography';
-import InputBase from '@mui/material/InputBase';
-import Badge from '@mui/material/Badge';
-import MenuItem from '@mui/material/MenuItem';
-import Menu from '@mui/material/Menu';
-import MenuIcon from '@mui/icons-material/Menu';
-import SearchIcon from '@mui/icons-material/Search';
-import AccountCircle from '@mui/icons-material/AccountCircle';
-import MailIcon from '@mui/icons-material/Mail';
-import NotificationsIcon from '@mui/icons-material/Notifications';
-import MoreIcon from '@mui/icons-material/MoreVert';
-import SearchField from "../components/Searchfield";
-import { SpaRounded } from "@material-ui/icons";
-import { isMobile } from "react-device-detect"
-
-const data = [
- {
- key: new Date("11/29/2019"),
- data: 10,
- },
- {
- key: new Date("11/30/2019"),
- data: 14,
- },
- {
- key: new Date("12/01/2019"),
- data: 5,
- },
- {
- key: new Date("12/02/2019"),
- data: 18,
- },
-];
-
-const useStyles1 = makeStyles((theme) => ({
- formControl: {
- margin: theme.spacing(1),
- minWidth: 120,
- },
- selectEmpty: {
- marginTop: theme.spacing(2),
- },
-}));
-
-
-const useStyles = makeStyles({
- table: {
- minWidth: 650,
- },
- root: {
- minWidth: 275,
- },
- bullet: {
- display: "inline-block",
- margin: "0 2px",
- transform: "scale(0.8)",
- },
- title: {
- fontSize: 14,
- },
- pos: {
- marginBottom: 12,
- },
-});
-
-function createData(name, calories, fat, carbs, protein) {
- return { name, calories, fat, carbs, protein };
-}
-
-const rows = [
- createData("Frozen yoghurt", 159, 6.0, 24, 4.0),
- createData("Ice cream sandwich", 237, 9.0, 37, 4.3),
- createData("Eclair", 262, 16.0, 24, 6.0),
- createData("Cupcake", 305, 3.7, 67, 4.3),
- createData("Gingerbread", 356, 16.0, 49, 3.9),
-];
-
-const Search = styled('div')(({ theme }) => ({
- position: 'relative',
- borderRadius: theme.shape.borderRadius,
- backgroundColor: alpha(theme.palette.common.white, 0.15),
- '&:hover': {
- backgroundColor: alpha(theme.palette.common.white, 0.25),
- },
- marginRight: theme.spacing(2),
- marginLeft: 0,
- width: '100%',
- [theme.breakpoints.up('sm')]: {
- marginLeft: theme.spacing(3),
- width: 'auto',
- },
-}));
-
-const SearchIconWrapper = styled('div')(({ theme }) => ({
- padding: theme.spacing(0, 2),
- height: '100%',
- position: 'absolute',
- pointerEvents: 'none',
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'center',
-}));
-
-const StyledInputBase = styled(InputBase)(({ theme }) => ({
- color: 'inherit',
- '& .MuiInputBase-input': {
- padding: theme.spacing(1, 1, 1, 0),
- // vertical padding + font size from searchIcon
- paddingLeft: `calc(1em + ${theme.spacing(4)})`,
- transition: theme.transitions.create('width'),
- width: '100%',
- [theme.breakpoints.up('md')]: {
- width: '20ch',
- },
- },
-}));
-
-function PrimarySearchAppBar() {
- const [anchorEl, setAnchorEl] = React.useState(null);
- const [mobileMoreAnchorEl, setMobileMoreAnchorEl] = React.useState(null);
-
- const isMenuOpen = Boolean(anchorEl);
- const isMobileMenuOpen = Boolean(mobileMoreAnchorEl);
-
- const handleProfileMenuOpen = (event) => {
- setAnchorEl(event.currentTarget);
- };
-
- const handleMobileMenuClose = () => {
- setMobileMoreAnchorEl(null);
- };
-
- const handleMenuClose = () => {
- setAnchorEl(null);
- handleMobileMenuClose();
- };
-
- const handleMobileMenuOpen = (event) => {
- setMobileMoreAnchorEl(event.currentTarget);
- };
-
- const menuId = 'primary-search-account-menu';
- const renderMenu = (
-
- );
-
- const mobileMenuId = 'primary-search-account-menu-mobile';
- const renderMobileMenu = (
-
- );
-
- return (
-
-
-
-
-
- {/* */}
-
-
-
- {renderMobileMenu}
- {renderMenu}
-
- );
-}
-
-const AppHub = () => {
- const classes = useStyles();
- const classes1 = useStyles1();
-
- const [usecases, setUsecases] = React.useState([
- {
- "name": "1. Collect",
- "color": "#c51152",
- "list": [
- {
- "name": "Email management",
- "priority": 100,
- "type": "communication",
- "items": {
- "name": "Release a quarantined message",
- "items": {}
- },
- "matches": []
- },
- {
- "name": "EDR to ticket",
- "priority": 100,
- "type": "edr",
- "items": {
- "name": "Get host information",
- "items": {}
- },
- "matches": []
- },
- {
- "name": "SIEM to ticket",
- "priority": 100,
- "type": "siem",
- "description": "Ensure tickets are forwarded to the correct destination. Alternatively add enrichment on it's way there.",
- "video": "https://www.youtube.com/watch?v=FBISHA7V15c&t=197s&ab_channel=OpenSecure",
- "blogpost": "https://medium.com/shuffle-automation/introducing-shuffle-an-open-source-soar-platform-part-1-58a529de7d12",
- "reference_image": "/images/detectionframework.png",
- "items": {},
- "matches": []
- },
- {
- "name": "2-way Ticket synchronization",
- "priority": 90,
- "items": {},
- "matches": []
- },
- {
- "name": "ChatOps",
- "priority": 70,
- "items": {},
- "matches": []
- },
- {
- "name": "Threat Intel received",
- "priority": 50,
- "items": {},
- "matches": []
- },
- {
- "name": "Assign tickets",
- "priority": 30,
- "items": {},
- "matches": []
- },
- {
- "name": "Firewall alerts",
- "priority": 90,
- "items": {
- "name": "URL filtering",
- "items": {}
- },
- "matches": []
- },
- {
- "name": "IDS/IPS alerts",
- "priority": 90,
- "items": {
- "name": "Manage policies",
- "items": {}
- },
- "matches": []
- },
- {
- "name": "Deduplicate information",
- "priority": 70,
- "items": {},
- "matches": []
- }
- ],
- "matches": []
- },
- {
- "name": "2. Enrich",
- "color": "#f4c20d",
- "list": [
- {
- "name": "Internal Enrichment",
- "priority": 100,
- "items": {
- "name": "...",
- "items": {}
- },
- "matches": []
- },
- {
- "name": "External historical Enrichment",
- "priority": 90,
- "items": {
- "name": "...",
- "items": {}
- },
- "matches": []
- },
- {
- "name": "Realtime",
- "priority": 50,
- "items": {
- "name": "Analyze screenshots",
- "items": {}
- },
- "matches": []
- }
- ],
- "matches": []
- },
- {
- "name": "3. Detect",
- "color": "#3cba54",
- "list": [
- {
- "name": "Search SIEM (Sigma)",
- "priority": 90,
- "items": {
- "name": "Endpoint",
- "items": {}
- },
- "matches": []
- },
- {
- "name": "Search EDR (OSQuery)",
- "priority": 90,
- "items": {},
- "matches": []
- },
- {
- "name": "Search emails (Sublime)",
- "priority": 90,
- "items": {
- "name": "Check headers and IOCs",
- "items": {}
- },
- "matches": []
- },
- {
- "name": "Search IOCs (ioc-finder)",
- "priority": 50,
- "items": {},
- "matches": []
- },
- {
- "name": "Search files (Yara)",
- "priority": 50,
- "items": {},
- "matches": []
- },
- {
- "name": "Memory Analysis (Volatility)",
- "priority": 50,
- "items": {},
- "matches": []
- },
- {
- "name": "IDS & IPS (Snort/Surricata)",
- "priority": 50,
- "items": {},
- "matches": []
- },
- {
- "name": "Validate old tickets",
- "priority": 50,
- "items": {},
- "matches": []
- },
- {
- "name": "Honeypot access",
- "priority": 50,
- "items": {
- "name": "...",
- "items": {}
- },
- "matches": []
- }
- ],
- "matches": []
- },
- {
- "name": "4. Respond",
- "color": "#4885ed",
- "list": [
- {
- "name": "Eradicate malware",
- "priority": 90,
- "items": {},
- "matches": []
- },
- {
- "name": "Quarantine host(s)",
- "priority": 90,
- "items": {},
- "matches": []
- },
- {
- "name": "Block IPs, URLs, Domains and Hashes",
- "priority": 90,
- "items": {},
- "matches": []
- },
- {
- "name": "Trigger scans",
- "priority": 50,
- "items": {},
- "matches": []
- },
- {
- "name": "Update indicators (FW, EDR, SIEM...)",
- "priority": 50,
- "items": {},
- "matches": []
- },
- {
- "name": "Autoblock activity when threat intel is received",
- "priority": 50,
- "items": {},
- "matches": []
- },
- {
- "name": "Lock/Delete/Reset account",
- "priority": 50,
- "items": {},
- "matches": []
- },
- {
- "name": "Lock vault",
- "priority": 50,
- "items": {},
- "matches": []
- },
- {
- "name": "Increase authentication",
- "priority": 50,
- "items": {},
- "matches": []
- },
- {
- "name": "Get policies from assets",
- "priority": 50,
- "items": {},
- "matches": []
- },
- {
- "name": "Run ansible scripts",
- "priority": 50,
- "items": {},
- "matches": []
- }
- ],
- "matches": []
- },
- {
- "name": "5. Verify",
- "color": "#7f00ff",
- "list": [
- {
- "name": "Discover vulnerabilities",
- "priority": 80,
- "items": {},
- "matches": []
- },
- {
- "name": "Discover assets",
- "priority": 80,
- "items": {},
- "matches": []
- },
- {
- "name": "Ensure policies are followed",
- "priority": 80,
- "items": {},
- "matches": []
- },
- {
- "name": "Find Inactive users",
- "priority": 50,
- "items": {},
- "matches": []
- },
- {
- "name": "Botnet tracker",
- "priority": 50,
- "items": {},
- "matches": []
- },
- {
- "name": "Ensure access rights match HR systems",
- "priority": 50,
- "items": {},
- "matches": []
- },
- {
- "name": "Ensure onboarding is followed",
- "priority": 50,
- "items": {},
- "matches": []
- },
- {
- "name": "Third party apps in SaaS",
- "priority": 50,
- "items": {},
- "matches": []
- },
- {
- "name": "Devices used for your cloud account",
- "priority": 50,
- "items": {},
- "matches": []
- },
- {
- "name": "Too much access in GCP/Azure/AWS/ other clouds",
- "priority": 50,
- "items": {},
- "matches": []
- },
- {
- "name": "Certificate validation",
- "priority": 50,
- "items": {},
- "matches": []
- },
- {
- "name": "Domain investigation with LetsEncrypt",
- "priority": 50,
- "items": {},
- "matches": []
- },
- {
- "name": "Monitor new DNS entries for domain with passive DNS",
- "priority": 50,
- "items": {},
- "matches": []
- },
- {
- "name": "Monitor and track password dumps",
- "priority": 50,
- "items": {},
- "matches": []
- },
- {
- "name": "Monitor for mentions of domain on darknet sites",
- "priority": 50,
- "items": {},
- "matches": []
- },
- {
- "name": "Reporting",
- "priority": 50,
- "items": {
- "name": "Monthly reports",
- "items": {
- "name": "...",
- "items": {}
- }
- },
- "matches": []
- }
- ],
- "matches": []
- }
- ]);
-
- const SideBar = {
- minWidth: 250,
- maxWidth: 300,
- borderRight: "1px solid rgba(255,255,255,0.3)",
- left: 0,
- position: "sticky",
- minHeight: "90vh",
- maxHeight: "90vh",
- overflowX: "hidden",
- overflowY: "auto",
- zIndex: 1000,
- color: "black"
- };
-
- const [age, setAge] = React.useState(0);
-
- const handleChange = (event) => {
- setAge(event.target.value);
-
- };
-
- return (
-
-
-
-
-
-
-
-
-

-
- SHUFFLE
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Categories
-
-
-
-
-
-
- Workflows
-
-
-
-
- Apps
-
-
-
-
- Docs
-
-
-
-
-
-
- Workflow
-
-
- {!isMobile && usecases !== null && usecases !== undefined && usecases.length > 0 ?
-
- : null}
-
-
-
-
-
-
-
- footer
-
-
-
-
- );
-};
-
-export default AppHub;
\ No newline at end of file
diff --git a/frontend/src/views/Appdemo.jsx b/frontend/src/views/Appdemo.jsx
deleted file mode 100644
index 3fe5aae1..00000000
--- a/frontend/src/views/Appdemo.jsx
+++ /dev/null
@@ -1,268 +0,0 @@
-import React, { useState, useEffect } from "react";
-import { Grid, Container, Divider, CardMedia, List, ListItem, ListItemText } from "@mui/material";
-import Typography from "@material-ui/core/Typography";
-
-import theme from '../theme';
-import {isMobile} from "react-device-detect";
-import AppGrid1 from "../components/AppGrid1.jsx"
-import WorkflowGrid from "../components/WorkflowGrid.jsx"
-import CreatorGrid from "../components/CreatorGrid.jsx"
-import DocsGrid from "../components/DocsGrid.jsx"
-import Button from '@mui/material/Button';
-import { useNavigate, Link } from "react-router-dom";
-
-import {
- Tabs,
- Paper,
- Tab,
-} from "@material-ui/core";
-
-import {
- Business as BusinessIcon,
- Apps as AppsIcon,
- Polymer as PolymerIcon,
- EmojiObjects as EmojiObjectsIcon,
- Description as DescriptionIcon,
-} from "@material-ui/icons";
-
-
-const bodyDivStyle = {
- margin: "auto",
- maxWidth: 1024,
- scrollX: "hidden",
- overflowX: "hidden",
-}
-
-// Should be different if logged in :|
-const Appdemo = (props) => {
- const { globalUrl, isLoaded, serverside, userdata, hidemargins, } = props;
- const [appCategory,setAppCategory] = useState();
- let navigate = useNavigate();
-
- const [curTab, setCurTab] = useState(0);
- const iconStyle = { marginRight: 10 };
-
- useEffect(() => {
- if (serverside !== true && window.location.search !== undefined && window.location.search !== null) {
- const urlSearchParams = new URLSearchParams(window.location.search)
- const params = Object.fromEntries(urlSearchParams.entries())
- const foundTab = params["tab"]
- if (foundTab !== null && foundTab !== undefined) {
- for (var key in Object.keys(views)) {
- const value = views[key]
- console.log(key, value)
- if (value === foundTab) {
- setConfig("", key)
- break
- }
- }
- }
- }
- }, [])
-
- if (serverside === true) {
- return null
- }
-
- const boxStyle = {
- color: "white",
- flex: "1",
- marginLeft: 10,
- marginRight: 10,
- paddingLeft: 30,
- paddingRight: 30,
- paddingBottom: 30,
- paddingTop: hidemargins === true ? 0 : 30,
- display: "flex",
- flexDirection: "column",
- overflowX: "hidden",
- minHeight: 400,
- }
- const NoArguments_NoReturn = () => {
-
- alert('Function Called...');
-
- }
- const SideBar = {
- minWidth: 250,
- maxWidth: 300,
- borderRight: "1px solid rgba(255,255,255,0.3)",
- left: 0,
- position: "sticky",
- minHeight: "90vh",
- maxHeight: "90vh",
- overflowX: "hidden",
- overflowY: "auto",
- zIndex: 1000,
- color: "white"
- };
- const catItems = (
-
-
-
-
- Categories
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-)
-
- const views = {
- 0: "apps",
- 1: "workflows",
- 2: "docs",
- 3: "creators",
- }
-
- const setConfig = (event, inputValue) => {
- const newValue = parseInt(inputValue)
-
- setCurTab(newValue)
- if (newValue === 0) {
- document.title = "Shuffle - search - apps";
- } else if (newValue === 1) {
- document.title = "Shuffle - search - workflows";
- } else if (newValue === 2) {
- document.title = "Shuffle - search - documentation";
- } else if (newValue === 3) {
- document.title = "Shuffle - search - creators";
- } else {
- document.title = "Shuffle - search";
- }
-
-
- const urlSearchParams = new URLSearchParams(window.location.search)
- const params = Object.fromEntries(urlSearchParams.entries())
- const foundQuery = params["q"]
- var extraQ = ""
- if (foundQuery !== null && foundQuery !== undefined) {
- extraQ = "&q="+foundQuery
- }
-
-
- if ((serverside === false || serverside === undefined) && window.location.pathname.includes("/search")) {
- navigate(`/search?tab=${views[newValue]}`+extraQ)
- }
- }
-
- if (isLoaded === false) {
- return null
- }
-
-
- // Random names for type & autoComplete. Didn't research :^)
- const landingpageDataBrowser =
-
-
-
-
- Apps
-
- />
-
-
- {curTab === 0 ?
-
- :
- curTab === 1 ?
- window.location.pathname === "/search" ?
-
- :
-
- :
- curTab === 2 ?
-
- :
- curTab === 3 ?
-
- :
- null}
-
-
- //{/*alternativeView={true} />*/}
-
- const loadedCheck = isLoaded ?
-
-
{landingpageDataBrowser}
-
- :
-
-
-
- // #1f2023?
- return(
-
- {catItems}
- {loadedCheck}
-
- )
-}
-
-export default Appdemo;
diff --git a/frontend/src/views/Contact.jsx b/frontend/src/views/Contact.jsx
deleted file mode 100755
index afd609a4..00000000
--- a/frontend/src/views/Contact.jsx
+++ /dev/null
@@ -1,343 +0,0 @@
-import React, { useState } from 'react';
-import { BrowserView, MobileView } from "react-device-detect";
-import theme from '../theme.jsx';
-
-import Paper from '@material-ui/core/Paper';
-import Button from '@material-ui/core/Button';
-
-import TextField from '@material-ui/core/TextField';
-
-
-const bodyDivStyle = {
- margin: "auto",
- textAlign: "center",
- width: "900px",
-}
-
-
-// Should be different if logged in :|
-const Contact = (props) => {
- const { globalUrl, isLoaded } = props;
-
- const boxStyle = {
- flex: "1",
- marginLeft: "10px",
- marginRight: "10px",
- paddingLeft: "30px",
- paddingRight: "30px",
- paddingBottom: "30px",
- paddingTop: "30px",
- backgroundColor: theme.palette.surfaceColor,
- display: "flex",
- flexDirection: "column"
- }
-
- const bodyTextStyle = {
- color: "#ffffff",
- }
-
- const [firstname, setFirstname] = useState("");
- const [lastname, setLastname] = useState("");
- const [title, setTitle] = useState("");
- const [companyname, setCompanyname] = useState("");
- const [email, setEmail] = useState("");
- const [phone, setPhone] = useState("");
- const [message, setMessage] = useState("");
-
- const [formMessage, setFormMessage] = useState("");
-
- const submitContact = () => {
- const data = {
- "firstname": firstname,
- "lastname": lastname,
- "title": title,
- "companyname": companyname,
- "email": email,
- "phone": phone,
- "message": message,
- }
- console.log(data)
-
- fetch(globalUrl + "/api/v1/contact", {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify(data),
- })
- .then(response => response.json())
- .then(response => {
- if (response.success === true) {
- setFormMessage(response.message)
- } else {
- setFormMessage("Something went wrong. Please contact frikky@shuffler.io.")
- }
- console.log(response)
- })
- .catch(error => {
- console.log(error)
- });
- }
-
- // Random names for type & autoComplete. Didn't research :^)
- const landingpageDataBrowser =
-
-
-
Contact us
- Lets talk!
-
-
-
- Contact Details
-
- setFirstname(e.target.value)}
- />
- setLastname(e.target.value)}
- />
-
-
- setTitle(e.target.value)}
- />
- setCompanyname(e.target.value)}
- />
-
-
- setEmail(e.target.value)}
- />
- setPhone(e.target.value)}
- />
-
-
-
Message
-
-
- setMessage(e.target.value)}
- />
-
-
- {formMessage}
-
-
-
-
- const landingpageDataMobile =
-
-
-
Contact us
- Lets talk!
-
-
-
- Contact Details
-
- setFirstname(e.target.value)}
- />
-
-
- setEmail(e.target.value)}
- />
-
-
-
Message
-
-
- setMessage(e.target.value)}
- />
-
-
- {formMessage}
-
-
-
-
-
- const loadedCheck = isLoaded ?
-
-
- {landingpageDataBrowser}
-
-
- {landingpageDataMobile}
-
-
- :
-
-
-
- return (
-
- {loadedCheck}
-
- )
-}
-export default Contact;
diff --git a/frontend/src/views/Dashboard.jsx b/frontend/src/views/Dashboard.jsx
index 29b0098d..6fd1557b 100755
--- a/frontend/src/views/Dashboard.jsx
+++ b/frontend/src/views/Dashboard.jsx
@@ -83,7 +83,6 @@ const useStyles = makeStyles({
},
inputRoot: {
color: "white",
- // This matches the specificity of the default styles at https://github.com/mui-org/material-ui/blob/v4.11.3/packages/material-ui-lab/src/Autocomplete/Autocomplete.js#L90
"&:hover .MuiOutlinedInput-notchedOutline": {
borderColor: "#f86a3e",
},
diff --git a/frontend/src/views/DashboardViews.jsx b/frontend/src/views/DashboardViews.jsx
index 950ae73e..4d9c4b14 100644
--- a/frontend/src/views/DashboardViews.jsx
+++ b/frontend/src/views/DashboardViews.jsx
@@ -93,7 +93,6 @@ const useStyles = makeStyles({
},
inputRoot: {
color: "white",
- // This matches the specificity of the default styles at https://github.com/mui-org/material-ui/blob/v4.11.3/packages/material-ui-lab/src/Autocomplete/Autocomplete.js#L90
"&:hover .MuiOutlinedInput-notchedOutline": {
borderColor: "#f86a3e",
},
diff --git a/frontend/src/views/EditSchedule.jsx b/frontend/src/views/EditSchedule.jsx
deleted file mode 100755
index ffc3eb1c..00000000
--- a/frontend/src/views/EditSchedule.jsx
+++ /dev/null
@@ -1,1574 +0,0 @@
-import React, { useState, useEffect } from "react";
-
-/*
- * It works a little something like this:
- * Choose what source and destination action you want
- * Select the source field to be used for a required destination field OR
- * write a static value for the field (FIXME) OR
- * run a generator action for the field (FIXME, these should be e.g. run workflow and get result)
- */
-
-import Grid from "@material-ui/core/Grid";
-import Dialog from "@material-ui/core/Dialog";
-import DialogTitle from "@material-ui/core/DialogTitle";
-import DialogActions from "@material-ui/core/DialogActions";
-import DialogContent from "@material-ui/core/DialogContent";
-
-import ButtonBase from "@material-ui/core/ButtonBase";
-import TextField from "@material-ui/core/TextField";
-import MenuItem from "@material-ui/core/MenuItem";
-import Paper from "@material-ui/core/Paper";
-import Button from "@material-ui/core/Button";
-import FormControl from "@material-ui/core/FormControl";
-import Select from "@material-ui/core/Select";
-import InputLabel from "@material-ui/core/InputLabel";
-import Table from "@material-ui/core/Table";
-import InputAdornment from "@material-ui/core/InputAdornment";
-import TableBody from "@material-ui/core/TableBody";
-import TableCell from "@material-ui/core/TableCell";
-import TableRow from "@material-ui/core/TableRow";
-
-import SearchIcon from "@material-ui/icons/Search";
-import DeleteIcon from "@material-ui/icons/Delete";
-
-import Downshift from "downshift";
-import deburr from "lodash/deburr";
-
-const EditSchedule = (props) => {
- const { globalUrl } = props;
-
- const [tmpSrcApp, setTmpSrcApp] = useState({});
- const [tmpDstApp, setTmpDstApp] = useState({});
- const [srcApp, setSrcApp] = useState({});
- const [srcAppConfig, setSrcAppConfig] = useState([]);
- const [srcAppConfigOpen, setSrcAppConfigOpen] = useState(false);
- const [srcAppAction, setSrcAppAction] = useState("");
-
- const [dstApp, setDstApp] = useState({});
- const [dstAppAction, setDstAppAction] = useState("");
- const [dstAppConfig, setDstAppConfig] = useState([]);
- const [dstAppConfigOpen, setDstAppConfigOpen] = useState(false);
-
- // Lets set the real data here
- const [selectedSrc, setSelectedSrc] = React.useState("");
- const [, setSelectedSrcData] = React.useState({});
- const [selectedDst, setSelectedDst] = React.useState([]);
-
- // FIXME
- const [suggestions, setSuggestions] = React.useState([]);
- const [inputappdata, setInputAppData] = React.useState({});
-
- const [scheduleConfig, setScheduleConfig] = React.useState({});
- const [selectedSrcParameters, setSelectedSrcParameters] = React.useState([]);
-
- const getCurrentSchedule = () => {
- fetch(globalUrl + "/api/v1/schedules/" + props.match.params.key, {
- method: "GET",
- headers: {
- "Content-Type": "application/json",
- Accept: "application/json",
- },
- })
- .then((response) => response.json())
- .then((responseJson) => {
- setScheduleConfig(responseJson);
- })
- .catch((error) => {
- console.log(error);
- });
- };
-
- const loadAppSuggestions = () => {
- fetch(globalUrl + "/api/v1/schedules/apps", {
- method: "GET",
- headers: {
- "Content-Type": "application/json",
- Accept: "application/json",
- },
- })
- .then((response) => response.json())
- .then((responseJson) => {
- setSuggestions(responseJson.apps);
- })
- .catch((error) => {
- console.log(error);
- });
- };
-
- // FIXME - this is generated from app selection input with required items
- useEffect(() => {
- if (Object.getOwnPropertyNames(scheduleConfig).length <= 0) {
- getCurrentSchedule();
- }
-
- // Load apps if destination or source is
- if (suggestions.length === 0) {
- loadAppSuggestions();
- }
-
- // Load everything else
- if (
- Object.getOwnPropertyNames(scheduleConfig).length > 0 &&
- Object.getOwnPropertyNames(scheduleConfig.appinfo.sourceapp).length > 0 &&
- Object.getOwnPropertyNames(srcApp).length <= 0
- ) {
- if (scheduleConfig.appinfo.sourceapp.name.length > 0) {
- setSrcApp(scheduleConfig.appinfo.sourceapp);
- setSrcAppAction(scheduleConfig.appinfo.sourceapp.action);
- }
- }
-
- // Use sourceapp.name&version and sourceapp.action and look for name in inputappdata
- // Basically fix everything in this one lol
- if (
- suggestions.length > 0 &&
- srcAppAction.length > 0 &&
- Object.getOwnPropertyNames(scheduleConfig).length > 0 &&
- Object.getOwnPropertyNames(inputappdata).length <= 0
- ) {
- // Loops all apps and finds current
- for (var key in suggestions) {
- var curapp = suggestions[key];
- if (curapp.name === srcApp.name) {
- break;
- }
- }
-
- setInputAppData(curapp);
-
- // Loops the apps actions to find current
- for (key in curapp.output) {
- var curappaction = curapp.output[key];
- if (curappaction.name === srcAppAction) {
- break;
- }
- }
-
- setSelectedSrcParameters(curappaction.outputparameters);
- if (curappaction.config !== null && curappaction.config !== undefined) {
- setSrcAppConfig(curappaction.config);
- }
-
- // FIXME - set src of all translator nodes to curappaction.outputparameters[0] if not defined
- //value={scheduleConfig.translator[count].src.name}
-
- //console.log(scheduleConfig)
- var newtranslator = [];
- for (key in scheduleConfig.translator) {
- var curtranslator = scheduleConfig.translator[key];
-
- // Overwrite issues
- if (curtranslator.src.name === "") {
- curtranslator.src = curappaction.outputparameters[0];
- }
-
- newtranslator.push(curtranslator);
- }
-
- scheduleConfig.translator = newtranslator;
- setScheduleConfig(scheduleConfig);
- }
-
- if (
- suggestions.length > 0 &&
- dstAppAction.length <= 0 &&
- Object.getOwnPropertyNames(scheduleConfig).length > 0
- ) {
- // Loops all apps and finds current
- for (key in suggestions) {
- curapp = suggestions[key];
- if (curapp.name === dstApp.name) {
- break;
- }
- }
-
- const curAction = scheduleConfig.appinfo.destinationapp.action;
-
- // Loops the apps actions to find current
- for (key in curapp.output) {
- curappaction = curapp.output[key];
- if (curappaction.name === curAction) {
- break;
- }
- }
-
- setDstAppAction(curappaction.name);
- if (curappaction.config !== null && curappaction.config !== undefined) {
- setDstAppConfig(curappaction.config);
- }
- }
- });
-
- const getSuggestions = (value, type, { showEmpty = false } = {}) => {
- const inputValue = deburr(value.trim()).toLowerCase();
- const inputLength = inputValue.length;
- let count = 0;
-
- return inputLength === 0 && !showEmpty
- ? []
- : suggestions.filter((suggestion) => {
- const keep =
- count < 5 &&
- suggestion.types &&
- suggestion.types.includes(type) &&
- suggestion.name.slice(0, inputLength).toLowerCase() === inputValue;
-
- if (keep) {
- count += 1;
- }
-
- return keep;
- });
- };
-
- const setSrcAppWrapper = (currentapps) => {
- setSrcApp(currentapps[0]);
- if (currentapps[0].output.length > 0) {
- selectSrcAction(currentapps[0].output[0].name);
- }
- };
-
- const setDstAppWrapper = (currentapps) => {
- setDstApp(currentapps[0]);
- if (currentapps[0].input.length > 0) {
- selectInitialDstAction(currentapps);
- }
- };
-
- const renderInput = (type, inputProps) => {
- const { InputProps, classes, ref, ...other } = inputProps;
-
- // Sets the srcapp if string is matching exactly for name
- if (
- InputProps["aria-activedescendant"] === null &&
- InputProps["value"].length > 0
- ) {
- const currentapps = suggestions.filter(
- (data) => data.name === InputProps["value"]
- );
- if (currentapps.length === 1) {
- if (type === "output") {
- if (currentapps[0].name !== srcApp.name) {
- setSrcAppWrapper(currentapps);
- }
- } else if (type === "input") {
- if (currentapps[0].name !== dstApp.name) {
- setDstAppWrapper(currentapps);
- }
- }
- }
- }
-
- return (
-
-
-
-
- ),
- }}
- {...other}
- />
-
- );
- };
-
- const renderSuggestion = (suggestionProps) => {
- const { suggestion, index, itemProps, highlightedIndex, selectedItem } =
- suggestionProps;
- const isHighlighted = highlightedIndex === index;
- const isSelected = (selectedItem || "").indexOf(suggestion.name) > -1;
-
- return (
-
- );
- };
-
- const bodyDivStyle = {
- marginLeft: "20px",
- marginTop: "50px",
- marginRight: "20px",
- margin: "auto",
- width: "1350px",
- display: "flex",
- };
-
- const appActionStyle = {
- height: "50px",
- marginTop: "10px",
- };
-
- // FIXME - set this
- //const setRelationshipsFromSource = () => {
-
- //}
-
- //// FIXME - set this
- //const setRelationshipsFromGenerator = () => {
-
- //}
-
- const selectDstAppAction = (event) => {
- if (event.target.value === dstAppAction) {
- return;
- }
-
- setDstAppAction(event.target.value);
- refactorTranslations(event.target.value);
- };
-
- const refactorTranslations = (action) => {
- // dstapp is chosen
- var found = false;
- for (var key in dstApp.input) {
- var curinput = dstApp.input[key];
- if (curinput.name === action) {
- found = true;
- break;
- }
- }
-
- // Should never happen..
- if (!found) {
- return;
- }
-
- var tmprelationships = [];
- for (key in curinput.inputparameters) {
- var curRelation = { dst: curinput.inputparameters[key], src: {} };
- tmprelationships.push(curRelation);
- }
-
- scheduleConfig["translator"] = tmprelationships;
- setScheduleConfig(scheduleConfig);
- };
-
- const selectInitialDstAction = (value) => {
- var action = value[0].input[0].name;
- setDstAppAction(action);
-
- var found = false;
- for (var key in value) {
- var curinput = value[0].input[key];
- if (curinput.name === action) {
- found = true;
- break;
- }
- }
-
- // Should never happen..
- if (!found) {
- return;
- }
-
- var tmprelationships = [];
- for (key in curinput.inputparameters) {
- var curRelation = { dst: curinput.inputparameters[key], src: {} };
- tmprelationships.push(curRelation);
- }
-
- scheduleConfig["translator"] = tmprelationships;
- setScheduleConfig(scheduleConfig);
- };
-
- const selectSrcAction = (value) => {
- // FIXME - load the config for this action
- var found = false;
-
- setSrcAppAction(value);
-
- var curitem = {};
- for (var key in inputappdata.output) {
- curitem = inputappdata.output[key];
- if (curitem.name === value) {
- found = true;
- break;
- }
- }
-
- if (!found) {
- setSelectedSrcParameters([]);
- return;
- }
-
- // Generate this for every relation?
- setSelectedSrcParameters(curitem.outputparameters);
-
- //FIXME - check if source has the right attribute
- var tmprelationships = [];
- key = 0;
- for (key in scheduleConfig.translator) {
- var curRelation = scheduleConfig.translator[key];
- curRelation["src"] = curitem.outputparameters[0];
- tmprelationships.push(curRelation);
- }
-
- scheduleConfig["translator"] = tmprelationships;
- setScheduleConfig(scheduleConfig);
- };
-
- // Wrapper to handle event click
- const selectSrcActionWrapper = (event) => {
- return selectSrcAction(event.target.value);
- };
-
- const srcappaction =
- Object.getOwnPropertyNames(srcApp).length > 0 && srcApp.output ? (
-
-
- Actions
-
-
-
- ) : null;
-
- const dstappaction =
- Object.getOwnPropertyNames(dstApp).length > 0 ? (
-
-
- Actions
-
-
-
- ) : null;
-
- const downshiftStyle = {
- //marginLeft: "20px",
- //marginTop: "20px",
- //marginRight: "20px",
- display: "flex",
- width: "100%",
- };
-
- const submitDisabled = selectedSrc.length > 0 && selectedDst.length > 0;
- const submitButtonClick = () => {
- var newtranslations = [];
- var tobeadded = [];
- var tobechanged = [];
-
- // Go find the information again in testdata
-
- //newrelationship["translator"] = {"src": {}, "dst": {}}
- //newrelationship["static"] = {}
-
- // Reformat relationships
- // clean up old relationships
- //
-
- if (Object.getOwnPropertyNames(scheduleConfig.Translator).length <= 0) {
- return;
- }
-
- // Clean up old translations for specified elements
- // FIXME - maybe just send a request with relationships and fix in backend?
- // FIXME - there is an issue here for some multifield stuff
- // Literally have to verify every single one anyway..
- for (var selected in selectedDst) {
- var found = false;
- var index = 0;
- for (var key in scheduleConfig["translator"]) {
- if (
- scheduleConfig["translator"][key]["dst"]["name"] ===
- selectedDst[selected]
- ) {
- index = key;
- found = true;
- break;
- }
- }
-
- if (!found) {
- tobeadded.push(selectedDst[selected]);
- } else {
- // Dst can be the
- tobechanged.push(index);
- }
- }
-
- var tmprelationships = scheduleConfig;
-
- key = 0;
- for (key in scheduleConfig["translator"]) {
- if (tobechanged.includes(key)) {
- var tmprel = scheduleConfig["translator"][key];
- tmprel["src"] = { name: selectedSrc };
- tmprelationships["translator"].splice(key, 1);
- newtranslations.push(tmprel);
- }
- }
-
- key = 0;
- for (key in tobeadded) {
- tmprel = { src: { name: selectedSrc }, dst: { name: tobeadded[key] } };
- newtranslations.push(tmprel);
- }
-
- // delete deletable keys from copy (new)
- //
- key = 0;
- for (key in newtranslations) {
- tmprelationships["translator"].push(newtranslations[key]);
- }
-
- setSelectedSrc("");
- setSelectedDst([]);
- setSelectedSrcData({});
-
- // FIXME - does this work?
- scheduleConfig["translator"] = tmprelationships["translator"];
- setScheduleConfig(scheduleConfig);
- };
-
- // When it's set, need to find the destination in the row and set static
- const setStaticValue = (event, row) => {
- console.log("HI");
- // FIXME - modify the row first
- // FIXME - set generator and source to "nothing"
-
- console.log(row.dst.name);
- console.log(row);
- console.log(event.target.value);
- var newsrcrow = {
- name: "static",
- description: "Static value set",
- type: "static",
- value: event.target.value,
- schema: { type: "string" },
- };
-
- var relationshipclone = JSON.parse(JSON.stringify(scheduleConfig));
- for (var key in scheduleConfig["translator"]) {
- var curItem = scheduleConfig["translator"][key];
- if (curItem.dst.name === row.dst.name) {
- break;
- }
- }
-
- relationshipclone["translator"][key]["src"] = newsrcrow;
-
- scheduleConfig["translator"] = relationshipclone["translator"];
- console.log(scheduleConfig);
-
- // Fuck this :(
- // DO DIS IN FRONTEND AND HAVE A SUBMIT BUTTON :(
- fetch(globalUrl + "/api/v1/schedules/" + props.match.params.key, {
- method: "PUT",
- headers: {
- "Content-Type": "application/json",
- Accept: "application/json",
- },
- body: JSON.stringify(scheduleConfig),
- })
- .then((response) => response.json())
- .then((responseJson) => {
- setScheduleConfig({});
- })
- .catch((error) => {
- console.log(error);
- });
- };
-
- // Rewrites relationships clientside
- const setCurrentSrcPropRelation = (event, rowkey) => {
- console.log(event, rowkey);
- var found = false;
-
- for (var key in selectedSrcParameters) {
- var curItem = selectedSrcParameters[key];
- if (curItem.name === event.target.value) {
- found = true;
- break;
- }
- }
-
- // No idea how this would ever happen, but but (:
- if (!found) {
- return;
- }
-
- var row = scheduleConfig.translator[rowkey];
- var rowclone = JSON.parse(JSON.stringify(row));
- rowclone.src = curItem;
-
- var relationshipclone = JSON.parse(JSON.stringify(scheduleConfig));
- for (key in scheduleConfig["translator"]) {
- curItem = scheduleConfig["translator"][key];
- if (curItem.dst.name === row.dst.name) {
- break;
- }
- }
-
- relationshipclone["translator"][key] = rowclone;
-
- scheduleConfig["translator"] = relationshipclone["translator"];
- console.log(scheduleConfig);
-
- // Fuck this :(
- // DO DIS IN FRONTEND AND HAVE A SUBMIT BUTTON :(
- fetch(globalUrl + "/api/v1/schedules/" + props.match.params.key, {
- method: "PUT",
- headers: {
- "Content-Type": "application/json",
- Accept: "application/json",
- },
- body: JSON.stringify(scheduleConfig),
- })
- .then((response) => response.json())
- .then((responseJson) => {
- setScheduleConfig({});
- })
- .catch((error) => {
- console.log(error);
- });
- return;
- };
-
- const relationshipBody =
- Object.getOwnPropertyNames(scheduleConfig).length > 0 &&
- scheduleConfig["translator"] !== undefined &&
- scheduleConfig.translator.length > 0 ? (
-
-
-
-
- Action
-
-
- Source Field
-
-
- Destination Field
-
-
- Field Type
-
-
- Required
-
-
- Static
-
-
- Generator
-
-
- Transform
-
-
- {scheduleConfig.translator.map((row, count) => {
- var buttonIcon = ;
- if (!row.dst.required) {
- buttonIcon = (
-
- );
- }
-
- const srcpropsSelector =
- (Object.getOwnPropertyNames(selectedSrcParameters).length > 0 ||
- Object.getOwnPropertyNames(scheduleConfig.translator).length >
- 0) &&
- Object.getOwnPropertyNames(srcApp).length > 0 ? (
-
- ) : (
- No defined fields
- );
-
- const placeholderValue =
- row.src.type === "static"
- ? row.src.value
- : "... Set a static value";
-
- return (
-
-
- {buttonIcon}
-
- {srcpropsSelector}
- {row.dst.name}
- {row.dst.schema.type}
- {row.dst.required}
-
- {
- if (event.key === "Enter") {
- event.preventDefault();
- console.log(`Pressed keyCode ${event.key}`);
- setStaticValue(event, row);
- }
- }}
- />
-
- INSERT SCRIPT THINGY - Cortex responder?
-
- );
- })}
-
-
- ) : null;
-
- // FIXME - use this
- //const submitRelationships = () => {
- // // Make an API-call to the backend for verification
- // // Return with failures etc, and mark row issues?
- //
- // var apiUrl = "http://localhost:5000"
- // fetch(apiUrl+"/api/v1/schedules",
- // {
- // method: "POST",
- // headers: {"content-type": "application/json"},
- // body: JSON.stringify(scheduleConfig),
- // }
- // )
- // .then((response) => response.json())
- // .then((responseJson) => {
- // console.log(responseJson)
- // })
- // .catch((error) => {
- // console.log(error);
- // });
- //}
-
- const executeSchedule = () => {
- fetch(
- globalUrl + "/api/v1/schedules/" + props.match.params.key + "/execute",
- {
- method: "GET",
- headers: {
- "Content-Type": "application/json",
- Accept: "application/json",
- },
- }
- )
- .then((response) => response.json())
- .then((responseJson) => {
- console.log(responseJson);
- })
- .catch((error) => {
- console.log(error);
- });
- };
-
- const submitButton = (
-
-
-
- );
-
- // Requires src or dst as input
- // FIXME - use this shit to edit an app or something
- //const editButtonFix = (app, apptype) => {
- // if (apptype === "src") {
-
- // } else if (apptype === "dst") {
-
- // }
- //}
-
- const editSrcApp = (event) => {
- // if tmpsrcapp, show RESET (can be an X or something too)
- // if reset is clicked, set source app back to the original
- setTmpSrcApp(scheduleConfig.appinfo.sourceapp);
-
- var tmpscheduleConfig = scheduleConfig;
- tmpscheduleConfig.appinfo.sourceapp = {};
-
- fetch(globalUrl + "/api/v1/schedules/" + props.match.params.key, {
- method: "PUT",
- headers: {
- "Content-Type": "application/json",
- Accept: "application/json",
- },
- body: JSON.stringify(tmpscheduleConfig),
- })
- .then((response) => response.json())
- .then((responseJson) => {
- setScheduleConfig({});
- setSrcApp({});
- setSrcAppAction("");
- })
- .catch((error) => {
- console.log(error);
- });
- };
-
- const editDstApp = (event) => {
- // if tmpsrcapp, show RESET (can be an X or something too)
- // if reset is clicked, set source app back to the original
- setTmpDstApp(scheduleConfig.appinfo.destinationapp);
-
- var tmpscheduleConfig = scheduleConfig;
- tmpscheduleConfig.appinfo.destinationapp = {};
-
- fetch(globalUrl + "/api/v1/schedules/" + props.match.params.key, {
- method: "PUT",
- headers: {
- "Content-Type": "application/json",
- Accept: "application/json",
- },
- body: JSON.stringify(tmpscheduleConfig),
- })
- .then((response) => response.json())
- .then((responseJson) => {
- setScheduleConfig({});
- setDstApp({});
- setDstAppAction("");
- })
- .catch((error) => {
- console.log(error);
- });
- };
-
- const scheduleApp = (app, actiondata) => {
- const editButton =
- actiondata === "src" ? (
-
- ) : (
-
- );
-
- const configureButton =
- actiondata === "src" ? (
-
- ) : (
-
- );
-
- // FIXME - set src vs dst
- return (
-
-
-
-
-
-
- {splitter}
-
-
-
-
-
{app.name}
-
- {app.description}
-
- {app.action}
-
- {splitter}
-
- {editButton}
- {configureButton}
-
-
-
- );
- };
-
- const splitter = (
-
- );
-
- const dstDownshift = (
-
- {({
- getInputProps,
- getItemProps,
- getMenuProps,
- highlightedIndex,
- inputValue,
- isOpen,
- selectedItem,
- }) => (
-
- {renderInput("input", {
- fullWidth: true,
- InputProps: getInputProps({
- placeholder: "Search destination apps",
- }),
- })}
-
-
-
- {isOpen ? (
-
- {getSuggestions(inputValue, "input").map(
- (suggestion, index) =>
- renderSuggestion({
- suggestion,
- index,
- itemProps: getItemProps({ item: suggestion.name }),
- highlightedIndex,
- selectedItem,
- })
- )}
-
- ) : null}
-
- {dstappaction}
-
-
- )}
-
- );
-
- const srcDownshift = (
-
- {({
- getInputProps,
- getItemProps,
- getMenuProps,
- highlightedIndex,
- inputValue,
- isOpen,
- selectedItem,
- }) => (
-
- {renderInput("output", {
- fullWidth: true,
- InputProps: getInputProps({
- placeholder: "Search source apps",
- }),
- })}
-
-
-
- {isOpen ? (
-
- {getSuggestions(inputValue, "output").map(
- (suggestion, index) =>
- renderSuggestion({
- suggestion,
- index,
- itemProps: getItemProps({ item: suggestion.name }),
- highlightedIndex,
- selectedItem,
- })
- )}
-
- ) : null}
-
- {srcappaction}
-
-
- )}
-
- );
-
- const submitDstApp = (event) => {
- var packagedSrc = {
- name: dstApp.name,
- id: dstApp.id,
- description: dstApp.description,
- action: dstAppAction,
- };
-
- var tmpscheduleConfig = scheduleConfig;
-
- tmpscheduleConfig.appinfo.destinationapp = packagedSrc;
-
- // Hmm, do this here? Idk
- fetch(globalUrl + "/api/v1/schedules/" + props.match.params.key, {
- method: "PUT",
- headers: {
- "Content-Type": "application/json",
- Accept: "application/json",
- },
- body: JSON.stringify(tmpscheduleConfig),
- })
- .then((response) => response.json())
- .then((responseJson) => {
- setScheduleConfig({});
- })
- .catch((error) => {
- console.log(error);
- });
- };
-
- const submitSrcApp = (event) => {
- var packagedSrc = {
- name: srcApp.name,
- id: srcApp.id,
- description: srcApp.description,
- action: srcAppAction,
- };
-
- var tmpscheduleConfig = scheduleConfig;
-
- // FIXME - future fred
- //
- tmpscheduleConfig.appinfo.sourceapp = packagedSrc;
-
- // Hmm, do this here? Idk
- fetch(globalUrl + "/api/v1/schedules/" + props.match.params.key, {
- method: "PUT",
- headers: {
- "Content-Type": "application/json",
- Accept: "application/json",
- },
- body: JSON.stringify(tmpscheduleConfig),
- })
- .then((response) => response.json())
- .then((responseJson) => {
- setScheduleConfig({});
- })
- .catch((error) => {
- console.log(error);
- });
- };
-
- const resetDstApp = (event) => {
- var tmpscheduleConfig = scheduleConfig;
- tmpscheduleConfig.appinfo.destinationapp = tmpDstApp;
-
- // Hmm, do this here? Idk
- fetch(globalUrl + "/api/v1/schedules/" + props.match.params.key, {
- method: "PUT",
- headers: {
- "Content-Type": "application/json",
- Accept: "application/json",
- },
- body: JSON.stringify(tmpscheduleConfig),
- })
- .then((response) => response.json())
- .then((responseJson) => {
- setScheduleConfig({});
- setDstApp(tmpSrcApp);
- setDstAppAction(tmpDstApp.action);
- setTmpDstApp({});
- })
- .catch((error) => {
- console.log(error);
- });
- };
-
- const resetSrcApp = (event) => {
- var tmpscheduleConfig = scheduleConfig;
- tmpscheduleConfig.appinfo.sourceapp = tmpSrcApp;
-
- // Hmm, do this here? Idk
- fetch(globalUrl + "/api/v1/schedules/" + props.match.params.key, {
- method: "PUT",
- headers: {
- "Content-Type": "application/json",
- Accept: "application/json",
- },
- body: JSON.stringify(tmpscheduleConfig),
- })
- .then((response) => response.json())
- .then((responseJson) => {
- setScheduleConfig({});
- setSrcApp(tmpSrcApp);
- setSrcAppAction(tmpSrcApp.action);
- setTmpSrcApp({});
- })
- .catch((error) => {
- console.log(error);
- });
- };
-
- // Based on some srcthing
- const searchGridSrc = (
-
-
- Choose Source app (FIXME) - clickable
-
- {splitter}
-
-
-
- {srcDownshift}
-
-
- {splitter}
-
-
-
-
-
-
-
-
-
-
- );
-
- const searchGridDst = (
-
-
- Choose Source app (FIXME) - clickable
-
- {splitter}
-
-
-
- {dstDownshift}
-
-
- {splitter}
-
-
-
-
-
-
-
-
-
-
- );
-
- const srcField =
- Object.getOwnPropertyNames(scheduleConfig).length > 0 &&
- Object.getOwnPropertyNames(scheduleConfig.appinfo.sourceapp).length > 0 &&
- scheduleConfig.appinfo.sourceapp.name.length > 0 ? (
-
-
- {scheduleApp(scheduleConfig.appinfo.sourceapp, "src")}
-
-
- ) : (
-
- );
-
- const dstField =
- Object.getOwnPropertyNames(scheduleConfig).length > 0 &&
- Object.getOwnPropertyNames(scheduleConfig.appinfo.destinationapp).length >
- 0 &&
- scheduleConfig.appinfo.destinationapp.name.length > 0 ? (
-
-
- {scheduleApp(scheduleConfig.appinfo.destinationapp, "dst")}
-
-
- ) : (
-
- );
-
- // Have to use array cus of datastore lol (no map[string]string)
- const srcModalData = [];
- const buildSrcModal = (event, fieldname) => {
- var fieldfound = false;
- for (var key in srcModalData) {
- if (srcModalData[key]["key"] === fieldname) {
- fieldfound = true;
- srcModalData[key]["value"] = event.target.value;
- break;
- }
- }
-
- if (!fieldfound) {
- srcModalData.push({ key: fieldname, value: event.target.value });
- }
- console.log(srcModalData);
- };
-
- // FIXME - verify required fields?
- const submitSrcConfig = () => {
- scheduleConfig.appinfo.sourceapp.config = srcModalData;
- setScheduleConfig(scheduleConfig);
- setSrcAppConfigOpen(false);
-
- fetch(globalUrl + "/api/v1/schedules/" + props.match.params.key, {
- method: "PUT",
- headers: {
- "Content-Type": "application/json",
- Accept: "application/json",
- },
- body: JSON.stringify(scheduleConfig),
- })
- .then((response) => response.json())
- .then((responseJson) => {
- console.log(responseJson);
- })
- .catch((error) => {
- console.log(error);
- });
- };
-
- const dstModalData = [];
- const buildDstModal = (event, fieldname) => {
- var fieldfound = false;
- for (var key in dstModalData) {
- if (dstModalData[key]["key"] === fieldname) {
- fieldfound = true;
- dstModalData[key]["value"] = event.target.value;
- break;
- }
- }
-
- if (!fieldfound) {
- dstModalData.push({ key: fieldname, value: event.target.value });
- }
- console.log(dstModalData);
- };
-
- // FIXME - verify required fields
- const submitDstConfig = () => {
- scheduleConfig.appinfo.destinationapp.config = dstModalData;
- setScheduleConfig(scheduleConfig);
- setDstAppConfigOpen(false);
-
- fetch(globalUrl + "/api/v1/schedules/" + props.match.params.key, {
- method: "PUT",
- headers: {
- "Content-Type": "application/json",
- Accept: "application/json",
- },
- body: JSON.stringify(scheduleConfig),
- })
- .then((response) => response.json())
- .then((responseJson) => {
- console.log(responseJson);
- })
- .catch((error) => {
- console.log(error);
- });
- };
-
- const dstConfigModal = dstAppConfigOpen ? (
-
- ) : null;
-
- // FIXME - load the actual fields!
- const srcConfigModal = srcAppConfigOpen ? (
-
- ) : null;
-
- return (
-
- {srcConfigModal}
- {dstConfigModal}
-
- {srcField}
- {dstField}
-
-
-
{submitButton}
-
{relationshipBody}
-
- );
-};
-
-export default EditSchedule;
diff --git a/frontend/src/views/EditWebhook.jsx b/frontend/src/views/EditWebhook.jsx
deleted file mode 100755
index e1a5d516..00000000
--- a/frontend/src/views/EditWebhook.jsx
+++ /dev/null
@@ -1,393 +0,0 @@
-import React, { useState, useEffect } from "react";
-
-import Button from "@material-ui/core/Button";
-import Paper from "@material-ui/core/Paper";
-import Divider from "@material-ui/core/Divider";
-import Select from "@material-ui/core/Select";
-import MenuItem from "@material-ui/core/MenuItem";
-
-import WebhookImage from "../assets/img/webhook.png";
-import KafkaImage from "../assets/img/kafka.png";
-
-import EditWorkflow from "./EditWorkflow";
-
-const EditWebhook = (props) => {
- const { globalUrl, isLoaded } = props;
-
- // FIXME
- //const [webhookData, setWebhookData] = useState(webhooktest)
- const [webhookData, setWebhookData] = useState({});
- const [workflows, setWorkflows] = useState([]);
- const [firstrequest, setFirstrequest] = React.useState(true);
-
- const [selectedWorkflows, setSelectedWorkflows] = useState([]);
-
- const getWorkflows = () => {
- fetch(globalUrl + "/api/v1/workflows", {
- method: "GET",
- headers: {
- "Content-Type": "application/json",
- Accept: "application/json",
- },
- credentials: "include",
- })
- .then((response) => {
- if (response.status !== 200) {
- console.log("Status not 200 for workflows :O!");
- }
- return response.json();
- })
- .then((responseJson) => {
- setWorkflows(responseJson);
- })
- .catch((error) => {
- console.log(error);
- });
- };
-
- const setWebhook = (inputdata) => {
- console.log(inputdata);
-
- fetch(globalUrl + "/api/v1/hooks/" + props.match.params.key, {
- method: "PUT",
- headers: {
- "Content-Type": "application/json",
- Accept: "application/json",
- },
- credentials: "include",
- body: JSON.stringify(inputdata),
- })
- .then((response) => response.json())
- .then((responseJson) => {
- console.log(responseJson);
- })
- .catch((error) => {
- console.log(error);
- });
- };
-
- const getCurrentWebhook = () => {
- fetch(globalUrl + "/api/v1/hooks/" + props.match.params.key, {
- method: "GET",
- headers: {
- "Content-Type": "application/json",
- Accept: "application/json",
- },
- credentials: "include",
- })
- .then((response) => {
- if (response.status !== 200) {
- console.log("Status not 200!");
- window.location.pathname = "webhooks";
- }
- return response.json();
- })
- .then((responseJson) => {
- if (responseJson.actions === null) {
- responseJson.actions = [];
- }
-
- if (responseJson.transforms === null) {
- responseJson.transforms = [];
- }
-
- setWebhookData(responseJson);
- })
- .catch((error) => {
- console.log(error);
- //window.location.pathname = "webhooks"
- });
- };
-
- useEffect(() => {
- if (firstrequest) {
- setFirstrequest(false);
- getCurrentWebhook();
- if (workflows.length <= 0) {
- getWorkflows();
- }
- }
-
- // After everything is loaded
- if (
- Object.getOwnPropertyNames(webhookData).length > 0 &&
- webhookData.actions.length > 0 &&
- workflows.length > 0 &&
- selectedWorkflows.length === 0
- ) {
- // Setting startup actions. making like this in case we want other actions
- var tmpActionWorkflows = [];
- for (var key in webhookData.actions) {
- if (webhookData.actions[key].type === "workflow") {
- tmpActionWorkflows.push(webhookData.actions[key]);
- }
- }
-
- // Fix duplicates... Meh
- var foundWorkflowIds = [];
- var tmpWorkflows = [];
- for (key in tmpActionWorkflows) {
- if (foundWorkflowIds.includes(tmpActionWorkflows[key].id)) {
- continue;
- }
-
- for (var subkey in workflows) {
- if (tmpActionWorkflows[key].id === workflows[subkey]["id_"]) {
- console.log(tmpActionWorkflows[key].id, workflows[subkey]["id_"]);
- foundWorkflowIds.push(tmpActionWorkflows[key].id);
- tmpWorkflows.push(workflows[subkey]);
- break;
- }
- }
- }
-
- if (tmpWorkflows.length > 0) {
- setSelectedWorkflows(tmpWorkflows);
- }
- }
- });
-
- const hookPicture =
- Object.getOwnPropertyNames(webhookData).length > 0 &&
- webhookData.type === "webhook" ? (
-
- ) : (
-
- );
-
- const executeHook = (action) => {
- fetch(
- globalUrl + "/api/v1/hooks/" + props.match.params.key + "/" + action,
- {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- Accept: "application/json",
- },
- credentials: "include",
- }
- )
- .then((response) => response.json())
- .then((responseJson) => {
- setWebhookData({});
- })
- .catch((error) => {
- console.log(error);
- });
- };
-
- const headerPaperStyle = {
- display: "flex",
- maxHeight: "800px",
- minHeight: "800px",
- margin: "10px 30px 10px 10px",
- padding: "10px 5px 5px 5px",
- flexDirection: "column",
- };
-
- // FIXME - add with counter to change the correct one (not just edit)
- const addNewWorkflow = (event) => {
- // Verify if it already exists in the array. Returns if it exists
- for (var key in selectedWorkflows) {
- var item = selectedWorkflows[key];
- if (item["id_"] === event.target.value["id_"]) {
- return;
- }
- }
-
- // FIXME - make this possible for all accounts
- if (selectedWorkflows.length === 0) {
- console.log("ADD FIRST ITEM FOR SELECTEDWORKFLOWS");
- console.log(event.target.value);
-
- // Cleanup previous actions
- var newActions = [];
- if (webhookData.actions.length > 0) {
- for (key in webhookData.actions) {
- if (
- webhookData.actions[key].type === "" ||
- webhookData.actions[key].type === undefined
- ) {
- continue;
- }
-
- newActions.push(webhookData.actions[key]);
- }
- }
-
- // FIXME - how to stringify this better hurr
- var formattedWorkflow = {
- type: "workflow",
- name: event.target.value.name,
- id: event.target.value.id_,
- field: "",
- };
-
- // FIXME: patch this n
- newActions.push(formattedWorkflow);
- console.log(newActions);
-
- webhookData.actions = newActions;
- setWebhook(webhookData);
- }
-
- var tmpSelectedWorkflows = [].concat(selectedWorkflows, [
- event.target.value,
- ]);
- setSelectedWorkflows(tmpSelectedWorkflows);
- };
-
- // FIXME
- // Create a list with + button
- // For each, choose the new workflow I wanna add
- // Current: JUST ONE
- const selectedWorkflowIds = selectedWorkflows.map((data) => {
- return data["id_"];
- });
- const availableWorkflows = workflows.filter(
- (data) => !selectedWorkflowIds.includes(data["id_"])
- );
-
- const WorkflowSelect = (counter) => {
- if (selectedWorkflows[counter.counter] === undefined) {
- return null;
- }
-
- console.log(selectedWorkflows[0]);
- console.log(selectedWorkflows[0]);
- console.log(selectedWorkflows[0]);
- console.log(selectedWorkflows[counter.counter]);
- console.log(selectedWorkflows[counter.counter].name);
- return (
-
- Workflow select:
-
-
- );
- };
-
- const extraWorkflow =
- workflows.length > 0 && availableWorkflows.length > 0 ? (
-
- ) : null;
-
- const multiWorkflowSelect =
- workflows.length > 0 && selectedWorkflows.length > 0 ? (
-
- {selectedWorkflows.map((data, count) => (
-
- ))}
- {extraWorkflow}
-
- ) : (
-
- );
-
- const headerInfo =
- Object.getOwnPropertyNames(webhookData).length > 0 ? (
-
-
-
-
{hookPicture}
-
-
-
Name: {webhookData.info.name}
-
-
-
-
- Description: {webhookData.info.description}
-
Id: {webhookData.id}
-
Url: {webhookData.info.url}
-
Type: {webhookData.type}
-
Status: {webhookData.status}
-
- CHOOSE ACTIONS:
- {multiWorkflowSelect}
-
-
-
-
-
-
-
-
-
-
-
-
-
- ) : null;
-
- // FIXME - needs refresh every time you add a new workflow
- const workflowdata =
- Object.getOwnPropertyNames(webhookData).length > 0 &&
- selectedWorkflows.length > 0 ? (
-
- ) : null;
-
- const loadedCheck = isLoaded ? (
-
-
{workflowdata}
-
{headerInfo}
-
- ) : (
-
- );
-
- // FIXME: Use this for testing
- // : null
- return {loadedCheck}
;
-};
-
-export default EditWebhook;
diff --git a/frontend/src/views/ForgotPassword.jsx b/frontend/src/views/ForgotPassword.jsx
deleted file mode 100755
index e4c95013..00000000
--- a/frontend/src/views/ForgotPassword.jsx
+++ /dev/null
@@ -1,118 +0,0 @@
-/* eslint-disable react/no-multi-comp */
-import React, { useState } from "react";
-
-import TextField from "@material-ui/core/TextField";
-import Button from "@material-ui/core/Button";
-import Paper from "@material-ui/core/Paper";
-
-const bodyDivStyle = {
- margin: "auto",
- marginTop: "100px",
- width: "500px",
-};
-
-const ForgotPassword = (props) => {
- const { globalUrl, isLoaded, isLoggedIn, surfaceColor, inputColor } = props;
-
- const boxStyle = {
- paddingLeft: "30px",
- paddingRight: "30px",
- paddingBottom: "30px",
- paddingTop: "30px",
- backgroundColor: surfaceColor,
- };
-
- const [username, setUsername] = useState("");
- const [resetInfo, setResetInfo] = useState(
- "You will receive an email with instructions shortly."
- );
-
- const handleValidateForm = () => {
- return username.length > 3;
- };
-
- if (isLoggedIn === true) {
- window.location.pathname = "/";
- }
-
- const onSubmit = (e) => {
- e.preventDefault();
- // FIXME - add some check here ROFL
-
- // Just use this one?
- var data = { username: username };
- var baseurl = globalUrl;
- var url = baseurl + "/api/v1/passwordresetmail";
- fetch(url, {
- method: "POST",
- body: JSON.stringify(data),
- headers: {
- "Content-Type": "application/json; charset=utf-8",
- },
- })
- .then((response) =>
- response.json().then((responseJson) => {
- if (responseJson["success"] === false) {
- setResetInfo(responseJson["reason"]);
- }
- })
- )
- .catch((error) => {
- setResetInfo("Error in userdata: " + error);
- });
- };
-
- const onChangeUser = (e) => {
- setUsername(e.target.value);
- };
-
- const data = (
-
- );
-
- const loadedCheck = isLoaded ? {data}
: ;
-
- return {loadedCheck}
;
-};
-
-export default ForgotPassword;
diff --git a/frontend/src/views/ForgotPasswordLink.jsx b/frontend/src/views/ForgotPasswordLink.jsx
deleted file mode 100755
index 8944deed..00000000
--- a/frontend/src/views/ForgotPasswordLink.jsx
+++ /dev/null
@@ -1,136 +0,0 @@
-import React, { useState, useEffect } from "react";
-
-import Paper from "@material-ui/core/Paper";
-import Button from "@material-ui/core/Button";
-
-import TextField from "@material-ui/core/TextField";
-
-const bodyDivStyle = {
- margin: "auto",
- textAlign: "center",
- width: "768px",
-};
-
-const boxStyle = {
- flex: "1",
- marginLeft: "10px",
- marginRight: "10px",
- paddingLeft: "30px",
- paddingRight: "30px",
- paddingBottom: "30px",
- paddingTop: "30px",
- backgroundColor: "#e8eaf6",
- display: "flex",
- flexDirection: "column",
-};
-
-//const tmpdata = {
-// "username": "frikky",
-// "firstname": "fred",
-// "lastname": "ode",
-// "title": "topkek",
-// "companyname": "company here",
-// "email": "your email pls",
-// "phone": "PHONE!!",
-//}
-
-// FIXME - add fetch for data fields
-// FIXME - remove tmpdata
-// FIXME: Use isLoggedIn :)
-const Settings = (props) => {
- const { globalUrl, isLoaded } = props;
-
- const [newPassword, setNewPassword] = useState("");
- const [newPassword2, setNewPassword2] = useState("");
- const [passwordFormMessage, setPasswordFormMessage] = useState("");
-
- const onPasswordChange = () => {
- const data = {
- newpassword: newPassword,
- newpassword2: newPassword2,
- reference: props.match.params.key,
- };
- const url = globalUrl + "/api/v1/passwordreset";
- fetch(url, {
- mode: "cors",
- method: "POST",
- body: JSON.stringify(data),
- credentials: "include",
- crossDomain: true,
- withCredentials: true,
- headers: {
- "Content-Type": "application/json; charset=utf-8",
- },
- })
- .then((response) =>
- response.json().then((responseJson) => {
- if (responseJson["success"] === false) {
- setPasswordFormMessage(responseJson["reason"]);
- }
- })
- )
- .catch((error) => {
- setPasswordFormMessage("Something went wrong.");
- });
- };
-
- // This should "always" have data
- useEffect(() => {});
-
- // Random names for type & autoComplete. Didn't research :^)
- const landingpageData = (
-
-
- Password Reset
-
- setNewPassword(e.target.value)}
- />
- setNewPassword2(e.target.value)}
- />
-
-
- {passwordFormMessage}
-
-
- );
-
- const loadedCheck = isLoaded ? (
- {landingpageData}
- ) : (
-
- );
-
- return {loadedCheck}
;
-};
-export default Settings;
diff --git a/frontend/src/views/GettingStarted.jsx b/frontend/src/views/GettingStarted.jsx
index fb96e671..caba5b97 100644
--- a/frontend/src/views/GettingStarted.jsx
+++ b/frontend/src/views/GettingStarted.jsx
@@ -58,9 +58,7 @@ import {
CloudDownload as CloudDownloadIcon,
} from "@mui/icons-material";
-//import {Search as SearchIcon, ArrowUpward as ArrowUpwardIcon, Visibility as VisibilityIcon, Done as DoneIcon, Close as CloseIcon, Error as ErrorIcon, FindReplace as FindreplaceIcon, ArrowLeft as ArrowLeftIcon, Cached as CachedIcon, DirectionsRun as DirectionsRunIcon, Add as AddIcon, Polymer as PolymerIcon, FormatListNumbered as FormatListNumberedIcon, Create as CreateIcon, PlayArrow as PlayArrowIcon, AspectRatio as AspectRatioIcon, MoreVert as MoreVertIcon, Apps as AppsIcon, Schedule as ScheduleIcon, FavoriteBorder as FavoriteBorderIcon, Pause as PauseIcon, Delete as DeleteIcon, AddCircleOutline as AddCircleOutlineIcon, Save as SaveIcon, KeyboardArrowLeft as KeyboardArrowLeftIcon, KeyboardArrowRight as KeyboardArrowRightIcon, ArrowBack as ArrowBackIcon, Settings as SettingsIcon, LockOpen as LockOpenIcon, ExpandMore as ExpandMoreIcon, VpnKey as VpnKeyIcon} from '@material-ui/icons';
-//https://next.material-ui.com/components/material-icons/
import { DataGrid, GridToolbar } from "@mui/x-data-grid";
//import JSONPretty from 'react-json-pretty';
diff --git a/frontend/src/views/Introduction.jsx b/frontend/src/views/Introduction.jsx
deleted file mode 100755
index e94295f3..00000000
--- a/frontend/src/views/Introduction.jsx
+++ /dev/null
@@ -1,221 +0,0 @@
-import React, { useEffect, useState } from "react";
-import { Link, useParams } from "react-router-dom";
-import theme from '../theme.jsx';
-
-import Grid from "@material-ui/core/Grid";
-import Card from "@material-ui/core/Card";
-import CardActionArea from "@material-ui/core/CardActionArea";
-import CardContent from "@material-ui/core/CardContent";
-import CardHeader from "@material-ui/core/CardHeader";
-import Typography from "@material-ui/core/Typography";
-import Button from "@material-ui/core/Button";
-
-const Workflows = (defaultprops) => {
- const { globalUrl, isLoggedIn, isLoaded } = defaultprops;
-
- const params = useParams();
- var props = JSON.parse(JSON.stringify(defaultprops))
- props.match = {}
- props.match.params = params
-
- const [curView, setCurView] = useState(0);
- const [firstrequest, setFirstrequest] = useState(true);
- const [selectedItems, setSelectedItems] = useState([]);
-
- const viewdata1 = [
- {
- title: "General",
- content: "Learn about our ticketing solutions",
- subitems: [
- {
- name: "Search",
- subtitle: "Search for anything, anywhere",
- },
- {
- name: "Message",
- subtitle: "Read and send messages",
- },
- {
- name: "Parse emails",
- subtitle: "what",
- },
- ],
- },
- {
- title: "Ticketing",
- subitems: [
- {
- name: "Search",
- subtitle: "Search for anything, anywhere",
- },
- {
- name: "Message",
- subtitle: "Read and send messages",
- },
- {
- name: "Parse emails",
- subtitle: "what",
- },
- ],
- },
- {
- title: "Threat intel",
- subitems: [
- {
- name: "Search",
- subtitle: "Search for anything, anywhere",
- },
- {
- name: "Message",
- subtitle: "Read and send messages",
- },
- {
- name: "Parse emails",
- subtitle: "what",
- },
- ],
- },
- ];
-
- if (firstrequest) {
- setFirstrequest(false);
- if (props.match.params.key) {
- console.log("PROPS: ", props.match.params.key);
- const viewitem = viewdata1.find(
- (item) =>
- item.title.toLowerCase() === props.match.params.key.toLowerCase()
- );
- if (viewitem !== undefined && viewitem !== null) {
- setCurView(1);
- //setSelectedItem(viewitem)
- }
- }
- }
-
- const cardContentStyle = {
- height: "100%",
- width: "100%",
- padding: 40,
- };
-
- const outerGridView = {
- width: "100%",
- marginTop: 15,
- };
-
- const paperStyle = {
- height: 300,
- color: "white",
- backgroundColor: theme.palette.surfaceColor,
- color: "white",
- cursor: "pointer",
- display: "flex",
- textAlign: "center",
- };
-
- const HandleSelection = (data) => {
- const [selected, setSelected] = useState(false);
-
- var baseStyle = JSON.parse(JSON.stringify(paperStyle));
- if (selected) {
- baseStyle.backgroundColor = "white";
- baseStyle.color = "black";
- }
-
- return (
- {
- console.log(selectedItems);
- if (selected) {
- const index = selectedItems.findIndex(
- (item) => item.title === data.title
- );
- if (index >= 0) {
- selectedItems.splice(index, 1);
- setSelectedItems(selectedItems);
- }
- } else {
- selectedItems.push(data);
- setSelectedItems(selectedItems);
- }
-
- setSelected(!selected);
-
- //setCurView(1)
- //setSelectedItem(data)
- //window.location.pathname += "/"+data.title.toLowerCase()
- }}
- >
-
-
-
- {data.title}
-
-
-
-
- );
- };
-
- const view1 =
- curView === 0 ? (
-
- What are you interested in?
-
- {viewdata1.map((data) => {
- return HandleSelection(data);
- })}
-
- {/*
-
- */}
-
- ) : null;
-
- const view2 =
- curView === 1 ? (
-
- Step 2.
- {/*
-
- {selectedItem.subitems === undefined ? null :
- selectedItem.subitems.map(data => {
- return (
-
-
-
-
-
- {data.name}
-
-
- {data.subtitle}
-
-
-
-
-
- )
- })}
-
- */}
-
- ) : null;
-
- const baseView = (
-
- {view1}
- {view2}
-
- );
-
- return {baseView}
;
-};
-
-export default Workflows;
diff --git a/frontend/src/views/Landingpage.jsx b/frontend/src/views/Landingpage.jsx
deleted file mode 100755
index a0de1eee..00000000
--- a/frontend/src/views/Landingpage.jsx
+++ /dev/null
@@ -1,207 +0,0 @@
-import React from "react";
-
-import Paper from "@material-ui/core/Paper";
-import Button from "@material-ui/core/Button";
-import Divider from "@material-ui/core/Divider";
-import { BrowserView, MobileView } from "react-device-detect";
-import {
- Schedule as ScheduleIcon,
- Web as WebIcon,
- AccountTree as AccountTreeIcon,
-} from "@mui/icons-material";
-
-const bodyDivStyle = {
- margin: "auto",
- marginTop: "75px",
- textAlign: "center",
- width: "1100px",
-};
-
-const surfaceColor = "#27292D";
-const boxStyle = {
- flex: "1",
- marginLeft: "10px",
- marginRight: "10px",
- height: "400px",
- //backgroundColor: "#e8eaf6",
- backgroundColor: surfaceColor,
- textAlign: "center",
- display: "flex",
- flexDirection: "column",
-};
-
-const bodyTextStyle = {
- color: "#ffffff",
-};
-
-const hrefStyle = {
- color: "black",
- textDecoration: "none",
-};
-
-// Should be different if logged in :|
-const LandingPage = (props) => {
- const { isLoaded } = props;
-
- const textColor = "#8899A6";
- const iconColor = "#1DA1F2";
- const iconSize = "8em";
- const GridLayout = (header, description, link, icon) => {
- return (
-
-
-
-
{header}
-
-
-
- {description}
-
- {icon}
-
-
-
-
- );
- };
-
- const listitems = [
- GridLayout(
- "Simple integrations",
- "Easily use others' or create your own integration",
- "/docs/apps",
-
- ),
- GridLayout(
- "Workflows",
- "Access the power of automation within minutes, whether its on premise or in the cloud",
- "/docs/workflows",
-
- ),
- GridLayout(
- "Realtime actions",
- "Beat the clock by leveraging our realtime triggers",
- "/docs/triggers",
-
- ),
- ];
-
- // The actual landing page
- //
- const landingpageDataBrowser = (
-
-
-
Shuffle
-
- A general automation solution for Infosec and IT Professionals
-
-
-
-
-
-
-
-
-
- {listitems.map((item) => {
- return
{item}
;
- })}
-
-
- );
-
- const landingpageDataMobile = (
-
-
-
Shuffle
-
A general automation solution for Infosec and IT Professionals
-
-
-
-
-
-
{listitems[0]}
-
{listitems[1]}
-
- {listitems[2]}
-
-
-
-
- );
-
- // Reroute if the user is logged in
- // const landingSite = isLoggedIn ? : {landingpageData}
- const landingSite = {landingpageDataBrowser}
;
-
- const loadedCheck = isLoaded ? (
-
- {landingSite}
- {landingpageDataMobile}
-
- ) : (
-
- );
-
- return {loadedCheck}
;
-};
-export default LandingPage;
diff --git a/frontend/src/views/LandingpageNew.jsx b/frontend/src/views/LandingpageNew.jsx
deleted file mode 100755
index c859beee..00000000
--- a/frontend/src/views/LandingpageNew.jsx
+++ /dev/null
@@ -1,531 +0,0 @@
-import React, { useState } from "react";
-
-import Paper from "@material-ui/core/Paper";
-import Card from "@material-ui/core/Card";
-import CardActionArea from "@material-ui/core/CardActionArea";
-import CardMedia from "@material-ui/core/CardMedia";
-import CardContent from "@material-ui/core/CardContent";
-import CardActions from "@material-ui/core/CardActions";
-import Button from "@material-ui/core/Button";
-import Divider from "@material-ui/core/Divider";
-import Grid from "@material-ui/core/Grid";
-import { BrowserView, MobileView } from "react-device-detect";
-
-import {
- Schedule as ScheduleIcon,
- Web as WebIcon,
- AccountTree as AccountTreeIcon,
- Info as InfoIcon,
- ArrowForward as ArrowForwardIcon,
- Create as CreateIcon,
-} from "@mui/icons-material";
-
-const bodyDivStyle = {
- margin: "auto",
-};
-
-const surfaceColor = "#27292D";
-const boxStyle = {
- flex: "1",
- marginLeft: "10px",
- marginRight: "10px",
- height: "400px",
- //backgroundColor: "#e8eaf6",
- backgroundColor: surfaceColor,
- textAlign: "center",
- display: "flex",
- flexDirection: "column",
-};
-
-const bodyTextStyle = {
- color: "#ffffff",
-};
-
-const hrefStyle = {
- color: "inherit",
- textDecoration: "none",
-};
-
-// Should be different if logged in :|
-const LandingPage = (props) => {
- const { isLoaded } = props;
-
- const textColor = "#8899A6";
- const iconColor = "#1DA1F2";
- const iconSize = "8em";
-
- const GridLayout = (header, description, link, icon) => {
- return (
-
-
-
-
{header}
-
-
-
- {description}
-
- {icon}
-
-
-
-
- );
- };
-
- const listitems = [
- GridLayout(
- "Simple integrations",
- "Easily use others' or create your own integration",
- "/docs/features",
-
- ),
- GridLayout(
- "Workflows",
- "Access the power of automation within minutes, whether its on premise or in the cloud",
- "/docs/features",
-
- ),
- GridLayout(
- "Realtime actions",
- "Beat the clock by leveraging our realtime triggers",
- "/docs/features",
-
- ),
- ];
-
- // The actual landing page
- //
- //We start by understanding your unique environment to help identify the right thing to automate.
- const secondaryColor = "rgba(167,46,87,1)";
- const primaryColor = "rgba(25, 35, 94, 1)";
-
- const paperStyle = {
- flex: 1,
- backgroundColor: "inherit",
- cursor: "pointer",
- };
-
- const secondaryItemList = [
- {
- primaryText: "No time to waste",
- secondaryText:
- "Bring all your applications into a single view, and make them all work together flawlessly!",
- image: "/images/time.jpg",
- },
- {
- primaryText: "Get a better overview",
- secondaryText:
- "Don't know what's happening? We'll help you track and act on your most valuable KPI's!",
- image: "/images/overview.jpg",
- },
- {
- primaryText: "Conquer your tasks",
- secondaryText:
- "Get access to powerful tools and pre-made workflows to help you crush your teams daily tasks!",
- image: "/images/burnout.jpg",
- },
- ];
- const [image, setImage] = useState(secondaryItemList[0].image);
-
- const landingpageDataBrowser = (
-
-
-
-
-
Shuffle
-
-
- Everyone run into the same fundamental operational problems. Mailbox
- chaos, tickets getting out of hand and a constant feeling of being
- overwhelmed. The good news?{" "}
-
- Shuffle solves them.
-
-
-
-
-
-
-
-
-
-
- Automation is just the beginning
-
-
-
- {secondaryItemList.map((data, index) => {
- const color =
- image === data.image
- ? "rgba(255,255,255,1)"
- : "rgba(255,255,255,0.4)";
- return (
-
setImage(data.image)}
- >
- {data.primaryText}
-
- {data.secondaryText}
-
-
- );
- })}
-
-
-
-

-
-
-
-
-
-
-
- Learn more about the benefits of Shuffle
-
-
-
-
-
-
-
- Focus on the work that matters to you
-
-
- Menial tasks, scattered content, constant copy pasting, waste of
- talent - there's a smarter way to work.
-
-
-
{
- window.location.pathname = "/docs/features";
- }}
- style={{ flex: 1, margin: 10, textAlign: "center" }}
- >
-
-
-
- Premade playbooks
- Get your automation done with minimal effort
-
-
-
-
-
{
- window.location.pathname = "/docs/features";
- }}
- style={{ flex: 1, margin: 10, textAlign: "center" }}
- >
-
-
-
- Open frameworks
- Mitre Att&ck, OpenAPI and more!
-
-
-
-
-
{
- window.location.pathname = "/docs/features";
- }}
- style={{ flex: 1, margin: 10, textAlign: "center" }}
- >
-
-
-
- Hundreds of integrations
- Quickly integrate your software applications
-
-
-
-
-
{
- window.location.pathname = "/docs/features";
- }}
- >
-
-
-
- Automated compliance
- Stuck with compliance needs you can't meet?
-
-
-
-
-
-
-
- );
-
- const landingpageDataMobile = (
-
-
-
Shuffle
-
A general automation solution for Infosec and IT Professionals
-
-
-
-
-
-
{listitems[0]}
-
{listitems[1]}
-
- {listitems[2]}
-
-
-
-
- );
-
- // Reroute if the user is logged in
- // const landingSite = isLoggedIn ? : {landingpageData}
- const landingSite = {landingpageDataBrowser}
;
-
- const loadedCheck = isLoaded ? (
-
- {landingSite}
- {landingpageDataMobile}
-
- ) : (
-
- );
-
- return {loadedCheck}
;
-};
-export default LandingPage;
diff --git a/frontend/src/views/MyView.jsx b/frontend/src/views/MyView.jsx
deleted file mode 100755
index 42c72bc3..00000000
--- a/frontend/src/views/MyView.jsx
+++ /dev/null
@@ -1,2147 +0,0 @@
-import React, { useEffect } from "react";
-import { useInterval } from "react-powerhooks";
-
-import Grid from "@material-ui/core/Grid";
-import Paper from "@material-ui/core/Paper";
-import Tooltip from "@material-ui/core/Tooltip";
-import Divider from "@material-ui/core/Divider";
-import Button from "@material-ui/core/Button";
-import TextField from "@material-ui/core/TextField";
-import FormControl from "@material-ui/core/FormControl";
-import IconButton from "@material-ui/core/IconButton";
-import Menu from "@material-ui/core/Menu";
-import MenuItem from "@material-ui/core/MenuItem";
-import FormControlLabel from "@material-ui/core/FormControlLabel";
-import Chip from "@material-ui/core/Chip";
-import Switch from "@material-ui/core/Switch";
-import Typography from "@material-ui/core/Typography";
-import Zoom from "@material-ui/core/Zoom";
-
-import CircularProgress from "@material-ui/core/CircularProgress";
-import CachedIcon from "@material-ui/icons/Cached";
-import GetAppIcon from "@material-ui/icons/GetApp";
-import AppsIcon from "@material-ui/icons/Apps";
-import EditIcon from "@material-ui/icons/Edit";
-import MoreVertIcon from "@material-ui/icons/MoreVert";
-import PlayArrowIcon from "@material-ui/icons/PlayArrow";
-import AddIcon from "@material-ui/icons/Add";
-import PublishIcon from "@material-ui/icons/Publish";
-//import JSONPretty from 'react-json-pretty';
-//import JSONPrettyMon from 'react-json-pretty/dist/monikai'
-import ReactJson from "react-json-view";
-
-import { Link } from "react-router-dom";
-import { useAlert } from "react-alert";
-import ChipInput from "material-ui-chip-input";
-
-import Dialog from "@material-ui/core/Dialog";
-import DialogTitle from "@material-ui/core/DialogTitle";
-import DialogActions from "@material-ui/core/DialogActions";
-import DialogContent from "@material-ui/core/DialogContent";
-import CloudDownloadIcon from "@material-ui/icons/CloudDownload";
-import BubbleChartIcon from "@material-ui/icons/BubbleChart";
-import RestoreIcon from "@material-ui/icons/Restore";
-
-import mobileImage from "../assets/img/mobile.svg";
-import bagImage from "../assets/img/bag.svg";
-import bookImage from "../assets/img/book.svg";
-
-import {
- DataGrid,
- GridToolbarContainer,
- GridDensitySelector,
- GridToolbar,
-} from "@mui/x-data-grid";
-
-import { makeStyles } from "@material-ui/core/styles";
-
-import ListIcon from "@material-ui/icons/List";
-import GridOnIcon from "@material-ui/icons/GridOn";
-
-const inputColor = "#383B40";
-const surfaceColor = "#27292D";
-
-const flexContainerStyle = {
- display: "flex",
- flexDirection: "row",
- justifyContent: "left",
- alignContent: "space-between",
-};
-
-const flexBoxStyle = {
- height: 125,
- borderRadius: 4,
- boxSizing: "border-box",
- letterSpacing: "0.4px",
- color: "#D6791E",
- margin: 10,
- flex: 1,
-};
-
-//const activeWorkflowStyle = {backgroundColor: "#FFF5EE"}
-//const notificationStyle = {backgroundColor: "#E5F9FF"}
-//const activeWorkflowStyle = {backgroundColor: "#3d3f43"}
-const availableWorkflowStyle = { backgroundColor: "#3d3f43" };
-const notificationStyle = { backgroundColor: "#3d3f43" };
-const activeWorkflowStyle = { backgroundColor: "#3d3f43" };
-
-const flexContentStyle = {
- display: "flex",
- flexDirection: "row",
-};
-
-const iconStyle = {
- width: "75px",
- height: "75px",
- padding: "20px",
-};
-
-const fontSize_16 = { fontSize: "16px" };
-const counterStyle = { fontSize: "36px", fontWeight: "bold" };
-const blockRightStyle = {
- textAlign: "right",
- padding: "20px 20px 0px 0px",
- width: "100%",
-};
-
-export const validateJson = (showResult) => {
- //showResult = showResult.split(" None").join(" \"None\"")
- showResult = showResult.split(" False").join(" false");
- showResult = showResult.split(" True").join(" true");
-
- var jsonvalid = true;
- try {
- const tmp = String(JSON.parse(showResult));
- if (!showResult.includes("{") && !showResult.includes("[")) {
- jsonvalid = false;
- }
- } catch (e) {
- showResult = showResult.split("'").join('"');
-
- try {
- const tmp = String(JSON.parse(showResult));
- if (!showResult.includes("{") && !showResult.includes("[")) {
- jsonvalid = false;
- }
- } catch (e) {
- jsonvalid = false;
- }
- }
-
- const result = jsonvalid ? JSON.parse(showResult) : showResult;
- //console.log("VALID: ", jsonvalid, result)
- return {
- valid: jsonvalid,
- result: result,
- };
-};
-
-const MyView = (props) => {
- const { globalUrl, isLoggedIn, isLoaded, userdata } = props;
- document.title = "Shuffle - Workflows";
-
- const alert = useAlert();
-
- var upload = "";
- const [file, setFile] = React.useState("");
-
- const [workflows, setWorkflows] = React.useState([]);
- const [selectedWorkflow, setSelectedWorkflow] = React.useState({});
- const [selectedExecution, setSelectedExecution] = React.useState({});
- const [workflowExecutions, setWorkflowExecutions] = React.useState([]);
- const [firstrequest, setFirstrequest] = React.useState(true);
- const [workflowDone, setWorkflowDone] = React.useState(false);
- const [, setTrackingId] = React.useState("");
- const [selectedWorkflowId, setSelectedWorkflowId] = React.useState("");
-
- const [collapseJson, setCollapseJson] = React.useState(false);
- const [field1, setField1] = React.useState("");
- const [field2, setField2] = React.useState("");
- const [downloadUrl, setDownloadUrl] = React.useState(
- "https://github.com/frikky/shuffle-workflows"
- );
- const [downloadBranch, setDownloadBranch] = React.useState("master");
- const [loadWorkflowsModalOpen, setLoadWorkflowsModalOpen] =
- React.useState(false);
-
- const [modalOpen, setModalOpen] = React.useState(false);
- const [newWorkflowName, setNewWorkflowName] = React.useState("");
- const [newWorkflowDescription, setNewWorkflowDescription] =
- React.useState("");
- const [newWorkflowTags, setNewWorkflowTags] = React.useState([]);
- const [update, setUpdate] = React.useState("test");
- const [deleteModalOpen, setDeleteModalOpen] = React.useState(false);
- const [editingWorkflow, setEditingWorkflow] = React.useState({});
- const [executionLoading, setExecutionLoading] = React.useState(false);
- const [view, setView] = React.useState("grid");
- const { start, stop } = useInterval({
- duration: 5000,
- startImmediate: false,
- callback: () => {
- //getWorkflowExecution(selectedWorkflow.id)
- },
- });
-
- // DEBUG HERE
- const handleClickLogout = () => {};
-
- const deleteModal = deleteModalOpen ? (
-
- ) : null;
-
- const getAvailableWorkflows = () => {
- fetch(globalUrl + "/api/v1/workflows", {
- method: "GET",
- headers: {
- "Content-Type": "application/json",
- Accept: "application/json",
- },
- credentials: "include",
- })
- .then((response) => {
- if (response.status !== 200) {
- console.log("Status not 200 for workflows :O!");
- return;
- }
- return response.json();
- })
- .then((responseJson) => {
- setSelectedExecution({});
- setWorkflowExecutions([]);
-
- if (responseJson !== undefined) {
- setWorkflows(responseJson);
- setWorkflowDone(true);
- } else {
- if (isLoggedIn) {
- alert.error("An error occurred while loading workflows");
- } else {
- handleClickLogout();
- }
-
- return;
- }
-
- if (responseJson.length > 0) {
- setSelectedWorkflow(responseJson[0]);
- //getWorkflowExecution(responseJson[0].id)
- }
- })
- .catch((error) => {
- alert.error(error.toString());
- });
- };
-
- useEffect(() => {
- if (workflows.length <= 0 && firstrequest) {
- setFirstrequest(false);
- getAvailableWorkflows();
- }
- });
-
- const viewStyle = {
- color: "#ffffff",
- width: "100%",
- display: "flex",
- minWidth: 1024,
- maxWidth: 1024,
- margin: "auto",
- /*maxHeight: "90vh",*/
- };
-
- const emptyWorkflowStyle = {
- paddingTop: "200px",
- width: 1024,
- margin: "auto",
- };
-
- const boxStyle = {
- padding: "20px 20px 20px 20px",
- width: "100%",
- height: "250px",
- color: "white",
- backgroundColor: surfaceColor,
- display: "flex",
- flexDirection: "column",
- };
-
- const scrollStyle = {
- marginTop: "10px",
- overflow: "scroll",
- height: "90%",
- overflowX: "hidden",
- overflowY: "auto",
- };
-
- const paperAppContainer = {
- display: "flex",
- flexWrap: "wrap",
- alignContent: "space-between",
- };
-
- const paperAppStyle = {
- minHeight: 130,
- width: "100%",
- color: "white",
- backgroundColor: surfaceColor,
- padding: "12px 12px 0px 15px",
- borderRadius: 5,
- display: "flex",
- boxSizing: "border-box",
- position: "relative",
- };
-
- const gridContainer = {
- height: "auto",
- color: "white",
- margin: "10px",
- backgroundColor: surfaceColor,
- };
-
- const workflowActionStyle = {
- flex: "1",
- display: "flex",
- width: 150,
- height: 44,
- justifyContent: "space-between",
- overflow: "hidden",
- };
-
- const getWorkflowExecution = (id) => {
- setExecutionLoading(true);
- fetch(globalUrl + "/api/v1/workflows/" + id + "/executions", {
- method: "GET",
- headers: {
- "Content-Type": "application/json",
- Accept: "application/json",
- },
- credentials: "include",
- })
- .then((response) => {
- setExecutionLoading(false);
- if (response.status !== 200) {
- console.log("Status not 200 for WORKFLOW EXECUTION :O!");
- }
-
- return response.json();
- })
- .then((responseJson) => {
- if (responseJson.success === false) {
- alert.error("Failed getting executions");
- } else {
- if (responseJson.length > 0) {
- setSelectedExecution(responseJson[0]);
- setWorkflowExecutions(responseJson);
- } else {
- //alert.info("Couldn't find executions for the workflow")
- setSelectedExecution({});
- setWorkflowExecutions([]);
- }
- }
- })
- .catch((error) => {
- setExecutionLoading(false);
- alert.error(error.toString());
- });
- };
-
- const abortExecution = (workflowid, executionid) => {
- alert.success("Aborting execution");
- fetch(
- globalUrl +
- "/api/v1/workflows/" +
- workflowid +
- "/executions/" +
- executionid +
- "/abort",
- {
- method: "GET",
- headers: {
- "Content-Type": "application/json",
- Accept: "application/json",
- },
- credentials: "include",
- }
- )
- .then((response) => {
- if (response.status !== 200) {
- console.log("Status not 200 for WORKFLOW EXECUTION :O!");
- }
- //getWorkflowExecution(workflowid)
-
- return response.json();
- })
- .catch((error) => {
- alert.error(error.toString());
- });
- };
-
- const executeWorkflow = (id) => {
- alert.show("Executing workflow " + id);
- setTrackingId(id);
- fetch(globalUrl + "/api/v1/workflows/" + id + "/execute", {
- method: "GET",
- headers: {
- "Content-Type": "application/json",
- Accept: "application/json",
- },
- credentials: "include",
- })
- .then((response) => {
- if (response.status !== 200) {
- console.log("Status not 200 for WORKFLOW EXECUTION :O!");
- }
-
- return response.json();
- })
- .then((responseJson) => {
- if (!responseJson.success) {
- alert.error(responseJson.reason);
- }
- })
- .catch((error) => {
- alert.error(error.toString());
- });
-
- if (id === selectedWorkflow.id) {
- sleep(2000).then(() => {
- stop();
- start();
- });
- }
- };
-
- function sleep(time) {
- return new Promise((resolve) => setTimeout(resolve, time));
- }
-
- const exportAllWorkflows = () => {
- for (var key in workflows) {
- exportWorkflow(workflows[key]);
- }
- };
-
- const exportWorkflow = (data) => {
- console.log("export");
- let dataStr = JSON.stringify(data);
-
- let dataUri =
- "data:application/json;charset=utf-8," + encodeURIComponent(dataStr);
- let exportFileDefaultName = data.name + ".json";
-
- data["owner"] = "";
- for (var key in data.triggers) {
- const trigger = data.triggers[key];
- if (trigger.app_name === "Shuffle Workflow") {
- if (trigger.parameters.length > 2) {
- trigger.parameters[2].value = "";
- }
- }
-
- if (trigger.status == "running") {
- trigger.status = "stopped";
- }
- }
-
- for (var key in data.actions) {
- data.actions[key].authentication_id = "";
- }
-
- //return
-
- data["org"] = [];
- data["org_id"] = "";
- data.execution_org = { id: "" };
- console.log(data);
-
- let linkElement = document.createElement("a");
- linkElement.setAttribute("href", dataUri);
- linkElement.setAttribute("download", exportFileDefaultName);
- linkElement.click();
- };
-
- const copyWorkflow = (data) => {
- data = JSON.parse(JSON.stringify(data));
- alert.success("Copying workflow " + data.name);
- console.log("data: ", data);
- data.id = "";
- data.name = data.name + "_copy";
- //return
-
- fetch(globalUrl + "/api/v1/workflows", {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- Accept: "application/json",
- },
- body: JSON.stringify(data),
- credentials: "include",
- })
- .then((response) => {
- if (response.status !== 200) {
- console.log("Status not 200 for workflows :O!");
- return;
- }
- return response.json();
- })
- .then((responseJson) => {
- getAvailableWorkflows();
- })
- .catch((error) => {
- alert.error(error.toString());
- });
- };
-
- const deleteWorkflow = (id) => {
- alert.success("Deleted workflow " + id);
- fetch(globalUrl + "/api/v1/workflows/" + id, {
- method: "DELETE",
- headers: {
- "Content-Type": "application/json",
- Accept: "application/json",
- },
- credentials: "include",
- })
- .then((response) => {
- if (response.status !== 200) {
- console.log("Status not 200 for setting workflows :O!");
- }
-
- return response.json();
- })
- .then((responseJson) => {
- getAvailableWorkflows();
- })
- .catch((error) => {
- alert.error(error.toString());
- });
- };
-
- const getWorkflowMeta = (data) => {
- let triggers = 0;
- let schedules = 0;
- let webhooks = 0;
- let subflows = 0;
- if (
- data.triggers !== undefined &&
- data.triggers !== null &&
- data.triggers.length > 0
- ) {
- triggers = data.triggers.length;
- for (let key in data.triggers) {
- if (data.triggers[key].app_name === "Webhook") {
- webhooks += 1;
- //webhookImg = data.triggers[key].large_image
- } else if (data.triggers[key].app_name === "Schedule") {
- schedules += 1;
- //scheduleImg = data.triggers[key].large_image
- } else if (data.triggers[key].app_name === "Subflow") {
- subflows += 1;
- }
- }
- }
-
- return [triggers, schedules, webhooks, subflows];
- };
-
- // dropdown with copy etc I guess
- const WorkflowPaper = (props) => {
- const { data } = props;
- const [open, setOpen] = React.useState(false);
- const [anchorEl, setAnchorEl] = React.useState(null);
-
- var boxWidth = "2px";
- if (selectedWorkflow.id === data.id) {
- boxWidth = "4px";
- }
-
- var boxColor = "#FECC00";
- if (data.is_valid) {
- boxColor = "#86c142";
- }
-
- if (!data.previously_saved) {
- boxColor = "#f85a3e";
- }
-
- const menuClick = (event) => {
- setOpen(!open);
- setAnchorEl(event.currentTarget);
- };
-
- var parsedName = data.name;
- if (
- parsedName !== undefined &&
- parsedName !== null &&
- parsedName.length > 25
- ) {
- parsedName = parsedName.slice(0, 25) + "..";
- }
-
- const actions = data.actions !== null ? data.actions.length : 0;
- const [triggers, schedules, webhooks, subflows] = getWorkflowMeta(data);
-
- return (
-
-
-
-
-
-
- {parsedName}
-
-
-
-
-
-
-
- {actions}
-
-
-
-
-
-
-
- {triggers}
-
-
-
-
-
-
-
- {subflows}
-
-
-
- {/*
-
-
-
-
-
-
- : null}
- {schedules > 0 ?
-
-
-
- : null}
- */}
-
-
- {data.tags !== undefined
- ? data.tags.map((tag, index) => {
- if (index >= 3) {
- return null;
- }
-
- return (
-
- );
- })
- : null}
-
-
- {data.actions !== undefined && data.actions !== null ? (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ) : null}
-
-
- );
- };
-
- const executionPaper = (data) => {
- var boxWidth = "2px";
- if (selectedExecution.execution_id === data.execution_id) {
- boxWidth = "4px";
- }
-
- var boxColor = "orange";
- if (
- data.status === "ABORTED" ||
- data.status === "UNFINISHED" ||
- data.status === "FAILURE"
- ) {
- boxColor = "red";
- } else if (data.status === "FINISHED") {
- boxColor = "green";
- }
-
- var t = new Date(data.started_at * 1000);
- if (data.workflow.actions === null || data.workflow.actions === undefined) {
- return null;
- }
-
- if (data.workflow.actions === null || data.workflow.actions === undefined) {
- return null;
- }
-
- var actions = data.workflow.actions.length;
- if (data.results !== null) {
- var results = data.results.length;
- }
-
- return (
- {
- setSelectedExecution(data);
- }}
- >
-
-
-
-
-
-
- Status: {data.status}
-
- Actions: {results}/{actions}
-
-
-
-
-
-
-
- Started: {t.toISOString()}
-
-
-
-
-
- );
- };
-
- const dividerColor = "rgb(225, 228, 232)";
-
- const resultPaperAppStyle = {
- minHeight: "100px",
- minWidth: "100%",
- overflow: "hidden",
- maxWidth: "100%",
- marginTop: "5px",
- color: "white",
- backgroundColor: surfaceColor,
- display: "flex",
- };
-
- function replaceAll(string, search, replace) {
- return string.split(search).join(replace);
- }
-
- const resultsPaper = (data) => {
- var boxWidth = "2px";
- var boxColor = "orange";
- if (
- data.status === "ABORTED" ||
- data.status === "UNFINISHED" ||
- data.status === "FAILURE"
- ) {
- boxColor = "red";
- } else if (data.status === "FINISHED" || data.status === "SUCCESS") {
- boxColor = "green";
- } else if (data.status === "SKIPPED" || data.status === "EXECUTING") {
- boxColor = "yellow";
- } else {
- boxColor = "green";
- }
-
- var t = new Date(data.started_at * 1000);
- var showResult = data.result.trim();
- const validate = validateJson(showResult);
-
- if (validate.valid) {
- showResult = (
-
- );
- } else {
- // FIXME - have everything parsed as json, either just for frontend
- // or in the backend?
- /*
- const newdata = {"result": data.result}
- showResult =
- */
- }
-
- return (
- {}}
- >
-
-
-
-
-
- Name: {data.action.label}
-
-
-
- App: {data.action.app_name}, Version: {data.action.app_version}
-
-
- Action: {data.action.name}, Environment: {data.action.environment}
- , Status: {data.status}
-
-
-
- Started: {t.toISOString()}
-
-
-
-
-
- {showResult}
-
-
-
-
-
- );
- };
-
- const resultsHandler =
- Object.getOwnPropertyNames(selectedExecution).length > 0 &&
- selectedExecution.results !== null ? (
-
- {selectedExecution.results
- .sort((a, b) => a.started_at - b.started_at)
- .map((data, index) => {
- return
{resultsPaper(data)}
;
- })}
-
- ) : (
- No results yet
- );
-
- const resultsLength =
- Object.getOwnPropertyNames(selectedExecution).length > 0 &&
- selectedExecution.results !== null
- ? selectedExecution.results.length
- : 0;
-
- const ExecutionDetails = () => {
- var starttime = new Date(selectedExecution.started_at * 1000);
- var endtime = new Date(selectedExecution.started_at * 1000);
-
- var parsedArgument = selectedExecution.execution_argument;
- if (
- selectedExecution.execution_argument !== undefined &&
- selectedExecution.execution_argument.length > 0
- ) {
- parsedArgument = replaceAll(parsedArgument, " None", ' "None"');
- }
-
- var arg = null;
- if (
- selectedExecution.execution_argument !== undefined &&
- selectedExecution.execution_argument.length > 0
- ) {
- var showResult = selectedExecution.execution_argument.trim();
- const validate = validateJson(showResult);
-
- arg = validate.valid ? (
-
- ) : (
- showResult
- );
- }
-
- var lastresult = null;
- if (
- selectedExecution.result !== undefined &&
- selectedExecution.result.length > 0
- ) {
- var showResult = selectedExecution.result.trim();
- const validate = validateJson(showResult);
- lastresult = validate.valid ? (
-
- ) : (
- showResult
- );
- }
-
- /*
-
- ID: {selectedExecution.execution_id}
-
-
- Last node: {selectedExecution.workflow.actions.find(data => data.id === selectedExecution.last_node).actions[0].label}
-
- */
- if (
- Object.getOwnPropertyNames(selectedExecution).length > 0 &&
- selectedExecution.workflow.actions !== null
- ) {
- return (
-
-
- Status: {selectedExecution.status}
-
-
- Started: {starttime.toISOString()}
-
-
- Finished: {endtime.toISOString()}
-
- {/*
-
- Last Result: {lastresult}
-
- */}
-
{arg}
-
- {resultsHandler}
-
- );
- }
-
- return executionLoading ? (
-
-
-
- ) : (
-
- There are no executiondetails yet. Click "execute" to run your first
- one.
-
- );
- };
-
- const ExecutionsView = () => {
- if (workflowExecutions.length > 0) {
- const sortedWorkflows = workflowExecutions
- .sort((a, b) => a.started_at - b.started_at)
- .reverse();
-
- return (
-
- {sortedWorkflows.map((data) => {
- return executionPaper(data);
- })}
-
- );
- }
- return executionLoading ? (
-
-
-
- ) : (
-
- Executions have been moved to the Workflow itself.
-
- Click here to see them
-
-
- );
- };
-
- // Can create and set workflows
- const setNewWorkflow = (
- name,
- description,
- tags,
- editingWorkflow,
- redirect
- ) => {
- var method = "POST";
- var extraData = "";
- var workflowdata = {};
-
- if (editingWorkflow.id !== undefined) {
- console.log("Building original workflow");
- method = "PUT";
- extraData = "/" + editingWorkflow.id;
- workflowdata = editingWorkflow;
-
- console.log("REMOVING OWNER");
- workflowdata["owner"] = "";
- // FIXME: Loop triggers and turn them off?
- }
-
- workflowdata["name"] = name;
- workflowdata["description"] = description;
- if (tags !== undefined) {
- workflowdata["tags"] = tags;
- }
- //console.log(workflowdata)
- //return
-
- return fetch(globalUrl + "/api/v1/workflows" + extraData, {
- method: method,
- headers: {
- "Content-Type": "application/json",
- Accept: "application/json",
- },
- body: JSON.stringify(workflowdata),
- credentials: "include",
- })
- .then((response) => {
- if (response.status !== 200) {
- console.log("Status not 200 for workflows :O!");
- return;
- }
- return response.json();
- })
- .then((responseJson) => {
- if (method === "POST" && redirect) {
- window.location.pathname = "/workflows/" + responseJson["id"];
- } else if (!redirect) {
- // Update :)
- getAvailableWorkflows();
- } else {
- alert.info("Successfully changed basic info for workflow");
- }
-
- return responseJson;
- })
- .catch((error) => {
- alert.error(error.toString());
- });
- };
-
- const importFiles = (event) => {
- console.log("Importing!");
- const file = event.target.value;
- if (event.target.files.length > 0) {
- for (var key in event.target.files) {
- const file = event.target.files[key];
- if (file.type !== "application/json") {
- if (file.type !== undefined) {
- alert.error("File has to contain valid json");
- }
-
- continue;
- }
-
- const reader = new FileReader();
- // Waits for the read
- reader.addEventListener("load", (event) => {
- var data = reader.result;
- try {
- data = JSON.parse(reader.result);
- } catch (e) {
- alert.error("Invalid JSON: " + e);
- return;
- }
-
- // Initialize the workflow itself
- const ret = setNewWorkflow(
- data.name,
- data.description,
- data.tags,
- {},
- false
- )
- .then((response) => {
- if (response !== undefined) {
- // SET THE FULL THING
- data.id = response.id;
-
- // Actually create it
- const ret = setNewWorkflow(
- data.name,
- data.description,
- data.tags,
- data,
- false
- ).then((response) => {
- if (response !== undefined) {
- alert.success("Successfully imported " + data.name);
- }
- });
- }
- })
- .catch((error) => {
- alert.error("Import error: " + error.toString());
- });
- });
-
- // Actually reads
- reader.readAsText(file);
- }
- }
-
- setLoadWorkflowsModalOpen(false);
- };
-
- const modalView = modalOpen ? (
-
- ) : null;
-
- const viewSize = {
- workflowView: 4,
- executionsView: 3,
- executionResults: 4,
- };
-
- const workflowViewStyle = {
- flex: viewSize.workflowView,
- marginLeft: "10px",
- marginRight: "10px",
- };
-
- if (viewSize.workflowView === 0) {
- workflowViewStyle.display = "none";
- }
-
- const workflowButtons = (
-
- {view === "grid" && (
-
-
-
- )}
- {view === "list" && (
-
-
-
- )}
- {workflows.length > 0 ? (
-
-
-
- ) : null}
-
-
-
- (upload = ref)}
- onChange={importFiles}
- />
- {workflows.length > 0 ? (
-
-
-
- ) : null}
-
-
-
-
- );
-
- const useStyles = makeStyles((theme) => ({
- root: {
- border: 0,
- "& .MuiDataGrid-columnsContainer": {
- backgroundColor: theme.palette.type === "light" ? "#fafafa" : "#1d1d1d",
- },
- "& .MuiDataGrid-iconSeparator": {
- display: "none",
- },
- "& .MuiDataGrid-colCell, .MuiDataGrid-cell": {
- borderRight: `1px solid ${
- theme.palette.type === "light" ? "white" : "#303030"
- }`,
- },
- "& .MuiDataGrid-columnsContainer, .MuiDataGrid-cell": {
- borderBottom: `1px solid ${
- theme.palette.type === "light" ? "#f0f0f0" : "#303030"
- }`,
- },
- "& .MuiDataGrid-cell": {
- color:
- theme.palette.type === "light" ? "white" : "rgba(255,255,255,0.65)",
- },
- "& .MuiPaginationItem-root, .MuiTablePagination-actions, .MuiTablePagination-caption":
- {
- borderRadius: 0,
- color: "white",
- },
- },
- }));
- const classes = useStyles();
-
- const WorkflowGridView = () => {
- let workflowData = "";
- if (workflows.length > 0) {
- const columns = [
- { field: "title", headerName: "Title", width: 330 },
- {
- field: "actions",
- headerName: "Actions",
- width: 200,
- sortable: false,
- disableClickEventBubbling: true,
- renderCell: (params) => {
- const data = params.row.record;
- let [triggers, schedules, webhooks, subflows] =
- getWorkflowMeta(data);
-
- return (
-
-
-
-
-
-
-
-
- executeWorkflow(data.id)}
- />
-
-
-
-
- {webhooks > 0 ? (
-
-
-
- ) : null}
- {schedules > 0 ? (
-
-
-
- ) : null}
-
- );
- },
- },
- {
- field: "tags",
- headerName: "Tags",
- width: 390,
- sortable: false,
- disableClickEventBubbling: true,
- renderCell: (params) => {
- const data = params.row.record;
- return (
-
- {data.tags !== undefined
- ? data.tags.map((tag, index) => {
- if (index >= 3) {
- return null;
- }
-
- return (
-
- );
- })
- : null}
-
- );
- },
- },
- ];
- let rows = [];
- rows = workflows.map((data, index) => {
- let obj = { id: index + 1, title: data.name, record: data };
- return obj;
- });
- workflowData = (
-
- );
- }
- return {workflowData}
;
- };
-
- const WorkflowView = () => {
- if (workflows.length === 0) {
- return (
-
-
-
-
Welcome to Shuffle
-
-
-
- Shuffle is a flexible, easy to use, automation platform
- allowing users to integrate their services and devices freely.
- It's made to significantly reduce the amount of manual labor,
- and is focused on security applications.{" "}
-
- Click here to learn more.
-
-
-
-
- If you want to jump straight into it, click here to create your
- first workflow:
-
-
-
-
-
- ..OR
-
- {workflowButtons}
-
-
-
-
- );
- }
-
- return (
-
-
-
-
-
-
-
-
-

-
-
-
{workflows.length}
-
ACTIVE WORKFLOWS
-
-
-
-
-
-
-

-
-
-
{workflows.length}
-
AVAILABE WORKFLOWS
-
-
-
-
-
-
-

-
-
-
{workflows.length}
-
NOTIFICATIONS
-
-
-
-
-
-
-
- {view === "grid" && (
-
- {workflows.map((data, index) => {
- return ;
- })}
-
- )}
-
- {view === "list" &&
}
-
-
-
-
- );
- };
-
- const importWorkflowsFromUrl = (url) => {
- console.log("IMPORT WORKFLOWS FROM ", downloadUrl);
-
- const parsedData = {
- url: url,
- field_3: downloadBranch || "master",
- };
-
- if (field1.length > 0) {
- parsedData["field_1"] = field1;
- }
-
- if (field2.length > 0) {
- parsedData["field_2"] = field2;
- }
-
- alert.success("Getting specific workflows from your URL.");
- var cors = "cors";
- fetch(globalUrl + "/api/v1/workflows/download_remote", {
- method: "POST",
- mode: "cors",
- headers: {
- Accept: "application/json",
- },
- body: JSON.stringify(parsedData),
- credentials: "include",
- })
- .then((response) => {
- if (response.status === 200) {
- alert.success("Successfully loaded workflows from " + downloadUrl);
- getAvailableWorkflows();
- }
-
- return response.json();
- })
- .then((responseJson) => {
- console.log("DATA: ", responseJson);
- if (!responseJson.success) {
- if (responseJson.reason !== undefined) {
- alert.error("Failed loading: " + responseJson.reason);
- } else {
- alert.error("Failed loading");
- }
- }
- })
- .catch((error) => {
- alert.error(error.toString());
- });
- };
-
- const handleGithubValidation = () => {
- importWorkflowsFromUrl(downloadUrl);
- setLoadWorkflowsModalOpen(false);
- };
-
- const workflowDownloadModalOpen = loadWorkflowsModalOpen ? (
-
- ) : null;
-
- const loadedCheck =
- isLoaded && isLoggedIn && workflowDone ? (
-
-
- {modalView}
- {deleteModal}
- {workflowDownloadModalOpen}
-
- ) : (
-
-
- Loading Workflows
-
- );
-
- // Maybe use gridview or something, idk
- return {loadedCheck}
;
-};
-
-export default MyView;
diff --git a/frontend/src/views/RegisterLink.jsx b/frontend/src/views/RegisterLink.jsx
deleted file mode 100755
index 1e4827c6..00000000
--- a/frontend/src/views/RegisterLink.jsx
+++ /dev/null
@@ -1,93 +0,0 @@
-import React, { useState, useEffect } from "react";
-import { useParams } from "react-router-dom";
-
-import Paper from "@material-ui/core/Paper";
-
-const bodyDivStyle = {
- margin: "auto",
- textAlign: "center",
- width: "768px",
-};
-
-//const tmpdata = {
-// "username": "frikky",
-// "firstname": "fred",
-// "lastname": "ode",
-// "title": "topkek",
-// "companyname": "company here",
-// "email": "your email pls",
-// "phone": "PHONE!!",
-//}
-
-// FIXME - add fetch for data fields
-// FIXME - remove tmpdata
-// FIXME: Use isLoggedIn :)
-const Settings = (defaultprops) => {
- const { globalUrl, isLoaded, surfaceColor } = defaultprops;
-
- const params = useParams();
- var props = JSON.parse(JSON.stringify(defaultprops))
- props.match = {}
- props.match.params = params
-
- const [firstRequest, setFirstRequest] = useState(true);
- const boxStyle = {
- flex: "1",
- marginLeft: "10px",
- marginRight: "10px",
- paddingLeft: "30px",
- paddingRight: "30px",
- paddingBottom: "30px",
- paddingTop: "30px",
- backgroundColor: surfaceColor,
- color: "white",
- display: "flex",
- flexDirection: "column",
- };
-
- const registerCall = () => {
- const url = globalUrl + "/api/v1/register/" + props.match.params.key;
- fetch(url, {
- method: "GET",
- credentials: "include",
- headers: {
- "Content-Type": "application/json; charset=utf-8",
- },
- })
- .then((response) =>
- response.json().then((responseJson) => {
- console.log(responseJson);
- })
- )
- .catch((error) => {
- console.log("SOMETHING WRONG");
- });
- };
-
- // This should "always" have data
- useEffect(() => {
- if (firstRequest) {
- setFirstRequest(false);
- registerCall();
- }
- });
-
- // Random names for type & autoComplete. Didn't research :^)
- const landingpageData = (
-
-
- Registration verification
- Thanks for verifying, redirecting you to our login!
-
-
- );
-
- const loadedCheck = isLoaded ? (
- {landingpageData}
- ) : (
-
- );
-
- return {loadedCheck}
;
-};
-export default Settings;
diff --git a/frontend/src/views/RegisterPage.jsx b/frontend/src/views/RegisterPage.jsx
deleted file mode 100755
index 34df7666..00000000
--- a/frontend/src/views/RegisterPage.jsx
+++ /dev/null
@@ -1,176 +0,0 @@
-/* eslint-disable react/no-multi-comp */
-import React, { useState } from "react";
-
-import DialogTitle from "@material-ui/core/DialogTitle";
-import Dialog from "@material-ui/core/Dialog";
-import TextField from "@material-ui/core/TextField";
-import Button from "@material-ui/core/Button";
-
-const LoginDialog = (props) => {
- const {
- classes,
- onClose,
- open,
- globalUrl,
- isLoggedIn,
- setIsLoggedIn,
- ...other
- } = props;
-
- const [username, setUsername] = useState("");
- const [password, setPassword] = useState("");
- //const [selectedValue, setSelectedValue] = useState(false);
-
- // Used to swap from login to register. True = login, false = register
- const [loginCheck, setLoginCheck] = useState(true);
-
- // Error messages etc
- const [loginInfo, setLoginInfo] = useState("");
-
- const handleValidateForm = () => {
- return username.length > 1 && password.length > 8;
- };
-
- const onSubmit = (e) => {
- e.preventDefault();
-
- // Just use this one?
- var data =
- '{"username": "' + username + '", "password": "' + password + '"}';
- var baseurl = globalUrl;
- if (loginCheck) {
- var url = baseurl + "/login";
- fetch(url, {
- method: "POST",
- body: data,
- headers: {
- "Content-Type": "application/json",
- },
- })
- .then((response) =>
- response.json().then((responseJson) => {
- console.log(responseJson);
- //console.log(e)
- if (responseJson["success"] === false) {
- setLoginInfo(responseJson["reason"]);
- } else {
- setLoginInfo("Successful login :)");
- onClose();
- setIsLoggedIn(true);
- }
- })
- )
- .catch((error) => {
- setLoginInfo("Error in userdata");
- });
- } else {
- url = baseurl + "/register";
- fetch(url, {
- method: "POST",
- body: data,
- headers: {
- "Content-Type": "application/json",
- },
- })
- .then((response) =>
- response.json().then((responseJson) => {
- if (responseJson["success"] === false) {
- setLoginInfo(responseJson["reason"]);
- } else {
- setLoginInfo("Successful register. Please check your mail :)");
- onClose();
- setIsLoggedIn(true);
- }
- })
- )
- .catch((error) => {
- setLoginInfo("Error in userdata");
- });
- }
- };
-
- const onChangeUser = (e) => {
- setUsername(e.target.value);
- };
-
- const onChangePass = (e) => {
- setPassword(e.target.value);
- };
-
- const onClickRegister = () => {
- setLoginCheck(!loginCheck);
- };
-
- //var loginChange = loginCheck ? (Want to register? Click here.
) : (Go back to login? Click here.
);
- var formtitle = loginCheck ? Login
: Register
;
- var formButton = loginCheck ? (
- Click to Register
- ) : (
- Click to Login
- );
-
- return (
-
- );
-};
-
-export default LoginDialog;
diff --git a/frontend/src/views/Schedules.jsx b/frontend/src/views/Schedules.jsx
deleted file mode 100755
index 88c92251..00000000
--- a/frontend/src/views/Schedules.jsx
+++ /dev/null
@@ -1,232 +0,0 @@
-import React, { useEffect } from "react";
-
-import Paper from "@material-ui/core/Paper";
-import Grid from "@material-ui/core/Grid";
-import ButtonBase from "@material-ui/core/ButtonBase";
-import List from "@material-ui/core/List";
-import ListItem from "@material-ui/core/ListItem";
-import Button from "@material-ui/core/Button";
-//import Breadcrumbs from '@material-ui/core/Breadcrumbs';
-
-const Schedules = (props) => {
- const { globalUrl } = props;
-
- //const [schedules, setSchedules] = React.useState(scheduledata);
- const [schedules, setSchedules] = React.useState({});
-
- const getAvailableSchedules = () => {
- fetch(globalUrl + "/api/v1/schedules", {
- method: "GET",
- headers: {
- "Content-Type": "application/json",
- Accept: "application/json",
- },
- })
- .then((response) => response.json())
- .then((responseJson) => {
- setSchedules(responseJson);
- })
- .catch((error) => {
- console.log(error);
- });
- };
-
- // FIXME - add automated redirection, as empty apps look horrible currently
- const newSchedule = () => {
- fetch(globalUrl + "/api/v1/schedules/new", {
- method: "POST",
- headers: { "content-type": "application/json" },
- body: JSON.stringify(),
- })
- .then((response) => response.json())
- .then((responseJson) => {
- console.log(responseJson);
- setSchedules({});
- })
- .catch((error) => {
- console.log(error);
- });
- };
-
- const deleteSchedule = (id) => {
- if (id === undefined) {
- return;
- }
-
- fetch(globalUrl + "/api/v1/schedules/" + id + "/delete", {
- method: "DELETE",
- headers: {
- "Content-Type": "application/json",
- Accept: "application/json",
- },
- })
- .then((response) => response.json())
- .then((responseJson) => {
- setSchedules({});
- })
- .catch((error) => {
- console.log(error);
- });
- };
-
- // FIXME - use this?
- //const getNewScheduleInfo = () => {
- // fetch(globalUrl+"/api/v1/schedules", {
- // method: 'GET',
- // headers: {
- // 'Content-Type': 'application/json',
- // 'Accept': 'application/json',
- // },
- // })
- // .then((response) => response.json())
- // .then((responseJson) => {
- // setSchedules(responseJson)
- // })
- // .catch(error => {
- // console.log(error)
- // });
- //}
-
- useEffect(() => {
- if (Object.getOwnPropertyNames(schedules).length <= 0) {
- getAvailableSchedules();
- }
- });
-
- const bodyDivStyle = {
- marginLeft: "20px",
- marginRight: "20px",
- width: "1350px",
- minWidth: "1350px",
- maxWidth: "1350px",
- };
-
- const scheduleApp = (app) => {
- console.log(app);
- return (
-
-
-
-
-
-
-
-
-
-
-
{app.name}
-
- {app.description}
-
- {app.action}
-
-
-
- );
- };
-
- const splitter = (
-
- );
-
- const hrefStyle = {
- color: "#385f71",
- textDecoration: "none",
- };
-
- // FIXME - add Schedule modal
- const schedulePaper = (schedule) => {
- return (
-
-
-
- {scheduleApp(schedule.appinfo.sourceapp)}
-
- ARROW
-
- {scheduleApp(schedule.appinfo.destinationapp)}
-
- {splitter}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
- };
-
- console.log(schedules);
- console.log(schedules);
- console.log(schedules.schedules);
- const schedulemap =
- Object.getOwnPropertyNames(schedules).length > 0 &&
- schedules.schedules &&
- schedules.schedules.length > 0 ? (
- {schedules.schedules.map((data) => schedulePaper(data))}
- ) : (
-
-
-
- );
-
- const scheduleView =
- Object.getOwnPropertyNames(schedules).length > 0 ? (
-
-
- {schedulemap}
-
- ) : null;
-
- // Maybe use gridview or something, idk
- return {scheduleView}
;
-};
-
-export default Schedules;
diff --git a/frontend/src/views/TempDashboard.jsx b/frontend/src/views/TempDashboard.jsx
deleted file mode 100644
index a34ac730..00000000
--- a/frontend/src/views/TempDashboard.jsx
+++ /dev/null
@@ -1,298 +0,0 @@
-import React from "react";
-import { Grid, Container, Divider } from "@mui/material";
-
-import { makeStyles } from "@mui/material/styles";
-import Card from "@material-ui/core/Card";
-import CardContent from "@material-ui/core/CardContent";
-import Typography from "@material-ui/core/Typography";
-
-import Table from "@material-ui/core/Table";
-import TableBody from "@material-ui/core/TableBody";
-import TableCell from "@material-ui/core/TableCell";
-import TableContainer from "@material-ui/core/TableContainer";
-import TableHead from "@material-ui/core/TableHead";
-import TableRow from "@material-ui/core/TableRow";
-import Paper from "@material-ui/core/Paper";
-
-import { LineChart, LineSeries, BarChart } from "reaviz";
-import { GridStripe } from "reaviz";
-//import { GridlineSeries } from "reaviz";
-
-import InputLabel from '@material-ui/core/InputLabel';
-import FormControl from '@material-ui/core/FormControl';
-import Select from '@material-ui/core/Select';
-import MenuItem from '@material-ui/core/MenuItem';
-
-const data = [
- {
- key: new Date("11/29/2019"),
- data: 10,
- },
- {
- key: new Date("11/30/2019"),
- data: 14,
- },
- {
- key: new Date("12/01/2019"),
- data: 5,
- },
- {
- key: new Date("12/02/2019"),
- data: 18,
- },
-];
-
-const useStyles1 = makeStyles((theme) => ({
- formControl: {
- margin: theme.spacing(1),
- minWidth: 120,
- },
- selectEmpty: {
- marginTop: theme.spacing(2),
- },
-}));
-
-
-const useStyles = makeStyles({
- table: {
- minWidth: 650,
- },
- root: {
- minWidth: 275,
- },
- bullet: {
- display: "inline-block",
- margin: "0 2px",
- transform: "scale(0.8)",
- },
- title: {
- fontSize: 14,
- },
- pos: {
- marginBottom: 12,
- },
-});
-
-function createData(name, calories, fat, carbs, protein) {
- return { name, calories, fat, carbs, protein };
-}
-
-const rows = [
- createData("Frozen yoghurt", 159, 6.0, 24, 4.0),
- createData("Ice cream sandwich", 237, 9.0, 37, 4.3),
- createData("Eclair", 262, 16.0, 24, 6.0),
- createData("Cupcake", 305, 3.7, 67, 4.3),
- createData("Gingerbread", 356, 16.0, 49, 3.9),
-];
-
-const DashboardPage = () => {
- const classes = useStyles();
- const classes1 = useStyles1();
-
- const [age, setAge] = React.useState(0);
-
- const handleChange = (event) => {
- setAge(event.target.value);
-
- };
-
- return (
-
-
-
-
-
- Dashboard
-
-
-
- Organization
-
-
-
-
-
-
-
-
-
-
-
-
- Total workflows executions
-
-
- 456
-
-
-
-
-
-
-
-
- Total Apps executions
-
-
- 587
-
-
-
-
-
-
-
-
- Total failed executions
-
-
- 999
-
-
-
-
-
-
-
-
-
-
- }
- series={}
- />
-
-
-
-
-
-
-
-
- Dessert (100g serving)
- Calories
- Fat (g)
- Carbs (g)
- Protein (g)
-
-
-
- {rows.map((row) => (
-
-
- {row.name}
-
- {row.calories}
- {row.fat}
- {row.carbs}
- {row.protein}
-
- ))}
-
-
-
-
-
-
- );
-};
-
-export default DashboardPage;
diff --git a/frontend/src/views/Webhooks.jsx b/frontend/src/views/Webhooks.jsx
deleted file mode 100755
index 64a463b9..00000000
--- a/frontend/src/views/Webhooks.jsx
+++ /dev/null
@@ -1,316 +0,0 @@
-import React, { useEffect } from "react";
-
-import Paper from "@material-ui/core/Paper";
-import Grid from "@material-ui/core/Grid";
-import ButtonBase from "@material-ui/core/ButtonBase";
-import Button from "@material-ui/core/Button";
-import List from "@material-ui/core/List";
-import ListItem from "@material-ui/core/ListItem";
-import TextField from "@material-ui/core/TextField";
-import Select from "@material-ui/core/Select";
-import MenuItem from "@material-ui/core/MenuItem";
-
-import Dialog from "@material-ui/core/Dialog";
-import DialogTitle from "@material-ui/core/DialogTitle";
-import DialogActions from "@material-ui/core/DialogActions";
-import DialogContent from "@material-ui/core/DialogContent";
-
-import WebhookImage from "../assets/img/webhook.png";
-import KafkaImage from "../assets/img/kafka.png";
-
-const Webhooks = (props) => {
- const { globalUrl, isLoaded } = props;
- const validtypes = ["webhook"];
-
- //const [hooks, setSchedules] = React.useState(hookdata);
- const [hooks, setHooks] = React.useState([]);
- const [modalOpen, setModalOpen] = React.useState(false);
- const [newHookName, setNewHookName] = React.useState("");
- const [newHookDescription, setNewHookDescription] = React.useState("");
- const [newHookType, setNewHookType] = React.useState("");
- const [firstrequest, setFirstrequest] = React.useState(true);
- const [, setModalError] = React.useState("");
-
- useEffect(() => {
- if (firstrequest) {
- setFirstrequest(false);
- getAvailableHooks();
- }
- });
-
- const newHook = () => {
- if (newHookName.length === 0) {
- setModalError("Missing name in modal");
- return;
- }
-
- if (!validtypes.includes(newHookType)) {
- setModalError(
- newHookType + " is not a valid type. Try this: " + validtypes
- );
- }
-
- fetch(globalUrl + "/api/v1/hooks/new", {
- method: "POST",
- headers: { "content-type": "application/json" },
- body: JSON.stringify({
- name: newHookName,
- description: newHookDescription,
- type: newHookType,
- }),
- credentials: "include",
- })
- .then((response) => response.json())
- .then((responseJson) => {
- console.log(responseJson);
- setHooks([]);
- })
- .catch((error) => {
- console.log(error);
- });
- };
-
- const getAvailableHooks = () => {
- fetch(globalUrl + "/api/v1/hooks", {
- method: "GET",
- headers: {
- "Content-Type": "application/json",
- Accept: "application/json",
- },
- credentials: "include",
- })
- .then((response) => response.json())
- .then((responseJson) => {
- setHooks(responseJson);
- })
- .catch((error) => {
- console.log(error);
- // window.location.pathname = "/"
- });
- };
-
- const deleteHook = (id) => {
- if (id === undefined) {
- return;
- }
-
- fetch(globalUrl + "/api/v1/hooks/" + id + "/delete", {
- method: "DELETE",
- headers: {
- "Content-Type": "application/json",
- Accept: "application/json",
- },
- credentials: "include",
- })
- .then((response) => response.json())
- .then((responseJson) => {
- setHooks([]);
- })
- .catch((error) => {
- console.log(error);
- });
- };
-
- const bodyDivStyle = {
- marginLeft: "20px",
- marginRight: "20px",
- width: "1350px",
- minWidth: "1350px",
- maxWidth: "1350px",
- };
-
- const hookApp = (app) => {
- // Might be more options, but should be webhook or MQ
- const appPicture =
- app.type === "webhook" ? (
-
- ) : (
-
- );
-
- return (
-
-
- {appPicture}
-
- {splitter}
-
-
-
-
-
{app.info.name}
-
- Desc: {app.info.description}
- Status: {app.status}
-
- {app.action}
-
-
-
- );
- };
-
- const splitter = (
-
- );
-
- const hrefStyle = {
- color: "#385f71",
- textDecoration: "none",
- };
-
- // FIXME - add Schedule modal
- const hookPaper = (hook) => {
- return (
-
-
- {hookApp(hook)}
- {splitter}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
- };
-
- const modalView = modalOpen ? (
-
- ) : null;
-
- const hookmap =
- hooks.length > 0 ? (
- {hooks.map((data) => hookPaper(data))}
- ) : (
-
-
-
- );
-
- const hookView = (
-
-
- {hookmap}
-
- );
-
- const loadedCheck = isLoaded ? (
-
- {modalView}
- {hookView}
-
- ) : (
-
- );
-
- // Maybe use gridview or something, idk
- return {loadedCheck}
;
-};
-
-export default Webhooks;
diff --git a/frontend/src/views/Workflows.jsx b/frontend/src/views/Workflows.jsx
index ab6eddd6..a892dbb3 100755
--- a/frontend/src/views/Workflows.jsx
+++ b/frontend/src/views/Workflows.jsx
@@ -75,14 +75,8 @@ import {
ArrowRight as ArrowRightIcon,
} from "@mui/icons-material";
-//import NestedMenuItem from "material-ui-nested-menu-item";
-//import {Search as SearchIcon, ArrowUpward as ArrowUpwardIcon, Visibility as VisibilityIcon, Close as CloseIcon, Error as ErrorIcon, FindReplace as FindreplaceIcon, ArrowLeft as ArrowLeftIcon, Cached as CachedIcon, DirectionsRun as DirectionsRunIcon, Add as AddIcon, Polymer as PolymerIcon, FormatListNumbered as FormatListNumberedIcon, Create as CreateIcon, PlayArrow as PlayArrowIcon, AspectRatio as AspectRatioIcon, MoreVert as MoreVertIcon, Apps as AppsIcon, Schedule as ScheduleIcon, FavoriteBorder as FavoriteBorderIcon, Pause as PauseIcon, Delete as DeleteIcon, AddCircleOutline as AddCircleOutlineIcon, Save as SaveIcon, KeyboardArrowLeft as KeyboardArrowLeftIcon, KeyboardArrowRight as KeyboardArrowRightIcon, ArrowBack as ArrowBackIcon, Settings as SettingsIcon, LockOpen as LockOpenIcon, ExpandMore as ExpandMoreIcon, VpnKey as VpnKeyIcon} from '@material-ui/icons';
-
-//https://next.material-ui.com/components/material-icons/
import { DataGrid, GridToolbar } from "@mui/x-data-grid";
-//import JSONPretty from 'react-json-pretty';
-//import JSONPrettyMon from 'react-json-pretty/dist/monikai'
import Dropzone from "../components/Dropzone.jsx";
import { useNavigate, Link } from "react-router-dom";
@@ -1747,13 +1741,6 @@ const Workflows = (props) => {
{"Duplicate Workflow"}