import React, { useState, useEffect } from "react"; import { IconButton, List, ListItem, ListItemText, ListItemAvatar, ListItemSecondaryAction, Tooltip, Button, FormControl, InputLabel, TextField, Divider, Select, MenuItem, } from "@material-ui/core"; import { OpenInNew as OpenInNewIcon, Edit as EditIcon, CloudDownload as CloudDownloadIcon, Delete as DeleteIcon, FileCopy as FileCopyIcon, Cached as CachedIcon, Publish as PublishIcon, Clear as ClearIcon, Add as AddIcon, } from "@material-ui/icons"; import { useAlert } from "react-alert"; import Dropzone from "../components/Dropzone.jsx"; import CodeEditor from "../components/ShuffleCodeEditor.jsx"; import theme from "../theme"; const Files = (props) => { const { globalUrl, userdata, serverside, selectedOrganization, } = props; const [files, setFiles] = React.useState([]); const [selectedNamespace, setSelectedNamespace] = React.useState("default"); const [openFileId, setOpenFileId] = React.useState(false); const [fileNamespaces, setFileNamespaces] = React.useState([]); const [fileContent, setFileContent] = React.useState(""); const [openEditor, setOpenEditor] = React.useState(false); const [renderTextBox, setRenderTextBox] = React.useState(false); const alert = useAlert(); const allowedFileTypes = ["txt", "py", "yaml", "yml","json", "html", "js", "csv",] var upload = ""; const handleKeyDown = (event) => { if (event.key === 'Enter') { console.log('do validate') console.log("new namespace name->",event.target.value); fileNamespaces.push(event.target.value); setSelectedNamespace(event.target.value); setRenderTextBox(false); } if (event.key === 'Escape'){ // not working for some reasons console.log('escape pressed') setRenderTextBox(false); } } const runUpdateText = (text) =>{ fetch(`${globalUrl}/api/v1/files/${openFileId}/edit`, { method: "PUT", headers: { "Content-Type": "application/json", Accept: "application/json", }, body:text, credentials: "include", }).then((response) => { if (response.status !== 200) { console.log("Can't update file"); } return response.json(); }) //console.log(text); } const getFiles = () => { fetch(globalUrl + "/api/v1/files", { method: "GET", headers: { "Content-Type": "application/json", Accept: "application/json", }, credentials: "include", }) .then((response) => { if (response.status !== 200) { console.log("Status not 200 for apps :O!"); return; } return response.json(); }) .then((responseJson) => { if (responseJson.files !== undefined && responseJson.files !== null) { setFiles(responseJson.files); } else { setFiles([]); } console.log("NAMESPACES: ", responseJson.namespaces); if ( responseJson.namespaces !== undefined && responseJson.namespaces !== null ) { setFileNamespaces(responseJson.namespaces); } }) .catch((error) => { alert.error(error.toString()); }); }; useEffect(() => { getFiles(); }, []); const deleteFile = (file) => { fetch(globalUrl + "/api/v1/files/" + file.id, { method: "DELETE", headers: { "Content-Type": "application/json", Accept: "application/json", }, credentials: "include", }) .then((response) => { if (response.status !== 200) { console.log("Status not 200 for file delete :O!"); } return response.json(); }) .then((responseJson) => { if (responseJson.success) { alert.info("Successfully deleted file " + file.name); } else if ( responseJson.reason !== undefined && responseJson.reason !== null ) { alert.error("Failed to delete file: " + responseJson.reason); } setTimeout(() => { getFiles(); }, 1500); console.log(responseJson); }) .catch((error) => { alert.error(error.toString()); }); }; const readFileData = (file) => { fetch(globalUrl + "/api/v1/files/" + file.id + "/content", { method: "GET", headers: { "Content-Type": "application/json", Accept: "application/json", }, credentials: "include", }) .then((response) => { if (response.status !== 200) { console.log("Status not 200 for file :O!"); return ""; } return response.text(); }) .then((respdata) => { // console.log("respdata ->", respdata); // console.log("respdata type ->", typeof(respdata)); if (respdata.length === 0) { alert.error("Failed getting file. Is it deleted?"); return; } return respdata }) .then((responseData) => { setFileContent(responseData); //console.log("filecontent state ",fileContent); }) .catch((error) => { alert.error(error.toString()); }); }; const downloadFile = (file) => { fetch(globalUrl + "/api/v1/files/" + file.id + "/content", { method: "GET", credentials: "include", }) .then((response) => { if (response.status !== 200) { console.log("Status not 200 for apps :O!"); return ""; } console.log("Resp: ", response) return response.blob() }) .then((respdata) => { if (respdata.length === 0) { alert.error("Failed getting file. Is it deleted?"); return; } var blob = new Blob([respdata], { type: "application/octet-stream", }); var url = URL.createObjectURL(blob); var link = document.createElement("a"); link.setAttribute("href", url); link.setAttribute("download", `${file.filename}`); 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); //return response.json() }) .then((responseJson) => { //console.log(responseJson) //setSchedules(responseJson) }) .catch((error) => { alert.error(error.toString()); }); }; const handleCreateFile = (filename, file) => { var data = { filename: filename, org_id: selectedOrganization.id, workflow_id: "global", }; if ( selectedNamespace !== undefined && selectedNamespace !== null && selectedNamespace.length > 0 && selectedNamespace !== "default" ) { data.namespace = selectedNamespace; } fetch(globalUrl + "/api/v1/files/create", { method: "POST", headers: { "Content-Type": "application/json", Accept: "application/json", }, credentials: "include", body: JSON.stringify(data), }) .then((response) => { if (response.status !== 200) { console.log("Status not 200 for apps :O!"); return; } return response.json(); }) .then((responseJson) => { //console.log("RESP: ", responseJson) if (responseJson.success === true) { handleFileUpload(responseJson.id, file); } else { alert.error("Failed to upload file ", filename); } }) .catch((error) => { alert.error("Failed to upload file ", filename); console.log(error.toString()); }); }; const handleFileUpload = (file_id, file) => { //console.log("FILE: ", file_id, file) fetch(`${globalUrl}/api/v1/files/${file_id}/upload`, { method: "POST", credentials: "include", body: file, }) .then((response) => { if (response.status !== 200 && response.status !== 201) { console.log("Status not 200 for apps :O!"); alert.error("File was created, but failed to upload."); return; } return response.json(); }) .then((responseJson) => { //console.log("RESPONSE: ", responseJson) //setFiles(responseJson) }) .catch((error) => { alert.error(error.toString()); }); }; const uploadFiles = (files) => { for (var key in files) { try { const filename = files[key].name; var filedata = new FormData(); filedata.append("shuffle_file", files[key]); if (typeof files[key] === "object") { handleCreateFile(filename, filedata); } /* reader.addEventListener('load', (e) => { var data = e.target.result; setIsDropzone(false) console.log(filename) console.log(data) console.log(files[key]) }) reader.readAsText(files[key]) */ } catch (e) { console.log("Error in dropzone: ", e); } } setTimeout(() => { getFiles(); }, 2500); }; 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(); //alert.info("Starting fileupload") uploadFiles(files); }; return ( 1366 ? 1366 : 1200, margin: "auto", padding: 20, }} onDrop={uploadFile} >

Files

Files from Workflows.{" "} Learn more
{/* */} (upload = ref)} onChange={(event) => { //const file = event.target.value //const fileObject = URL.createObjectURL(actualFile) //setFile(fileObject) //const files = event.target.files[0] uploadFiles(event.target.files); }} /> {fileNamespaces !== undefined && fileNamespaces !== null && fileNamespaces.length > 1 ? ( File Category ) : null}
{renderTextBox ? : } {renderTextBox && { handleKeyDown(event); }} InputProps={{ style: { color: "white", }, }} color="primary" placeholder="File category name" required margin="dense" defaultValue={""} autoFocus />}
{files === undefined || files === null || files.length === 0 ? null : files.map((file, index) => { if (file.namespace === "") { file.namespace = "default"; } if (file.namespace !== selectedNamespace) { return null; } var bgColor = "#27292d"; if (index % 2 === 0) { bgColor = "#1f2023"; } const filenamesplit = file.filename.split(".") const iseditable = file.filesize < 100000 && file.status === "active" && allowedFileTypes.includes(filenamesplit[filenamesplit.length-1]) return ( ) : ( ) } style={{ minWidth: 100, maxWidth: 100, overflow: "hidden", }} /> { setOpenEditor(true) setOpenFileId(file.id) readFileData(file) }} > { downloadFile(file); }} > { const elementName = "copy_element_shuffle"; var copyText = document.getElementById(elementName); if ( copyText !== null && copyText !== undefined ) { const clipboard = navigator.clipboard; if (clipboard === undefined) { alert.error( "Can only copy over HTTPS (port 3443)" ); return; } navigator.clipboard.writeText(file.id); copyText.select(); copyText.setSelectionRange( 0, 99999 ); /* For mobile devices */ /* Copy the text inside the text field */ document.execCommand("copy"); alert.info(file.id + " copied to clipboard"); } }} > { deleteFile(file); }} > style={{ minWidth: 250, maxWidth: 250, // overflow: "hidden", }} /> ); }) }
) } export default Files;