Fixed file category loading and small workflow changes

This commit is contained in:
Frikky
2024-02-21 09:32:33 +01:00
parent 51935b96a8
commit f8640d854f
14 changed files with 375 additions and 122 deletions
+291 -21
View File
@@ -16,6 +16,11 @@ import {
Divider,
Select,
MenuItem,
Dialog,
DialogTitle,
DialogContent,
DialogActions,
Typography,
} from "@mui/material";
import {
@@ -30,9 +35,8 @@ import {
Add as AddIcon,
} from "@mui/icons-material";
//import { useAlert
import Dropzone from "../components/Dropzone.jsx";
import CodeEditor from "../components/ShuffleCodeEditor.jsx";
import ShuffleCodeEditor from "../components/ShuffleCodeEditor1.jsx";
import theme from "../theme.jsx";
const Files = (props) => {
@@ -45,6 +49,13 @@ const Files = (props) => {
const [fileContent, setFileContent] = React.useState("");
const [openEditor, setOpenEditor] = React.useState(false);
const [renderTextBox, setRenderTextBox] = React.useState(false);
const [loadFileModalOpen, setLoadFileModalOpen] = React.useState(false);
const [field1, setField1] = React.useState("");
const [field2, setField2] = React.useState("");
const [downloadUrl, setDownloadUrl] = React.useState("https://github.com/shuffle/standards")
const [downloadBranch, setDownloadBranch] = React.useState("main");
const [downloadFolder, setDownloadFolder] = React.useState("translation_standards");
//const alert = useAlert();
const allowedFileTypes = ["txt", "py", "yaml", "yml","json", "html", "js", "csv", "log"]
@@ -67,7 +78,7 @@ const Files = (props) => {
}
const runUpdateText = (text) =>{
const runUpdateText = (text) =>{
fetch(`${globalUrl}/api/v1/files/${openFileId}/edit`, {
method: "PUT",
headers: {
@@ -76,17 +87,34 @@ const Files = (props) => {
},
body:text,
credentials: "include",
}).then((response) => {
})
.then((response) => {
if (response.status !== 200) {
console.log("Can't update file");
}
return response.json();
})
//console.log(text);
})
.then((responseJson) => {
if (responseJson.success === true) {
toast("Successfully updated file");
}
})
.catch((error) => {
toast("Error updating file: " + error.toString());
})
}
const getFiles = () => {
fetch(globalUrl + "/api/v1/files", {
const getFiles = (namespace) => {
var parsedurl = `${globalUrl}/api/v1/files`
if (namespace === undefined || namespace === "default") {
} else if (namespace !== undefined && namespace !== null && namespace !== "") {
parsedurl = `${globalUrl}/api/v1/files/namespaces/${namespace}?ids=true`
} else if (selectedNamespace !== undefined && selectedNamespace !== null && selectedNamespace !== "default" && selectedNamespace !== "") {
parsedurl = `${globalUrl}/api/v1/files/namespaces/${selectedNamespace}?ids=true`
}
fetch(parsedurl, {
method: "GET",
headers: {
"Content-Type": "application/json",
@@ -104,12 +132,23 @@ const Files = (props) => {
})
.then((responseJson) => {
if (responseJson.files !== undefined && responseJson.files !== null) {
setFiles(responseJson.files);
} else {
setFiles(responseJson.files);
} else if (responseJson.list !== undefined && responseJson.list !== null) {
// Set the "namespace" field in all items
if (namespace !== undefined && namespace !== null) {
responseJson.list.forEach((item) => {
item.namespace = namespace
item.filename = item.name
item.workflow_id = "global"
})
}
setFiles(responseJson.list);
} else {
setFiles([]);
}
if (responseJson.namespaces !== undefined && responseJson.namespaces !== null) {
if (responseJson.namespaces !== undefined && responseJson.namespaces !== null && (fileNamespaces.length === 0 || responseJson.namespaces.length > fileNamespaces.length)) {
setFileNamespaces(responseJson.namespaces);
}
})
@@ -119,9 +158,214 @@ const Files = (props) => {
};
useEffect(() => {
getFiles();
getFiles(selectedNamespace)
}, []);
const importStandardsFromUrl = (url, folder) => {
if (url === undefined || url === null || url.length < 5) {
toast("Please enter a valid URL");
return;
}
if (folder === undefined || folder === null || folder.length < 2) {
toast("Please enter a valid folder name")
return
}
const parsedData = {
url: url,
path: folder,
field_3: downloadBranch || "master",
};
if (field1.length > 0) {
parsedData["field_1"] = field1;
}
if (field2.length > 0) {
parsedData["field_2"] = field2;
}
toast(`Getting files from url ${url}. This may take a while if the repository is large. Please wait...`);
fetch(globalUrl + "/api/v1/files/download_remote", {
method: "POST",
mode: "cors",
headers: {
Accept: "application/json",
},
body: JSON.stringify(parsedData),
credentials: "include",
})
.then((response) => {
if (response.status === 200) {
toast("Successfully loaded files from " + downloadUrl);
setLoadFileModalOpen(false);
}
return response.json();
})
.then((responseJson) => {
if (!responseJson.success) {
if (responseJson.reason !== undefined) {
toast("Failed loading: " + responseJson.reason);
} else {
toast("Failed loading");
}
}
})
.catch((error) => {
toast(error.toString());
});
}
const handleGithubValidation = () => {
importStandardsFromUrl(downloadUrl, downloadFolder);
}
const fileDownloadModal = loadFileModalOpen ?
<Dialog
open={loadFileModalOpen}
onClose={() => {}}
PaperProps={{
style: {
backgroundColor: theme.palette.surfaceColor,
color: "white",
minWidth: "800px",
minHeight: "320px",
},
}}
>
<DialogTitle>
<div style={{ color: "rgba(255,255,255,0.9)" }}>
Load Files from Github
</div>
<Typography variant="body2" color="textSecondary">
Files will be loaded from the repository and branch you specify, with the focus on files in one folder at a time. This is NOT recursive.
</Typography>
</DialogTitle>
<DialogContent style={{ color: "rgba(255,255,255,0.65)" }}>
Repository URL (supported: github, gitlab, bitbucket)
<TextField
style={{ backgroundColor: theme.palette.inputColor }}
variant="outlined"
margin="normal"
defaultValue={downloadUrl}
InputProps={{
style: {
color: "white",
height: "50px",
fontSize: "1em",
},
}}
onChange={(e) => setDownloadUrl(e.target.value)}
placeholder="https://github.com/shuffle/standards"
fullWidth
/>
<div style={{ display: "flex" }}>
<span>
<span style={{ marginTop: 10 }}>
Branch (default value is "main"):
</span>
<TextField
style={{ backgroundColor: theme.palette.inputColor }}
variant="outlined"
margin="normal"
defaultValue={downloadBranch}
InputProps={{
style: {
color: "white",
height: "50px",
fontSize: "1em",
},
}}
onChange={(e) => setDownloadBranch(e.target.value)}
placeholder="master"
fullWidth
/>
</span>
<span>
<span style={{ marginTop: 10 }}>
Folder (can use / for subfolders):
</span>
<TextField
style={{ backgroundColor: theme.palette.inputColor }}
variant="outlined"
margin="normal"
defaultValue={downloadFolder}
InputProps={{
style: {
color: "white",
height: "50px",
fontSize: "1em",
},
}}
onChange={(e) => setDownloadFolder(e.target.value)}
placeholder="translation_standards"
fullWidth
/>
</span>
</div>
<span style={{ marginTop: 10 }}>
Authentication (optional - private repos etc):
</span>
<div style={{ display: "flex" }}>
<TextField
style={{ flex: 1, backgroundColor: theme.palette.inputColor }}
variant="outlined"
margin="normal"
InputProps={{
style: {
color: "white",
height: "50px",
fontSize: "1em",
},
}}
onChange={(e) => setField1(e.target.value)}
type="username"
placeholder="Username / APIkey (optional)"
fullWidth
/>
<TextField
style={{ flex: 1, backgroundColor: theme.palette.inputColor }}
variant="outlined"
margin="normal"
InputProps={{
style: {
color: "white",
height: "50px",
fontSize: "1em",
},
}}
onChange={(e) => setField2(e.target.value)}
type="password"
placeholder="Password (optional)"
fullWidth
/>
</div>
</DialogContent>
<DialogActions>
<Button
style={{ borderRadius: "0px" }}
onClick={() => setLoadFileModalOpen(false)}
color="primary"
>
Cancel
</Button>
<Button
variant="contained"
style={{ borderRadius: "0px" }}
disabled={downloadUrl.length === 0 || !downloadUrl.includes("http")}
onClick={() => {
handleGithubValidation();
}}
color="primary"
>
Submit
</Button>
</DialogActions>
</Dialog>
: null
const deleteFile = (file) => {
fetch(globalUrl + "/api/v1/files/" + file.id, {
method: "DELETE",
@@ -140,7 +384,7 @@ const Files = (props) => {
})
.then((responseJson) => {
if (responseJson.success) {
toast("Successfully deleted file " + file.name);
toast("Successfully deleted file")
} else if (
responseJson.reason !== undefined &&
responseJson.reason !== null
@@ -254,7 +498,7 @@ const Files = (props) => {
});
};
const handleCreateFile = (filename, file) => {
const handleCreateFile = (filename, file) => {
var data = {
filename: filename,
org_id: selectedOrganization.id,
@@ -355,7 +599,7 @@ const Files = (props) => {
}
setTimeout(() => {
getFiles();
getFiles()
}, 2500);
};
@@ -378,7 +622,21 @@ const Files = (props) => {
}}
onDrop={uploadFile}
>
<div>
<div style={{position: "relative"}}>
<Tooltip color="primary" title={"Import files to Shuffle from Git"} placement="top">
<IconButton
color="secondary"
style={{position: "absolute", right: 0, top: 0, }}
variant="text"
onClick={() => setLoadFileModalOpen(true)}
>
<CloudDownloadIcon />
</IconButton>
</Tooltip>
{fileDownloadModal}
<div style={{ marginTop: 20, marginBottom: 20 }}>
<h2 style={{ display: "inline" }}>Files</h2>
<span style={{ marginLeft: 25 }}>
@@ -393,6 +651,9 @@ const Files = (props) => {
</a>
</span>
</div>
<Button
color="primary"
variant="contained"
@@ -426,6 +687,8 @@ const Files = (props) => {
<CachedIcon />
</Button>
{fileNamespaces !== undefined &&
fileNamespaces !== null &&
fileNamespaces.length > 1 ? (
@@ -442,8 +705,13 @@ const Files = (props) => {
}}
value={selectedNamespace}
onChange={(event) => {
console.log("CHANGE NAMESPACE: ", event.target);
setSelectedNamespace(event.target.value);
if (event.target.value === "all" || event.target.value === "default") {
getFiles()
} else {
getFiles(event.target.value)
}
}}
>
{fileNamespaces.map((data, index) => {
@@ -453,7 +721,7 @@ const Files = (props) => {
value={data}
style={{ color: "white" }}
>
{data}
{data.replaceAll("_", " ")}
</MenuItem>
);
})}
@@ -487,6 +755,8 @@ const Files = (props) => {
<AddIcon/>
</Button>
</Tooltip> }
{renderTextBox && <TextField
onKeyPress={(event)=>{
handleKeyDown(event);
@@ -504,7 +774,7 @@ const Files = (props) => {
autoFocus
/>}</div>
<CodeEditor
<ShuffleCodeEditor
isCloud={isCloud}
expansionModalOpen={openEditor}
setExpansionModalOpen={setOpenEditor}
@@ -602,7 +872,7 @@ const Files = (props) => {
/>
<ListItemText
primary={
file.workflow_id === "global" ? (
file.workflow_id === "global" || file.workflow_id === "" || file.workflow_id === null || file.workflow_id === undefined ?
<IconButton
disabled={file.workflow_id === "global"}
>
@@ -615,7 +885,7 @@ const Files = (props) => {
}}
/>
</IconButton>
) : (
: (
<Tooltip
title={"Go to workflow"}
style={{}}