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'; //import appdata from './appdata'; const EditSchedule = (props) => { const { globalUrl } = props; const [tmpSrcApp, setTmpSrcApp] = useState({}) const [tmpDstApp, setTmpDstApp] = useState({}) const [srcApp, setSrcApp] = useState({}) const [srcAppConfig, setSrcAppConfig] = useState([]) const [srcAppConfigOpen, setSrcAppConfigOpen] = useState(false) const [srcAppAction, setSrcAppAction] = useState("") const [dstApp, setDstApp] = useState({}) const [dstAppAction, setDstAppAction] = useState("") const [dstAppConfig, setDstAppConfig] = useState([]) const [dstAppConfigOpen, setDstAppConfigOpen] = useState(false) // Lets set the real data here const [selectedSrc, setSelectedSrc] = React.useState(""); const [, setSelectedSrcData] = React.useState({}); const [selectedDst, setSelectedDst] = React.useState([]); // FIXME const [suggestions, setSuggestions] = React.useState([]); const [inputappdata, setInputAppData] = React.useState({}); const [scheduleConfig, setScheduleConfig] = React.useState({}) const [selectedSrcParameters, setSelectedSrcParameters] = React.useState([]) const getCurrentSchedule = () => { fetch(globalUrl+"/api/v1/schedules/"+props.match.params.key, { method: 'GET', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, }) .then((response) => response.json()) .then((responseJson) => { setScheduleConfig(responseJson) }) .catch(error => { console.log(error) }); } const loadAppSuggestions = () => { fetch(globalUrl+"/api/v1/schedules/apps", { method: 'GET', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, }) .then((response) => response.json()) .then((responseJson) => { setSuggestions(responseJson.apps) }) .catch(error => { console.log(error) }); } // FIXME - this is generated from app selection input with required items useEffect(() => { if (Object.getOwnPropertyNames(scheduleConfig).length <= 0) { getCurrentSchedule() } // Load apps if destination or source is if (suggestions.length === 0) { loadAppSuggestions() } // Load everything else if (Object.getOwnPropertyNames(scheduleConfig).length > 0 && Object.getOwnPropertyNames(scheduleConfig.appinfo.sourceapp).length > 0 && Object.getOwnPropertyNames(srcApp).length <= 0) { if (scheduleConfig.appinfo.sourceapp.name.length > 0) { setSrcApp(scheduleConfig.appinfo.sourceapp) setSrcAppAction(scheduleConfig.appinfo.sourceapp.action) } } // Use sourceapp.name&version and sourceapp.action and look for name in inputappdata // Basically fix everything in this one lol if (suggestions.length > 0 && srcAppAction.length > 0 && Object.getOwnPropertyNames(scheduleConfig).length > 0 && Object.getOwnPropertyNames(inputappdata).length <= 0) { // Loops all apps and finds current for (var key in suggestions) { var curapp = suggestions[key] if (curapp.name === srcApp.name) { break } } setInputAppData(curapp) // Loops the apps actions to find current for (key in curapp.output) { var curappaction = curapp.output[key] if (curappaction.name === srcAppAction) { break } } setSelectedSrcParameters(curappaction.outputparameters) if (curappaction.config !== null && curappaction.config !== undefined) { setSrcAppConfig(curappaction.config) } // FIXME - set src of all translator nodes to curappaction.outputparameters[0] if not defined //value={scheduleConfig.translator[count].src.name} //console.log(scheduleConfig) var newtranslator = [] for (key in scheduleConfig.translator) { var curtranslator = scheduleConfig.translator[key] // Overwrite issues if (curtranslator.src.name === "") { curtranslator.src = curappaction.outputparameters[0] } newtranslator.push(curtranslator) } scheduleConfig.translator = newtranslator setScheduleConfig(scheduleConfig) } if (suggestions.length > 0 && dstAppAction.length <= 0 && Object.getOwnPropertyNames(scheduleConfig).length > 0) { // Loops all apps and finds current for (key in suggestions) { curapp = suggestions[key] if (curapp.name === dstApp.name) { break } } const curAction = scheduleConfig.appinfo.destinationapp.action // Loops the apps actions to find current for (key in curapp.output) { curappaction = curapp.output[key] if (curappaction.name === curAction) { break } } setDstAppAction(curappaction.name) if (curappaction.config !== null && curappaction.config !== undefined) { setDstAppConfig(curappaction.config) } } }) const getSuggestions = (value, type, { showEmpty = false } = {}) => { const inputValue = deburr(value.trim()).toLowerCase(); const inputLength = inputValue.length; let count = 0; return inputLength === 0 && !showEmpty ? [] : suggestions.filter(suggestion => { const keep = count < 5 && suggestion.types && suggestion.types.includes(type) && suggestion.name.slice(0, inputLength).toLowerCase() === inputValue; if (keep) { count += 1; } return keep; }); } const setSrcAppWrapper = (currentapps) => { setSrcApp(currentapps[0]) if (currentapps[0].output.length > 0) { selectSrcAction(currentapps[0].output[0].name) } } const setDstAppWrapper = (currentapps) => { setDstApp(currentapps[0]) if (currentapps[0].input.length > 0) { selectInitialDstAction(currentapps) } } const renderInput = (type, inputProps) => { const { InputProps, classes, ref, ...other } = inputProps; // Sets the srcapp if string is matching exactly for name if (InputProps["aria-activedescendant"] === null && InputProps["value"].length > 0) { const currentapps = suggestions.filter(data => data.name === InputProps["value"]) if (currentapps.length === 1) { if (type === "output") { if (currentapps[0].name !== srcApp.name) { setSrcAppWrapper(currentapps) } } else if (type === "input") { if (currentapps[0].name !== dstApp.name) { setDstAppWrapper(currentapps) } } } } return (
), }} {...other} />
); } const renderSuggestion = (suggestionProps) => { const { suggestion, index, itemProps, highlightedIndex, selectedItem } = suggestionProps; const isHighlighted = highlightedIndex === index; const isSelected = (selectedItem || '').indexOf(suggestion.name) > -1; return ( {suggestion.name} ); } const bodyDivStyle = { marginLeft: "20px", marginTop: "50px", marginRight: "20px", margin: "auto", width: "1350px", display: "flex", } const appActionStyle = { height: "50px", marginTop: "10px", } // FIXME - set this //const setRelationshipsFromSource = () => { //} //// FIXME - set this //const setRelationshipsFromGenerator = () => { //} const selectDstAppAction = (event) => { if (event.target.value === dstAppAction) { return } setDstAppAction(event.target.value) refactorTranslations(event.target.value) } const refactorTranslations = (action) => { // dstapp is chosen var found = false for (var key in dstApp.input) { var curinput = dstApp.input[key] if (curinput.name === action) { found = true break } } // Should never happen.. if (!found) { return } var tmprelationships = [] for (key in curinput.inputparameters) { var curRelation = {"dst": curinput.inputparameters[key], "src": {}} tmprelationships.push(curRelation) } scheduleConfig["translator"] = tmprelationships setScheduleConfig(scheduleConfig) } const selectInitialDstAction = (value) => { var action = value[0].input[0].name setDstAppAction(action) var found = false for (var key in value) { var curinput = value[0].input[key] if (curinput.name === action) { found = true break } } // Should never happen.. if (!found) { return } var tmprelationships = [] for (key in curinput.inputparameters) { var curRelation = {"dst": curinput.inputparameters[key], "src": {}} tmprelationships.push(curRelation) } scheduleConfig["translator"] = tmprelationships setScheduleConfig(scheduleConfig) } const selectSrcAction = (value) => { // FIXME - load the config for this action var found = false setSrcAppAction(value) var curitem = {} for (var key in inputappdata.output) { curitem = inputappdata.output[key] if (curitem.name === value) { found = true break } } if (!found) { setSelectedSrcParameters([]) return } // Generate this for every relation? setSelectedSrcParameters(curitem.outputparameters) //FIXME - check if source has the right attribute var tmprelationships = [] key = 0 for (key in scheduleConfig.translator) { var curRelation = scheduleConfig.translator[key] curRelation["src"] = curitem.outputparameters[0] tmprelationships.push(curRelation) } scheduleConfig["translator"] = tmprelationships setScheduleConfig(scheduleConfig) } // Wrapper to handle event click const selectSrcActionWrapper = (event) => { return selectSrcAction(event.target.value) } const srcappaction = Object.getOwnPropertyNames(srcApp).length > 0 && srcApp.output ?
Actions
: null const dstappaction = Object.getOwnPropertyNames(dstApp).length > 0 ?
Actions
: null const downshiftStyle = { //marginLeft: "20px", //marginTop: "20px", //marginRight: "20px", display: "flex", width: "100%", } const submitDisabled = selectedSrc.length > 0 && selectedDst.length > 0 const submitButtonClick = () => { var newtranslations = [] var tobeadded = [] var tobechanged = [] // Go find the information again in testdata //newrelationship["translator"] = {"src": {}, "dst": {}} //newrelationship["static"] = {} // Reformat relationships // clean up old relationships // if (Object.getOwnPropertyNames(scheduleConfig.Translator).length <= 0) { return } // Clean up old translations for specified elements // FIXME - maybe just send a request with relationships and fix in backend? // FIXME - there is an issue here for some multifield stuff // Literally have to verify every single one anyway.. for (var selected in selectedDst) { var found = false var index = 0 for (var key in scheduleConfig["translator"]) { if (scheduleConfig["translator"][key]["dst"]["name"] === selectedDst[selected]) { index = key found = true break } } if (!found) { tobeadded.push(selectedDst[selected]) } else { // Dst can be the tobechanged.push(index) } } var tmprelationships = scheduleConfig key = 0 for (key in scheduleConfig["translator"]) { if (tobechanged.includes(key)) { var tmprel = scheduleConfig["translator"][key] tmprel["src"] = {"name": selectedSrc} tmprelationships["translator"].splice(key, 1) newtranslations.push(tmprel) } } key = 0 for (key in tobeadded) { tmprel = {"src": {"name": selectedSrc}, "dst": {"name": tobeadded[key]}} newtranslations.push(tmprel) } // delete deletable keys from copy (new) // key = 0 for (key in newtranslations) { tmprelationships["translator"].push(newtranslations[key]) } setSelectedSrc("") setSelectedDst([]) setSelectedSrcData({}) // FIXME - does this work? scheduleConfig["translator"] = tmprelationships["translator"] setScheduleConfig(scheduleConfig) } // When it's set, need to find the destination in the row and set static const setStaticValue = (event, row) => { console.log("HI") // FIXME - modify the row first // FIXME - set generator and source to "nothing" console.log(row.dst.name) console.log(row) console.log(event.target.value) var newsrcrow = {"name": "static", "description": "Static value set", "type": "static", "value": event.target.value, "schema": {"type": "string"}} var relationshipclone = JSON.parse(JSON.stringify(scheduleConfig)); for (var key in scheduleConfig["translator"]) { var curItem = scheduleConfig["translator"][key] if (curItem.dst.name === row.dst.name) { break } } relationshipclone["translator"][key]["src"] = newsrcrow scheduleConfig["translator"] = relationshipclone["translator"] console.log(scheduleConfig) // Fuck this :( // DO DIS IN FRONTEND AND HAVE A SUBMIT BUTTON :( fetch(globalUrl+"/api/v1/schedules/"+props.match.params.key, { method: 'PUT', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, body: JSON.stringify(scheduleConfig), }) .then((response) => response.json()) .then((responseJson) => { setScheduleConfig({}) }) .catch(error => { console.log(error) }); } // Rewrites relationships clientside const setCurrentSrcPropRelation = (event, rowkey) => { console.log(event, rowkey) var found = false for (var key in selectedSrcParameters) { var curItem = selectedSrcParameters[key] if (curItem.name === event.target.value) { found = true break } } // No idea how this would ever happen, but but (: if (!found) { return } var row = scheduleConfig.translator[rowkey] var rowclone = JSON.parse(JSON.stringify(row)); rowclone.src = curItem var relationshipclone = JSON.parse(JSON.stringify(scheduleConfig)); for (key in scheduleConfig["translator"]) { curItem = scheduleConfig["translator"][key] if (curItem.dst.name === row.dst.name) { break } } relationshipclone["translator"][key] = rowclone scheduleConfig["translator"] = relationshipclone["translator"] console.log(scheduleConfig) // Fuck this :( // DO DIS IN FRONTEND AND HAVE A SUBMIT BUTTON :( fetch(globalUrl+"/api/v1/schedules/"+props.match.params.key, { method: 'PUT', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, body: JSON.stringify(scheduleConfig), }) .then((response) => response.json()) .then((responseJson) => { setScheduleConfig({}) }) .catch(error => { console.log(error) }); return } const relationshipBody = Object.getOwnPropertyNames(scheduleConfig).length > 0 && scheduleConfig["translator"] !== undefined && scheduleConfig.translator.length > 0 ? Action Source Field Destination Field Field Type Required Static Generator Transform {scheduleConfig.translator.map((row, count) => { var buttonIcon = if (!row.dst.required) { buttonIcon = } const srcpropsSelector = (Object.getOwnPropertyNames(selectedSrcParameters).length > 0 || Object.getOwnPropertyNames(scheduleConfig.translator).length > 0) && Object.getOwnPropertyNames(srcApp).length > 0 ? :
No defined fields
const placeholderValue = row.src.type === "static" ? row.src.value : "... Set a static value" return( {buttonIcon} {srcpropsSelector} {row.dst.name} {row.dst.schema.type} {row.dst.required} { if (event.key === 'Enter') { event.preventDefault(); console.log(`Pressed keyCode ${event.key}`); setStaticValue(event, row) } }} /> INSERT SCRIPT THINGY - Cortex responder? ) })}
: null // FIXME - use this //const submitRelationships = () => { // // Make an API-call to the backend for verification // // Return with failures etc, and mark row issues? // // var apiUrl = "http://localhost:5000" // fetch(apiUrl+"/api/v1/schedules", // { // method: "POST", // headers: {"content-type": "application/json"}, // body: JSON.stringify(scheduleConfig), // } // ) // .then((response) => response.json()) // .then((responseJson) => { // console.log(responseJson) // }) // .catch((error) => { // console.log(error); // }); //} const executeSchedule = () => { fetch(globalUrl+"/api/v1/schedules/"+props.match.params.key+"/execute", { method: 'GET', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, }) .then((response) => response.json()) .then((responseJson) => { console.log(responseJson) }) .catch(error => { console.log(error) }); } const submitButton =
// Requires src or dst as input // FIXME - use this shit to edit an app or something //const editButtonFix = (app, apptype) => { // if (apptype === "src") { // } else if (apptype === "dst") { // } //} const editSrcApp = (event) => { // if tmpsrcapp, show RESET (can be an X or something too) // if reset is clicked, set source app back to the original setTmpSrcApp(scheduleConfig.appinfo.sourceapp) var tmpscheduleConfig = scheduleConfig tmpscheduleConfig.appinfo.sourceapp = {} fetch(globalUrl+"/api/v1/schedules/"+props.match.params.key, { method: 'PUT', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, body: JSON.stringify(tmpscheduleConfig), }) .then((response) => response.json()) .then((responseJson) => { setScheduleConfig({}) setSrcApp({}) setSrcAppAction("") }) .catch(error => { console.log(error) }); } const editDstApp = (event) => { // if tmpsrcapp, show RESET (can be an X or something too) // if reset is clicked, set source app back to the original setTmpDstApp(scheduleConfig.appinfo.destinationapp) var tmpscheduleConfig = scheduleConfig tmpscheduleConfig.appinfo.destinationapp = {} fetch(globalUrl+"/api/v1/schedules/"+props.match.params.key, { method: 'PUT', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, body: JSON.stringify(tmpscheduleConfig), }) .then((response) => response.json()) .then((responseJson) => { setScheduleConfig({}) setDstApp({}) setDstAppAction("") }) .catch(error => { console.log(error) }); } const scheduleApp = (app, actiondata) => { const editButton = actiondata === "src" ? : const configureButton = actiondata === "src" ? : // FIXME - set src vs dst return( {splitter}

