Many fixes for frontend and backend related to Oauth2 and environment control
This commit is contained in:
@@ -269,35 +269,8 @@ const EditWorkflow = (props) => {
|
||||
/>
|
||||
</div>
|
||||
<div style={{display: "flex", marginTop: 10, }}>
|
||||
<MuiChipsInput
|
||||
style={{ flex: 1, maxHeight: 40, }}
|
||||
InputProps={{
|
||||
style: {
|
||||
color: "white",
|
||||
},
|
||||
}}
|
||||
placeholder="Tags"
|
||||
color="primary"
|
||||
fullWidth
|
||||
value={newWorkflowTags}
|
||||
onChange={(chip) => {
|
||||
console.log("Chip: ", chip)
|
||||
//newWorkflowTags.push(chip);
|
||||
setNewWorkflowTags(chip);
|
||||
}}
|
||||
onAdd={(chip) => {
|
||||
newWorkflowTags.push(chip);
|
||||
setNewWorkflowTags(newWorkflowTags);
|
||||
}}
|
||||
onDelete={(chip, index) => {
|
||||
console.log("Deleting: ", chip, index)
|
||||
newWorkflowTags.splice(index, 1);
|
||||
setNewWorkflowTags(newWorkflowTags);
|
||||
setUpdate(Math.random());
|
||||
}}
|
||||
/>
|
||||
{usecases !== null && usecases !== undefined && usecases.length > 0 ?
|
||||
<FormControl style={{flex: 1, marginLeft: 5, }}>
|
||||
<FormControl style={{flex: 1, marginRight: 5,}}>
|
||||
<InputLabel htmlFor="grouped-select-usecase">Usecases</InputLabel>
|
||||
<Select
|
||||
defaultValue=""
|
||||
@@ -350,6 +323,33 @@ const EditWorkflow = (props) => {
|
||||
</Select>
|
||||
</FormControl>
|
||||
: null}
|
||||
<MuiChipsInput
|
||||
style={{ flex: 1, maxHeight: 120, overflow: "auto",}}
|
||||
InputProps={{
|
||||
style: {
|
||||
color: "white",
|
||||
},
|
||||
}}
|
||||
placeholder="Tags"
|
||||
color="primary"
|
||||
fullWidth
|
||||
value={newWorkflowTags}
|
||||
onChange={(chip) => {
|
||||
console.log("Chip: ", chip)
|
||||
//newWorkflowTags.push(chip);
|
||||
setNewWorkflowTags(chip);
|
||||
}}
|
||||
onAdd={(chip) => {
|
||||
newWorkflowTags.push(chip);
|
||||
setNewWorkflowTags(newWorkflowTags);
|
||||
}}
|
||||
onDelete={(chip, index) => {
|
||||
console.log("Deleting: ", chip, index)
|
||||
newWorkflowTags.splice(index, 1);
|
||||
setNewWorkflowTags(newWorkflowTags);
|
||||
setUpdate(Math.random());
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{showMoreClicked === true ?
|
||||
@@ -365,7 +365,8 @@ const EditWorkflow = (props) => {
|
||||
onChange={(e) => {
|
||||
console.log("Data: ", e.target.value)
|
||||
|
||||
innerWorkflow.workflow_type = e.target.value
|
||||
//innerWorkflow.workflow_type = e.target.value
|
||||
innerWorkflow.status = e.target.value
|
||||
setInnerWorkflow(innerWorkflow)
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -1352,14 +1352,17 @@ const Header = (props) => {
|
||||
);
|
||||
|
||||
// <Divider style={{height: "1px", width: "100%", backgroundColor: "rgb(91, 96, 100)"}}/>
|
||||
return !isMobile ?
|
||||
isLoggedIn ?
|
||||
//
|
||||
/*
|
||||
!isLoggedIn ?
|
||||
<div style={{minHeight: 68, maxHeight: 68, backgroundColor: theme.palette.backgroundColor, }}>
|
||||
<BrowserView style={{position: "sticky", top: 0, }}>
|
||||
{loginTextBrowser}
|
||||
</BrowserView>
|
||||
</div>
|
||||
:
|
||||
*/
|
||||
return !isMobile ?
|
||||
<AppBar
|
||||
position="sticky"
|
||||
color="transparent"
|
||||
|
||||
@@ -112,8 +112,6 @@ const AuthenticationOauth2 = (props) => {
|
||||
authenticationType.client_secret.length > 0
|
||||
);
|
||||
|
||||
console.log("AUTH: ", authenticationType)
|
||||
|
||||
const [clientId, setClientId] = React.useState(defaultConfigSet ? authenticationType.client_id : "");
|
||||
const [clientSecret, setClientSecret] = React.useState(defaultConfigSet ? authenticationType.client_secret : "");
|
||||
|
||||
@@ -125,7 +123,7 @@ const AuthenticationOauth2 = (props) => {
|
||||
const [offlineAccess, setOfflineAccess] = React.useState(true);
|
||||
|
||||
const allscopes = authenticationType.scope !== undefined && authenticationType.scope !== null ? authenticationType.scope : [];
|
||||
const [selectedScopes, setSelectedScopes] = React.useState(allscopes !== null && allscopes !== undefined ? allscopes.length > 0 && allscopes.length <= 3 ? [allscopes[0]] : [] : [])
|
||||
const [selectedScopes, setSelectedScopes] = React.useState(allscopes !== null && allscopes !== undefined ? allscopes.length > 0 && allscopes.length <= 3 ? allscopes : [] : [])
|
||||
|
||||
const [manuallyConfigure, setManuallyConfigure] = React.useState(
|
||||
defaultConfigSet ? false : true
|
||||
@@ -303,6 +301,23 @@ const AuthenticationOauth2 = (props) => {
|
||||
if ((authenticationType.redirect_uri === undefined || authenticationType.redirect_uri === null || authenticationType.redirect_uri.length === 0) && (authenticationType.token_uri !== undefined && authenticationType.token_uri !== null && authenticationType.token_uri.length > 0)) {
|
||||
console.log("No redirect URI found, and token URI found. Assuming client credentials flow and saving directly in the database")
|
||||
|
||||
|
||||
var tokenUri = authenticationType.token_uri;
|
||||
if (oauthUrl !== undefined && oauthUrl !== null && oauthUrl.length > 0 && selectedApp !== undefined && selectedApp !== null) {
|
||||
var same = false
|
||||
for (var i = 0; i < selectedApp.authentication.parameters.length; i++) {
|
||||
const param = selectedApp.authentication.parameters[i];
|
||||
if (param.name === "url" && (param.value === oauthUrl || param.example === oauthUrl)) {
|
||||
same = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (!same) {
|
||||
tokenUri = oauthUrl
|
||||
}
|
||||
}
|
||||
|
||||
// Find app.configuration=true fields in the app.paramters
|
||||
var parsedFields = [{
|
||||
"key": "client_id",
|
||||
@@ -318,7 +333,7 @@ const AuthenticationOauth2 = (props) => {
|
||||
},
|
||||
{
|
||||
"key": "token_uri",
|
||||
"value": authenticationType.token_uri,
|
||||
"value": tokenUri,
|
||||
}]
|
||||
|
||||
if (authenticationType.grant_type !== undefined && authenticationType.grant_type !== null && authenticationType.grant_type.length > 0) {
|
||||
@@ -360,14 +375,14 @@ const AuthenticationOauth2 = (props) => {
|
||||
"reference_workflow": workflowId,
|
||||
}
|
||||
|
||||
setNewAppAuth(appAuthData)
|
||||
setNewAppAuth(appAuthData, true)
|
||||
|
||||
// Wait 1 second, then get app auth with update
|
||||
//
|
||||
if (getAppAuthentication !== undefined) {
|
||||
setTimeout(() => {
|
||||
getAppAuthentication(true, true, true);
|
||||
}, 1000)
|
||||
}
|
||||
//if (getAppAuthentication !== undefined) {
|
||||
// setTimeout(() => {
|
||||
// getAppAuthentication(true, true, true);
|
||||
// }, 1000)
|
||||
//}
|
||||
|
||||
return
|
||||
}
|
||||
@@ -397,8 +412,6 @@ const AuthenticationOauth2 = (props) => {
|
||||
}
|
||||
|
||||
const authentication_url = authenticationType.token_uri;
|
||||
//console.log("AUTH: ", authenticationType)
|
||||
//console.log("SCOPES2: ", resources)
|
||||
const redirectUri = `${window.location.protocol}//${window.location.host}/set_authentication`;
|
||||
const workflowId = workflow !== undefined ? workflow.id : "";
|
||||
var state = `workflow_id%3D${workflowId}%26reference_action_id%3d${selectedAction.app_id}%26app_name%3d${selectedAction.app_name}%26app_id%3d${selectedAction.app_id}%26app_version%3d${selectedAction.app_version}%26authentication_url%3d${authentication_url}%26scope%3d${resources}%26client_id%3d${client_id}%26client_secret%3d${client_secret}`;
|
||||
@@ -523,7 +536,6 @@ const AuthenticationOauth2 = (props) => {
|
||||
}
|
||||
|
||||
const handleSubmitCheck = () => {
|
||||
console.log("NEW AUTH: ", authenticationOption);
|
||||
if (authenticationOption.label.length === 0) {
|
||||
authenticationOption.label = `Auth for ${selectedApp.name}`;
|
||||
//toast("Label can't be empty")
|
||||
@@ -673,7 +685,7 @@ const AuthenticationOauth2 = (props) => {
|
||||
)}
|
||||
</Button>
|
||||
|
||||
if (authButtonOnly === true && (authenticationType.grant_type === undefined || authenticationType.grant_type === null || authenticationType.grant_type === "")) {
|
||||
if (authButtonOnly === true && (authenticationType.redirect_uri !== undefined && authenticationType.redirect_uri !== null && authenticationType.redirect_uri.length > 0) && (authenticationType.token_uri !== undefined && authenticationType.token_uri !== null && authenticationType.token_uri.length > 0)) {
|
||||
return autoAuthButton
|
||||
}
|
||||
|
||||
@@ -777,10 +789,14 @@ const AuthenticationOauth2 = (props) => {
|
||||
setOauthUrl(data.value);
|
||||
}
|
||||
|
||||
const defaultValue = data.name === "url" && authenticationType.token_uri !== undefined && authenticationType.token_uri !== null && authenticationType.token_uri.length > 0 && (authenticationType.authorizationUrl === undefined || authenticationType.authorizationUrl === null || authenticationType.authorizationUrl.length === 0) ? authenticationType.token_uri : data.value === undefined || data.value === null ? "" : data.value
|
||||
const fieldname = data.name === "url" && authenticationType.grant_type !== undefined && authenticationType.grant_type !== null && authenticationType.grant_type.length > 0 ? "Token URL" : data.name
|
||||
|
||||
return (
|
||||
<div key={index} style={{ marginTop: 10 }}>
|
||||
<LockOpenIcon style={{ marginRight: 10 }} />
|
||||
<b>{data.name}</b>
|
||||
|
||||
<b>{fieldname}</b>
|
||||
|
||||
{data.schema !== undefined &&
|
||||
data.schema !== null &&
|
||||
@@ -793,6 +809,7 @@ const AuthenticationOauth2 = (props) => {
|
||||
}}
|
||||
defaultValue={"false"}
|
||||
fullWidth
|
||||
label={fieldname}
|
||||
onChange={(e) => {
|
||||
console.log("Value: ", e.target.value);
|
||||
authenticationOption.fields[data.name] = e.target.value;
|
||||
@@ -842,16 +859,11 @@ const AuthenticationOauth2 = (props) => {
|
||||
: "text"
|
||||
}
|
||||
color="primary"
|
||||
defaultValue={
|
||||
data.value !== undefined && data.value !== null
|
||||
? data.value
|
||||
: ""
|
||||
}
|
||||
defaultValue={defaultValue}
|
||||
placeholder={data.example}
|
||||
onChange={(event) => {
|
||||
authenticationOption.fields[data.name] =
|
||||
event.target.value;
|
||||
console.log("Setting oauth url");
|
||||
authenticationOption.fields[data.name] = event.target.value;
|
||||
console.log("Setting oauth url: ", event.target.value);
|
||||
setOauthUrl(event.target.value);
|
||||
//const [oauthUrl, setOauthUrl] = React.useState("")
|
||||
}}
|
||||
|
||||
@@ -181,6 +181,8 @@ const ParsedAction = (props) => {
|
||||
const [fieldCount, setFieldCount] = React.useState(0);
|
||||
const [hiddenDescription, setHiddenDescription] = React.useState(true);
|
||||
|
||||
const [autoCompleting, setAutocompleting] = React.useState(false);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (setLastSaved !== undefined) {
|
||||
@@ -2909,9 +2911,11 @@ const ParsedAction = (props) => {
|
||||
marginLeft: 15,
|
||||
paddingRight: 0,
|
||||
}}
|
||||
disabled={autoCompleting}
|
||||
onClick={() => {
|
||||
// aiSubmit(aiMsg, undefined, undefined, newSelectedAction)
|
||||
aiSubmit("Fill based on previous values", undefined, undefined, selectedAction)
|
||||
setAutocompleting(true)
|
||||
}}
|
||||
>
|
||||
<Tooltip
|
||||
@@ -2919,7 +2923,11 @@ const ParsedAction = (props) => {
|
||||
title={"Autocompletes fields. Uses NAME of the action and previous values' results."}
|
||||
placement="top"
|
||||
>
|
||||
{autoCompleting ?
|
||||
<CircularProgress style={{height: 20, width: 20, }} />
|
||||
:
|
||||
<AutoFixHighIcon style={{ color: "rgba(255,255,255,0.7)", height: 24, }} />
|
||||
}
|
||||
</Tooltip>
|
||||
</IconButton>
|
||||
</div>
|
||||
|
||||
@@ -315,16 +315,26 @@ const RuntimeDebugger = (props) => {
|
||||
)
|
||||
},
|
||||
},
|
||||
{ field: 'startTimestamp', headerName: 'Start time', width: 160, },
|
||||
{ field: 'endTimestamp', headerName: 'End time', width: 160, },
|
||||
{ field: 'startTimestamp', headerName: 'Start time (UTC)', width: 160, },
|
||||
{ field: 'endTimestamp', headerName: 'End time (UTC)', width: 160, },
|
||||
{
|
||||
field: 'id',
|
||||
headerName: 'Explore',
|
||||
width: 65,
|
||||
renderCell: (params) => (
|
||||
<Link href={`/workflows/${params.row.workflow.id}?execution_id=${params.row.id}`} target="_blank" rel="noopener noreferrer">
|
||||
<OpenInNewIcon fontSize="small" />
|
||||
</Link>
|
||||
<Tooltip arrow placement="right" title={
|
||||
<Typography variant="body2" style={{whiteSpace: "pre-line", }}>
|
||||
{params.row.result !== null && params.row.result !== undefined && params.row.result !== "" ?
|
||||
params.row.result
|
||||
:
|
||||
null
|
||||
}
|
||||
</Typography>
|
||||
} >
|
||||
<Link href={`/workflows/${params.row.workflow.id}?execution_id=${params.row.id}`} target="_blank" rel="noopener noreferrer">
|
||||
<OpenInNewIcon fontSize="small" />
|
||||
</Link>
|
||||
</Tooltip>
|
||||
),
|
||||
},
|
||||
]
|
||||
|
||||
@@ -22,6 +22,7 @@ import { isMobile } from "react-device-detect"
|
||||
import { NestedMenuItem } from "mui-nested-menu"
|
||||
import { GetParsedPaths, FindJsonPath } from "../views/Apps.jsx";
|
||||
import { SetJsonDotnotation } from "../views/AngularWorkflow.jsx";
|
||||
import { vscodeDark, vscodeDarkInit } from '@uiw/codemirror-theme-vscode';
|
||||
|
||||
import {
|
||||
FullscreenExit as FullscreenExitIcon,
|
||||
@@ -82,6 +83,7 @@ const pythonFilters = [
|
||||
{"name": "Handle JSON", "value": `{% python %}\nimport json\njsondata = json.loads(r"""$nodename""")\n{% endpython %}`, "example": ``},
|
||||
]
|
||||
|
||||
/*
|
||||
const shuffleTheme = createTheme({
|
||||
theme: 'dark',
|
||||
settings: {
|
||||
@@ -110,6 +112,7 @@ const shuffleTheme = createTheme({
|
||||
{ tag: t.attributeName, color: '#5c6166' },
|
||||
],
|
||||
});
|
||||
*/
|
||||
|
||||
const CodeEditor = (props) => {
|
||||
const {
|
||||
@@ -547,7 +550,7 @@ const CodeEditor = (props) => {
|
||||
var code_lines = localcodedata.split('\n')
|
||||
for (var i = 0; i < code_lines.length; i++){
|
||||
var current_code_line = code_lines[i]
|
||||
// console.log(current_code_line)
|
||||
console.log("Codeline: ", current_code_line)
|
||||
|
||||
var variable_occurence = current_code_line.match(/[\\]{0,1}[$]{1}([a-zA-Z0-9_-]+\.?){1}([a-zA-Z0-9#_-]+\.?){0,}/g)
|
||||
|
||||
@@ -609,9 +612,10 @@ const CodeEditor = (props) => {
|
||||
const fixedVariable = fixVariable(variable_occurence[occ])
|
||||
var correctVariable = availableVariables.includes(fixedVariable)
|
||||
if(!correctVariable) {
|
||||
console.log("Line: ", i, "ch: ", dollar_occurence[occ])
|
||||
|
||||
value.markText({line:i, ch:dollar_occurence[occ]}, {line:i, ch:dollar_occurence_len[occ]+dollar_occurence[occ]}, {"css": "background-color: rgb(248, 106, 62, 0.9); padding-top: 2px; padding-bottom: 2px; color: white"})
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
value.markText({line:i, ch:dollar_occurence[occ]}, {line:i, ch:dollar_occurence_len[occ]+dollar_occurence[occ]}, {"css": "background-color: #8b8e26; padding-top: 2px; padding-bottom: 2px; color: white"})
|
||||
}
|
||||
// console.log(correctVariables)
|
||||
@@ -674,36 +678,33 @@ const CodeEditor = (props) => {
|
||||
try {
|
||||
for (var i = 0; i < found.length; i++) {
|
||||
try {
|
||||
// For found specifically, should replace .#\d with .# with regex
|
||||
|
||||
|
||||
//found[i] = found[i].toLowerCase()
|
||||
const fixedVariable = fixVariable(found[i])
|
||||
//var correctVariable = availableVariables.includes(fixedVariable)
|
||||
|
||||
//
|
||||
var valuefound = false
|
||||
for (var j = 0; j < actionlist.length; j++) {
|
||||
if(fixedVariable.slice(1,).toLowerCase() === actionlist[j].autocomplete.toLowerCase()){
|
||||
valuefound = true
|
||||
if(fixedVariable.slice(1,).toLowerCase() !== actionlist[j].autocomplete.toLowerCase()){
|
||||
continue
|
||||
}
|
||||
|
||||
try {
|
||||
if (typeof actionlist[j].example === "object") {
|
||||
input = input.replace(found[i], JSON.stringify(actionlist[j].example), -1);
|
||||
valuefound = true
|
||||
|
||||
} else if (actionlist[j].example.trim().startsWith("{") || actionlist[j].example.trim().startsWith("[")) {
|
||||
input = input.replace(found[i], JSON.stringify(actionlist[j].example), -1);
|
||||
} else {
|
||||
input = input.replace(found[i], actionlist[j].example, -1)
|
||||
}
|
||||
} catch (e) {
|
||||
try {
|
||||
if (typeof actionlist[j].example === "object") {
|
||||
input = input.replace(found[i], JSON.stringify(actionlist[j].example), -1);
|
||||
|
||||
} else if (actionlist[j].example.trim().startsWith("{") || actionlist[j].example.trim().startsWith("[")) {
|
||||
input = input.replace(found[i], JSON.stringify(actionlist[j].example), -1);
|
||||
} else {
|
||||
input = input.replace(found[i], actionlist[j].example, -1)
|
||||
}
|
||||
} else {
|
||||
// Couldn't find the correct example value
|
||||
} catch (e) {
|
||||
input = input.replace(found[i], actionlist[j].example, -1)
|
||||
}
|
||||
}
|
||||
|
||||
//if (!valuefound) {
|
||||
// console.log("Couldn't find value "+fixedVariable)
|
||||
//}
|
||||
|
||||
if (!valuefound && availableVariables.includes(fixedVariable)) {
|
||||
var shouldbreak = false
|
||||
for (var k=0; k < actionlist.length; k++){
|
||||
@@ -714,46 +715,48 @@ const CodeEditor = (props) => {
|
||||
|
||||
for (var key in parsedPaths) {
|
||||
const fullpath = "$"+actionlist[k].autocomplete.toLowerCase()+parsedPaths[key].autocomplete
|
||||
if (fullpath === fixedVariable) {
|
||||
//if (actionlist[k].example === undefined) {
|
||||
// actionlist[k].example = "TMP"
|
||||
//}
|
||||
if (fullpath !== fixedVariable) {
|
||||
continue
|
||||
}
|
||||
|
||||
var new_input = ""
|
||||
try {
|
||||
new_input = FindJsonPath(fullpath, actionlist[k].example)
|
||||
} catch (e) {
|
||||
console.log("ERR IN INPUT: ", e)
|
||||
}
|
||||
//if (actionlist[k].example === undefined) {
|
||||
// actionlist[k].example = "TMP"
|
||||
//}
|
||||
|
||||
//console.log("Got output for: ", fullpath, new_input, actionlist[k].example, typeof new_input)
|
||||
var new_input = ""
|
||||
try {
|
||||
new_input = FindJsonPath(fullpath, actionlist[k].example)
|
||||
} catch (e) {
|
||||
console.log("ERR IN INPUT: ", e)
|
||||
}
|
||||
|
||||
if (typeof new_input === "object") {
|
||||
new_input = JSON.stringify(new_input)
|
||||
console.log("Got output for: ", fullpath, new_input, actionlist[k].example, typeof new_input)
|
||||
|
||||
if (typeof new_input === "object") {
|
||||
new_input = JSON.stringify(new_input)
|
||||
} else {
|
||||
if (typeof new_input === "string") {
|
||||
new_input = new_input
|
||||
} else {
|
||||
if (typeof new_input === "string") {
|
||||
new_input = new_input
|
||||
} else {
|
||||
console.log("NO TYPE? ", typeof new_input)
|
||||
try {
|
||||
new_input = new_input.toString()
|
||||
} catch (e) {
|
||||
new_input = ""
|
||||
}
|
||||
console.log("NO TYPE? ", typeof new_input)
|
||||
try {
|
||||
new_input = new_input.toString()
|
||||
} catch (e) {
|
||||
new_input = ""
|
||||
}
|
||||
}
|
||||
|
||||
//console.log("FOUND2: ", fixedVariable, actionlist[j].example)
|
||||
input = input.replace(fixedVariable, new_input, -1)
|
||||
input = input.replace(found[i], new_input, -1)
|
||||
|
||||
//} catch (e) {
|
||||
// input = input.replace(found[i], actionlist[k].example)
|
||||
//}
|
||||
|
||||
shouldbreak = true
|
||||
break
|
||||
}
|
||||
|
||||
//console.log("FOUND2: ", fixedVariable, actionlist[j].example)
|
||||
input = input.replace(fixedVariable, new_input, -1)
|
||||
input = input.replace(found[i], new_input, -1)
|
||||
|
||||
//} catch (e) {
|
||||
// input = input.replace(found[i], actionlist[k].example)
|
||||
//}
|
||||
|
||||
shouldbreak = true
|
||||
break
|
||||
}
|
||||
|
||||
if (shouldbreak) {
|
||||
@@ -766,7 +769,7 @@ const CodeEditor = (props) => {
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
//console.log("Outer replace error: ", e)
|
||||
console.log("Outer replace error: ", e)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -895,7 +898,7 @@ const CodeEditor = (props) => {
|
||||
aria-labelledby="draggable-code-modal"
|
||||
disableBackdropClick={true}
|
||||
disableEnforceFocus={true}
|
||||
//style={{ pointerEvents: "none" }}
|
||||
//style={{ pointerEvents: "none" }}
|
||||
hideBackdrop={true}
|
||||
open={expansionModalOpen}
|
||||
onClose={() => {
|
||||
@@ -964,6 +967,7 @@ const CodeEditor = (props) => {
|
||||
}}
|
||||
>
|
||||
<div style={{display: "flex"}}>
|
||||
{/*
|
||||
<DialogTitle
|
||||
id="draggable-dialog-title"
|
||||
style={{
|
||||
@@ -974,59 +978,9 @@ const CodeEditor = (props) => {
|
||||
>
|
||||
Code Editor
|
||||
</DialogTitle>
|
||||
<IconButton
|
||||
style={{
|
||||
marginLeft: isMobile ? "80%" : 350,
|
||||
height: 50,
|
||||
width: 50,
|
||||
}}
|
||||
onClick={() => {
|
||||
|
||||
}}
|
||||
>
|
||||
<Tooltip
|
||||
color="primary"
|
||||
title={"Test Liquid in the playground"}
|
||||
placement="top"
|
||||
>
|
||||
<a
|
||||
href="https://pwwang.github.io/liquidpy/playground/"
|
||||
rel="norefferer"
|
||||
target="_blank"
|
||||
>
|
||||
<ExtensionIcon style={{color: "rgba(255,255,255,0.7)"}}/>
|
||||
</a>
|
||||
</Tooltip>
|
||||
</IconButton>
|
||||
<IconButton
|
||||
style={{
|
||||
height: 50,
|
||||
width: 50,
|
||||
}}
|
||||
disabled={isAiLoading}
|
||||
onClick={() => {
|
||||
autoFormat(localcodedata)
|
||||
}}
|
||||
>
|
||||
<Tooltip
|
||||
color="primary"
|
||||
title={"Auto format data"}
|
||||
placement="top"
|
||||
>
|
||||
{isAiLoading ?
|
||||
<CircularProgress style={{height: 20, width: 20, color: "rgba(255,255,255,0.7)"}}/>
|
||||
:
|
||||
<AutoFixHighIcon style={{color: "rgba(255,255,255,0.7)"}}/>
|
||||
}
|
||||
</Tooltip>
|
||||
</IconButton>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
*/}
|
||||
{ isFileEditor ? null :
|
||||
<div style={{display: "flex"}}>
|
||||
<div style={{display: "flex", maxHeight: 40, }}>
|
||||
<Button
|
||||
id="basic-button"
|
||||
aria-haspopup="true"
|
||||
@@ -1035,7 +989,7 @@ const CodeEditor = (props) => {
|
||||
variant="outlined"
|
||||
color="secondary"
|
||||
style={{
|
||||
textTransform: "none",
|
||||
textTransform: "none",
|
||||
width: 100,
|
||||
}}
|
||||
onClick={(event) => {
|
||||
@@ -1143,9 +1097,9 @@ const CodeEditor = (props) => {
|
||||
variant="outlined"
|
||||
color="secondary"
|
||||
style={{
|
||||
textTransform: "none",
|
||||
textTransform: "none",
|
||||
width: 130,
|
||||
marginLeft: 170,
|
||||
marginLeft: 20,
|
||||
}}
|
||||
onClick={(event) => {
|
||||
setMenuPosition({
|
||||
@@ -1393,28 +1347,86 @@ const CodeEditor = (props) => {
|
||||
</Menu>
|
||||
</div>
|
||||
}
|
||||
<span style={{
|
||||
<IconButton
|
||||
style={{
|
||||
marginLeft: isMobile ? "80%" : 30,
|
||||
height: 50,
|
||||
width: 50,
|
||||
}}
|
||||
onClick={() => {
|
||||
|
||||
}}
|
||||
>
|
||||
<Tooltip
|
||||
color="primary"
|
||||
title={"Test Liquid in the playground"}
|
||||
placement="top"
|
||||
>
|
||||
<a
|
||||
href="https://pwwang.github.io/liquidpy/playground/"
|
||||
rel="norefferer"
|
||||
target="_blank"
|
||||
>
|
||||
<ExtensionIcon style={{color: "rgba(255,255,255,0.7)"}}/>
|
||||
</a>
|
||||
</Tooltip>
|
||||
</IconButton>
|
||||
<IconButton
|
||||
style={{
|
||||
height: 50,
|
||||
width: 50,
|
||||
}}
|
||||
disabled={isAiLoading}
|
||||
onClick={() => {
|
||||
autoFormat(localcodedata)
|
||||
}}
|
||||
>
|
||||
<Tooltip
|
||||
color="primary"
|
||||
title={"Auto format data"}
|
||||
placement="top"
|
||||
>
|
||||
{isAiLoading ?
|
||||
<CircularProgress style={{height: 20, width: 20, color: "rgba(255,255,255,0.7)"}}/>
|
||||
:
|
||||
<AutoFixHighIcon style={{color: "rgba(255,255,255,0.7)"}}/>
|
||||
}
|
||||
</Tooltip>
|
||||
</IconButton>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
|
||||
<div style={{
|
||||
borderRadius: theme.palette.borderRadius,
|
||||
position: "relative",
|
||||
paddingTop: 0,
|
||||
minHeight: 548,
|
||||
overflow: "hidden",
|
||||
}}>
|
||||
<CodeMirror
|
||||
theme={vscodeDark}
|
||||
value={localcodedata}
|
||||
height={isFileEditor ? 450 : 525}
|
||||
height={isFileEditor ? 450 : 500}
|
||||
width={isFileEditor ? 650 : 600}
|
||||
style={{
|
||||
maxWidth: isFileEditor ? 450 : 500,
|
||||
maxWidth: isFileEditor ? 450 : 600,
|
||||
maxHeight: 548,
|
||||
minHeight: 548,
|
||||
wordBreak: "break-word",
|
||||
marginTop: 0,
|
||||
paddingTop: 0,
|
||||
backgroundColor: "rgba(40,40,40,1)",
|
||||
minHeight: 470,
|
||||
paddingBottom: 10,
|
||||
overflow: "hidden",
|
||||
}}
|
||||
onCursorActivity = {(value) => {
|
||||
// console.log(value.getCursor())
|
||||
console.log("CURSOR: ", value.getCursor())
|
||||
setCurrentCharacter(value.getCursor().ch)
|
||||
setCurrentLine(value.getCursor().line)
|
||||
// console.log(value.getCursor().ch, value.getCursor().line)
|
||||
findIndex(value.getCursor().line, value.getCursor().ch)
|
||||
|
||||
highlight_variables(value)
|
||||
}}
|
||||
onChange={(value, viewUpdate) => {
|
||||
@@ -1422,20 +1434,19 @@ const CodeEditor = (props) => {
|
||||
setlocalcodedata(value)
|
||||
expectedOutput(value)
|
||||
|
||||
highlight_variables(value)
|
||||
|
||||
//if(value.display.input.prevInput.startsWith('$') || value.display.input.prevInput.endsWith('$')){
|
||||
// setEditorPopupOpen(true)
|
||||
//}
|
||||
}}
|
||||
extensions={[]}//indentWithTab]}
|
||||
theme={shuffleTheme}
|
||||
options={{
|
||||
styleSelectedText: true,
|
||||
keyMap: 'sublime',
|
||||
mode: validation === true ? "json" : "python",
|
||||
lineWrapping: linewrap,
|
||||
theme: vscodeDark,
|
||||
}}
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/*editorPopupOpen ?
|
||||
<Paper
|
||||
@@ -1550,13 +1561,14 @@ const CodeEditor = (props) => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{flex: 1, marginLeft: 25, }}>
|
||||
<div style={{flex: 1, marginLeft: 5, borderLeft: "1px solid rgba(255,255,255,0.3)", paddingLeft: 5, }}>
|
||||
{isFileEditor ? null :
|
||||
<div>
|
||||
{isMobile ? null :
|
||||
<DialogTitle
|
||||
style={{
|
||||
paddingLeft: 10,
|
||||
paddingTop: 0,
|
||||
display: "flex",
|
||||
}}
|
||||
>
|
||||
@@ -1564,7 +1576,7 @@ const CodeEditor = (props) => {
|
||||
Expected Output
|
||||
</span>
|
||||
|
||||
<IconButton disabled={executing} color="primary" style={{border: `1px solid ${theme.palette.primary.main}`, marginLeft: 100, padding: 8}} variant="contained" onClick={() => {
|
||||
<IconButton disabled={executing} color="secondary" style={{border: `1px solid ${theme.palette.primary.main}`, marginLeft: 250, padding: 8}} variant="contained" onClick={() => {
|
||||
executeSingleAction(expOutput)
|
||||
}}>
|
||||
<Tooltip title="Try it! This runs the Shuffle Tools 'repeat back to me' or 'execute python' action with what you see in the expected output window. Commonly used to test your Python scripts or Liquid filters, not requiring the full workflow to run again." placement="top">
|
||||
@@ -1613,8 +1625,8 @@ const CodeEditor = (props) => {
|
||||
borderRadius: theme.palette.borderRadius,
|
||||
maxHeight: 500,
|
||||
minHeight: 500,
|
||||
minWidth: 500,
|
||||
maxWidth: 500,
|
||||
minWidth: 580,
|
||||
maxWidth: 580,
|
||||
overflow: "auto",
|
||||
whiteSpace: "pre-wrap",
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user