diff --git a/backend/app_sdk/app_base.py b/backend/app_sdk/app_base.py index 1ae7049c..a7e1e7bf 100755 --- a/backend/app_sdk/app_base.py +++ b/backend/app_sdk/app_base.py @@ -1212,7 +1212,7 @@ class AppBase: return results # Downloads all files from a namespace - # Currently only working on local version of Shuffle + # Currently only working on local version of Shuffle (2023) def get_file_category_ids(self, category): org_id = self.full_execution["workflow"]["execution_org"]["id"] diff --git a/backend/go-app/go.mod b/backend/go-app/go.mod index 278ea169..ccfc643b 100644 --- a/backend/go-app/go.mod +++ b/backend/go-app/go.mod @@ -18,7 +18,7 @@ require ( github.com/gorilla/mux v1.8.0 github.com/h2non/filetype v1.1.3 github.com/satori/go.uuid v1.2.0 - github.com/shuffle/shuffle-shared v0.5.77 + github.com/shuffle/shuffle-shared v0.5.78 golang.org/x/crypto v0.16.0 google.golang.org/api v0.125.0 google.golang.org/grpc v1.55.0 @@ -52,7 +52,7 @@ require ( github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/emirpasic/gods v1.18.1 // indirect - github.com/frikky/schemaless v0.0.5 // indirect + github.com/frikky/schemaless v0.0.6 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-logr/logr v1.2.4 // indirect github.com/go-openapi/jsonpointer v0.19.5 // indirect diff --git a/backend/go-app/go.sum b/backend/go-app/go.sum index 3bdc7d06..bdd5b7b7 100644 --- a/backend/go-app/go.sum +++ b/backend/go-app/go.sum @@ -176,8 +176,8 @@ github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM github.com/frikky/kin-openapi v0.41.0/go.mod h1:ev9OZAw7Bv5p0w93j91++6a1ElPzGcCofst+kmrWsj4= github.com/frikky/kin-openapi v0.42.0 h1:d5Z6vnuQ6RnCCPIxZaDL+TH2ODLxT8abytOt+Zh+Kd0= github.com/frikky/kin-openapi v0.42.0/go.mod h1:ev9OZAw7Bv5p0w93j91++6a1ElPzGcCofst+kmrWsj4= -github.com/frikky/schemaless v0.0.5 h1:ptQ0FpQpm/+e7HCYt7Wmc+vcMSelTYCRpKqtLVN2SOY= -github.com/frikky/schemaless v0.0.5/go.mod h1:mooDxY+D6weHjhKvjy3+IE9S7P4g4cpNnidkdRv/cHQ= +github.com/frikky/schemaless v0.0.6 h1:mPWbqCxiOz0HUmdN+IiVOHqquCzA0aachzOdMTCaKtg= +github.com/frikky/schemaless v0.0.6/go.mod h1:mooDxY+D6weHjhKvjy3+IE9S7P4g4cpNnidkdRv/cHQ= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsouza/go-dockerclient v1.9.7 h1:FlIrT71E62zwKgRvCvWGdxRD+a/pIy+miY/n3MXgfuw= @@ -455,6 +455,8 @@ github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/shuffle/shuffle-shared v0.5.78 h1:emHTEu+WboTZQUUcPDrxMx70RtVuZ1LtkYjG2KzncBE= +github.com/shuffle/shuffle-shared v0.5.78/go.mod h1:Lg6/+qjQlWzNKwj4/4ATpvScyP2JQGLkTPlNlRM6RJk= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= diff --git a/backend/go-app/main.go b/backend/go-app/main.go index b2e901d5..0eca60ba 100755 --- a/backend/go-app/main.go +++ b/backend/go-app/main.go @@ -4953,6 +4953,7 @@ func initHandlers() { // PS: For cloud, this has to use cloud storage. // https://developer.box.com/reference/get-files-id-content/ // 1. Creating the "get file" option. Make it possible to run this in the frontend. + r.HandleFunc("/api/v1/files/download_remote", shuffle.HandleDownloadRemoteFiles).Methods("POST", "OPTIONS") r.HandleFunc("/api/v1/files/namespaces/{namespace}", shuffle.HandleGetFileNamespace).Methods("GET", "OPTIONS") r.HandleFunc("/api/v1/files/{fileId}/content", shuffle.HandleGetFileContent).Methods("GET", "OPTIONS") r.HandleFunc("/api/v1/files/create", shuffle.HandleCreateFile).Methods("POST", "OPTIONS") diff --git a/frontend/src/components/ConfigureWorkflow.jsx b/frontend/src/components/ConfigureWorkflow.jsx index ef727fde..e3938c65 100755 --- a/frontend/src/components/ConfigureWorkflow.jsx +++ b/frontend/src/components/ConfigureWorkflow.jsx @@ -77,7 +77,6 @@ const ConfigureWorkflow = (props) => { const [checkStarted, setCheckStarted] = React.useState(false); useEffect(() => { - //console.log("Configure Workflow: Required actions: ", requiredActions) if (requiredActions.length === 0) { if (setConfigurationFinished !== undefined) { setConfigurationFinished(true) @@ -703,9 +702,9 @@ const ConfigureWorkflow = (props) => { }) .then((responseJson) => { if (!responseJson.success) { - toast("Failed to set app auth: " + responseJson.reason); + toast("Failed to set app authentication: " + responseJson.reason); } else { - toast("App auth set for app " + app.name.replace("_", " ")); + toast("App authentication set for app " + app.name.replace("_", " ")); setFinalized(true) setOpened(false) } @@ -743,6 +742,25 @@ const ConfigureWorkflow = (props) => {
{ setOpened(!opened); + + // Scroll to it + const element = document.getElementById("app-config"); + if (element) { + // Scroll down 100px + setTimeout(() => { + element.scrollIntoView({ + behavior: "smooth", + top: 100, + }) + + //element.scrollIntoView({ + // behavior: "smooth", + // block: "center", + // inline: "center" + //}); + }, 250) + } + }} >
@@ -1317,7 +1335,7 @@ const ConfigureWorkflow = (props) => { : null} - + {requiredActions.map((data, index) => { // AppWrapper = Default in a workflow, only shows with steps diff --git a/frontend/src/components/Files.jsx b/frontend/src/components/Files.jsx index 670cba97..73dbcfb7 100644 --- a/frontend/src/components/Files.jsx +++ b/frontend/src/components/Files.jsx @@ -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 ? + {}} + PaperProps={{ + style: { + backgroundColor: theme.palette.surfaceColor, + color: "white", + minWidth: "800px", + minHeight: "320px", + }, + }} + > + +
+ Load Files from Github +
+ + 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. + +
+ + Repository URL (supported: github, gitlab, bitbucket) + setDownloadUrl(e.target.value)} + placeholder="https://github.com/shuffle/standards" + fullWidth + /> +
+ + + Branch (default value is "main"): + + setDownloadBranch(e.target.value)} + placeholder="master" + fullWidth + /> + + + + Folder (can use / for subfolders): + + setDownloadFolder(e.target.value)} + placeholder="translation_standards" + fullWidth + /> + +
+ + Authentication (optional - private repos etc): + +
+ setField1(e.target.value)} + type="username" + placeholder="Username / APIkey (optional)" + fullWidth + /> + setField2(e.target.value)} + type="password" + placeholder="Password (optional)" + fullWidth + /> +
+
+ + + + +
+ : 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} > -
+
+ + + setLoadFileModalOpen(true)} + > + + + + + {fileDownloadModal} +

