Files
shuffle-cracked/frontend/src/views/EditSchedule.jsx
T

1389 lines
36 KiB
React

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 (
<div>
<TextField
id="standard-search"
type="search"
inputStyle={{ fontSize: '10rem' }}
InputProps={{
disableUnderline: true,
inputRef: ref,
...InputProps,
startAdornment: (
<InputAdornment position="start">
<SearchIcon />
</InputAdornment>
),
}}
{...other}
/>
</div>
);
}
const renderSuggestion = (suggestionProps) => {
const { suggestion, index, itemProps, highlightedIndex, selectedItem } = suggestionProps;
const isHighlighted = highlightedIndex === index;
const isSelected = (selectedItem || '').indexOf(suggestion.name) > -1;
return (
<MenuItem
{...itemProps}
key={suggestion.name}
selected={isHighlighted}
component="div"
style={{
fontWeight: isSelected ? 500 : 400,
}}
>
{suggestion.name}
</MenuItem>
);
}
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 ?
<div>
<FormControl variant="outlined" style={{marginTop: "10px"}}>
<InputLabel htmlFor="outlined-age-simple">
Actions
</InputLabel>
<Select
value={srcAppAction}
onChange={selectSrcActionWrapper}
style={appActionStyle}
>
{srcApp.output.map(data => (
<MenuItem value={data.name}>
{data.name}
</MenuItem>
))}
</Select>
</FormControl>
</div>
: null
const dstappaction = Object.getOwnPropertyNames(dstApp).length > 0 ?
<div>
<FormControl fullWidth="true" variant="outlined" style={{marginTop: "20px"}}>
<InputLabel htmlFor="outlined-age-simple">
Actions
</InputLabel>
<Select
value={dstAppAction}
onChange={selectDstAppAction}
style={appActionStyle}
>
{dstApp.input.map(data => (
<MenuItem value={data.name}>
{data.name}
</MenuItem>
))}
</Select>
</FormControl>
</div>
: 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 ?
<Table style={{marginBottom: "30px"}}>
<TableBody>
<TableRow key="header">
<TableCell component="th" scope="row">
Action
</TableCell>
<TableCell component="th" scope="row">
Source Field
</TableCell>
<TableCell component="th" scope="row">
Destination Field
</TableCell>
<TableCell component="th" scope="row">
Field Type
</TableCell>
<TableCell component="th" scope="row">
Required
</TableCell>
<TableCell component="th" scope="row">
Static
</TableCell>
<TableCell component="th" scope="row">
Generator
</TableCell>
<TableCell component="th" scope="row">
Transform
</TableCell>
</TableRow>
{scheduleConfig.translator.map((row, count) => {
var buttonIcon = <DeleteIcon />
if (!row.dst.required) {
buttonIcon = <Button
disabled={!submitDisabled}
onClick={submitButtonClick}
variant="outlined"
color="primary"
>REMOVEME</Button>
}
const srcpropsSelector = (Object.getOwnPropertyNames(selectedSrcParameters).length > 0 || Object.getOwnPropertyNames(scheduleConfig.translator).length > 0) && Object.getOwnPropertyNames(srcApp).length > 0 ?
<Select
value={scheduleConfig.translator[count].src.name}
style={appActionStyle}
onChange={(e) => {setCurrentSrcPropRelation(e, count)}}
>
{selectedSrcParameters.map(data => (
<MenuItem value={data.name}>
{data.name}
</MenuItem>
))}
</Select> : <div>No defined fields</div>
const placeholderValue = row.src.type === "static" ? row.src.value : "... Set a static value"
return(
<TableRow>
<TableCell component="th" scope="row">
{buttonIcon}
</TableCell>
<TableCell>{srcpropsSelector}</TableCell>
<TableCell>{row.dst.name}</TableCell>
<TableCell>{row.dst.schema.type}</TableCell>
<TableCell>{row.dst.required}</TableCell>
<TableCell>
<TextField
color="primary"
name="searchtext"
placeholder={placeholderValue}
InputProps={{
disableUnderline: true,
}}
onKeyPress={(event) => {
if (event.key === 'Enter') {
event.preventDefault();
console.log(`Pressed keyCode ${event.key}`);
setStaticValue(event, row)
}
}}
/>
</TableCell>
<TableCell>INSERT SCRIPT THINGY - Cortex responder?</TableCell>
</TableRow>
)
})}
</TableBody>
</Table> : 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 =
<div style={{margin: "auto", marginTop: "20px"}}>
<Button
onClick={executeSchedule}
variant="outlined"
color="primary"
>
Execute
</Button>
</div>
// 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" ?
<Button
onClick={(event) => {editSrcApp(event)}}
style={{left: "50%", top: "50%", transform: "translate(-50%, -50%)"}}
variant="outlined"
color="primary"
>Edit</Button>
:
<Button
onClick={(event) => {editDstApp(event)}}
style={{left: "50%", top: "50%", transform: "translate(-50%, -50%)"}}
variant="outlined"
color="primary"
>Edit</Button>
const configureButton = actiondata === "src" ?
<Button
disabled={srcAppConfig.length === 0}
style={{left: "50%", top: "50%", transform: "translate(-50%, -50%)"}}
onClick={() => setSrcAppConfigOpen(true)}
variant="outlined"
color="primary"
>Config</Button>
: <Button
disabled={dstAppConfig.length === 0}
style={{left: "50%", top: "50%", transform: "translate(-50%, -50%)"}}
onClick={() => setDstAppConfigOpen(true)}
variant="outlined"
color="primary"
>Config</Button>
// FIXME - set src vs dst
return(
<Grid container spacing={2} style={{margin: "10px 10px 10px 10px"}}>
<Grid item>
<ButtonBase>
<img alt="" style={{width: "100px", height: "100px"}} />
</ButtonBase>
</Grid>
{splitter}
<Grid item xs={12} sm container style={{marginLeft: "10px"}}>
<Grid item xs container direction="column" spacing={2}>
<Grid item xs>
<div>
<h2>{app.name}</h2>
</div>
<div>
{app.description}
</div>
</Grid>
<Grid item>
{app.action}
</Grid>
</Grid>
{splitter}
<Grid item style={{marginLeft: "10px", display: "flex", flexDirection: "column"}}>
<div style={{flex: "1"}}>
{editButton}
</div>
<div style={{flex: "1"}}>
{configureButton}
</div>
</Grid>
</Grid>
</Grid>
)
}
const splitter = <div style={{width: "1px", backgroundColor: "grey", margin:"5px 5px 5px 5px"}} />
const dstDownshift =
<Downshift style={downshiftStyle}>
{({
getInputProps,
getItemProps,
getMenuProps,
highlightedIndex,
inputValue,
isOpen,
selectedItem,
}) => (
<div style={{flex: "1"}}>
{renderInput("input", {
fullWidth: true,
InputProps: getInputProps({
placeholder: 'Search destination apps',
}),
})}
<div>
<div {...getMenuProps()}>
{isOpen ? (
<Paper square>
{getSuggestions(inputValue, "input").map((suggestion, index) =>
renderSuggestion({
suggestion,
index,
itemProps: getItemProps({ item: suggestion.name }),
highlightedIndex,
selectedItem,
}),
)}
</Paper>
) : null}
</div>
{dstappaction}
</div>
</div>
)}
</Downshift>
const srcDownshift =
<Downshift style={downshiftStyle}>
{({
getInputProps,
getItemProps,
getMenuProps,
highlightedIndex,
inputValue,
isOpen,
selectedItem,
}) => (
<div style={{flex: "1"}}>
{renderInput("output", {
fullWidth: true,
InputProps: getInputProps({
placeholder: 'Search source apps',
}),
})}
<div>
<div {...getMenuProps()}>
{isOpen ? (
<Paper square>
{getSuggestions(inputValue, "output").map((suggestion, index) =>
renderSuggestion({
suggestion,
index,
itemProps: getItemProps({ item: suggestion.name }),
highlightedIndex,
selectedItem,
}),
)}
</Paper>
) : null}
</div>
{srcappaction}
</div>
</div>
)}
</Downshift>
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 =
<Grid container spacing={2} style={{margin: "10px 10px 10px 10px"}}>
<Grid item style={{width: "100px", height: "100px"}}>
Choose Source app (FIXME) - clickable
</Grid>
{splitter}
<Grid item xs={12} sm container style={{marginLeft: "10px"}}>
<Grid item xs container direction="column" spacing={2}>
<Grid item xs>
<div>
{srcDownshift}
</div>
</Grid>
</Grid>
{splitter}
<Grid item style={{marginLeft: "10px", display: "flex", flexDirection: "column"}}>
<div style={{flex: "1"}}>
<Button
disabled={Object.getOwnPropertyNames(srcApp).length === 0}
onClick={(event) => {submitSrcApp(event)}}
style={{left: "50%", top: "50%", transform: "translate(-50%, -50%)"}}
variant="outlined"
color="primary"
>Submit</Button>
</div>
<div style={{flex: "1"}}>
<Button
disabled={Object.getOwnPropertyNames(tmpSrcApp).length === 0}
onClick={resetSrcApp}
style={{left: "50%", top: "50%", transform: "translate(-50%, -50%)"}}
variant="outlined"
color="primary"
>Reset</Button>
</div>
</Grid>
</Grid>
</Grid>
const searchGridDst =
<Grid container spacing={2} style={{margin: "10px 10px 10px 10px"}}>
<Grid item style={{width: "100px", height: "100px"}}>
Choose Source app (FIXME) - clickable
</Grid>
{splitter}
<Grid item xs={12} sm container style={{marginLeft: "10px"}}>
<Grid item xs container direction="column" spacing={2}>
<Grid item xs>
<div>
{dstDownshift}
</div>
</Grid>
</Grid>
{splitter}
<Grid item style={{marginLeft: "10px", display: "flex", flexDirection: "column"}}>
<div style={{flex: "1"}}>
<Button
disabled={Object.getOwnPropertyNames(dstApp).length === 0}
onClick={(event) => {submitDstApp(event)}}
style={{left: "50%", top: "50%", transform: "translate(-50%, -50%)"}}
variant="outlined"
color="primary"
>Submit</Button>
</div>
<div style={{flex: "1"}}>
<Button
disabled={Object.getOwnPropertyNames(tmpDstApp).length === 0}
onClick={resetDstApp}
style={{left: "50%", top: "50%", transform: "translate(-50%, -50%)"}}
variant="outlined"
color="primary"
>Reset</Button>
</div>
</Grid>
</Grid>
</Grid>
const srcField = (Object.getOwnPropertyNames(scheduleConfig).length > 0 && Object.getOwnPropertyNames(scheduleConfig.appinfo.sourceapp).length > 0 && scheduleConfig.appinfo.sourceapp.name.length > 0) ?
<div style={{marginLeft: "20px", margintop: "20px", marginRight: "20px", flex:"1"}}>
<Paper style={{maxWidth: "100%", display: "flex", padding: "10px 10px 10px 10px"}}>
{scheduleApp(scheduleConfig.appinfo.sourceapp, "src")}
</Paper>
</div>
:
<div style={{marginLeft: "20px", margintop: "20px", marginRight: "20px", flex:"1"}}>
<Paper style={{minHeight: "136px", maxHeight: "136px", maxWidth: "100%", display: "flex", padding: "10px 10px 10px 10px"}}>
{searchGridSrc}
</Paper>
</div>
const dstField = (Object.getOwnPropertyNames(scheduleConfig).length > 0 && Object.getOwnPropertyNames(scheduleConfig.appinfo.destinationapp).length > 0 && scheduleConfig.appinfo.destinationapp.name.length > 0) ?
<div style={{marginLeft: "20px", margintop: "20px", marginRight: "20px", flex:"1"}}>
<Paper style={{maxWidth: "100%", display: "flex", padding: "10px 10px 10px 10px"}}>
{scheduleApp(scheduleConfig.appinfo.destinationapp, "dst")}
</Paper>
</div>
:
<div style={{marginLeft: "20px", margintop: "20px", marginRight: "20px", flex:"1"}}>
<Paper style={{minHeight: "136px", maxHeight: "136px", maxWidth: "100%", display: "flex", padding: "10px 10px 10px 10px"}}>
{searchGridDst}
</Paper>
</div>
// 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 ?
<Dialog modal
open={dstAppConfigOpen}
onClose={() => {setDstAppConfigOpen(false)}}
>
<DialogTitle>Source configuration</DialogTitle>
<DialogContent>
Configure {dstApp.name}'s required fields
{dstAppConfig.map(data => (
<TextField
onChange={(event) => {buildDstModal(event, data.name)}}
autofocus
color="primary"
name="searchtext"
placeholder={data.name}
margin="dense"
id={data.name}
label={data.name}
fullWidth
/>
))}
</DialogContent>
<DialogActions>
<Button onClick={() => setDstAppConfigOpen(false)} color="primary">
Cancel
</Button>
<Button onClick={() => submitDstConfig()} color="primary">
Submit
</Button>
</DialogActions>
</Dialog> : null
// FIXME - load the actual fields!
const srcConfigModal = srcAppConfigOpen ?
<Dialog modal
open={srcAppConfigOpen}
onClose={() => {setSrcAppConfigOpen(false)}}
>
<DialogTitle>Source configuration</DialogTitle>
<DialogContent>
Configure {srcApp.name}'s required fields
{srcAppConfig.map(data => (
<TextField
onChange={(event) => {buildSrcModal(event, data.name)}}
autofocus
color="primary"
name="searchtext"
placeholder={data.name}
margin="dense"
id={data.name}
label={data.name}
fullWidth
/>
))}
</DialogContent>
<DialogActions>
<Button onClick={() => setSrcAppConfigOpen(false)} color="primary">
Cancel
</Button>
<Button onClick={() => submitSrcConfig()} color="primary">
Submit
</Button>
</DialogActions>
</Dialog> : null
return(
<div>
{srcConfigModal}
{dstConfigModal}
<div style={bodyDivStyle}>
{srcField}
{dstField}
</div>
<div style={bodyDivStyle}>
{submitButton}
</div>
<div style={bodyDivStyle}>
{relationshipBody}
</div>
</div>
)
}
export default EditSchedule