import React, { useEffect, useContext, memo } from "react"; import { useInterval } from "react-powerhooks"; import theme from '../theme.jsx'; import { IconButton, Typography, Grid, Select, Paper, Divider, ButtonBase, Button, TextField, FormControl, MenuItem, Tooltip, FormControlLabel, Switch, Input, Breadcrumbs, Chip, Dialog, DialogTitle, DialogActions, DialogContent, CircularProgress, Zoom, InputAdornment, List, ListItem, ListItemAvatar, ListItemText, Avatar, } from "@mui/material"; import { AutoFixHigh as AutoFixHighIcon, LockOpen as LockOpenIcon, OpenInNew as OpenInNewIcon, Apps as AppsIcon, Cached as CachedIcon, Publish as PublishIcon, CloudDownload as CloudDownloadIcon, Edit as EditIcon, Delete as DeleteIcon, Search as SearchIcon, Folder as FolderIcon, LibraryBooks as LibraryBooksIcon, } from "@mui/icons-material"; import { Context } from "../context/ContextApi.jsx"; import { ForkRight as ForkRightIcon, } from '@mui/icons-material'; import aa from 'search-insights' import { InstantSearch, Configure, connectSearchBox, connectHits, Index } from 'react-instantsearch-dom'; import algoliasearch from 'algoliasearch/lite'; import YAML from "yaml"; import { useNavigate, Link, useParams } from "react-router-dom"; //import { useAlert import { ToastContainer, toast } from "react-toastify" import Dropzone from "../components/Dropzone.jsx"; const surfaceColor = "#27292D"; const inputColor = "#383B40"; const chipStyle = { backgroundColor: "#3d3f43", height: 28, marginRight: 5, paddingLeft: 5, paddingRight: 5, cursor: "pointer", borderColor: "#3d3f43", color: "white", }; // Fixes names by making them uppercase and such // Used for labels. A lot of places don't use this yet export const FixName = (name) => { if (name === undefined || name === null) { return "" } const newAppname = ( name.charAt(0).toUpperCase() + name.substring(1) ).replaceAll("_", " ") return newAppname } // Takes input of e.g. $node.data.#.asd and a matching value from a json blob // Returns export const FindJsonPath = (path, inputdata) => { const splitkey = "."; var parsedValues = []; if (inputdata === undefined || inputdata === null) { console.log("Input is ", inputdata, ". Returning.") return inputdata } if (typeof inputdata !== "object") { console.log("Input is NOT an object. Returning.") return inputdata } var keysplit = path.split(splitkey) if (path.startsWith("$") && keysplit.length > 1) { keysplit = keysplit.slice(1,) } if (keysplit.length === 0) { console.log("Couldn't find key: length is 0 for keysplit.") return inputdata } // FIXME: Check list - always getting FIRST item, not digging too deep. // If object, send further if (keysplit[0].includes("#")) { if (Object.prototype.toString.call(inputdata) === '[object Array]') { if (inputdata.length === 0) { return "" } else { // Fix the list if (keysplit.length === 1) { return inputdata[0] } else { const joinedsplit = keysplit.slice(1,).join(".") return FindJsonPath(joinedsplit, inputdata[0]) } } } else { return "" } } var found = false for (const [key, value] of Object.entries(inputdata)) { const newkey = key.valueOf().toLowerCase().replaceAll(" ", "_") if (key === keysplit[0] || newkey === keysplit[0]) { found = true // Return if no more keys // Else, dig deeper if (keysplit.length === 1) { return value } else { const joinedsplit = keysplit.slice(1,).join(".") return FindJsonPath(joinedsplit, value) } } else { //console.log("N: ", key) } } return inputdata } export const internalIds = ["shuffle tools", "http", "email"]; // Parses JSON data into keys that can be used everywhere :) // Reverse of this is FindJsonPath export const GetParsedPaths = (inputdata, basekey) => { const splitkey = "."; var parsedValues = []; if (inputdata === undefined || inputdata === null) { return parsedValues; } if (typeof inputdata !== "object") { return parsedValues } for (var [key, value] of Object.entries(inputdata)) { key = key.replaceAll(" ", "_") // Check if loop or JSON const extra = basekey.length > 0 ? splitkey : ""; const basekeyname = `${basekey .slice(1, basekey.length) .split(".") .join(splitkey)}${extra}${key}` // Handle direct loop! if (!isNaN(key) && basekey === "") { parsedValues.push({ type: "object", name: "Node", autocomplete: `${basekey.replaceAll(" ", "_")}`, }); //parsedValues.push({ // type: "value", // name: `${basekey} length`, // autocomplete: `{{ ${basekey.replaceAll(" ", "_")} | size }}`, //}); parsedValues.push({ type: "list", name: `${splitkey}list`, autocomplete: `${basekey.replaceAll(" ", "_")}.#`, }) const returnValues = GetParsedPaths(value, `${basekey}.#`); for (var subkey in returnValues) { parsedValues.push(returnValues[subkey]); } return parsedValues; } //console.log("KEY: ", key, "VALUE: ", value, "BASEKEY: ", basekeyname) if (typeof value === "object") { if (Array.isArray(value)) { // Check if each item is object parsedValues.push({ type: "object", name: basekeyname, autocomplete: `${basekey}.${key.replaceAll(" ", "_")}`, }); //parsedValues.push({ // type: "value", // name: `${basekeyname} length`, // autocomplete: "{{ "+`${basekey}.${key.replaceAll(" ", "_")} | size }}`, //}); parsedValues.push({ type: "list", name: `${basekeyname}${splitkey}list`, autocomplete: `${basekey}.${key.replaceAll(" ", "_")}.#`, }); // Only check the first. This would be probably be dumb otherwise. for (var subkey in value) { if (typeof value === "object") { const returnValues = GetParsedPaths( value[subkey], `${basekey}.${key}.#` ); for (var subkey in returnValues) { parsedValues.push(returnValues[subkey]); } } // Don't need else as # (all items) is already defined before the loop break; } //console.log(key+" is array") } else { parsedValues.push({ type: "object", name: basekeyname, autocomplete: `${basekey}.${key.replaceAll(" ", "_")}`, }); const returnValues = GetParsedPaths(value, `${basekey}.${key}`); for (var subkey in returnValues) { parsedValues.push(returnValues[subkey]); } } } else { parsedValues.push({ type: "value", name: basekeyname, autocomplete: `${basekey}.${key.replaceAll(" ", "_")}`, value: value, }); } } return parsedValues; }; const searchClient = algoliasearch("JNSS5CFDZZ", "c8f882473ff42d41158430be09ec2b4e") const Apps = (props) => { const { globalUrl, isLoggedIn, isLoaded, userdata, serverside, } = props; //const [workflows, setWorkflows] = React.useState([]); const baseRepository = "https://github.com/frikky/shuffle-apps"; //const alert = useAlert(); let navigate = useNavigate(); const [selectedApp, setSelectedApp] = React.useState({}); const [firstrequest, setFirstrequest] = React.useState(true); const [apps, setApps] = React.useState([]); const [filteredApps, setFilteredApps] = React.useState([]); const [validation, setValidation] = React.useState(false); const [isLoading, setIsLoading] = React.useState(true); const [appSearchLoading, setAppSearchLoading] = React.useState(false); const [selectedAction, setSelectedAction] = React.useState({}); const [searchBackend, setSearchBackend] = React.useState(false); const [searchableApps, setSearchableApps] = React.useState([]); const [publishModalOpen, setPublishModalOpen] = React.useState(false); const [openApi, setOpenApi] = React.useState(""); const [openApiData, setOpenApiData] = React.useState(""); const [appValidation, setAppValidation] = React.useState(""); const [loadAppsModalOpen, setLoadAppsModalOpen] = React.useState(false); const [deleteModalOpen, setDeleteModalOpen] = React.useState(false); const [openApiModal, setOpenApiModal] = React.useState(false); const [generateAppModal, setGenerateAppModal] = React.useState(false); const [openApiModalType, setOpenApiModalType] = React.useState(""); const [openApiError, setOpenApiError] = React.useState(""); const [field1, setField1] = React.useState(""); const [field2, setField2] = React.useState(""); const [cursearch, setCursearch] = React.useState(""); const [sharingConfiguration, setSharingConfiguration] = React.useState("you"); const [downloadBranch, setDownloadBranch] = React.useState("master"); const [creatorProfile, setCreatorProfile] = React.useState({}); const [contact, setContact] = React.useState(""); const [isDropzone, setIsDropzone] = React.useState(false); const upload = React.useRef(null); const [firstLoad, setFirstLoad] = React.useState(true); const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io" ? true : false; const borderRadius = 3; const viewWidth = 590; const { start, stop } = useInterval({ duration: 5000, startImmediate: false, callback: () => { getApps(); }, }); useEffect(() => { console.log("APPVALID: ", appValidation) redirectOpenApi() }, [appValidation]) const getUserProfile = (username) => { if (serverside === true || !isCloud) { setCreatorProfile({}) return; } fetch(`${globalUrl}/api/v1/users/creators/${username}`, { method: "GET", headers: { "Content-Type": "application/json", Accept: "application/json", }, credentials: "include", }) .then((response) => { if (response.status !== 200) { console.log("Status not 200 for WORKFLOW EXECUTION :O!"); } return response.json(); }) .then((responseJson) => { if (responseJson.success !== false) { setCreatorProfile(responseJson); } else { setCreatorProfile({}) } }) .catch((error) => { console.log(error); setCreatorProfile({}) }); }; useEffect(() => { if (apps.length <= 0 && firstrequest) { document.title = "Shuffle - Apps"; if (!isLoggedIn && isLoaded) { if (isCloud) { navigate("/search?tab=apps") } else { navigate("/login") } } setFirstrequest(false); getApps(); } }); function sortByKey(array, key) { if (array === undefined || array === null) { return array; } return array.sort(function (a, b) { var x = a[key]; var y = b[key]; if (typeof x == "string") { x = ("" + x).toLowerCase(); } if (typeof y == "string") { y = ("" + y).toLowerCase(); } return x < y ? 1 : x > y ? -1 : 0; }); } const appViewStyle = { color: "#ffffff", width: "100%", display: "flex", margin: "auto", }; const paperAppStyle = { minHeight: 130, maxHeight: 130, minWidth: "100%", maxWidth: 612.5, marginBottom: 5, borderRadius: theme.palette?.borderRadius, color: "white", backgroundColor: surfaceColor, cursor: "pointer", display: "flex", }; const getApps = () => { // Get apps from localstorage var storageApps = [] try { const appstorage = localStorage.getItem("apps") storageApps = JSON.parse(appstorage) if (storageApps === null || storageApps === undefined || storageApps.length === 0) { storageApps = [] } else { setApps(storageApps) setFilteredApps(storageApps) setAppSearchLoading(false) } } catch (e) { //console.log("Failed to get apps from localstorage: ", e) } fetch(globalUrl + "/api/v1/apps", { method: "GET", headers: { "Content-Type": "application/json", Accept: "application/json", }, credentials: "include", }) .then((response) => { setIsLoading(false); if (response.status !== 200) { console.log("Status not 200 for apps :O!"); //if (isCloud) { // window.location.pathname = "/search"; //} } return response.json(); }) .then((responseJson) => { //responseJson = sortByKey(responseJson, "large_image") //responseJson = sortByKey(responseJson, "is_valid") //setFilteredApps(responseJson.filter(app => !internalIds.includes(app.name) && !(!app.activated && app.generated))) var privateapps = []; var valid = []; var invalid = []; for (var key in responseJson) { const app = responseJson[key]; if (app.is_valid && !(!app.activated && app.generated)) { privateapps.push(app); } else if ( app.private_id !== undefined && app.private_id.length > 0 ) { valid.push(app); } else { invalid.push(app); } } //console.log(privateapps) //console.log(valid) //console.log(invalid) //console.log(privateapps) //privateapps.reverse() privateapps.push(...valid); privateapps.push(...invalid); setApps(privateapps); setCursearch(""); //handleSearchChange(event.target.value) //setCursearch(event.target.value) setFilteredApps(privateapps); if (privateapps.length > 0) { if (selectedApp.id === undefined || selectedApp.id === null) { if (privateapps[0].owner !== undefined && privateapps[0].owner !== null) { getUserProfile(privateapps[0].owner); } setContact(privateapps[0].contact_info) setSelectedApp(privateapps[0]); setSharingConfiguration(privateapps[0].sharing === true ? "public" : "you") } if ( privateapps[0].actions !== null && privateapps[0].actions.length > 0 ) { setSelectedAction(privateapps[0].actions[0]); } else { setSelectedAction({}); } } if (privateapps.length > 0 && storageApps.length === 0) { try { localStorage.setItem("apps", JSON.stringify(privateapps)) } catch (e) { console.log("Failed to set apps in localstorage: ", e) } } //setTimeout(() => { // setFirstLoad(false) //}, 5000) }) .catch((error) => { toast(error.toString()); setIsLoading(false); }); }; const downloadApp = (inputdata) => { const id = inputdata.id; toast("Downloading.."); fetch(globalUrl + "/api/v1/apps/" + id + "/config", { method: "GET", headers: { "Content-Type": "application/json", Accept: "application/json", }, credentials: "include", }) .then((response) => { if (response.status !== 200) { window.location.pathname = "/apps"; } return response.json(); }) .then((responseJson) => { if (!responseJson.success) { toast("Failed to download file"); } else { console.log(responseJson); const basedata = atob(responseJson.openapi); console.log("BASE: ", basedata); var inputdata = JSON.parse(basedata); console.log("POST INPUT: ", inputdata); inputdata = JSON.parse(inputdata.body); const newpaths = {}; if (inputdata["paths"] !== undefined) { Object.keys(inputdata["paths"]).forEach(function (key) { newpaths[key.split("?")[0]] = inputdata.paths[key]; }); } inputdata.paths = newpaths; console.log("INPUT: ", inputdata); var name = inputdata.info.title; name = name.replace(/ /g, "_", -1); name = name.toLowerCase(); delete inputdata.id; delete inputdata.editing; const data = YAML.stringify(inputdata); var blob = new Blob([data], { type: "application/octet-stream", }); var url = URL.createObjectURL(blob); var link = document.createElement("a"); link.setAttribute("href", url); link.setAttribute("download", `${name}.yaml`); var event = document.createEvent("MouseEvents"); event.initMouseEvent( "click", true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null ); link.dispatchEvent(event); //link.parentNode.removeChild(link) } }) .catch((error) => { console.log(error); toast(error.toString()); }); }; // dropdown with copy etc I guess const AppPaper = (props) => { const { app } = props let data = app if (data.name === "" && data.id === "") { return null; } var boxWidth = "2px"; if (selectedApp.id === data.id) { boxWidth = "4px"; } var boxColor = "orange"; if (data.is_valid) { boxColor = "green"; } if (!data.activated && data.generated) { boxColor = "orange"; } if (data.invalid) { boxColor = "red"; } //
//
var imageline = data.large_image === undefined || data.large_image.length === 0 ? ( {data.title} ) : ( {data.title} { //console.log("IMG LOADED!: ", event.target) }} /> ); var newAppname = data.name; if (newAppname === undefined) { newAppname = "Undefined"; } else { newAppname = newAppname.charAt(0).toUpperCase() + newAppname.substring(1); newAppname = newAppname.replaceAll("_", " "); } var sharing = "public"; if (!data.sharing) { sharing = "private"; } var valid = "true"; if (!data.valid) { valid = "false"; } if (data.actions === undefined || data.actions === null) { // Check if data type undefined/bool if (typeof data === "boolean") { data = {} } data.actions = [] } if (data === undefined || data.actions === undefined || data.actions === null || data.actions.length === 0) { valid = "false" } var description = data.description; const maxDescLen = 60; if (description.length > maxDescLen) { description = data.description.slice(0, maxDescLen) + "..."; } const version = data.app_version; return ( { if (selectedApp.id !== data.id) { if (data.owner !== undefined && data.owner !== null) { getUserProfile(data.owner); } setContact(data.contact_info) data.name = newAppname; setSelectedApp(data); setSharingConfiguration(data.sharing === true ? "public" : "you") if ( data.actions !== undefined && data.actions !== null && data.actions.length > 0 ) { setSelectedAction(data.actions[0]); } else { setSelectedAction({}); } if (data.sharing) { setSharingConfiguration("public"); } } }} > {imageline}
{newAppname}
{description}
{data.tags === null || data.tags === undefined ? null : data.tags.map((tag, index) => { if (index >= 3) { return null; } return ( { //console.log("SEARCH: ", event.target.value) handleSearchChange(tag); setCursearch(tag); //id="app_search_field" const searchfield = document.getElementById("app_search_field"); if ( searchfield !== null && searchfield !== undefined ) { console.log("SEARCHFIELD: ", searchfield); searchfield.value = tag; } }} /> ); })}
{data.activated && data.private_id !== undefined && data.private_id.length > 0 && data.generated ? ( { downloadApp(data); }} > ) : null} ); }; const dividerColor = "rgb(225, 228, 232)"; const uploadViewPaperStyle = { minWidth: viewWidth, maxWidth: viewWidth, color: "white", borderRadius: theme.palette?.borderRadius, backgroundColor: surfaceColor, //display: "flex", marginBottom: 10, overflow: "hidden", }; const UploadView = () => { //var imageline = selectedApp.large_image === undefined || selectedApp.large_image.length === 0 ? // // : // PICTURE // FIXME - add label to apps, as this might be slow with A LOT of apps var newAppname = selectedApp.name; if (newAppname !== undefined && newAppname.length > 0) { newAppname = newAppname.replaceAll("_", " "); newAppname = newAppname.charAt(0).toUpperCase() + newAppname.substring(1); } else { newAppname = ""; } var description = selectedApp.description; const editUrl = "/apps/edit/" + selectedApp.id; const activateUrl = "/apps/new?id=" + selectedApp.id; var downloadButton = selectedApp.activated && selectedApp.private_id !== undefined && selectedApp.private_id.length > 0 && selectedApp.generated ? ( ) : null; // Should always reference the original ID. //if (selectedApp.name !== undefined && selectedApp.name !== null && selectedApp.name.includes("New")) { //} var editButton = selectedApp.activated && selectedApp.private_id !== undefined && selectedApp.private_id.length > 0 && selectedApp.generated ? ( ) : null; //var editNewButton = editButton === null ? var editNewButton = selectedApp.generated && selectedApp.activated && props.userdata.id !== selectedApp.owner && isCloud ? : null const activateButton = selectedApp.generated && !selectedApp.activated ? (
) : null; const deleteButton = ((selectedApp.private_id !== undefined && selectedApp.private_id.length > 0 && selectedApp.generated) || (selectedApp.downloaded !== undefined && selectedApp.downloaded == true) || !selectedApp.generated) && activateButton === null ? ( ) : null; var imageline = selectedApp.large_image === undefined || selectedApp.large_image.length === 0 ? ( {selectedApp.title} ) : ( {selectedApp.title} ); const GetAppExample = () => { if (selectedAction.returns === undefined) { return null; } var showResult = selectedAction.returns.example; if ( showResult === undefined || showResult === null || showResult.length === 0 ) { return null; } var jsonvalid = true; try { const tmp = String(JSON.parse(showResult)); if (!tmp.includes("{") && !tmp.includes("[")) { jsonvalid = false; } } catch (e) { jsonvalid = false; } // FIXME: In here -> parse the values into a list or something if (jsonvalid) { const paths = GetParsedPaths(JSON.parse(showResult), ""); console.log("PATHS: ", paths); return (
{paths.map((data, index) => { const circleSize = 10; return ( console.log(data.autocomplete)} > {data.name} ); })}
); } return (
Example return
{selectedAction.returns.example}
); }; const userRoles = ["you", "public"]; // Admin in org or creator of app // FIXME: Missing check for if same creator account const canEditApp = userdata !== undefined && (userdata.admin === "true" || userdata.id === selectedApp.owner || selectedApp.owner === "" || (userdata.admin === "true" && userdata.active_org.id === selectedApp.reference_org)) || !selectedApp.generated //fetch(globalUrl+"/api/v1/get_openapi/"+urlParams.get("id"), var baseInfo = newAppname.length > 0 ? (
{imageline}
{newAppname} Version {selectedApp.app_version} {description}
{selectedApp.versions !== null && selectedApp.versions !== undefined && selectedApp.versions.length > 1 ? ( ) : null} {isCloud ? ( ) : null} {activateButton} { /* editNewButton === null && */ } {canEditApp ? (
{editButton} {downloadButton} {deleteButton}
) :
{editNewButton}
} {canEditApp ? (
{/*

ID: {selectedApp.id}

*/} Sharing {/*isCloud && (selectedApp.sharing === true || selectedApp.public === true || creatorProfile.github_avatar !== undefined) && !internalIds.includes(selectedApp.name.toLowerCase()) */} {isCloud && !internalIds.includes(selectedApp.name.toLowerCase()) ? : null}
) : null}
{isCloud && Object.getOwnPropertyNames(creatorProfile).length !== 0 && creatorProfile.github_avatar !== undefined && creatorProfile.github_avatar !== null ?
{ //setAnchorElAvatar(event.currentTarget); }} > Shared by{" "} {creatorProfile.github_username}
: null} {selectedApp.tags !== undefined && selectedApp.tags !== null ? (
{selectedApp.tags.map((tag, index) => { if (index >= 3) { return null; } return ( ); })}
) : null}
{/*

Owner: {selectedApp.owner}

*/} {selectedApp.privateId !== undefined && selectedApp.privateId.length > 0 ? (

PrivateID: {selectedApp.privateId}

) : null}
{selectedApp.link.length > 0 ? (

URL: {selectedApp.link}

) : null}
Actions {selectedApp.actions !== null && selectedApp.actions.length > 0 ? ( ) : (
There are no actions defined for this app.
)}
{selectedAction.parameters !== undefined && selectedAction.parameters !== null ? (
Parameters {selectedAction.parameters.map((data) => { var itemColor = "#f85a3e"; if (!data.required) { itemColor = "#ffeb3b"; } const circleSize = 10; return ( {data.configuration === true ? ( ) : (
)} {data.name} ); })}
) : null} {selectedAction.description !== undefined && selectedAction.description !== null && selectedAction.description.length > 0 ? (
Action Description
{selectedAction.description}
) : null}
) : null; const AppCreateButton = (props) => { const { text, func, icon } = props; const [hover, setHover] = React.useState(false); const makeFancy = text?.includes("Generate") var parsedStyle = { flex: 1, padding: 15, margin: 10, paddingTop: 25, backgroundColor: hover ? theme.palette.surfaceColor : "transparent", cursor: hover ? "pointer" : "default", textAlign: "center", minHeight: 150, maxHeight: 150, borderRadius: theme.palette?.borderRadius, } if (!makeFancy) { parsedStyle.border = hover ? "1px solid #f85a3e" : "1px solid rgba(255,255,255,0.3)" } else { parsedStyle.border = "1px solid transparent" parsedStyle.borderImage = "linear-gradient(45deg, red, orange, yellow, green, blue, indigo, violet) 1" parsedStyle.borderRadius = 0 // This doesn't work. Try to hover with a high one, and it's weird due to borderImage } return ( setHover(true)} onMouseLeave={() => setHover(false)} onClick={func} style={parsedStyle} > {icon} {text} ) } return (

App Creator

{ setOpenApiModal(true) }} icon={} /> { setGenerateAppModal(true) }} icon={} />
{/* How it works  -{" "} Security API's  -{" "} OpenAPI directory  -{" "} OpenAPI Validator
Apps interact with eachother in workflows. They are created with the app creator, using OpenAPI specification or manually in python. The links above are references to OpenAPI tools and other app repositories. There's thousands of them.
 OR 
*/}
{baseInfo}
); }; const handleSearchChange = (search) => { if (apps === undefined || apps === null || apps.length === 0) { return; } const searchfield = search.toLowerCase(); var newapps = apps.filter( (data) => data.name.toLowerCase().includes(searchfield) || data.description.toLowerCase().includes(searchfield) || (data.tags !== null && data.tags.includes(search)) ); var tmpapps = searchableApps.filter( (data) => data.name.toLowerCase().includes(searchfield) || data.description.toLowerCase().includes(searchfield) || (data.tags !== null && data.tags.includes(search)) ); newapps.push(...tmpapps); //console.log(newapps) setFilteredApps(newapps); //if ((newapps.length === 0 || searchBackend) && !appSearchLoading) { // //setAppSearchLoading(true) // //runAppSearch(searchfield) //} else { //} }; const uploadFileDocumentation = (e) => { const isDropzone = e.dataTransfer === undefined ? false : e.dataTransfer.files.length > 0; const files = isDropzone ? e.dataTransfer.files : e.target.files; const reader = new FileReader(); try { reader.addEventListener("load", (e) => { const content = e.target.result; setOpenApiData(content); setIsDropzone(isDropzone); setOpenApiModal(true); }); } catch (e) { console.log("Error in dropzone: ", e); } try { reader.readAsText(files[0]); } catch (error) { toast("Failed to read file"); } }; const uploadFile = (e) => { const isDropzone = e.dataTransfer === undefined ? false : e.dataTransfer.files.length > 0; const files = isDropzone ? e.dataTransfer.files : e.target.files; const reader = new FileReader(); try { reader.addEventListener("load", (e) => { const content = e.target.result; setOpenApiData(content); setIsDropzone(isDropzone); setOpenApiModal(true); }); } catch (e) { console.log("Error in dropzone: ", e); } try { reader.readAsText(files[0]); } catch (error) { toast("Failed to read file"); } }; useEffect(() => { if (openApiData.length > 0) { setOpenApiError(""); validateOpenApi(openApiData); } }, [openApiData]); useEffect(() => { if (appValidation && isDropzone) { redirectOpenApi(); setIsDropzone(false); } }, [appValidation, isDropzone]); var appDelay = -75 const leftBarSize = viewWidth const SearchBox = ({ currentRefinement, refine, isSearchStalled, }) => { useEffect(() => { if (document !== undefined) { const appsearchValue = document.getElementById("app_search_field") if (appsearchValue !== undefined && appsearchValue !== null) { console.log("Value2: ", appsearchValue.value) if (appsearchValue.value !== undefined && appsearchValue.value !== null && appsearchValue.value.length > 0) { refine(appsearchValue.value) } } //} } }, []) return (