Fixed visuals and targeting during onboarding
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -167,7 +167,7 @@ const ParsedAction = (props) => {
|
|||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
|
|
||||||
const [expansionModalOpen, setExpansionModalOpen] = React.useState(false);
|
const [expansionModalOpen, setExpansionModalOpen] = React.useState(false);
|
||||||
const [hideBody, setHideBody] = React.useState(false);
|
const [hideBody, setHideBody] = React.useState(true);
|
||||||
const [activateHidingBody, setActivateHidingBody] = React.useState(false);
|
const [activateHidingBody, setActivateHidingBody] = React.useState(false);
|
||||||
const [codedata, setcodedata] = React.useState("");
|
const [codedata, setcodedata] = React.useState("");
|
||||||
const [fieldCount, setFieldCount] = React.useState(0);
|
const [fieldCount, setFieldCount] = React.useState(0);
|
||||||
@@ -980,11 +980,13 @@ const ParsedAction = (props) => {
|
|||||||
|
|
||||||
//console.log("AUTH: ", authenticationType)
|
//console.log("AUTH: ", authenticationType)
|
||||||
if (authenticationType !== undefined && authenticationType !== null && authenticationType.type === "oauth2") {
|
if (authenticationType !== undefined && authenticationType !== null && authenticationType.type === "oauth2") {
|
||||||
|
/*
|
||||||
return (
|
return (
|
||||||
<Typography variant="body1" color="textSecondary" style={{marginTop: 15}}>
|
<Typography variant="body1" color="textSecondary" style={{marginTop: 15}}>
|
||||||
You must authenticate before using oauth2 apps.
|
You must authenticate before using oauth2 apps.
|
||||||
</Typography>
|
</Typography>
|
||||||
)
|
)
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Issue #40 - selectedActionParameters not reset
|
// FIXME: Issue #40 - selectedActionParameters not reset
|
||||||
@@ -1074,7 +1076,7 @@ const ParsedAction = (props) => {
|
|||||||
multiline = true;
|
multiline = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var placeholder = "Static value";
|
var placeholder = "Value";
|
||||||
if (
|
if (
|
||||||
data.example !== undefined &&
|
data.example !== undefined &&
|
||||||
data.example !== null &&
|
data.example !== null &&
|
||||||
@@ -1163,6 +1165,9 @@ const ParsedAction = (props) => {
|
|||||||
|
|
||||||
for (var key in selectedActionParameters) {
|
for (var key in selectedActionParameters) {
|
||||||
var currentItem = selectedActionParameters[key];
|
var currentItem = selectedActionParameters[key];
|
||||||
|
if (currentItem.name === "ssl_verify") {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (currentItem.description === openApiFieldDesc) {
|
if (currentItem.description === openApiFieldDesc) {
|
||||||
currentItem.field_active = !hideBody;
|
currentItem.field_active = !hideBody;
|
||||||
@@ -1191,7 +1196,7 @@ const ParsedAction = (props) => {
|
|||||||
setActivateHidingBody(true);
|
setActivateHidingBody(true);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log("SHOW BUTTON");
|
//console.log("SHOW BUTTON");
|
||||||
|
|
||||||
rows = "1";
|
rows = "1";
|
||||||
disabled = true;
|
disabled = true;
|
||||||
|
|||||||
@@ -23,18 +23,18 @@ const CodeEditor = (props) => {
|
|||||||
const [localcodedata, setlocalcodedata] = React.useState(codedata === undefined || codedata === null || codedata.length === 0 ? "" : codedata);
|
const [localcodedata, setlocalcodedata] = React.useState(codedata === undefined || codedata === null || codedata.length === 0 ? "" : codedata);
|
||||||
// const {codelang, setcodelang} = props
|
// const {codelang, setcodelang} = props
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
const [validation, setvalidation] = React.useState(" ");
|
const [validation, setvalidation] = React.useState(" ");
|
||||||
|
const [expOutput, setexpOutput] = React.useState(" ");
|
||||||
|
|
||||||
function IsJsonString(str) {
|
function IsJsonString(str) {
|
||||||
try {
|
try {
|
||||||
var o = JSON.parse(str);
|
var o = JSON.parse(str);
|
||||||
if (o && typeof o === "object") {
|
if (o && typeof o === "object") {
|
||||||
setvalidation("Validation Status: Correct!")
|
setvalidation("Correct!")
|
||||||
}
|
}
|
||||||
} catch (e) {setvalidation("Validation Status: Incorrect!");}
|
} catch (e) {setvalidation("Incorrect!");}
|
||||||
}
|
}
|
||||||
|
|
||||||
const [expOutput, setexpOutput] = React.useState(" ");
|
|
||||||
function expectedOutput(input) {
|
function expectedOutput(input) {
|
||||||
|
|
||||||
const found = input.match(/[$]{1}([a-zA-Z0-9_-]+\.?){1}([a-zA-Z0-9#_-]+\.?){0,}/g)
|
const found = input.match(/[$]{1}([a-zA-Z0-9_-]+\.?){1}([a-zA-Z0-9#_-]+\.?){0,}/g)
|
||||||
@@ -96,6 +96,7 @@ const CodeEditor = (props) => {
|
|||||||
<DialogTitle
|
<DialogTitle
|
||||||
style={{
|
style={{
|
||||||
paddingBottom:20,
|
paddingBottom:20,
|
||||||
|
paddingLeft: 10,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Code Editor
|
Code Editor
|
||||||
@@ -129,6 +130,7 @@ const CodeEditor = (props) => {
|
|||||||
<DialogTitle
|
<DialogTitle
|
||||||
style={{
|
style={{
|
||||||
paddingTop: 30,
|
paddingTop: 30,
|
||||||
|
paddingLeft: 10,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
@@ -150,6 +152,7 @@ const CodeEditor = (props) => {
|
|||||||
marginTop: -2,
|
marginTop: -2,
|
||||||
border: `2px solid ${theme.palette.inputColor}`,
|
border: `2px solid ${theme.palette.inputColor}`,
|
||||||
borderRadius: theme.palette.borderRadius,
|
borderRadius: theme.palette.borderRadius,
|
||||||
|
maxHeight: 400,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{expOutput}
|
{expOutput}
|
||||||
@@ -159,10 +162,11 @@ const CodeEditor = (props) => {
|
|||||||
color: "white",
|
color: "white",
|
||||||
fontFamily: "monospace",
|
fontFamily: "monospace",
|
||||||
padding: 20,
|
padding: 20,
|
||||||
|
paddingLeft: 10,
|
||||||
marginTop: -15,
|
marginTop: -15,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{validation}
|
JSON Validation: {validation}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ const data = [{
|
|||||||
'text-algin': 'center',
|
'text-algin': 'center',
|
||||||
'width': '85px',
|
'width': '85px',
|
||||||
'height': '85px',
|
'height': '85px',
|
||||||
'border-width': '1px',
|
'border-width': '3px',
|
||||||
'border-color': '#8a8a8a',
|
'border-color': '#8a8a8a',
|
||||||
'color': '#f85a3e',
|
'color': '#f85a3e',
|
||||||
'text-margin-x': '0px',
|
'text-margin-x': '0px',
|
||||||
@@ -42,6 +42,16 @@ const data = [{
|
|||||||
'font-size': '13px',
|
'font-size': '13px',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
selector: `node[!is_valid]`,
|
||||||
|
css: {
|
||||||
|
'height': '20px',
|
||||||
|
'width': '20px',
|
||||||
|
'background-color': '#6d9eeb',
|
||||||
|
'border-color': '#4c6ea4',
|
||||||
|
'border-width': '1px',
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
selector: `edge[?human]`,
|
selector: `edge[?human]`,
|
||||||
css: {
|
css: {
|
||||||
|
|||||||
@@ -66,6 +66,34 @@ const theme = createMuiTheme({
|
|||||||
backgroundColor: "#383B40",
|
backgroundColor: "#383B40",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
MuiCssBaseline: {
|
||||||
|
'@global': {
|
||||||
|
/*
|
||||||
|
scrollbarColor: "#6b6b6b #2b2b2b",
|
||||||
|
"&::-webkit-scrollbar, & *::-webkit-scrollbar": {
|
||||||
|
backgroundColor: "#2b2b2b",
|
||||||
|
},
|
||||||
|
"&::-webkit-scrollbar-thumb, & *::-webkit-scrollbar-thumb": {
|
||||||
|
borderRadius: 8,
|
||||||
|
backgroundColor: "#6b6b6b",
|
||||||
|
minHeight: 24,
|
||||||
|
border: "3px solid #2b2b2b",
|
||||||
|
},
|
||||||
|
"&::-webkit-scrollbar-thumb:focus, & *::-webkit-scrollbar-thumb:focus": {
|
||||||
|
backgroundColor: "#959595",
|
||||||
|
},
|
||||||
|
"&::-webkit-scrollbar-thumb:active, & *::-webkit-scrollbar-thumb:active": {
|
||||||
|
backgroundColor: "#959595",
|
||||||
|
},
|
||||||
|
"&::-webkit-scrollbar-thumb:hover, & *::-webkit-scrollbar-thumb:hover": {
|
||||||
|
backgroundColor: "#959595",
|
||||||
|
},
|
||||||
|
"&::-webkit-scrollbar-corner, & *::-webkit-scrollbar-corner": {
|
||||||
|
backgroundColor: "#2b2b2b",
|
||||||
|
},
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -6903,8 +6903,8 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
</div>
|
</div>
|
||||||
{outlookButton}
|
{outlookButton}
|
||||||
{gmailButton}
|
{gmailButton}
|
||||||
<Typography variant="body2" color="textSecondary">
|
<Typography variant="body2" color="textSecondary" style={{marginTop: 5}}>
|
||||||
If you have trouble using the triggers, please <a href="https://shuffler.io/contact" rel="noopener noreferrer" target="_blank">contact us</a> to get access
|
If you have trouble using this trigger, please <a href="https://shuffler.io/contact" rel="noopener noreferrer" target="_blank" style={{ textDecoration: "none", color: "#f86a3e"}}>contact us</a> to get access
|
||||||
</Typography>
|
</Typography>
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1792,7 +1792,7 @@ const AppCreator = (defaultprops) => {
|
|||||||
in: "path",
|
in: "path",
|
||||||
name: queryitem,
|
name: queryitem,
|
||||||
description: "Generated by shuffler.io OpenAPI",
|
description: "Generated by shuffler.io OpenAPI",
|
||||||
required: true,
|
required: false,
|
||||||
schema: {
|
schema: {
|
||||||
type: "string",
|
type: "string",
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -0,0 +1,82 @@
|
|||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
import DetectionFramework from "../components/DetectionFramework.jsx";
|
||||||
|
import { useAlert } from "react-alert";
|
||||||
|
import { Link, useParams } from "react-router-dom";
|
||||||
|
import theme from '../theme';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
} from "@material-ui/core";
|
||||||
|
|
||||||
|
const Framework = (props) => {
|
||||||
|
const {globalUrl, isLoaded, isLoggedIn, showOptions, selectedOption, rolling, } = props;
|
||||||
|
|
||||||
|
const alert = useAlert()
|
||||||
|
const [frameworkLoaded, setFrameworkLoaded] = useState(false)
|
||||||
|
const [frameworkData, setFrameworkData] = useState()
|
||||||
|
|
||||||
|
const getFramework = () => {
|
||||||
|
fetch(globalUrl + "/api/v1/apps/frameworkConfiguration", {
|
||||||
|
method: "GET",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
Accept: "application/json",
|
||||||
|
},
|
||||||
|
credentials: "include",
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (response.status !== 200) {
|
||||||
|
console.log("Status not 200 for framework!");
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then((responseJson) => {
|
||||||
|
if (responseJson.success === false) {
|
||||||
|
if (responseJson.reason !== undefined) {
|
||||||
|
alert.error("Failed loading: " + responseJson.reason)
|
||||||
|
} else {
|
||||||
|
alert.error("Failed to load framework for your org.")
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setFrameworkLoaded(true)
|
||||||
|
setFrameworkData(responseJson)
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
alert.error(error.toString());
|
||||||
|
setFrameworkLoaded(true)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getFramework()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div style={{marginBottom: 25, marginTop: 25, width: 300, margin: "auto", textAlign: "center",}}>
|
||||||
|
<Link style={{textDecoration: "none", }} to="/getting-started">
|
||||||
|
<Button variant="outlined" color="secondary">
|
||||||
|
Back to getting started
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
{frameworkLoaded === true ?
|
||||||
|
<DetectionFramework
|
||||||
|
frameworkData={frameworkData}
|
||||||
|
selectedOption={"Draw"}
|
||||||
|
showOptions={false}
|
||||||
|
|
||||||
|
isLoaded={isLoaded}
|
||||||
|
isLoggedIn={isLoggedIn}
|
||||||
|
globalUrl={globalUrl}
|
||||||
|
/>
|
||||||
|
: null}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Framework;
|
||||||
@@ -30,6 +30,7 @@ import {
|
|||||||
} from "@material-ui/core";
|
} from "@material-ui/core";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
Check as CheckIcon,
|
||||||
GridOn as GridOnIcon,
|
GridOn as GridOnIcon,
|
||||||
List as ListIcon,
|
List as ListIcon,
|
||||||
Close as CloseIcon,
|
Close as CloseIcon,
|
||||||
@@ -2502,34 +2503,55 @@ const GettingStarted = (props) => {
|
|||||||
|
|
||||||
const textSpacingDiff = 8
|
const textSpacingDiff = 8
|
||||||
const textType = "body2"
|
const textType = "body2"
|
||||||
|
|
||||||
|
// Discover <a target="_blank" href="https://shuffler.io/creators" style={{textDecoration: "none", color: "#f86a3e",}}>use-cases made by other creators</a>!
|
||||||
const steps = [
|
const steps = [
|
||||||
{
|
{
|
||||||
html: (
|
html: (
|
||||||
<Typography variant={textType} style={{marginTop: textSpacingDiff}}>
|
<Typography variant={textType} style={{marginTop: textSpacingDiff}}>
|
||||||
<Link to="/detectionframework" style={{textDecoration: "none", color: "#f86a3e",}}>Find your integrations</Link> by following our simple detection framework!
|
<Link to="/detectionframework" style={{textDecoration: "none", color: "#f86a3e",}}>Find your integrations</Link> by following our simple detection framework!
|
||||||
</Typography>
|
</Typography>
|
||||||
)
|
),
|
||||||
},
|
tutorial: "find_integrations",
|
||||||
{
|
|
||||||
html: (
|
|
||||||
<Typography variant={textType} style={{marginTop: textSpacingDiff}}>
|
|
||||||
<span style={{cursor: "pointer", color: "#f86a3e",}} onClick={() => {setModalOpen(true)}}>
|
|
||||||
Create your first workflow
|
|
||||||
</span> and learn the ropes.
|
|
||||||
</Typography>
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
html:
|
html:
|
||||||
<Typography variant={textType} style={{marginTop: textSpacingDiff}}>
|
<Typography variant={textType} style={{marginTop: textSpacingDiff}}>
|
||||||
<Link target="_blank" to={{pathname: "https://shuffler.io/creators"}} style={{textDecoration: "none", color: "#f86a3e",}}>Discover use-cases</Link> other creators have made!
|
Discover <span style={{cursor: "pointer", textDecoration: "none", color: "#f86a3e",}} onClick={() => {
|
||||||
|
alert.success("TBD: Coming in version 1.0.0");
|
||||||
|
|
||||||
|
const ele = document.getElementById("shuffle_search_field")
|
||||||
|
if (ele !== undefined && ele !== null) {
|
||||||
|
console.log("Found ele: ", ele)
|
||||||
|
ele.focus()
|
||||||
|
ele.style.borderColor = "#f86a3e"
|
||||||
|
ele.style.borderWidth = "2px"
|
||||||
|
|
||||||
|
} else {
|
||||||
|
alert.success("TBD: Coming in version 1.0.0");
|
||||||
|
}
|
||||||
|
}}>
|
||||||
|
use-cases made by other creators</span>!
|
||||||
|
</Typography>,
|
||||||
|
tutorial: "discover_workflows",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
html: (
|
||||||
|
<Typography variant={textType} style={{marginTop: textSpacingDiff}}>
|
||||||
|
Learn to use Shuffle by
|
||||||
|
<span style={{cursor: "pointer", color: "#f86a3e",}} onClick={() => {setModalOpen(true)}}>
|
||||||
|
creating your first workflow
|
||||||
|
</span> and <Link to="/docs" style={{textDecoration: "none", color: "#f86a3e",}}>reading the docs.</Link>
|
||||||
</Typography>
|
</Typography>
|
||||||
|
),
|
||||||
|
tutorial: "learn_shuffle",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
html:
|
html:
|
||||||
<Typography variant={textType} style={{marginTop: textSpacingDiff}}>
|
<Typography variant={textType} style={{marginTop: textSpacingDiff}}>
|
||||||
Configure your organization <Link to="/admin" style={{textDecoration: "none", color: "#f86a3e",}}>in the admin panel</Link>
|
Configure your organization <Link to="/admin" style={{textDecoration: "none", color: "#f86a3e",}}>in the admin panel</Link>
|
||||||
</Typography>
|
</Typography>,
|
||||||
|
tutorial: "configure_organization",
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2544,11 +2566,25 @@ const GettingStarted = (props) => {
|
|||||||
</Typography>
|
</Typography>
|
||||||
<Paper style={{backgroundColor: theme.palette.surfaceColor, border: "1px solid rgba(255,255,255,0.3)", padding: 40, marginTop: 25, }}>
|
<Paper style={{backgroundColor: theme.palette.surfaceColor, border: "1px solid rgba(255,255,255,0.3)", padding: 40, marginTop: 25, }}>
|
||||||
{steps.map((data, index) => {
|
{steps.map((data, index) => {
|
||||||
|
var tutorialFound = false
|
||||||
|
if (userdata.tutorials !== undefined && userdata.tutorials !== null && userdata.tutorials.length > 0 && data.tutorial !== undefined) {
|
||||||
|
const foundTutorial = userdata.tutorials.find(tutorial => tutorial === data.tutorial)
|
||||||
|
if (foundTutorial !== undefined && foundTutorial !== null) {
|
||||||
|
console.log("Found tutorial for ", data.tutorial)
|
||||||
|
tutorialFound = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div key={index} style={{display: "flex", marginBottom: index === steps.length-1 ? 0 : 20, }}>
|
<div key={index} style={{display: "flex", marginBottom: index === steps.length-1 ? 0 : 20, }}>
|
||||||
<div style={{maxWidth: 50, marginRight: 25, }}>
|
<div style={{maxWidth: 50, marginRight: 25, }}>
|
||||||
<Typography variant="h6">
|
<Typography variant="h6">
|
||||||
<b>{index+1}</b>
|
{tutorialFound ?
|
||||||
|
<CheckIcon style={{color: "green", paddingTop: 5,}} />
|
||||||
|
:
|
||||||
|
<b>{index+1}</b>
|
||||||
|
}
|
||||||
</Typography>
|
</Typography>
|
||||||
</div>
|
</div>
|
||||||
<div style={{}}>
|
<div style={{}}>
|
||||||
@@ -2593,7 +2629,7 @@ const GettingStarted = (props) => {
|
|||||||
>
|
>
|
||||||
Join Discord community
|
Join Discord community
|
||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/*
|
{/*
|
||||||
|
|||||||
@@ -2540,14 +2540,11 @@ const Workflows = (props) => {
|
|||||||
|
|
||||||
const WorkflowView = () => {
|
const WorkflowView = () => {
|
||||||
if (workflows.length === 0) {
|
if (workflows.length === 0) {
|
||||||
/*
|
|
||||||
console.log("USER: ", userdata)
|
console.log("USER: ", userdata)
|
||||||
console.log("PROPS: ", props)
|
console.log("PROPS: ", props)
|
||||||
if (userdata.tutorials !== undefined && userdata.tutorials !== null && !userdata.tutorials.includes("getting-started")) {
|
if (userdata.tutorials !== undefined && userdata.tutorials !== null && !userdata.tutorials.includes("getting-started")) {
|
||||||
//return <Redirect to='/getting-started' />;
|
|
||||||
return <Navigate to="/getting-started" replace />;
|
return <Navigate to="/getting-started" replace />;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={emptyWorkflowStyle}>
|
<div style={emptyWorkflowStyle}>
|
||||||
|
|||||||
@@ -859,7 +859,7 @@ func handleExecutionResult(workflowExecution shuffle.WorkflowExecution) {
|
|||||||
executedIds = append(executedIds, newExecId)
|
executedIds = append(executedIds, newExecId)
|
||||||
toRemove = append(toRemove, index)
|
toRemove = append(toRemove, index)
|
||||||
} else {
|
} else {
|
||||||
log.Printf("\n\n[DEBUG] %s is already executed. Continuing.", newExecId)
|
//log.Printf("\n\n[DEBUG] %s is already executed. Continuing.", newExecId)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user