Last sync for onprem
This commit is contained in:
@@ -1183,6 +1183,7 @@ const ApiExplorer = memo(({ openapi, globalUrl, userdata, HandleApiExecution, se
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var prefixCheck = "/v1";
|
var prefixCheck = "/v1";
|
||||||
if (parentUrl.includes("/")) {
|
if (parentUrl.includes("/")) {
|
||||||
const urlsplit = parentUrl.split("/");
|
const urlsplit = parentUrl.split("/");
|
||||||
@@ -1242,7 +1243,7 @@ const ApiExplorer = memo(({ openapi, globalUrl, userdata, HandleApiExecution, se
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
newActions = newActions2;
|
newActions = newActions2
|
||||||
|
|
||||||
// Rearrange them by which has action_label
|
// Rearrange them by which has action_label
|
||||||
const firstActions = newActions.filter(
|
const firstActions = newActions.filter(
|
||||||
@@ -1257,9 +1258,9 @@ const ApiExplorer = memo(({ openapi, globalUrl, userdata, HandleApiExecution, se
|
|||||||
data.action_label === null ||
|
data.action_label === null ||
|
||||||
data.action_label === "No Label"
|
data.action_label === "No Label"
|
||||||
);
|
);
|
||||||
newActions = firstActions.concat(secondActions);
|
newActions = firstActions.concat(secondActions)
|
||||||
setActions(newActions);
|
setActions(newActions)
|
||||||
setExampleBody(newActions[0]?.body);
|
setExampleBody(newActions[0]?.body)
|
||||||
}, [openapi]);
|
}, [openapi]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -1546,7 +1547,7 @@ const ActionsList = memo(({
|
|||||||
overflow: "hidden",
|
overflow: "hidden",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{action.name.replaceAll("_", " ")}
|
{action?.name?.replaceAll("_", " ")}
|
||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
))
|
))
|
||||||
@@ -1798,7 +1799,7 @@ const Action = memo((
|
|||||||
response.result = JSON.parse(response.result);
|
response.result = JSON.parse(response.result);
|
||||||
} catch (parseError) {
|
} catch (parseError) {
|
||||||
console.error("Error parsing result:", parseError);
|
console.error("Error parsing result:", parseError);
|
||||||
toast.error("Error parsing response result.");
|
//toast.error("Error parsing response result.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2228,11 +2229,12 @@ const Action = memo((
|
|||||||
}}
|
}}
|
||||||
|
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
const newUrl = e.target.value;
|
const newUrl = e.target.value
|
||||||
setActionUrl(newUrl);
|
setActionUrl(newUrl);
|
||||||
const params = extractParamsFromText(newUrl);
|
const params = extractParamsFromText(newUrl);
|
||||||
setRequestParams(params);
|
setRequestParams(params);
|
||||||
|
|
||||||
|
|
||||||
if (newUrl.startsWith("http://") || newUrl.startsWith("https://")) {
|
if (newUrl.startsWith("http://") || newUrl.startsWith("https://")) {
|
||||||
try {
|
try {
|
||||||
const url = new URL(newUrl);
|
const url = new URL(newUrl);
|
||||||
@@ -2241,9 +2243,12 @@ const Action = memo((
|
|||||||
|
|
||||||
setPath(newPath);
|
setPath(newPath);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Invalid URL:", error);
|
console.error("Invalid URL:", newUrl, error);
|
||||||
|
toast("The URL is not a valid one. Please check and try again.")
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
//toast("The URL needs to start with http:// or https://")
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import {
|
|||||||
MenuItem,
|
MenuItem,
|
||||||
Button,
|
Button,
|
||||||
ButtonGroup,
|
ButtonGroup,
|
||||||
|
Collapse,
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
|
|
||||||
import theme from '../theme.jsx';
|
import theme from '../theme.jsx';
|
||||||
@@ -23,6 +24,7 @@ import { isMobile } from "react-device-detect"
|
|||||||
import { NestedMenuItem } from "mui-nested-menu"
|
import { NestedMenuItem } from "mui-nested-menu"
|
||||||
import { GetParsedPaths, FindJsonPath } from "../views/Apps.jsx";
|
import { GetParsedPaths, FindJsonPath } from "../views/Apps.jsx";
|
||||||
import { SetJsonDotnotation } from "../views/AngularWorkflow.jsx";
|
import { SetJsonDotnotation } from "../views/AngularWorkflow.jsx";
|
||||||
|
import Draggable from "react-draggable";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
FullscreenExit as FullscreenExitIcon,
|
FullscreenExit as FullscreenExitIcon,
|
||||||
@@ -152,6 +154,7 @@ const CodeEditor = (props) => {
|
|||||||
const [anchorEl3, setAnchorEl3] = React.useState(null);
|
const [anchorEl3, setAnchorEl3] = React.useState(null);
|
||||||
const [mainVariables, setMainVariables] = React.useState([]);
|
const [mainVariables, setMainVariables] = React.useState([]);
|
||||||
const [availableVariables, setAvailableVariables] = React.useState([]);
|
const [availableVariables, setAvailableVariables] = React.useState([]);
|
||||||
|
const [sourceDataOpen, setSourceDataOpen] = React.useState(false);
|
||||||
|
|
||||||
const [codeTheme, setcodeTheme] = React.useState("gruvbox-dark");
|
const [codeTheme, setcodeTheme] = React.useState("gruvbox-dark");
|
||||||
|
|
||||||
@@ -1150,20 +1153,23 @@ const CodeEditor = (props) => {
|
|||||||
// Define a custom completer for the Ace Editor
|
// Define a custom completer for the Ace Editor
|
||||||
const customCompleter = {
|
const customCompleter = {
|
||||||
getCompletions: function(editor, session, pos, prefix, callback) {
|
getCompletions: function(editor, session, pos, prefix, callback) {
|
||||||
console.log("CUSTOM COMPLETER: ", prefix)
|
|
||||||
|
|
||||||
callback(null, availableVariables.map((variable) => {
|
callback(null, availableVariables.map((variable) => {
|
||||||
console.log("CUSTOM VAR: ", variable)
|
//console.log("CUSTOM VAR: ", variable)
|
||||||
|
|
||||||
return ({
|
return ({
|
||||||
caption: variable,
|
caption: variable,
|
||||||
value: variable,
|
value: variable,
|
||||||
meta: 'custom',
|
meta: 'var',
|
||||||
})
|
})
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const editorLoad = (editor) => {
|
||||||
|
console.log("EDITOR: ", editor)
|
||||||
|
editor.completers = [customCompleter]
|
||||||
|
}
|
||||||
|
|
||||||
if (fullScreenMode) {
|
if (fullScreenMode) {
|
||||||
return (
|
return (
|
||||||
<AceEditor
|
<AceEditor
|
||||||
@@ -1187,7 +1193,6 @@ const CodeEditor = (props) => {
|
|||||||
highlightActiveLine={false}
|
highlightActiveLine={false}
|
||||||
|
|
||||||
enableBasicAutocompletion={true}
|
enableBasicAutocompletion={true}
|
||||||
completers={[customCompleter]}
|
|
||||||
|
|
||||||
style={{
|
style={{
|
||||||
wordBreak: "break-word",
|
wordBreak: "break-word",
|
||||||
@@ -1212,12 +1217,146 @@ const CodeEditor = (props) => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const ValueBox = (props) => {
|
||||||
|
const { name, value } = props
|
||||||
|
|
||||||
|
const [dragging, setDragging] = React.useState(false)
|
||||||
|
const [hovering, setHovering] = React.useState(false)
|
||||||
|
|
||||||
|
if (name === undefined || name === null || name.length === 0) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value === undefined || value === null || value.length === 0) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Draggable
|
||||||
|
style={{
|
||||||
|
position: "absolute",
|
||||||
|
zIndex: 15000,
|
||||||
|
}}
|
||||||
|
onDrag={(e) => {
|
||||||
|
e.preventDefault()
|
||||||
|
// Check if inside div.ace_content
|
||||||
|
if (e.srcElement.className === "ace_content") {
|
||||||
|
// Input on the correct line. Each line is:
|
||||||
|
// Show some tooltip at mouse cursor that shows "Insert Action"
|
||||||
|
|
||||||
|
// Append the text to the DOM
|
||||||
|
} else {
|
||||||
|
//console.log("PAGEX: ", e.pageX, e.pageY)
|
||||||
|
//console.log("OffsetX: ", e.offsetX, e.offsetY)
|
||||||
|
//console.log("E: ", e)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dragging) {
|
||||||
|
setDragging(true)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onStop={(e) => {
|
||||||
|
if (e.srcElement.className === "ace_content") {
|
||||||
|
console.log("DRAG STOP IN CONTENT!", e.srcElement.className)
|
||||||
|
|
||||||
|
const usedposition = e.offsetY
|
||||||
|
if (usedposition === undefined || usedposition === null) {
|
||||||
|
toast.info("Error: LayerY is undefined or null. Please contact support@shuffler.io")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (usedposition === 0) {
|
||||||
|
usedposition = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
const lineheight = 15
|
||||||
|
const codedatasplit = localcodedata.split('\n')
|
||||||
|
if (codedatasplit === undefined || codedatasplit === null || codedatasplit.length === 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int
|
||||||
|
const lineposition = parseInt(usedposition/lineheight)
|
||||||
|
|
||||||
|
// Find the correct line
|
||||||
|
if (lineposition > codedatasplit.length) {
|
||||||
|
codedatasplit[codedatasplit.length-1] += value
|
||||||
|
} else {
|
||||||
|
codedatasplit[lineposition] += value
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//e.srcElement.layerY
|
||||||
|
setlocalcodedata(codedatasplit.join('\n'))
|
||||||
|
}
|
||||||
|
|
||||||
|
setDragging(false)
|
||||||
|
}}
|
||||||
|
dragging={dragging}
|
||||||
|
position={{
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
}}
|
||||||
|
onMouseHover={() => {
|
||||||
|
setHovering(true)
|
||||||
|
}}
|
||||||
|
onMouseLeave={() => {
|
||||||
|
setHovering(false)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
cursor: dragging ? "grabbing" : "grab",
|
||||||
|
minWidth: 100,
|
||||||
|
border: "1px solid rgba(255,255,255,0.5)",
|
||||||
|
borderRadius: theme.palette.borderRadius/2,
|
||||||
|
marginRight: 10,
|
||||||
|
padding: 5,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{value}
|
||||||
|
</div>
|
||||||
|
</Draggable>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const SourceDataOption = (option) => {
|
||||||
|
const { innerdata, parsedPaths, defaultExpanded } = option
|
||||||
|
|
||||||
|
const [expanded, setExpanded] = React.useState(defaultExpanded === true ? true : false)
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{minHeight: 40, marginTop: 10, }}>
|
||||||
|
<div style={{
|
||||||
|
cursor: "pointer",
|
||||||
|
display: "flex",
|
||||||
|
position: "relative",
|
||||||
|
}} onClick={() => {
|
||||||
|
setExpanded(!expanded)
|
||||||
|
}}>
|
||||||
|
<ValueBox name={innerdata?.name} value={innerdata?.value} />
|
||||||
|
<Typography style={{marginTop: 5, maxWidth: 150, maxHeight: 40, overflow: "hidden", }}>
|
||||||
|
{innerdata?.name}
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
<Collapse in={expanded}>
|
||||||
|
HELO
|
||||||
|
</Collapse>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
aria-labelledby="draggable-dialog-title"
|
aria-labelledby="draggable-dialog-title"
|
||||||
// disableBackdropClick={true}
|
// disableBackdropClick={true}
|
||||||
disableEnforceFocus={true}
|
disableEnforceFocus={true}
|
||||||
style={{ pointerEvents: "none", zIndex: activeDialog === "codeeditor" ? 1200 : 1100 }}
|
style={{
|
||||||
|
pointerEvents: "none",
|
||||||
|
zIndex: activeDialog === "codeeditor" ? 1200 : 1100,
|
||||||
|
}}
|
||||||
hideBackdrop={true}
|
hideBackdrop={true}
|
||||||
open={expansionModalOpen}
|
open={expansionModalOpen}
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
@@ -1248,7 +1387,6 @@ const CodeEditor = (props) => {
|
|||||||
maxHeight: isMobile ? "100%" : 700,
|
maxHeight: isMobile ? "100%" : 700,
|
||||||
border: "3px solid rgba(255,255,255,0.3)",
|
border: "3px solid rgba(255,255,255,0.3)",
|
||||||
padding: isMobile ? "25px 10px 25px 10px" : 25,
|
padding: isMobile ? "25px 10px 25px 10px" : 25,
|
||||||
// zoom: 0.8,
|
|
||||||
backgroundColor: "black",
|
backgroundColor: "black",
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
@@ -1308,7 +1446,92 @@ const CodeEditor = (props) => {
|
|||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<div style={{ display: "flex" }}>
|
<div style={{ display: "flex" }}>
|
||||||
<div style={{ flex: 1, }}>
|
{sourceDataOpen ?
|
||||||
|
<div style={{ minWidth: 350, maxWidth: 350, marginLeft: 5, borderRight: "1px solid rgba(255,255,255,0.3)", paddingLeft: 5, overflow: "hidden", marginRight: 10, }}>
|
||||||
|
<Typography variant="h6">
|
||||||
|
Source Data
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body2" color="textSecondary">
|
||||||
|
Drag the data you want into the text editor
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
{actionlist?.map((innerdata) => {
|
||||||
|
const icon =
|
||||||
|
innerdata.type === "action" ? (
|
||||||
|
<AppsIcon style={{ marginRight: 10 }} />
|
||||||
|
) : innerdata.type === "workflow_variable" ||
|
||||||
|
innerdata.type === "execution_variable" ? (
|
||||||
|
<FavoriteBorderIcon style={{ marginRight: 10 }} />
|
||||||
|
) : (
|
||||||
|
<ScheduleIcon style={{ marginRight: 10 }} />
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleExecArgumentHover = (inside) => {
|
||||||
|
var exec_text_field = document.getElementById(
|
||||||
|
"execution_argument_input_field"
|
||||||
|
);
|
||||||
|
if (exec_text_field !== null) {
|
||||||
|
if (inside) {
|
||||||
|
exec_text_field.style.border = "2px solid #f85a3e";
|
||||||
|
} else {
|
||||||
|
exec_text_field.style.border = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleActionHover = (inside, actionId) => {
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMouseover = () => {
|
||||||
|
if (innerdata.type === "Execution Argument") {
|
||||||
|
handleExecArgumentHover(true);
|
||||||
|
} else if (innerdata.type === "action") {
|
||||||
|
handleActionHover(true, innerdata.id);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMouseOut = () => {
|
||||||
|
if (innerdata.type === "Execution Argument") {
|
||||||
|
handleExecArgumentHover(false);
|
||||||
|
} else if (innerdata.type === "action") {
|
||||||
|
handleActionHover(false, innerdata.id);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var parsedPaths = [];
|
||||||
|
if (innerdata.type === "workflow_variable") {
|
||||||
|
// Try to parse the value if it's a string that could be JSON
|
||||||
|
if (typeof innerdata.value === "string") {
|
||||||
|
try {
|
||||||
|
const parsedValue = JSON.parse(innerdata.value)
|
||||||
|
if (typeof parsedValue === "object") {
|
||||||
|
parsedPaths = GetParsedPaths(parsedValue, "");
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// Not valid JSON, use the value directly
|
||||||
|
parsedPaths = GetParsedPaths(innerdata.value, "");
|
||||||
|
}
|
||||||
|
} else if (typeof innerdata.value === "object") {
|
||||||
|
parsedPaths = GetParsedPaths(innerdata.value, "");
|
||||||
|
}
|
||||||
|
} else if (typeof innerdata.example === "object") {
|
||||||
|
parsedPaths = GetParsedPaths(innerdata.example, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
const coverColor = "#82ccc3"
|
||||||
|
|
||||||
|
if (innerdata?.name === "Execution Argument") {
|
||||||
|
innerdata.name = "Runtime Argument"
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SourceDataOption innerdata={innerdata} parsedPaths={parsedPaths} />
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
: null}
|
||||||
|
|
||||||
|
<div style={{ flex: 3, }}>
|
||||||
{isFileEditor ?
|
{isFileEditor ?
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
@@ -1348,6 +1571,26 @@ const CodeEditor = (props) => {
|
|||||||
{isFileEditor ? null :
|
{isFileEditor ? null :
|
||||||
<div style={{ display: "flex", maxHeight: 40, }}>
|
<div style={{ display: "flex", maxHeight: 40, }}>
|
||||||
<ButtonGroup style={{ borderRadius: theme.palette.borderRadius, }}>
|
<ButtonGroup style={{ borderRadius: theme.palette.borderRadius, }}>
|
||||||
|
{/*
|
||||||
|
<Button
|
||||||
|
id="basic-button"
|
||||||
|
aria-haspopup="true"
|
||||||
|
aria-controls={!!menuPosition ? 'basic-menu' : undefined}
|
||||||
|
aria-expanded={!!menuPosition ? 'true' : undefined}
|
||||||
|
variant={!sourceDataOpen ? "contained" : "outlined"}
|
||||||
|
color="secondary"
|
||||||
|
style={{
|
||||||
|
textTransform: "none",
|
||||||
|
width: 175,
|
||||||
|
}}
|
||||||
|
onClick={(event) => {
|
||||||
|
setSourceDataOpen(!sourceDataOpen)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<AddIcon /> Show Source Data
|
||||||
|
</Button>
|
||||||
|
*/}
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
id="basic-button"
|
id="basic-button"
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
@@ -1401,6 +1644,26 @@ const CodeEditor = (props) => {
|
|||||||
>
|
>
|
||||||
Python Code
|
Python Code
|
||||||
</Button>
|
</Button>
|
||||||
|
<Button
|
||||||
|
id="basic-button"
|
||||||
|
aria-haspopup="true"
|
||||||
|
aria-controls={!!menuPosition ? 'basic-menu' : undefined}
|
||||||
|
aria-expanded={!!menuPosition ? 'true' : undefined}
|
||||||
|
variant={"outlined"}
|
||||||
|
color="secondary"
|
||||||
|
style={{
|
||||||
|
textTransform: "none",
|
||||||
|
width: 130,
|
||||||
|
}}
|
||||||
|
onClick={(event) => {
|
||||||
|
setMenuPosition({
|
||||||
|
top: event.pageY,
|
||||||
|
left: event.pageX,
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<AddIcon /> Autocomplete
|
||||||
|
</Button>
|
||||||
<Menu
|
<Menu
|
||||||
id="basic-menu"
|
id="basic-menu"
|
||||||
anchorEl={anchorEl3}
|
anchorEl={anchorEl3}
|
||||||
@@ -1431,26 +1694,6 @@ const CodeEditor = (props) => {
|
|||||||
})}
|
})}
|
||||||
</Menu>
|
</Menu>
|
||||||
|
|
||||||
<Button
|
|
||||||
id="basic-button"
|
|
||||||
aria-haspopup="true"
|
|
||||||
aria-controls={!!menuPosition ? 'basic-menu' : undefined}
|
|
||||||
aria-expanded={!!menuPosition ? 'true' : undefined}
|
|
||||||
variant="outlined"
|
|
||||||
color="secondary"
|
|
||||||
style={{
|
|
||||||
textTransform: "none",
|
|
||||||
width: 130,
|
|
||||||
}}
|
|
||||||
onClick={(event) => {
|
|
||||||
setMenuPosition({
|
|
||||||
top: event.pageY,
|
|
||||||
left: event.pageX,
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<AddIcon /> Autocomplete
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
<Menu
|
<Menu
|
||||||
anchorReference="anchorPosition"
|
anchorReference="anchorPosition"
|
||||||
@@ -1774,13 +2017,19 @@ const CodeEditor = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
<div style={{
|
<div
|
||||||
borderRadius: theme.palette?.borderRadius,
|
style={{
|
||||||
position: "relative",
|
borderRadius: theme.palette?.borderRadius,
|
||||||
paddingTop: 0,
|
position: "relative",
|
||||||
// minHeight: 548,
|
paddingTop: 0,
|
||||||
// overflow: "hidden",
|
}}
|
||||||
}}>
|
onDragOver={(e) => {
|
||||||
|
console.log("DRAGGING OVER: ", e)
|
||||||
|
}}
|
||||||
|
onDrop={(e) => {
|
||||||
|
console.log("DROP: ", e)
|
||||||
|
}}
|
||||||
|
>
|
||||||
{(availableVariables !== undefined && availableVariables !== null && availableVariables.length > 0) || isFileEditor ? (
|
{(availableVariables !== undefined && availableVariables !== null && availableVariables.length > 0) || isFileEditor ? (
|
||||||
<AceEditor
|
<AceEditor
|
||||||
id="shuffle-codeeditor"
|
id="shuffle-codeeditor"
|
||||||
@@ -1806,9 +2055,12 @@ const CodeEditor = (props) => {
|
|||||||
wordWrap: "break-word",
|
wordWrap: "break-word",
|
||||||
backgroundColor: "rgba(40,40,40,1)",
|
backgroundColor: "rgba(40,40,40,1)",
|
||||||
zIndex: activeDialog === "codeeditor" ? 1200 : 1100,
|
zIndex: activeDialog === "codeeditor" ? 1200 : 1100,
|
||||||
|
|
||||||
|
|
||||||
}}
|
}}
|
||||||
onLoad={(editor) => {
|
onLoad={(editor) => {
|
||||||
highlight_variables(localcodedata)
|
highlight_variables(localcodedata)
|
||||||
|
editorLoad(editor)
|
||||||
}}
|
}}
|
||||||
onCursorChange={(cursorPosition, editor, value) => {
|
onCursorChange={(cursorPosition, editor, value) => {
|
||||||
setCurrentCharacter(cursorPosition.cursor.column)
|
setCurrentCharacter(cursorPosition.cursor.column)
|
||||||
@@ -1847,8 +2099,15 @@ const CodeEditor = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{isFileEditor ? null :
|
{isFileEditor ? null :
|
||||||
<div style={{ flex: 1, marginLeft: 5, borderLeft: "1px solid rgba(255,255,255,0.3)", paddingLeft: 5, overflow: "hidden", }}>
|
<div style={{
|
||||||
|
flex: sourceDataOpen ? 1.5 : 3,
|
||||||
|
marginLeft: 5,
|
||||||
|
borderLeft: "1px solid rgba(255,255,255,0.3)",
|
||||||
|
paddingLeft: 5,
|
||||||
|
overflow: "hidden",
|
||||||
|
transitions: "all 1s ease-in-out",
|
||||||
|
}}>
|
||||||
<div>
|
<div>
|
||||||
{isMobile ? null :
|
{isMobile ? null :
|
||||||
<DialogTitle
|
<DialogTitle
|
||||||
@@ -1861,7 +2120,7 @@ const CodeEditor = (props) => {
|
|||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<span style={{ color: "white" }}>
|
<span style={{ color: "white" }}>
|
||||||
{selectedAction === undefined ? "" : selectedAction.name === "execute_python" || selectedAction.name === "execute_bash" ? "Code to run" : `Expected Output'`}
|
{selectedAction === undefined ? "" : selectedAction.name === "execute_python" || selectedAction.name === "execute_bash" ? "Code to run" : `Output`}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -95,6 +95,10 @@ const ApiExplorerWrapper = (props) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (openapi?.id === "HTTP") {
|
||||||
|
selectedAppData.name = "HTTP"
|
||||||
|
}
|
||||||
|
|
||||||
if (selectedAppData !== undefined && selectedAppData !== null && Object.getOwnPropertyNames(selectedAppData).length > 0) {
|
if (selectedAppData !== undefined && selectedAppData !== null && Object.getOwnPropertyNames(selectedAppData).length > 0) {
|
||||||
HandleAppAuthentication(selectedAppData?.name)
|
HandleAppAuthentication(selectedAppData?.name)
|
||||||
}
|
}
|
||||||
@@ -136,7 +140,10 @@ const ApiExplorerWrapper = (props) => {
|
|||||||
const runAlgoliaAppSearch = (appname) => {
|
const runAlgoliaAppSearch = (appname) => {
|
||||||
const index = searchClient.initIndex("appsearch");
|
const index = searchClient.initIndex("appsearch");
|
||||||
|
|
||||||
console.log("Running appsearch for: ", appname);
|
if (appname === "HTTP" || appname === "http") {
|
||||||
|
navigate("/apis")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
index
|
index
|
||||||
.search(appname)
|
.search(appname)
|
||||||
@@ -151,6 +158,7 @@ const ApiExplorerWrapper = (props) => {
|
|||||||
|
|
||||||
if (newname?.includes(appsearchname)) {
|
if (newname?.includes(appsearchname)) {
|
||||||
found = true
|
found = true
|
||||||
|
|
||||||
getAppData(hit.objectID)
|
getAppData(hit.objectID)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -160,6 +168,7 @@ const ApiExplorerWrapper = (props) => {
|
|||||||
toast.error(`Failed to get API data for '${appname}' (1). Contact support@shuffler.io if this persists.`, {
|
toast.error(`Failed to get API data for '${appname}' (1). Contact support@shuffler.io if this persists.`, {
|
||||||
"autoClose": 10000,
|
"autoClose": 10000,
|
||||||
})
|
})
|
||||||
|
|
||||||
setTimeout(()=>{
|
setTimeout(()=>{
|
||||||
navigate("/search?tab=apps");
|
navigate("/search?tab=apps");
|
||||||
},3000)
|
},3000)
|
||||||
@@ -181,11 +190,29 @@ const ApiExplorerWrapper = (props) => {
|
|||||||
// Fetch data when appid is available
|
// Fetch data when appid is available
|
||||||
const getAppData = useCallback((appid) => {
|
const getAppData = useCallback((appid) => {
|
||||||
if (appid === undefined || appid === null || appid.length === 0) {
|
if (appid === undefined || appid === null || appid.length === 0) {
|
||||||
toast.error("No API data to load (4). Please contact support@shuffler.io if this persists.")
|
toast.warning("No app ID loaded. Showing default API testing window. ")
|
||||||
|
setOpenapi({
|
||||||
|
"id": "HTTP",
|
||||||
|
"servers": [
|
||||||
|
{"url": "https://shuffler.io"},
|
||||||
|
],
|
||||||
|
"info": {
|
||||||
|
"title": "HTTP",
|
||||||
|
"x-logo": theme.palette?.defaultImage,
|
||||||
|
},
|
||||||
|
"paths": {
|
||||||
|
"/api/v1/workflows/usecases": {
|
||||||
|
"get": {
|
||||||
|
"summary": "Custom Action",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
setAppLoaded(true)
|
||||||
|
|
||||||
setTimeout(() => {
|
//setTimeout(() => {
|
||||||
navigate("/search?tab=apps")
|
// navigate("/search?tab=apps")
|
||||||
}, 3000)
|
//}, 3000)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -413,6 +440,13 @@ const ApiExplorerWrapper = (props) => {
|
|||||||
selectedAppData.name = appname
|
selectedAppData.name = appname
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log("APPNAME: ", appname, openapi.id)
|
||||||
|
if (openapi?.id === "HTTP" || appname === "HTTP" || appname === "http") {
|
||||||
|
setAppAuthentication(data)
|
||||||
|
setSelectedAuthentication({})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const filteredData = data.filter((appAuth) => appAuth?.app?.id === appid || appAuth?.app?.name?.replaceAll(" ", "_").toLowerCase() === selectedAppData?.name?.replaceAll(" ", "_").toLowerCase());
|
const filteredData = data.filter((appAuth) => appAuth?.app?.id === appid || appAuth?.app?.name?.replaceAll(" ", "_").toLowerCase() === selectedAppData?.name?.replaceAll(" ", "_").toLowerCase());
|
||||||
if (filteredData.length === 0) {
|
if (filteredData.length === 0) {
|
||||||
setAppAuthentication([])
|
setAppAuthentication([])
|
||||||
@@ -505,7 +539,7 @@ const ApiExplorerWrapper = (props) => {
|
|||||||
}else if (openapi?.id?.length > 0) {
|
}else if (openapi?.id?.length > 0) {
|
||||||
appid = openapi?.id;
|
appid = openapi?.id;
|
||||||
}else{
|
}else{
|
||||||
toast.error("App id is missing. Please try again.");
|
toast.error("App id is missing and we can't run the API. Please contact support@shuffler.io if this persists.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -692,6 +726,7 @@ const ApiExplorerWrapper = (props) => {
|
|||||||
'& .MuiList-root': {
|
'& .MuiList-root': {
|
||||||
backgroundColor: "#1f1f1f",
|
backgroundColor: "#1f1f1f",
|
||||||
},
|
},
|
||||||
|
maxWidth: 500,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
@@ -723,6 +758,7 @@ const ApiExplorerWrapper = (props) => {
|
|||||||
No Selection
|
No Selection
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<Divider />
|
<Divider />
|
||||||
|
|
||||||
{appAuthentication?.length > 0 ? appAuthentication.map((appAuth) => (
|
{appAuthentication?.length > 0 ? appAuthentication.map((appAuth) => (
|
||||||
<div
|
<div
|
||||||
key={appAuth?.id}
|
key={appAuth?.id}
|
||||||
@@ -732,13 +768,13 @@ const ApiExplorerWrapper = (props) => {
|
|||||||
backgroundColor: '#1f1f1f',
|
backgroundColor: '#1f1f1f',
|
||||||
color: 'white',
|
color: 'white',
|
||||||
padding: '5px',
|
padding: '5px',
|
||||||
|
textAlign: "left",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
value={appAuth?.id}
|
value={appAuth?.id}
|
||||||
sx={{
|
sx={{
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
justifyContent: 'space-between',
|
|
||||||
color: 'white',
|
color: 'white',
|
||||||
}}
|
}}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
@@ -746,6 +782,11 @@ const ApiExplorerWrapper = (props) => {
|
|||||||
setAuthenticationName(appAuth.app?.name)
|
setAuthenticationName(appAuth.app?.name)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
{appAuth?.app?.large_image !== undefined && appAuth?.app?.large_image !== null && appAuth?.app?.large_image.length > 0 ?
|
||||||
|
<Tooltip title={appAuth?.app?.name} placement="top">
|
||||||
|
<img src={appAuth?.app?.large_image} alt={appAuth?.app?.name} style={{ maxWidth: 20, maxHeight: 20, marginRight: 10, borderRadius: 5 }} />
|
||||||
|
</Tooltip>
|
||||||
|
: null}
|
||||||
{appAuth?.validation?.valid === true ?
|
{appAuth?.validation?.valid === true ?
|
||||||
<Tooltip title="Validated" placement="top">
|
<Tooltip title="Validated" placement="top">
|
||||||
<CheckCircleIcon style={{ color: green, marginRight: 10, }} />
|
<CheckCircleIcon style={{ color: green, marginRight: 10, }} />
|
||||||
@@ -1645,7 +1686,9 @@ const ApiExplorerWrapper = (props) => {
|
|||||||
>
|
>
|
||||||
<div style={{display: "flex", }}>
|
<div style={{display: "flex", }}>
|
||||||
<div style={{width: 600, margin: "auto", display: "flex", }}>
|
<div style={{width: 600, margin: "auto", display: "flex", }}>
|
||||||
{isLoggedIn === true ?
|
{openapi?.id === "HTTP" ?
|
||||||
|
null
|
||||||
|
: isLoggedIn === true ?
|
||||||
<Button
|
<Button
|
||||||
variant={authHighlighted ? "contained" : "outlined"}
|
variant={authHighlighted ? "contained" : "outlined"}
|
||||||
style={{
|
style={{
|
||||||
@@ -1681,17 +1724,20 @@ const ApiExplorerWrapper = (props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{appAuthentication?.length > 0 ?
|
{appAuthentication?.length > 0 ?
|
||||||
<div style={{display: "flex", flex: 2, }}>
|
<div style={{display: "flex", flex: 2, textAlign: "center", }}>
|
||||||
<Typography style={{textAlign: "center", flex: 1, color: "white", marginTop: 15, }} variant="body1">
|
{openapi?.id === "HTTP" ? null :
|
||||||
or use
|
<Typography style={{textAlign: "center", flex: 1, color: "white", marginTop: 15, }} variant="body1">
|
||||||
</Typography>
|
or use
|
||||||
|
</Typography>
|
||||||
|
}
|
||||||
|
|
||||||
<div style={{
|
<div style={{
|
||||||
flex: 1,
|
flex: 1,
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
marginLeft: 'auto',
|
margin: 'auto',
|
||||||
|
maxWidth: 200,
|
||||||
}}>
|
}}>
|
||||||
<AuthenticationList />
|
<AuthenticationList />
|
||||||
</div>
|
</div>
|
||||||
@@ -1804,7 +1850,7 @@ const Wrapper = ({children, isLoaded,isLoggedIn})=>{
|
|||||||
|
|
||||||
return(
|
return(
|
||||||
|
|
||||||
<div className="api-explorer-wrapper" style={{ zoom: 0.8, paddingLeft: (isLoggedIn && isLoaded) ? leftSideBarOpenByClick ? 280 : 100 : 0, transition: 'padding-left 0.3s ease' }}>
|
<div className="api-explorer-wrapper" style={{ paddingLeft: (isLoggedIn && isLoaded) ? leftSideBarOpenByClick ? 280 : 100 : 0, transition: 'padding-left 0.3s ease' }}>
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -3167,6 +3167,12 @@ const AppCreator = (defaultprops) => {
|
|||||||
setOauth2Scopes(chips)
|
setOauth2Scopes(chips)
|
||||||
setUpdate(Math.random())
|
setUpdate(Math.random())
|
||||||
}}
|
}}
|
||||||
|
onBlur={(e) => {
|
||||||
|
var newchips = oauth2Scopes
|
||||||
|
newchips.push(e.target.value)
|
||||||
|
setOauth2Scopes(newchips)
|
||||||
|
setUpdate(Math.random())
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : null;
|
) : null;
|
||||||
|
|||||||
Reference in New Issue
Block a user