{app.name}

{app.description}
{app.action}
{splitter}
{editButton}
{configureButton}
) } const splitter =
const dstDownshift = {({ getInputProps, getItemProps, getMenuProps, highlightedIndex, inputValue, isOpen, selectedItem, }) => (
{renderInput("input", { fullWidth: true, InputProps: getInputProps({ placeholder: 'Search destination apps', }), })}
{isOpen ? ( {getSuggestions(inputValue, "input").map((suggestion, index) => renderSuggestion({ suggestion, index, itemProps: getItemProps({ item: suggestion.name }), highlightedIndex, selectedItem, }), )} ) : null}
{dstappaction}
)}
const srcDownshift = {({ getInputProps, getItemProps, getMenuProps, highlightedIndex, inputValue, isOpen, selectedItem, }) => (
{renderInput("output", { fullWidth: true, InputProps: getInputProps({ placeholder: 'Search source apps', }), })}
{isOpen ? ( {getSuggestions(inputValue, "output").map((suggestion, index) => renderSuggestion({ suggestion, index, itemProps: getItemProps({ item: suggestion.name }), highlightedIndex, selectedItem, }), )} ) : null}
{srcappaction}
)}
const submitDstApp = (event) => { var packagedSrc = { name: dstApp.name, id: dstApp.id, description: dstApp.description, action: dstAppAction, } var tmpscheduleConfig = scheduleConfig tmpscheduleConfig.appinfo.destinationapp = packagedSrc // Hmm, do this here? Idk fetch(globalUrl+"/api/v1/schedules/"+props.match.params.key, { method: 'PUT', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, body: JSON.stringify(tmpscheduleConfig), }) .then((response) => response.json()) .then((responseJson) => { setScheduleConfig({}) }) .catch(error => { console.log(error) }); } const submitSrcApp = (event) => { var packagedSrc = { name: srcApp.name, id: srcApp.id, description: srcApp.description, action: srcAppAction, } var tmpscheduleConfig = scheduleConfig // FIXME - future fred // tmpscheduleConfig.appinfo.sourceapp = packagedSrc // Hmm, do this here? Idk fetch(globalUrl+"/api/v1/schedules/"+props.match.params.key, { method: 'PUT', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, body: JSON.stringify(tmpscheduleConfig), }) .then((response) => response.json()) .then((responseJson) => { setScheduleConfig({}) }) .catch(error => { console.log(error) }); } const resetDstApp = (event) => { var tmpscheduleConfig = scheduleConfig tmpscheduleConfig.appinfo.destinationapp = tmpDstApp // Hmm, do this here? Idk fetch(globalUrl+"/api/v1/schedules/"+props.match.params.key, { method: 'PUT', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, body: JSON.stringify(tmpscheduleConfig), }) .then((response) => response.json()) .then((responseJson) => { setScheduleConfig({}) setDstApp(tmpSrcApp) setDstAppAction(tmpDstApp.action) setTmpDstApp({}) }) .catch(error => { console.log(error) }); } const resetSrcApp = (event) => { var tmpscheduleConfig = scheduleConfig tmpscheduleConfig.appinfo.sourceapp = tmpSrcApp // Hmm, do this here? Idk fetch(globalUrl+"/api/v1/schedules/"+props.match.params.key, { method: 'PUT', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, body: JSON.stringify(tmpscheduleConfig), }) .then((response) => response.json()) .then((responseJson) => { setScheduleConfig({}) setSrcApp(tmpSrcApp) setSrcAppAction(tmpSrcApp.action) setTmpSrcApp({}) }) .catch(error => { console.log(error) }); } // Based on some srcthing const searchGridSrc = Choose Source app (FIXME) - clickable {splitter}
{srcDownshift}
{splitter}
const searchGridDst = Choose Source app (FIXME) - clickable {splitter}
{dstDownshift}
{splitter}
const srcField = (Object.getOwnPropertyNames(scheduleConfig).length > 0 && Object.getOwnPropertyNames(scheduleConfig.appinfo.sourceapp).length > 0 && scheduleConfig.appinfo.sourceapp.name.length > 0) ?
{scheduleApp(scheduleConfig.appinfo.sourceapp, "src")}
:
{searchGridSrc}
const dstField = (Object.getOwnPropertyNames(scheduleConfig).length > 0 && Object.getOwnPropertyNames(scheduleConfig.appinfo.destinationapp).length > 0 && scheduleConfig.appinfo.destinationapp.name.length > 0) ?
{scheduleApp(scheduleConfig.appinfo.destinationapp, "dst")}
:
{searchGridDst}
// 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 ? {setDstAppConfigOpen(false)}} > Source configuration Configure {dstApp.name}'s required fields {dstAppConfig.map(data => ( {buildDstModal(event, data.name)}} autofocus color="primary" name="searchtext" placeholder={data.name} margin="dense" id={data.name} label={data.name} fullWidth /> ))} : null // FIXME - load the actual fields! const srcConfigModal = srcAppConfigOpen ? {setSrcAppConfigOpen(false)}} > Source configuration Configure {srcApp.name}'s required fields {srcAppConfig.map(data => ( {buildSrcModal(event, data.name)}} autofocus color="primary" name="searchtext" placeholder={data.name} margin="dense" id={data.name} label={data.name} fullWidth /> ))} : null return(
{srcConfigModal} {dstConfigModal}
{srcField} {dstField}
{submitButton}
{relationshipBody}
) } export default EditSchedule