Files

@@ -393,6 +651,9 @@ const Files = (props) => {
+ + + + + {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("_", " ")} ); })} @@ -487,6 +755,8 @@ const Files = (props) => { } + + {renderTextBox && { handleKeyDown(event); @@ -504,7 +774,7 @@ const Files = (props) => { autoFocus />}
- { /> @@ -615,7 +885,7 @@ const Files = (props) => { }} /> - ) : ( + : ( { - const { globalUrl, inworkflow } = props; + const { globalUrl, inworkflow, height, width } = props; const [elements, setElements] = useState([]); const [workflow, setWorkflow] = useState(inworkflow); const [cy, setCy] = React.useState(); - const bodyWidth = 200; - const bodyHeight = 150; + const bodyWidth = height === undefined ? 1000 : width + const bodyHeight = width === undefined ? 1000 : height const setupGraph = () => { const actions = workflow.actions.map((action) => { @@ -76,29 +76,6 @@ const CytoscapeWrapper = (props) => { }; // This is an attempt at prettier edges. The numbers are weird to work with. - /* - //http://manual.graphspace.org/projects/graphspace-python/en/latest/demos/edge-types.html - const sourcenode = actions.find(node => node.data._id === branch.source_id) - const destinationnode = actions.find(node => node.data._id === branch.destination_id) - if (sourcenode !== undefined && destinationnode !== undefined && branch.source_id !== branch.destination_id) { - //node.data._id = action["id"] - console.log("SOURCE: ", sourcenode.position) - console.log("DESTINATIONNODE: ", destinationnode.position) - - var opposite = true - if (sourcenode.position.x > destinationnode.position.x) { - opposite = false - } else { - opposite = true - } - - edge.style = { - 'control-point-distance': opposite ? ["25%", "-75%"] : ["-10%", "90%"], - 'control-point-weight': ['0.3', '0.7'], - } - } - */ - return edge; }); @@ -135,9 +112,10 @@ const CytoscapeWrapper = (props) => { elements={elements} minZoom={0.35} maxZoom={2.0} + zoom={1.0} style={{ - width: bodyWidth - 15, - height: bodyHeight - 5, + width: bodyWidth, + height: bodyHeight, backgroundColor: surfaceColor, }} stylesheet={cystyle} diff --git a/frontend/src/components/ShuffleCodeEditor.jsx b/frontend/src/components/ShuffleCodeEditor.jsx index 15aec446..3b6e02a2 100644 --- a/frontend/src/components/ShuffleCodeEditor.jsx +++ b/frontend/src/components/ShuffleCodeEditor.jsx @@ -57,7 +57,6 @@ import { padding, textAlign } from '@mui/system'; import data from '../frameworkStyle.jsx'; import { useNavigate, Link, useParams } from "react-router-dom"; import { tags as t } from '@lezer/highlight'; -import { createTheme } from '@uiw/codemirror-themes'; @@ -84,37 +83,6 @@ const pythonFilters = [ {"name": "Handle JSON", "value": `{% python %}\nimport json\njsondata = json.loads(r"""$nodename""")\n{% endpython %}`, "example": ``}, ] -/* -const shuffleTheme = createTheme({ - theme: 'dark', - settings: { - background: "rgba(40,40,40, 1)", - foreground: '#75baff', - caret: '#5d00ff', - selection: '#036dd626', - selectionMatch: '#036dd626', - lineHighlight: '#8a91991a', - gutterForeground: '#8a919966', - }, - styles: [ - { tag: t.comment, color: '#787b8099' }, - { tag: t.variableName, color: '#0080ff' }, - { tag: [t.string, t.special(t.brace)], color: '#5c6166' }, - { tag: t.number, color: '#5c6166' }, - { tag: t.bool, color: '#5c6166' }, - { tag: t.null, color: '#5c6166' }, - { tag: t.keyword, color: '#5c6166' }, - { tag: t.operator, color: '#5c6166' }, - { tag: t.className, color: '#5c6166' }, - { tag: t.definition(t.typeName), color: '#5c6166' }, - { tag: t.typeName, color: '#5c6166' }, - { tag: t.angleBracket, color: '#5c6166' }, - { tag: t.tagName, color: '#5c6166' }, - { tag: t.attributeName, color: '#5c6166' }, - ], -}); -*/ - const CodeEditor = (props) => { const { globalUrl, diff --git a/frontend/src/components/WorkflowTemplatePopup.jsx b/frontend/src/components/WorkflowTemplatePopup.jsx index 08817eda..6df11b9b 100644 --- a/frontend/src/components/WorkflowTemplatePopup.jsx +++ b/frontend/src/components/WorkflowTemplatePopup.jsx @@ -5,6 +5,7 @@ import theme from '../theme.jsx'; import { useNavigate, Link, useParams } from "react-router-dom"; import AppSearchButtons from "../components/AppSearchButtons.jsx"; import { isMobile } from "react-device-detect"; +import RenderCytoscape from "../components/RenderCytoscape.jsx"; import { Button, Typography, @@ -43,6 +44,8 @@ const WorkflowTemplatePopup = (props) => { const [missingDestination, setMissingDestination] = React.useState(undefined); const [configurationFinished, setConfigurationFinished] = React.useState(false); const [appSetupDone, setAppSetupDone] = React.useState(false) + + const [requestSent, setRequestSent] = React.useState(false) const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io"; let navigate = useNavigate(); @@ -294,6 +297,9 @@ const WorkflowTemplatePopup = (props) => { // middle:[] // name: "Email analysis" // source:{app_id: "accdaaf2eeba6a6ed43b2efc0112032d", app_name + if (requestSent === true) { + return + } if (srcapp.includes(":default") || dstapp.includes(":default")) { @@ -331,6 +337,7 @@ const WorkflowTemplatePopup = (props) => { }, } + setRequestSent(true) const url = isCloud ? `${globalUrl}/api/v1/workflows/merge` : `https://shuffler.io/api/v1/workflows/merge` fetch(url, { method: "POST", @@ -344,6 +351,7 @@ const WorkflowTemplatePopup = (props) => { .then((response) => { if (response.status !== 200) { //console.log("Status not 200 for framework!"); + setRequestSent(false) } setWorkflowLoading(false) @@ -361,6 +369,7 @@ const WorkflowTemplatePopup = (props) => { if (responseJson.success === false) { //console.log("Error in workflow template: ", responseJson.error); + setRequestSent(false) const defaultMessage = "Failed to generate workflow the workflow - the Shuffle team has been notified. Contact support@shuffler.io for further assistance." if (responseJson.reason !== undefined && responseJson.reason !== null && responseJson.reason !== "") { @@ -386,6 +395,7 @@ const WorkflowTemplatePopup = (props) => { }) .catch((error) => { console.log("err in framework: ", error.toString()); + setRequestSent(false) setWorkflowLoading(false) }) } @@ -422,6 +432,9 @@ const WorkflowTemplatePopup = (props) => { return null } + const divHeight = 500 + const divWidth = 500 + return ( { setConfigurationFinished={setConfigurationFinished} /> + + {/*workflow !== undefined && workflow !== null && workflow.id !== undefined && workflow.id !== null && workflow.id !== "" ? +
+ +
+ : null*/} + {errorMessage === "" && configurationFinished === true && workflow.id !== undefined && workflowLoading === false ? - - + + { + // Open in new tab + window.open("/workflows/" + workflow.id, "_blank") + }} + > {/* */} - - Workflow generated! + + Workflow Successfully Generated! @@ -686,6 +716,7 @@ const WorkflowTemplatePopup = (props) => { : ""}
+
diff --git a/frontend/src/views/Admin.jsx b/frontend/src/views/Admin.jsx index ce774122..984ebb30 100755 --- a/frontend/src/views/Admin.jsx +++ b/frontend/src/views/Admin.jsx @@ -5,8 +5,6 @@ import { makeStyles } from "@mui/styles"; import { useNavigate, Link } from "react-router-dom"; import countries from "../components/Countries.jsx"; -import CodeEditor from "../components/ShuffleCodeEditor.jsx"; -import getLocalCodeData from "../components/ShuffleCodeEditor.jsx"; import CacheView from "../components/CacheView.jsx"; import { diff --git a/frontend/src/views/AngularWorkflow.jsx b/frontend/src/views/AngularWorkflow.jsx index fc7aae3c..30161530 100755 --- a/frontend/src/views/AngularWorkflow.jsx +++ b/frontend/src/views/AngularWorkflow.jsx @@ -121,7 +121,7 @@ import * as edgehandles from "cytoscape-edgehandles"; import CytoscapeComponent from "react-cytoscapejs"; import Draggable from "react-draggable"; import cytoscapestyle from "../defaultCytoscapeStyle.jsx"; -import ShuffleCodeEditor from "../components/ShuffleCodeEditor.jsx"; +import ShuffleCodeEditor from "../components/ShuffleCodeEditor1.jsx"; import { validateJson, GetIconInfo } from "../views/Workflows.jsx"; import { GetParsedPaths, internalIds, } from "../views/Apps.jsx"; diff --git a/frontend/src/views/Dashboard.jsx b/frontend/src/views/Dashboard.jsx index 04b53a40..e9a5c201 100755 --- a/frontend/src/views/Dashboard.jsx +++ b/frontend/src/views/Dashboard.jsx @@ -1,16 +1,11 @@ -import React, { useState, useEffect } from "react"; -import { useInterval } from "react-powerhooks"; -import AppFramework from "../components/AppFramework.jsx"; -import { makeStyles, } from "@mui/styles"; -// nodejs library that concatenates classes -import classNames from "classnames"; -import theme from '../theme.jsx'; -import { useNavigate, Link, useParams } from "react-router-dom"; -import WorkflowTemplatePopup from "../components/WorkflowTemplatePopup.jsx"; - -// react plugin used to create charts -//import { Line, Bar } from "react-chartjs-2"; -//import { useAlert +import React, { useState, useEffect } from "react" +import { useInterval } from "react-powerhooks" +import AppFramework from "../components/AppFramework.jsx" +import { makeStyles, } from "@mui/styles" +import classNames from "classnames" +import theme from '../theme.jsx' +import { useNavigate, Link, useParams } from "react-router-dom" +import WorkflowTemplatePopup from "../components/WorkflowTemplatePopup.jsx" import { ToastContainer, toast } from "react-toastify" import { parsedDatatypeImages } from "../components/AppFramework.jsx" import { findSpecificApp } from "../components/AppFramework.jsx" diff --git a/frontend/src/views/Workflows.jsx b/frontend/src/views/Workflows.jsx index fdf23604..f453c98a 100755 --- a/frontend/src/views/Workflows.jsx +++ b/frontend/src/views/Workflows.jsx @@ -551,9 +551,7 @@ const Workflows = (props) => { const [field1, setField1] = React.useState(""); const [field2, setField2] = React.useState(""); - const [downloadUrl, setDownloadUrl] = React.useState( - "https://github.com/frikky/shuffle-workflows" - ); + const [downloadUrl, setDownloadUrl] = React.useState("https://github.com/shuffle/workflows") const [downloadBranch, setDownloadBranch] = React.useState("master"); const [loadWorkflowsModalOpen, setLoadWorkflowsModalOpen] = React.useState(false); @@ -3630,7 +3628,7 @@ const Workflows = (props) => { const handleGithubValidation = () => { importWorkflowsFromUrl(downloadUrl); setLoadWorkflowsModalOpen(false); - }; + } const workflowDownloadModalOpen = loadWorkflowsModalOpen ? ( { }, }} onChange={(e) => setDownloadUrl(e.target.value)} - placeholder="https://github.com/frikky/shuffle-apps" + placeholder="https://github.com/shuffle/workflows" fullWidth /> - Branch (default value is "master"): + Branch (default value is "main"):