diff --git a/tensormap-client/.eslintrc.json b/tensormap-client/.eslintrc.json index a9d13bd..44631d1 100644 --- a/tensormap-client/.eslintrc.json +++ b/tensormap-client/.eslintrc.json @@ -1,18 +1,23 @@ { "env": { - "browser": true, - "es2021": true, - "jest":true + "browser": true, + "es2021": true, + "jest": true }, "extends": [ - "react-app", - "react-app/jest", - "airbnb" + "react-app", + "react-app/jest", + "airbnb" ], "parserOptions": { - "ecmaVersion": "latest", - "sourceType": "module" + "ecmaVersion": "latest", + "sourceType": "module" }, "rules": { + "react/jsx-filename-extension": "off", + "react/prop-types": "off", + "no-unused-vars": "off", + "react/function-component-definition": "off" } -} + } + \ No newline at end of file diff --git a/tensormap-client/src/App.js b/tensormap-client/src/App.js index 5cd0b5a..047171f 100644 --- a/tensormap-client/src/App.js +++ b/tensormap-client/src/App.js @@ -1,24 +1,27 @@ -import {BrowserRouter, Route, Switch, Redirect} from "react-router-dom"; -import Layout from "./components/Layout/Layout"; -import Home from "./containers/Home/Home"; -import DataUpload from "./containers/DataUpload/DataUpload"; -import DataProcess from "./containers/DataProcess/DataProcess"; -import DeepLearning from "./containers/DeepLearning/DeepLearning"; +import React from 'react'; +import { + BrowserRouter, Route, Switch, Redirect, +} from 'react-router-dom'; +import Layout from './components/Layout/Layout'; +import Home from './containers/Home/Home'; +import DataUpload from './containers/DataUpload/DataUpload'; +import DataProcess from './containers/DataProcess/DataProcess'; +import DeepLearning from './containers/DeepLearning/DeepLearning'; import * as urls from './constants/Urls'; function App() { return ( - - - - - - - - - - - + + + + + + + + + + + ); } diff --git a/tensormap-client/src/App.test.js b/tensormap-client/src/App.test.js index 1f03afe..6151077 100644 --- a/tensormap-client/src/App.test.js +++ b/tensormap-client/src/App.test.js @@ -3,6 +3,6 @@ import App from './App'; test('renders learn react link', () => { render(); - const linkElement = screen.getByText(/learn react/i); + const linkElement = screen.getByText(/TensorMap is a web application that enables you to create deep learning models using a graphical interface without having to know how to code. It is an open-source application./i); expect(linkElement).toBeInTheDocument(); }); diff --git a/tensormap-client/src/components/DragAndDropCanvas/Canvas.js b/tensormap-client/src/components/DragAndDropCanvas/Canvas.js index 72ca36b..d37944d 100644 --- a/tensormap-client/src/components/DragAndDropCanvas/Canvas.js +++ b/tensormap-client/src/components/DragAndDropCanvas/Canvas.js @@ -1,7 +1,7 @@ -import React, { useState, useRef, useCallback,Fragment } from 'react'; -import { Grid,Form,Button } from 'semantic-ui-react'; -import * as strings from "../../constants/Strings"; -import ModalComponent from '../shared/Modal'; +import React, { + useState, useRef, useCallback, Fragment, +} from 'react'; +import { Grid, Form, Button } from 'semantic-ui-react'; import ReactFlow, { ReactFlowProvider, addEdge, @@ -9,8 +9,11 @@ import ReactFlow, { useEdgesState, Controls, Background, - BackgroundVariant + BackgroundVariant, } from 'reactflow'; +import { useRecoilState } from 'recoil'; +import * as strings from '../../constants/Strings'; +import ModalComponent from '../shared/Modal'; import 'reactflow/dist/style.css'; import InputNode from './CustomNodes/InputNode/InputNode.js'; import DenseNode from './CustomNodes/DenseNode/DenseNode.js'; @@ -19,107 +22,110 @@ import FlattenNode from './CustomNodes/FlattenNode/FlattenNode.js'; import Sidebar from './Sidebar.js'; import PropertiesBar from '../PropertiesBar/PropertiesBar.js'; import './Canvas.css'; -import { enableValidateButton,generateModelJSON,InitialFormState } from './Helpers.js'; +import { enableValidateButton, generateModelJSON, InitialFormState } from './Helpers.js'; import { validateModel } from '../../services/ModelServices'; import { models as allModels } from '../../shared/atoms'; -import {useRecoilState} from 'recoil' let id = 0; const getId = () => `dndnode_${id++}`; -const nodeTypes = { custominput: InputNode,customdense:DenseNode,customflatten:FlattenNode } -const Canvas = () => { +const nodeTypes = { custominput: InputNode, customdense: DenseNode, customflatten: FlattenNode }; +function Canvas() { const reactFlowWrapper = useRef(null); - const [modelList,setModelList] = useRecoilState(allModels) + const [modelList, setModelList] = useRecoilState(allModels); const [nodes, setNodes, onNodesChange] = useNodesState([]); const [edges, setEdges, onEdgesChange] = useEdgesState([]); const [reactFlowInstance, setReactFlowInstance] = useState(null); - const [formState,setFormState] = useState(InitialFormState) - const defaultViewport = { x: 10, y: 15, zoom: 0.5 } + const [formState, setFormState] = useState(InitialFormState); + const defaultViewport = { x: 10, y: 15, zoom: 0.5 }; const onConnect = useCallback((params) => setEdges((eds) => addEdge(params, eds)), [setEdges]); - + const onDragOver = useCallback((event) => { event.preventDefault(); event.dataTransfer.dropEffect = 'move'; }, []); - const modelData = (reactFlowInstance===null?{}:reactFlowInstance.toObject()) + const modelData = (reactFlowInstance === null ? {} : reactFlowInstance.toObject()); /* * Model related functions controls the feedback of the request * * */ const closeModel = () => { - setFormState(prevState => ({...prevState, + setFormState((prevState) => ({ + ...prevState, modalOpen: false, })); - } + }; const openModel = () => { - setFormState(prevState => ({...prevState, + setFormState((prevState) => ({ + ...prevState, modalOpen: true, - }))}; + })); + }; const validatedSuccessfully = ( -); + modalOpen={formState.modalOpen} + modelClose={closeModel} + sucess + Modalmessage={strings.MODEL_VALIDATION_MODAL_MESSAGE} + /> + ); -const errorInValidation = ( + const errorInValidation = ( -); + ); - const modelValidateHandler = ()=>{ - let data = { - "code": { - "dataset": { - "file_id": formState.selectedFile, - "target_field": formState.targetField, - "training_split": formState.trainTestRatio + const modelValidateHandler = () => { + const data = { + code: { + dataset: { + file_id: formState.selectedFile, + target_field: formState.targetField, + training_split: formState.trainTestRatio, + }, + dl_model: { + model_name: formState.modalName, + optimizer: formState.optimizer, + metric: formState.metric, + epochs: formState.epochCount, }, - "dl_model": { - "model_name": formState.modalName, - "optimizer": formState.optimizer, - "metric": formState.metric, - "epochs": formState.epochCount + problem_type_id: formState.problemType, }, - "problem_type_id": formState.problemType - }, - "model" : {...generateModelJSON(reactFlowInstance.toObject()),"model_name": formState.modalName,} - } + model: { ...generateModelJSON(reactFlowInstance.toObject()), model_name: formState.modalName }, + }; - // Send the model data to the backend for validation and update the Modal state accordingly - validateModel(data) - .then(validationResp => { - if (validationResp.success){ - setModelList(prevList => ( - [...prevList,{ - "text": formState.modalName + strings.MODEL_EXTENSION, - "value": formState.modalName, - "key": prevList.length+1 - }] - )) - } - setFormState(prevState => ({...prevState, - modelValidatedSuccessfully: validationResp.success, - modalContent:validationResp.message - })); - openModel(); - }) - .catch(error => { - console.error(error); - setFormState({ modelValidatedSuccessfully: false,modalContent:error.message }); - openModel(); - }); - } + // Send the model data to the backend for validation and update the Modal state accordingly + validateModel(data) + .then((validationResp) => { + if (validationResp.success) { + setModelList((prevList) => ( + [...prevList, { + text: formState.modalName + strings.MODEL_EXTENSION, + value: formState.modalName, + key: prevList.length + 1, + }] + )); + } + setFormState((prevState) => ({ + ...prevState, + modelValidatedSuccessfully: validationResp.success, + modalContent: validationResp.message, + })); + openModel(); + }) + .catch((error) => { + console.error(error); + setFormState({ modelValidatedSuccessfully: false, modalContent: error.message }); + openModel(); + }); + }; - const onDrop = useCallback( (event) => { event.preventDefault(); @@ -136,92 +142,91 @@ const errorInValidation = ( x: event.clientX - reactFlowBounds.left, y: event.clientY - reactFlowBounds.top, }); - let newNode - if (type==='custominput'){ + let newNode; + if (type === 'custominput') { newNode = { id: getId(), type, position, - data: { label: `${type} node`,params:{"dim-x":'',"dim-y":''} }, + data: { label: `${type} node`, params: { 'dim-x': '', 'dim-y': '' } }, }; - }else if(type==='customdense'){ + } else if (type === 'customdense') { newNode = { id: getId(), type, position, - data: { label: `${type} node`,params:{"units":'', "activation":'default'} }, + data: { label: `${type} node`, params: { units: '', activation: 'default' } }, }; - }else if (type==='customflatten'){ + } else if (type === 'customflatten') { newNode = { id: getId(), type, position, - data: { label: `${type} node`,params:{"dim-x":'',"dim-y":''}}, - }} - else{ - newNode = { - id: getId(), - type, - position, - data: { label: `${type} node`}, - } - } + data: { label: `${type} node`, params: { 'dim-x': '', 'dim-y': '' } }, + }; + } else { + newNode = { + id: getId(), + type, + position, + data: { label: `${type} node` }, + }; + } setNodes((nds) => nds.concat(newNode)); - }, - [reactFlowInstance,setNodes] - ); - - return ( - - {(formState.modelValidatedSuccessfully)? validatedSuccessfully : errorInValidation} - - - -
- - -
- - - - -
+ [reactFlowInstance, setNodes], + ); + + return ( + <> + {(formState.modelValidatedSuccessfully) ? validatedSuccessfully : errorInValidation} + + + +
+ + +
+ + + + +
-
-
-
- - -
- - - -
-
-
-
- +
+
+
+ + +
+ + + +
+
+
+
+ ); -}; +} export default Canvas; diff --git a/tensormap-client/src/components/DragAndDropCanvas/CustomNodes/DenseNode/DenseNode.js b/tensormap-client/src/components/DragAndDropCanvas/CustomNodes/DenseNode/DenseNode.js index 8d69b8b..1ac8d69 100644 --- a/tensormap-client/src/components/DragAndDropCanvas/CustomNodes/DenseNode/DenseNode.js +++ b/tensormap-client/src/components/DragAndDropCanvas/CustomNodes/DenseNode/DenseNode.js @@ -1,43 +1,44 @@ -import {Handle,Position,useStoreApi,useReactFlow} from 'reactflow' +import { + Handle, Position, useStoreApi, useReactFlow, +} from 'reactflow'; -import './DenseNode.css' +import './DenseNode.css'; const activations = [ - {value:'default',label:'Select activation'}, - {value:'relu',label:'ReLU'}, - {value:'linear',label:'Linear'} -] + { value: 'default', label: 'Select activation' }, + { value: 'relu', label: 'ReLU' }, + { value: 'linear', label: 'Linear' }, +]; - -const DenseNode = ({data,id }) => { - const {setNodes} = useReactFlow(); - const store = useStoreApi(); - const updateNodeState = (evt) => { - const { nodeInternals } = store.getState(); - const { name, value } = evt.target; - setNodes( - Array.from(nodeInternals.values()).map((node) => { - if (node.id === id) { - node.data = { - ...node.data, - params: { - ...node.data.params, - [name]: name === 'units' ? Number(value) : value, - }, - }; - } - return node; - }) - ); - }; - return ( -
- -
Dense Node
- - - - + + - -
- ); - } + + + ); +} - export default DenseNode; \ No newline at end of file +export default DenseNode; diff --git a/tensormap-client/src/components/DragAndDropCanvas/CustomNodes/FlattenNode/FlattenNode.js b/tensormap-client/src/components/DragAndDropCanvas/CustomNodes/FlattenNode/FlattenNode.js index 0846c98..38e8f72 100644 --- a/tensormap-client/src/components/DragAndDropCanvas/CustomNodes/FlattenNode/FlattenNode.js +++ b/tensormap-client/src/components/DragAndDropCanvas/CustomNodes/FlattenNode/FlattenNode.js @@ -1,40 +1,42 @@ -import {Handle,Position,useStoreApi,useReactFlow} from 'reactflow' +import { + Handle, Position, useStoreApi, useReactFlow, +} from 'reactflow'; -import './FlattenNode.css' +import './FlattenNode.css'; -const FlattenNode = ({data,id }) => { - const {setNodes} = useReactFlow(); - const store = useStoreApi(); - const updateNodeState = (evt) => { - const { nodeInternals } = store.getState(); - const { name, value } = evt.target; - setNodes( - Array.from(nodeInternals.values()).map((node) => { - if (node.id === id) { - node.data = { - ...node.data, - params: { - ...node.data.params, - [name]: Number(value), - }, - }; - } - return node; - }) - ); - }; - return ( -
- -
Flatten Node
- - -
- - - -
+function FlattenNode({ data, id }) { + const { setNodes } = useReactFlow(); + const store = useStoreApi(); + const updateNodeState = (evt) => { + const { nodeInternals } = store.getState(); + const { name, value } = evt.target; + setNodes( + Array.from(nodeInternals.values()).map((node) => { + if (node.id === id) { + node.data = { + ...node.data, + params: { + ...node.data.params, + [name]: Number(value), + }, + }; + } + return node; + }), ); - } + }; + return ( +
+ +
Flatten Node
+ + +
+ + + +
+ ); +} - export default FlattenNode; \ No newline at end of file +export default FlattenNode; diff --git a/tensormap-client/src/components/DragAndDropCanvas/CustomNodes/InputNode/InputNode.js b/tensormap-client/src/components/DragAndDropCanvas/CustomNodes/InputNode/InputNode.js index 7f53af1..4c2ea5c 100644 --- a/tensormap-client/src/components/DragAndDropCanvas/CustomNodes/InputNode/InputNode.js +++ b/tensormap-client/src/components/DragAndDropCanvas/CustomNodes/InputNode/InputNode.js @@ -1,39 +1,41 @@ -import {Handle,Position,useStoreApi,useReactFlow} from 'reactflow' +import { + Handle, Position, useStoreApi, useReactFlow, +} from 'reactflow'; -import './InputNode.css' +import './InputNode.css'; -const InputNode = ({data,id }) => { - const {setNodes} = useReactFlow(); - const store = useStoreApi(); - const updateNodeState = (evt) => { - const { nodeInternals } = store.getState(); - const { name, value } = evt.target; - setNodes( - Array.from(nodeInternals.values()).map((node) => { - if (node.id === id) { - node.data = { - ...node.data, - params: { - ...node.data.params, - [name]: Number(value), - }, - }; - } - return node; - }) - ); - }; - return ( -
-
Input Node
- - -
- - - -
+function InputNode({ data, id }) { + const { setNodes } = useReactFlow(); + const store = useStoreApi(); + const updateNodeState = (evt) => { + const { nodeInternals } = store.getState(); + const { name, value } = evt.target; + setNodes( + Array.from(nodeInternals.values()).map((node) => { + if (node.id === id) { + node.data = { + ...node.data, + params: { + ...node.data.params, + [name]: Number(value), + }, + }; + } + return node; + }), ); - } + }; + return ( +
+
Input Node
+ + +
+ + + +
+ ); +} - export default InputNode; \ No newline at end of file +export default InputNode; diff --git a/tensormap-client/src/components/DragAndDropCanvas/Helpers.js b/tensormap-client/src/components/DragAndDropCanvas/Helpers.js index 2baed1f..2b349d8 100644 --- a/tensormap-client/src/components/DragAndDropCanvas/Helpers.js +++ b/tensormap-client/src/components/DragAndDropCanvas/Helpers.js @@ -1,92 +1,92 @@ export const InitialFormState = { - fileList:null, - totalDetails:null, - fieldsList: [{"text":"Select a file first", "value":null, "key":0,disabled:true}], - selectedFile:null, - targetField:null, - modalName:"", - problemType:null, - optimizer:null, - metric:null, - epochCount:0, - trainTestRatio:0, - disableButton:true, - modalOpen:false, - modelValidatedSuccessfully:false, - modalContent:null, - batchSize:1 -} + fileList: null, + totalDetails: null, + fieldsList: [{ + text: 'Select a file first', value: null, key: 0, disabled: true, + }], + selectedFile: null, + targetField: null, + modalName: '', + problemType: null, + optimizer: null, + metric: null, + epochCount: 0, + trainTestRatio: 0, + disableButton: true, + modalOpen: false, + modelValidatedSuccessfully: false, + modalContent: null, + batchSize: 1, +}; -// Checks whether all the node inputs, form inputs are filled and the graph is connected before enabling validate button -export const enableValidateButton = (formState,modelData)=>{ - if (formState.selectedFile !== null && formState.targetField !==null && formState.modalName !== "" && formState.problemType !== null && formState.optimizer !== null && formState.metric !== null && formState.epochCount !== 0 && formState.trainTestRatio !== 0){ - if (modelData.edges.length !==0 || modelData.nodes.length !==0 ){ - for (let i = 0; i < modelData.nodes.length; i++){ - if (modelData.nodes[i].type==="customdense"){ - if (modelData.nodes[i].data.params.activation === "default" || modelData.nodes[i].data.params.units===0 || modelData.nodes[i].data.params.units===''){ - return true - } - }else if (modelData.nodes[i].type==='custominput'){ - if (modelData.nodes[i].data.params["dim-x"]=== 0 || modelData.nodes[i].data.params["dim-y"]=== '' || modelData.nodes[i].data.params.units===''){ - return true - } - }else if (modelData.nodes[i].type==='customflatten'){ - if (modelData.nodes[i].data.params["dim-x"]=== 0 || modelData.nodes[i].data.params["dim-y"]=== '' || modelData.nodes[i].data.params.units===''){ - return true - } - } - } - return !isGraphConnected(modelData) - }else{ - return true +// Checks whether all the node inputs, form inputs are filled and the graph is connected before enabling validate button +export const enableValidateButton = (formState, modelData) => { + if (formState.selectedFile !== null && formState.targetField !== null && formState.modalName !== '' && formState.problemType !== null && formState.optimizer !== null && formState.metric !== null && formState.epochCount !== 0 && formState.trainTestRatio !== 0) { + if (modelData.edges.length !== 0 || modelData.nodes.length !== 0) { + for (let i = 0; i < modelData.nodes.length; i++) { + if (modelData.nodes[i].type === 'customdense') { + if (modelData.nodes[i].data.params.activation === 'default' || modelData.nodes[i].data.params.units === 0 || modelData.nodes[i].data.params.units === '') { + return true; + } + } else if (modelData.nodes[i].type === 'custominput') { + if (modelData.nodes[i].data.params['dim-x'] === 0 || modelData.nodes[i].data.params['dim-y'] === '' || modelData.nodes[i].data.params.units === '') { + return true; + } + } else if (modelData.nodes[i].type === 'customflatten') { + if (modelData.nodes[i].data.params['dim-x'] === 0 || modelData.nodes[i].data.params['dim-y'] === '' || modelData.nodes[i].data.params.units === '') { + return true; + } } + } + return !isGraphConnected(modelData); } - return true -} + return true; + } + return true; +}; // Runs a BFS through the graph and checks whether the graph is connect or not -const isGraphConnected = (graph) => { - const visited = new Set(); - const firstNodeId = graph.nodes[0].id; - const queue = [firstNodeId]; - visited.add(firstNodeId); - - while (queue.length > 0) { - const currentNodeId = queue.shift() - const adjacentNodes = graph.edges - .filter((edge) => edge.source === currentNodeId || edge.target === currentNodeId) - .map((edge) => (edge.source === currentNodeId ? edge.target : edge.source)); - - for (const nodeId of adjacentNodes) { - if (!visited.has(nodeId)) { - queue.push(nodeId); - visited.add(nodeId); - } +const isGraphConnected = (graph) => { + const visited = new Set(); + const firstNodeId = graph.nodes[0].id; + const queue = [firstNodeId]; + visited.add(firstNodeId); + + while (queue.length > 0) { + const currentNodeId = queue.shift(); + const adjacentNodes = graph.edges + .filter((edge) => edge.source === currentNodeId || edge.target === currentNodeId) + .map((edge) => (edge.source === currentNodeId ? edge.target : edge.source)); + + for (const nodeId of adjacentNodes) { + if (!visited.has(nodeId)) { + queue.push(nodeId); + visited.add(nodeId); } } - return visited.size === graph.nodes.length; } - + return visited.size === graph.nodes.length; +}; export const generateModelJSON = (model_data) => { - let filteredJSON = model_data - - filteredJSON.nodes.forEach(node => { - delete node.width; - delete node.height; - delete node.position; - delete node.positionAbsolute; - delete node.selected; - delete node.dragging - delete node.data.label - }); + const filteredJSON = model_data; + + filteredJSON.nodes.forEach((node) => { + delete node.width; + delete node.height; + delete node.position; + delete node.positionAbsolute; + delete node.selected; + delete node.dragging; + delete node.data.label; + }); - filteredJSON.edges.forEach(edge => { - delete edge.sourceHandle - delete edge.targetHandle - delete edge.id - }) + filteredJSON.edges.forEach((edge) => { + delete edge.sourceHandle; + delete edge.targetHandle; + delete edge.id; + }); - delete filteredJSON.viewport - return filteredJSON -} \ No newline at end of file + delete filteredJSON.viewport; + return filteredJSON; +}; diff --git a/tensormap-client/src/components/DragAndDropCanvas/Sidebar.js b/tensormap-client/src/components/DragAndDropCanvas/Sidebar.js index 440f886..dc30030 100644 --- a/tensormap-client/src/components/DragAndDropCanvas/Sidebar.js +++ b/tensormap-client/src/components/DragAndDropCanvas/Sidebar.js @@ -1,6 +1,6 @@ import React from 'react'; -const Sidebar = () => { +function Sidebar() { const onDragStart = (event, nodeType) => { event.dataTransfer.setData('application/reactflow', nodeType); event.dataTransfer.effectAllowed = 'move'; @@ -8,18 +8,17 @@ const Sidebar = () => { return ( ); -}; +} - -export default Sidebar; \ No newline at end of file +export default Sidebar; diff --git a/tensormap-client/src/components/Layout/Layout.js b/tensormap-client/src/components/Layout/Layout.js index 7528b6e..3c1d6f7 100644 --- a/tensormap-client/src/components/Layout/Layout.js +++ b/tensormap-client/src/components/Layout/Layout.js @@ -1,14 +1,14 @@ import React from 'react'; -import NavBar from "./NavBar/NavBar"; -import SideBar from "./SideBar/SideBar"; +import NavBar from './NavBar/NavBar'; +import SideBar from './SideBar/SideBar'; -const Layout = (props) => { - return ( -
- - -
- ); -}; +function Layout(props) { + return ( +
+ + +
+ ); +} export default Layout; diff --git a/tensormap-client/src/components/Layout/NavBar/NavBar.js b/tensormap-client/src/components/Layout/NavBar/NavBar.js index f90aa78..c917565 100644 --- a/tensormap-client/src/components/Layout/NavBar/NavBar.js +++ b/tensormap-client/src/components/Layout/NavBar/NavBar.js @@ -1,23 +1,22 @@ import React from 'react'; import { Menu } from 'semantic-ui-react'; -const NavBar = () => { - return ( -
- - - logo - +function NavBar() { + return ( +
+ + + logo + - - -
- ); -}; + +
+
+ ); +} export default NavBar; diff --git a/tensormap-client/src/components/Layout/SideBar/SideBar.js b/tensormap-client/src/components/Layout/SideBar/SideBar.js index 6acbee5..a63fcf4 100644 --- a/tensormap-client/src/components/Layout/SideBar/SideBar.js +++ b/tensormap-client/src/components/Layout/SideBar/SideBar.js @@ -1,82 +1,77 @@ -import React, {Component} from 'react'; +import React, { useState, useEffect } from 'react'; import { Grid, Menu, Segment } from 'semantic-ui-react'; +import { withRouter } from 'react-router-dom'; import * as constants from '../../../constants/Strings'; import * as urls from '../../../constants/Urls'; -import { withRouter } from "react-router-dom"; -class SideBar extends Component { +const SideBar = ({ location, history, mainProps }) => { + const [activeItem, setActiveItem] = useState(''); - state = { activeItem:''}; + useEffect(() => { + updateActiveItem(); + }, [location.pathname]); - componentDidMount(){ - this.updateActiveItem(); - } - - componentDidUpdate(prevProps){ - if (prevProps.location.pathname !== this.props.location.pathname){ - this.updateActiveItem(); - } - } + const updateActiveItem = () => { + setActiveItem(location.pathname); + }; - updateActiveItem = () => { - const {pathname} = this.props.location; - this.setState({activeItem:pathname}) + const handleItemClick = (name) => { + switch (name) { + case constants.HOME_SIDEBAR: + history.push(urls.HOME_URL); + break; + case constants.DATA_UPLOAD_SIDEBAR: + history.push(urls.DATA_UPLOAD_URL); + break; + case constants.DATA_PROCESS_SIDEBAR: + history.push(urls.DATA_PROCESS_URL); + break; + default: + history.push(urls.DEEP_LEARN_URL); + break; } + }; - handleItemClick = (e, { name }) => { - if (name === constants.HOME_SIDEBAR){ - this.props.history.push(urls.HOME_URL); - }else if (name === constants.DATA_UPLOAD_SIDEBAR){ - this.props.history.push(urls.DATA_UPLOAD_URL); - }else if (name === constants.DATA_PROCESS_SIDEBAR){ - this.props.history.push(urls.DATA_PROCESS_URL); - }else { - this.props.history.push(urls.DEEP_LEARN_URL); - } - }; + return ( +
+ + + + handleItemClick(constants.HOME_SIDEBAR)} + style={{ fontWeight: 'bold' }} + /> + handleItemClick(constants.DATA_UPLOAD_SIDEBAR)} + style={{ fontWeight: 'bold' }} + /> + handleItemClick(constants.DATA_PROCESS_SIDEBAR)} + style={{ fontWeight: 'bold' }} + /> + handleItemClick(constants.DEEP_LEARNING_SIDEBAR)} + style={{ fontWeight: 'bold' }} + /> + + - render() { - return ( -
- - - - - - - - - - - - - {this.props.mainProps.children} - - - -
- ); - } -} + + + {mainProps.children} + + +
+
+ ); +}; export default withRouter(SideBar); diff --git a/tensormap-client/src/components/Process/DataTypes.js b/tensormap-client/src/components/Process/DataTypes.js index 19570a9..4ebb35d 100644 --- a/tensormap-client/src/components/Process/DataTypes.js +++ b/tensormap-client/src/components/Process/DataTypes.js @@ -1,29 +1,29 @@ -import React from 'react' -import { Table,Header } from 'semantic-ui-react'; +import React from 'react'; +import { Table, Header } from 'semantic-ui-react'; - -const DataTypes = ({ dataTypes }) => { +function DataTypes({ dataTypes }) { return (
-
Datatypes
- - - - Column Name - Data Type - - +
Datatypes
+
+ + + Column Name + Data Type + + - - {Object.entries(dataTypes).map(([column, dtype]) => ( - - {column} - {dtype} - - ))} - -
- ) + + {Object.entries(dataTypes).map(([column, dtype]) => ( + + {column} + {dtype} + + ))} + + + + ); } -export default DataTypes \ No newline at end of file +export default DataTypes; diff --git a/tensormap-client/src/components/Process/HeatMapComp.js b/tensormap-client/src/components/Process/HeatMapComp.js index 8b6e033..3975821 100644 --- a/tensormap-client/src/components/Process/HeatMapComp.js +++ b/tensormap-client/src/components/Process/HeatMapComp.js @@ -1,33 +1,36 @@ -import React from 'react' -import HeatMap from 'react-heatmap-grid' -import { Header} from 'semantic-ui-react' +import React from 'react'; +import HeatMap from 'react-heatmap-grid'; +import { Header } from 'semantic-ui-react'; -const HeatMapComp = (props) => { - console.log(props) +function HeatMapComp(props) { + console.log(props); const xLabels = Object.keys(props.corrMatrix); - const data = xLabels.map(x => { - return Object.keys(props.corrMatrix[x]).map(y => props.corrMatrix[x][y]); - }); + const data = xLabels.map((x) => Object.keys(props.corrMatrix[x]).map((y) => props.corrMatrix[x][y])); return ( -
Co-relation Matrix
-
- ({ +
+
Co-relation Matrix
+
+ ({ background: `rgba(66, 86, 244, ${1 - (max - value) / (max - min)})`, - fontSize: "11px", - })} - cellRender={value => value && `${value.toFixed(4)}`} - /> -
- ) + fontSize: '11px', + })} + cellRender={(value) => value && `${value.toFixed(4)}`} + /> +
+
+ ); } -export default HeatMapComp \ No newline at end of file +export default HeatMapComp; diff --git a/tensormap-client/src/components/Process/MetricTable.js b/tensormap-client/src/components/Process/MetricTable.js index 48adef7..5e30769 100644 --- a/tensormap-client/src/components/Process/MetricTable.js +++ b/tensormap-client/src/components/Process/MetricTable.js @@ -1,46 +1,43 @@ import React from 'react'; -import { Table,Header } from 'semantic-ui-react'; +import { Table, Header } from 'semantic-ui-react'; -const MetricTable = ({ metrics }) => { +function MetricTable({ metrics }) { + const roundValue = (value) => (typeof value === 'number' ? value.toFixed(2) : value); - const roundValue = (value) => { - return typeof value === 'number' ? value.toFixed(2) : value; - }; - return (
-
Dataset Metrics
- - - - Feature - Count - Mean - Standard Deviation - Min - 25% - 50% - 75% - Max - - - - - {Object.entries(metrics).map(([feature, values]) => ( - - {roundValue(feature)} - {roundValue(values.count)} - {roundValue(values.mean)} - {roundValue(values.std)} - {roundValue(values.min)} - {roundValue(values["25%"])} - {roundValue(values["50%"])} - {roundValue(values["75%"])} - {roundValue(values.max)} +
Dataset Metrics
+
+ + + Feature + Count + Mean + Standard Deviation + Min + 25% + 50% + 75% + Max - ))} - -
+ + + + {Object.entries(metrics).map(([feature, values]) => ( + + {roundValue(feature)} + {roundValue(values.count)} + {roundValue(values.mean)} + {roundValue(values.std)} + {roundValue(values.min)} + {roundValue(values['25%'])} + {roundValue(values['50%'])} + {roundValue(values['75%'])} + {roundValue(values.max)} + + ))} + +
); } diff --git a/tensormap-client/src/components/Process/Metrics.js b/tensormap-client/src/components/Process/Metrics.js index 20348e7..326a872 100644 --- a/tensormap-client/src/components/Process/Metrics.js +++ b/tensormap-client/src/components/Process/Metrics.js @@ -1,28 +1,45 @@ -import { Grid } from 'semantic-ui-react' +import { Grid } from 'semantic-ui-react'; import HeatMapComp from './HeatMapComp'; import DataTypes from './DataTypes'; import MetricTable from './MetricTable'; -const Metrics = (props) => { - return ( -
- - - - - - - - - - - - - - - -
- ); +function Metrics(props) { + return ( +
+ + + + + + + + + + + + + + + +
+ ); } -export default Metrics \ No newline at end of file +export default Metrics; diff --git a/tensormap-client/src/components/Process/SelectFileModal.js b/tensormap-client/src/components/Process/SelectFileModal.js index 708d367..d9b576c 100644 --- a/tensormap-client/src/components/Process/SelectFileModal.js +++ b/tensormap-client/src/components/Process/SelectFileModal.js @@ -1,15 +1,20 @@ -import { Header, Icon} from 'semantic-ui-react' +import { Header, Icon } from 'semantic-ui-react'; -const SelectFileModal = () => ( -
-
- - Select a File - - Select a dataset to view the metrics of the Dataset - -
-
-) +function SelectFileModal() { + return ( +
+
+ + Select a File + + Select a dataset to view the metrics of the Dataset + +
+
+ ); +} -export default SelectFileModal \ No newline at end of file +export default SelectFileModal; diff --git a/tensormap-client/src/components/PropertiesBar/PropertiesBar.js b/tensormap-client/src/components/PropertiesBar/PropertiesBar.js index 5ee2d9e..346f5c9 100644 --- a/tensormap-client/src/components/PropertiesBar/PropertiesBar.js +++ b/tensormap-client/src/components/PropertiesBar/PropertiesBar.js @@ -1,219 +1,205 @@ -import React, {Component} from 'react'; -import {Form, Message, Segment, Dropdown} from 'semantic-ui-react'; +import React, { useEffect } from 'react'; +import { + Form, Message, Segment, Dropdown, +} from 'semantic-ui-react'; import { getAllFiles } from '../../services/FileServices'; -class PropertiesBar extends Component { - - componentDidMount() { - - // Get the list of datafiles from the backend for the file selector - getAllFiles() - .then( - response => { - const fileList = response.map((file,index)=>( - {"text": file.file_name +"."+ file.file_type, "value": file.file_id, "key":index} - )) - this.props.setFormState(prevState => ({ - ...prevState, - fileList: fileList, - totalDetails: response - })) - } - - ) - .catch(err => { - console.error(err) - }) - } - - fileSelectHandler = (event,val) => { - const selectedFIleDetails = this.props.formState.totalDetails.filter(item => item.file_id === val.value); - const newFieldsList = selectedFIleDetails[0].fields.map((item, index) => ({ - text: item, - value: item, - key: index, - })); - this.props.setFormState((prevState) => ({ - ...prevState, - selectedFile: val.value, - fieldsList: newFieldsList, - })) - }; - - fieldSelectHandler = (event,val) => { - this.props.setFormState((prevState) => ({ - ...prevState, - targetField: val.value, - })) - - } - - modalNameHandler = (event) => { - this.props.setFormState((prevState) => ({ - ...prevState, - modalName: event.target.value, - })) - } - - problemTypeHandler = (event,val) => { - this.props.setFormState((prevState) => ({ - ...prevState, - problemType: val.value, - })) - - } - - optimizerHandler = (event,val) => { - this.props.setFormState((prevState) => ({ - ...prevState, - optimizer: val.value, - })) - - } - - metricHandler = (event,val) => { - this.props.setFormState((prevState) => ({ - ...prevState, - metric: val.value, - })) - - } - - epochCountHandler = (event)=> { - this.props.setFormState((prevState) => ({ - ...prevState, - epochCount: event.target.value, - })) - - } - - trainTestRatioHandler = (event)=>{ - this.props.setFormState((prevState) => ({ - ...prevState, - trainTestRatio: event.target.value, - })) - - - } - - batchSizeHandler = (event) => { - this.props.setFormState((prevState) => ( - { ...prevState, - batchSize:event.target.value} - )) - } - - - optimizerOptions = [ - { key: 'opt_1', text: 'Adam', value: 'adam' }, - ] - - metricOptions = [ - { key: 'acc_1', text: 'Accuracy', value: 'accuracy' }, - ] - - problemTypeOptions = [ - { key: 'prob_type_1', text: 'Multi class classification [All values float]', value: 1 }, - ] - - activationOptions = [ - { key: 'act_1', text: 'ReLU', value: "relu" }, - { key: 'act_2', text: 'Linear', value: "linear" } - ] - - render() { - - let fileFieldsList = - - - - return ( -
- - Code Related -
- - - - - - - - - - - - - - - - - - - - - - - {fileFieldsList} - - - - -
-
- -
- ); - } -} +const PropertiesBar = ({ formState, setFormState }) => { + useEffect(() => { + // Get the list of datafiles from the backend for the file selector + getAllFiles() + .then((response) => { + const fileList = response.map((file, index) => ({ + text: `${file.file_name}.${file.file_type}`, + value: file.file_id, + key: index, + })); + setFormState((prevState) => ({ + ...prevState, + fileList, + totalDetails: response, + })); + }) + .catch((err) => { + console.error(err); + }); + }, [setFormState]); + + const fileSelectHandler = (event, val) => { + const selectedFileDetails = formState.totalDetails.filter((item) => item.file_id === val.value); + const newFieldsList = selectedFileDetails[0].fields.map((item, index) => ({ + text: item, + value: item, + key: index, + })); + setFormState((prevState) => ({ + ...prevState, + selectedFile: val.value, + fieldsList: newFieldsList, + })); + }; + + const modalNameHandler = (event) => { + setFormState((prevState) => ({ + ...prevState, + modalName: event.target.value, + })); + }; + + const problemTypeHandler = (event, val) => { + setFormState((prevState) => ({ + ...prevState, + problemType: val.value, + })); + }; + + const optimizerHandler = (event, val) => { + setFormState((prevState) => ({ + ...prevState, + optimizer: val.value, + })); + }; + + const metricHandler = (event, val) => { + setFormState((prevState) => ({ + ...prevState, + metric: val.value, + })); + }; + + const epochCountHandler = (event) => { + setFormState((prevState) => ({ + ...prevState, + epochCount: event.target.value, + })); + }; + + const trainTestRatioHandler = (event) => { + setFormState((prevState) => ({ + ...prevState, + trainTestRatio: event.target.value, + })); + }; + + const batchSizeHandler = (event) => { + setFormState((prevState) => ({ + ...prevState, + batchSize: event.target.value, + })); + }; + + const optimizerOptions = [ + { key: 'opt_1', text: 'Adam', value: 'adam' }, + ]; + + const metricOptions = [ + { key: 'acc_1', text: 'Accuracy', value: 'accuracy' }, + ]; + + const problemTypeOptions = [ + { key: 'prob_type_1', text: 'Multi class classification [All values float]', value: 1 }, + ]; + + const activationOptions = [ + { key: 'act_1', text: 'ReLU', value: 'relu' }, + { key: 'act_2', text: 'Linear', value: 'linear' } + ]; + + const fileFieldsList = ( + + ); + + return ( +
+ + Code Related +
+ + + + + + + + + + + + + + + + + + + + + + + {fileFieldsList} + + + + +
+
+
+ ); +}; export default PropertiesBar; diff --git a/tensormap-client/src/components/ResultPanel/Result/Result.js b/tensormap-client/src/components/ResultPanel/Result/Result.js index 02a9789..be7a5d7 100644 --- a/tensormap-client/src/components/ResultPanel/Result/Result.js +++ b/tensormap-client/src/components/ResultPanel/Result/Result.js @@ -1,15 +1,15 @@ import React from 'react'; -import {Message} from 'semantic-ui-react'; +import { Message } from 'semantic-ui-react'; -const Result = (props) => { - return ( -
- -
- ); -}; +function Result(props) { + return ( +
+ +
+ ); +} export default Result; diff --git a/tensormap-client/src/components/ResultPanel/ResultPanel.js b/tensormap-client/src/components/ResultPanel/ResultPanel.js index 2275e43..980bee5 100644 --- a/tensormap-client/src/components/ResultPanel/ResultPanel.js +++ b/tensormap-client/src/components/ResultPanel/ResultPanel.js @@ -1,184 +1,182 @@ -import React, {useState,useEffect} from 'react'; -import io from "socket.io-client"; +import React, { useState, useEffect } from 'react'; +import io from 'socket.io-client'; +import { + Grid, Menu, Button, Form, Dropdown, Segment, Dimmer, Loader, +} from 'semantic-ui-react'; +import { useRecoilState } from 'recoil'; import * as urls from '../../constants/Urls'; -import * as strings from "../../constants/Strings"; -import {Grid, Menu, Button, Form, Dropdown, Segment, Dimmer, Loader} from 'semantic-ui-react'; -import Result from "./Result/Result"; -import {download_code,runModel } from '../../services/ModelServices'; -import {useRecoilState} from 'recoil' -import {models as modelListAtom} from '../../shared/atoms' -import { getAllModels } from '../../services/ModelServices'; - -const ResultPanel = () => { - const [modelList,setModelList] = useRecoilState(modelListAtom) - - const [selectedModel,setSelectedModel] = useState(null); - const [disableDownloadButton,setDisableDownloadButton] = useState(true); - const [disableRunButton,setDisableRunButton] = useState(true); - const [disableClearButton, setDisableClearButton] = useState(true); - const [resultValues, setResultValues] = useState([]); - const [resultFinished, setResultFinished] = useState(null); - - - - useEffect(() => { - try { - const socket = io(urls.WS_DL_RESULTS); - - const dlResultListener = (resp) => { - if (resp.includes('Starting')) { - setResultValues([]); - } else if (resp.includes('Finish')) { - setResultFinished(true); - } else if (Array.isArray(resultValues) && resultFinished === null) { - setResultValues((prevState) => [...prevState, resp]); - } - }; - - socket.on(strings.DL_RESULT_LISTENER, dlResultListener); - - // Fetch models and set the modelList state - getAllModels().then((response) => { - const models = response.map((file, index) => ({ - text: file + strings.MODEL_EXTENSION, - value: file, - key: index, - })); - setModelList(models); - }); - - // Cleanup function to unsubscribe from the socket event listener - return () => { - socket.off(strings.DL_RESULT_LISTENER, dlResultListener); - }; - } catch (error) { - console.error('Error connecting to the socket:', error); - } - }, []); - - const modelSelectHandler = (event, { value }) => { - setSelectedModel(value); - setDisableDownloadButton(false); - setDisableRunButton(false); - }; - - const modelDownloadHandler = () => { - if (selectedModel != null) { - const model_name = selectedModel; - download_code(model_name).catch((error) => { - console.error(error); - }); +import * as strings from '../../constants/Strings'; +import Result from './Result/Result'; +import { download_code, runModel, getAllModels } from '../../services/ModelServices'; +import { models as modelListAtom } from '../../shared/atoms'; + +function ResultPanel() { + const [modelList, setModelList] = useRecoilState(modelListAtom); + + const [selectedModel, setSelectedModel] = useState(null); + const [disableDownloadButton, setDisableDownloadButton] = useState(true); + const [disableRunButton, setDisableRunButton] = useState(true); + const [disableClearButton, setDisableClearButton] = useState(true); + const [resultValues, setResultValues] = useState([]); + const [resultFinished, setResultFinished] = useState(null); + + useEffect(() => { + try { + const socket = io(urls.WS_DL_RESULTS); + + const dlResultListener = (resp) => { + if (resp.includes('Starting')) { + setResultValues([]); + } else if (resp.includes('Finish')) { + setResultFinished(true); + } else if (Array.isArray(resultValues) && resultFinished === null) { + setResultValues((prevState) => [...prevState, resp]); } }; - const runButtonHandler = () => { - setResultValues(''); - if (selectedModel != null) { - runModel(selectedModel) - .then((message) => { - console.log(message); - setDisableRunButton(false); - setDisableClearButton(false); - }) - .catch((error) => { - console.error(error.response.data); - setResultValues([error.response.data.message]) - setDisableClearButton(false); - }); - - setDisableRunButton(true); - } - }; - - const clearButtonHandler = () => { - setResultValues(null); - setDisableClearButton(true); + socket.on(strings.DL_RESULT_LISTENER, dlResultListener); + + // Fetch models and set the modelList state + getAllModels().then((response) => { + const models = response.map((file, index) => ({ + text: file + strings.MODEL_EXTENSION, + value: file, + key: index, + })); + setModelList(models); + }); + + // Cleanup function to unsubscribe from the socket event listener + return () => { + socket.off(strings.DL_RESULT_LISTENER, dlResultListener); }; + } catch (error) { + console.error('Error connecting to the socket:', error); + } + }, []); + + const modelSelectHandler = (event, { value }) => { + setSelectedModel(value); + setDisableDownloadButton(false); + setDisableRunButton(false); + }; + + const modelDownloadHandler = () => { + if (selectedModel != null) { + const model_name = selectedModel; + download_code(model_name).catch((error) => { + console.error(error); + }); + } + }; + + const runButtonHandler = () => { + setResultValues(''); + if (selectedModel != null) { + runModel(selectedModel) + .then((message) => { + console.log(message); + setDisableRunButton(false); + setDisableClearButton(false); + }) + .catch((error) => { + console.error(error.response.data); + setResultValues([error.response.data.message]); + setDisableClearButton(false); + }); - - let results = null; - - if(resultValues === ""){ - results = ( - - - - - - ); - } - - if (Array.isArray(resultValues) ){ - results = resultValues.map((item, index) => ); - } - - - - return ( -
- - - - Model Execution - - -
- - - -
-
- - - - - - - - - - - - - - -
-
-
- - - {results} - - - - -
+ setDisableRunButton(true); + } + }; + + const clearButtonHandler = () => { + setResultValues(null); + setDisableClearButton(true); + }; + + let results = null; + + if (resultValues === '') { + results = ( + + + + + ); + } + + if (Array.isArray(resultValues)) { + results = resultValues.map((item, index) => ); + } + + return ( +
+ + + + Model Execution + + +
+ + + +
+
+ + + + + + + + + + + + + + +
+
+
+ + + {results} + + + +
+ ); } -export default ResultPanel \ No newline at end of file +export default ResultPanel; diff --git a/tensormap-client/src/components/Upload/FilesList/File/File.js b/tensormap-client/src/components/Upload/FilesList/File/File.js index e78c53e..612d665 100644 --- a/tensormap-client/src/components/Upload/FilesList/File/File.js +++ b/tensormap-client/src/components/Upload/FilesList/File/File.js @@ -1,15 +1,15 @@ import React from 'react'; import { Segment } from 'semantic-ui-react'; -const File = (props) => { - return ( -
- - {props.savedFileName} - {props.savedFileType} - -
- ); -}; +function File(props) { + return ( +
+ + {props.savedFileName} + {props.savedFileType} + +
+ ); +} export default File; diff --git a/tensormap-client/src/components/Upload/FilesList/FilesList.js b/tensormap-client/src/components/Upload/FilesList/FilesList.js index 62ca2a1..8e8a6ef 100644 --- a/tensormap-client/src/components/Upload/FilesList/FilesList.js +++ b/tensormap-client/src/components/Upload/FilesList/FilesList.js @@ -1,23 +1,19 @@ import React from 'react'; -import File from "./File/File"; +import File from './File/File'; - -const FilesList = (props) => { - - const fileList = props.fileList.map((file, index) => { - return ( - - ); - }); - return ( -
- {fileList} -
- ); -}; +function FilesList(props) { + const fileList = props.fileList.map((file, index) => ( + + )); + return ( +
+ {fileList} +
+ ); +} export default FilesList; diff --git a/tensormap-client/src/components/Upload/NewFile/NewFile.js b/tensormap-client/src/components/Upload/NewFile/NewFile.js index 12e47e5..cc08957 100644 --- a/tensormap-client/src/components/Upload/NewFile/NewFile.js +++ b/tensormap-client/src/components/Upload/NewFile/NewFile.js @@ -1,159 +1,166 @@ -import React, {Component} from 'react'; -import {Form, Button, Icon} from 'semantic-ui-react'; -import * as strings from "../../../constants/Strings"; +import React, { Component } from 'react'; +import { Form, Button, Icon } from 'semantic-ui-react'; +import * as strings from '../../../constants/Strings'; import ModalComponent from '../../shared/Modal'; -import { uploadFile } from '../../../services/FileServices' +import { uploadFile } from '../../../services/FileServices'; class NewFile extends Component { - - state = { - fileType:'', - fileName:'', - file: null, - uploadButtonDisabledStatus: true, - fileAddedSuccessfully:false, - modalOpen:false - } - - componentDidMount() { - this.setState({fileType:'', fileName:'', file: null, uploadButtonDisabledStatus: true}); - }; - - - fileTypes = [ - { key: 'csv', text: 'CSV', value: 'csv' } - ] - - dataTypeHandler = (event,val) => { - this.setState({...this.state, fileType: val.value}, - ()=> { - this.submitButtonEnableHandler(); - }); - }; - - fileChange = e => { - this.setState({...this.state, file: e.target.files[0], fileName: e.target.files[0].name}, - ()=> { - this.submitButtonEnableHandler(); - }); - }; - - - /* + state = { + fileType: '', + fileName: '', + file: null, + uploadButtonDisabledStatus: true, + fileAddedSuccessfully: false, + modalOpen: false, + }; + + componentDidMount() { + this.setState({ + fileType: '', fileName: '', file: null, uploadButtonDisabledStatus: true, + }); + } + + fileTypes = [ + { key: 'csv', text: 'CSV', value: 'csv' }, + ]; + + dataTypeHandler = (event, val) => { + this.setState( + { ...this.state, fileType: val.value }, + () => { + this.submitButtonEnableHandler(); + }, + ); + }; + + fileChange = (e) => { + this.setState( + { ...this.state, file: e.target.files[0], fileName: e.target.files[0].name }, + () => { + this.submitButtonEnableHandler(); + }, + ); + }; + + /* * Submission button enable only after the all the necessary fields added. * * */ - submitButtonEnableHandler = () => { - if (this.state.fileType !== '' && this.state.fileName !== '' && this.state.file !== null){ - this.setState({...this.state, uploadButtonDisabledStatus:false}) - } - }; + submitButtonEnableHandler = () => { + if (this.state.fileType !== '' && this.state.fileName !== '' && this.state.file !== null) { + this.setState({ ...this.state, uploadButtonDisabledStatus: false }); + } + }; - /* + /* * handle file uploads and send a request to backend * * */ - fileUploadHandler = () => { - - uploadFile(this.state.file) - .then(fileAddedSuccessfully => { + fileUploadHandler = () => { + uploadFile(this.state.file) + .then((fileAddedSuccessfully) => { this.setState({ fileAddedSuccessfully }); this.modelOpen(); }) - .catch(error => { + .catch((error) => { console.error(error); this.setState({ fileAddedSuccessfully: false }); this.modelOpen(); }); - }; + }; - - /* + /* * Model related functions controls the feedback of the request * * */ - modelClose = () => { - this.setState({ ...this.state, modalOpen: false }); - window.location.reload(); - } - - modelOpen = () => this.setState({ modalOpen: true }); + modelClose = () => { + this.setState({ ...this.state, modalOpen: false }); + window.location.reload(); + }; - render() { + modelOpen = () => this.setState({ modalOpen: true }); - /* + render() { + /* * addedSuccessfully and errorInAddition are modals that will pop up after successful addition or failure. * * */ - const addedSuccessfully = ( - - ); - - const errorInAddition = ( - - ); - - return ( -
- - {(this.state.fileAddedSuccessfully)? addedSuccessfully : errorInAddition} - -
- - - - - - - - - - - - - - -
-
- ); - } + const addedSuccessfully = ( + + ); + + const errorInAddition = ( + + ); + + return ( +
+ + {(this.state.fileAddedSuccessfully) ? addedSuccessfully : errorInAddition} + +
+ + + + + + + + + + + + + + +
+
+ ); + } } export default NewFile; diff --git a/tensormap-client/src/components/__tests__/HeatMapComp.test.js b/tensormap-client/src/components/__tests__/HeatMapComp.test.js index fe74aa1..e3194e0 100644 --- a/tensormap-client/src/components/__tests__/HeatMapComp.test.js +++ b/tensormap-client/src/components/__tests__/HeatMapComp.test.js @@ -4,33 +4,31 @@ import HeatMapComp from '../Process/HeatMapComp'; import '@testing-library/jest-dom/extend-expect'; // Mocking the external HeatMap component -jest.mock('react-heatmap-grid', () => { - return { - __esModule: true, - default: () =>
- }; -}); +jest.mock('react-heatmap-grid', () => ({ + __esModule: true, + default: () =>
, +})); describe('', () => { - const mockProps = { - corrMatrix: { - A: { A: 1, B: 0.5 }, - B: { A: 0.5, B: 1 } - } - }; + const mockProps = { + corrMatrix: { + A: { A: 1, B: 0.5 }, + B: { A: 0.5, B: 1 }, + }, + }; - it('renders without crashing', () => { - render(); - }); + it('renders without crashing', () => { + render(); + }); - it('displays the "Co-relation Matrix" header', () => { - const { getByText } = render(); - expect(getByText('Co-relation Matrix')).toBeInTheDocument(); - }); + it('displays the "Co-relation Matrix" header', () => { + const { getByText } = render(); + expect(getByText('Co-relation Matrix')).toBeInTheDocument(); + }); - it('renders the heatmap with correct labels and data', () => { - const { getByTestId } = render(); - const heatmap = getByTestId('mock-heatmap'); - expect(heatmap).toBeInTheDocument(); - }); + it('renders the heatmap with correct labels and data', () => { + const { getByTestId } = render(); + const heatmap = getByTestId('mock-heatmap'); + expect(heatmap).toBeInTheDocument(); + }); }); diff --git a/tensormap-client/src/components/__tests__/Helpers.test.js b/tensormap-client/src/components/__tests__/Helpers.test.js index 5ed5b1f..ec1dc35 100644 --- a/tensormap-client/src/components/__tests__/Helpers.test.js +++ b/tensormap-client/src/components/__tests__/Helpers.test.js @@ -1,54 +1,51 @@ import { enableValidateButton, generateModelJSON, InitialFormState } from '../DragAndDropCanvas/Helpers'; describe('Utility Functions', () => { - - describe('enableValidateButton', () => { - it('should return true if any necessary parameter is missing', () => { - const formState = { ...InitialFormState }; - const modelData = { edges: [], nodes: [] }; - expect(enableValidateButton(formState, modelData)).toBe(true); - }); - + describe('enableValidateButton', () => { + it('should return true if any necessary parameter is missing', () => { + const formState = { ...InitialFormState }; + const modelData = { edges: [], nodes: [] }; + expect(enableValidateButton(formState, modelData)).toBe(true); }); + }); - describe('generateModelJSON', () => { - it('should remove unwanted properties from nodes and edges', () => { - const model_data = { - nodes: [{ - id: 'a', - width: 100, - height: 100, - position: {}, - positionAbsolute: {}, - selected: true, - dragging: true, - data: { label: "Label A" } - }], - edges: [{ - source: 'a', - target: 'b', - sourceHandle: 'handle1', - targetHandle: 'handle2', - id: 'edge1' - }], - viewport: {} - }; - const result = generateModelJSON(model_data); + describe('generateModelJSON', () => { + it('should remove unwanted properties from nodes and edges', () => { + const model_data = { + nodes: [{ + id: 'a', + width: 100, + height: 100, + position: {}, + positionAbsolute: {}, + selected: true, + dragging: true, + data: { label: 'Label A' }, + }], + edges: [{ + source: 'a', + target: 'b', + sourceHandle: 'handle1', + targetHandle: 'handle2', + id: 'edge1', + }], + viewport: {}, + }; + const result = generateModelJSON(model_data); - - expect(result.nodes[0].width).toBeUndefined(); - expect(result.nodes[0].height).toBeUndefined(); - expect(result.nodes[0].position).toBeUndefined(); - expect(result.nodes[0].positionAbsolute).toBeUndefined(); - expect(result.nodes[0].selected).toBeUndefined(); - expect(result.nodes[0].dragging).toBeUndefined(); - expect(result.nodes[0].data.label).toBeUndefined(); + expect(result.nodes[0].width).toBeUndefined(); + expect(result.nodes[0].height).toBeUndefined(); + expect(result.nodes[0].position).toBeUndefined(); + expect(result.nodes[0].positionAbsolute).toBeUndefined(); + expect(result.nodes[0].selected).toBeUndefined(); + expect(result.nodes[0].dragging).toBeUndefined(); + expect(result.nodes[0].data.label).toBeUndefined(); - expect(result.edges[0].sourceHandle).toBeUndefined(); - expect(result.edges[0].targetHandle).toBeUndefined(); - expect(result.edges[0].id).toBeUndefined(); + expect(result.edges[0].sourceHandle).toBeUndefined(); + expect(result.edges[0].targetHandle).toBeUndefined(); + expect(result.edges[0].id).toBeUndefined(); - expect(result.viewport).toBeUndefined(); - }); + expect(result.viewport).toBeUndefined(); }); + }); }); diff --git a/tensormap-client/src/components/__tests__/NavBar.test.js b/tensormap-client/src/components/__tests__/NavBar.test.js index 3139284..3d8b62b 100644 --- a/tensormap-client/src/components/__tests__/NavBar.test.js +++ b/tensormap-client/src/components/__tests__/NavBar.test.js @@ -4,14 +4,14 @@ import NavBar from '../Layout/NavBar/NavBar'; import '@testing-library/jest-dom/extend-expect'; describe('', () => { - it('renders without crashing', () => { - render(); - }); + it('renders without crashing', () => { + render(); + }); - it('renders the logo image correctly', () => { - const { getByAltText } = render(); - const logoImg = getByAltText('logo'); - expect(logoImg).toBeInTheDocument(); - expect(logoImg.src).toBe('https://react.semantic-ui.com/logo.png'); - }); + it('renders the logo image correctly', () => { + const { getByAltText } = render(); + const logoImg = getByAltText('logo'); + expect(logoImg).toBeInTheDocument(); + expect(logoImg.src).toBe('https://react.semantic-ui.com/logo.png'); + }); }); diff --git a/tensormap-client/src/components/__tests__/Sidebar.test.js b/tensormap-client/src/components/__tests__/Sidebar.test.js index 8c173b6..3e136b6 100644 --- a/tensormap-client/src/components/__tests__/Sidebar.test.js +++ b/tensormap-client/src/components/__tests__/Sidebar.test.js @@ -1,6 +1,6 @@ import React from 'react'; import { render, fireEvent } from '@testing-library/react'; -import Sidebar from '../DragAndDropCanvas/Sidebar' +import Sidebar from '../DragAndDropCanvas/Sidebar'; describe('', () => { it('renders without crashing', () => { @@ -14,22 +14,22 @@ describe('', () => { const { getByText } = render(); const dataTransferMock = { setData: jest.fn(), - effectAllowed: '' + effectAllowed: '', }; fireEvent.dragStart(getByText('Input Node'), { - dataTransfer: dataTransferMock + dataTransfer: dataTransferMock, }); expect(dataTransferMock.setData).toHaveBeenCalledWith('application/reactflow', 'custominput'); expect(dataTransferMock.effectAllowed).toBe('move'); fireEvent.dragStart(getByText('Dense Node'), { - dataTransfer: dataTransferMock + dataTransfer: dataTransferMock, }); expect(dataTransferMock.setData).toHaveBeenCalledWith('application/reactflow', 'customdense'); fireEvent.dragStart(getByText('Flatten Node'), { - dataTransfer: dataTransferMock + dataTransfer: dataTransferMock, }); expect(dataTransferMock.setData).toHaveBeenCalledWith('application/reactflow', 'customflatten'); }); diff --git a/tensormap-client/src/components/shared/Modal.js b/tensormap-client/src/components/shared/Modal.js index e079cf7..a668e8f 100644 --- a/tensormap-client/src/components/shared/Modal.js +++ b/tensormap-client/src/components/shared/Modal.js @@ -1,30 +1,36 @@ -import React from "react"; -import {Button, Icon, Modal, Header} from 'semantic-ui-react'; +import React from 'react'; +import { + Button, Icon, Modal, Header, +} from 'semantic-ui-react'; -import * as strings from "../../constants/Strings"; +import * as strings from '../../constants/Strings'; -const ModalComponent = ({ modalOpen, modelClose, sucess, Modalmessage, modalText="" }) => { - const successModelButton = strings.PROCESS_SUCCESS_MODEL_BUTTON; - const failModelButton = strings.PROCESS_FAIL_MODEL_BUTTON; - - return ( - -
- {!sucess && } - - - - - ); - }; - - export default ModalComponent; +function ModalComponent({ + modalOpen, modelClose, sucess, Modalmessage, modalText = '', +}) { + const successModelButton = strings.PROCESS_SUCCESS_MODEL_BUTTON; + const failModelButton = strings.PROCESS_FAIL_MODEL_BUTTON; + + return ( + +
+ {!sucess && } + + + + + ); +} + +export default ModalComponent; diff --git a/tensormap-client/src/constants/Strings.js b/tensormap-client/src/constants/Strings.js index 7cce2df..ebaa550 100644 --- a/tensormap-client/src/constants/Strings.js +++ b/tensormap-client/src/constants/Strings.js @@ -1,43 +1,43 @@ -export const HOME_SIDEBAR = "Home"; -export const DATA_UPLOAD_SIDEBAR = "Data Upload"; -export const DATA_PROCESS_SIDEBAR = "Data Processing"; -export const DEEP_LEARNING_SIDEBAR = "Deep leaning Modeling"; -export const HOME_MAIN_TITLE = "TensorMap"; -export const HOME_MAIN_CONTENT = "TensorMap is a web application that enables you to create deep learning models " + - "using a graphical interface without having to know how to code. It is an open-source application." -export const HOME_ABILITY_TITLE = "You can"; -export const HOME_ABILITY_CONTENT_1 = "Upload Data for Preprocessing."; -export const HOME_ABILITY_CONTENT_2 = "Make Neural Network Models using Drag and Drop Feature."; -export const HOME_ABILITY_CONTENT_3 = "Visualise uploaded Data."; -export const HOME_ABILITY_CONTENT_4 = "Change Data Columns,Rows etc."; -export const HOME_ABILITY_CONTENT_5 = "Get Generated Code for Neural Network Model Made."; -export const UPLOAD_FILE_TITLE = "Uploaded File Details"; -export const UPLOAD_NEW_FILE_TITLE = "Upload New File"; -export const UPLOAD_SELECT_FILE_TYPE = "Select File Type"; -export const UPLOAD_BUTTON_CONTEXT = "Upload File"; -export const UPLOAD_HIDDEN_BUTTON_CONTEXT = "Choose a File"; -export const UPLOAD_NEW_FILE_INPUT_LABEL = "File Chosen: "; -export const UPLOAD_NEW_FILE_INPUT_PLACEHOLDER = "Use the above bar to browse your file system"; -export const PROCESS_SELECT_FILE_TITLE = "Select the file"; -export const PROCESS_SELECT_FILE_FIELD_BEFORE = "First select a file"; -export const PROCESS_TARGET_FIELD_SUBMIT_BUTTON = "Add Target Field"; -export const PROCESS_SUCCESS_MODEL_MESSAGE = "Target field added successfully"; -export const MODEL_VALIDATION_MODAL_MESSAGE = "Model validated successfully"; -export const PROCESS_SUCCESS_MODEL_BUTTON = "Got it"; -export const PROCESS_FAIL_MODEL_MESSAGE = "Error occurred !!! "; -export const PROCESS_FAIL_MODEL_BUTTON = "Try again"; -export const UPLOAD_FILES_LOADING = "Files are Loading ..." -export const UPLOAD_SUCCESS_MODEL_MESSAGE = "File uploaded successfully"; -export const DL_MODEL_DENSE_TYPE = "dense"; -export const DL_MODEL_FLATTEN_TYPE = "Flatten"; -export const DL_MODEL_INPUT_TYPE = "input"; -export const DL_MODEL_DENSE_NAME = "Dense Node"; -export const DL_MODEL_FLATTEN_NAME = "Flatten Node"; -export const DL_MODEL_INPUT_NAME = "Input Node"; -export const DL_MODEL_DENSE_COLOR = "rgb(43, 161, 255)" -export const DL_MODEL_INPUT_COLOR = "rgb(105, 172, 61)" -export const DL_MODEL_FLATTEN_COLOR = "rgb(247, 173, 20)" -export const DL_NODE_IN = "In"; -export const DL_NODE_OUT = "Out"; -export const DL_RESULT_LISTENER = "result :::" -export const MODEL_EXTENSION = ".py" +export const HOME_SIDEBAR = 'Home'; +export const DATA_UPLOAD_SIDEBAR = 'Data Upload'; +export const DATA_PROCESS_SIDEBAR = 'Data Processing'; +export const DEEP_LEARNING_SIDEBAR = 'Deep leaning Modeling'; +export const HOME_MAIN_TITLE = 'TensorMap'; +export const HOME_MAIN_CONTENT = 'TensorMap is a web application that enables you to create deep learning models ' + + 'using a graphical interface without having to know how to code. It is an open-source application.'; +export const HOME_ABILITY_TITLE = 'You can'; +export const HOME_ABILITY_CONTENT_1 = 'Upload Data for Preprocessing.'; +export const HOME_ABILITY_CONTENT_2 = 'Make Neural Network Models using Drag and Drop Feature.'; +export const HOME_ABILITY_CONTENT_3 = 'Visualise uploaded Data.'; +export const HOME_ABILITY_CONTENT_4 = 'Change Data Columns,Rows etc.'; +export const HOME_ABILITY_CONTENT_5 = 'Get Generated Code for Neural Network Model Made.'; +export const UPLOAD_FILE_TITLE = 'Uploaded File Details'; +export const UPLOAD_NEW_FILE_TITLE = 'Upload New File'; +export const UPLOAD_SELECT_FILE_TYPE = 'Select File Type'; +export const UPLOAD_BUTTON_CONTEXT = 'Upload File'; +export const UPLOAD_HIDDEN_BUTTON_CONTEXT = 'Choose a File'; +export const UPLOAD_NEW_FILE_INPUT_LABEL = 'File Chosen: '; +export const UPLOAD_NEW_FILE_INPUT_PLACEHOLDER = 'Use the above bar to browse your file system'; +export const PROCESS_SELECT_FILE_TITLE = 'Select the file'; +export const PROCESS_SELECT_FILE_FIELD_BEFORE = 'First select a file'; +export const PROCESS_TARGET_FIELD_SUBMIT_BUTTON = 'Add Target Field'; +export const PROCESS_SUCCESS_MODEL_MESSAGE = 'Target field added successfully'; +export const MODEL_VALIDATION_MODAL_MESSAGE = 'Model validated successfully'; +export const PROCESS_SUCCESS_MODEL_BUTTON = 'Got it'; +export const PROCESS_FAIL_MODEL_MESSAGE = 'Error occurred !!! '; +export const PROCESS_FAIL_MODEL_BUTTON = 'Try again'; +export const UPLOAD_FILES_LOADING = 'Files are Loading ...'; +export const UPLOAD_SUCCESS_MODEL_MESSAGE = 'File uploaded successfully'; +export const DL_MODEL_DENSE_TYPE = 'dense'; +export const DL_MODEL_FLATTEN_TYPE = 'Flatten'; +export const DL_MODEL_INPUT_TYPE = 'input'; +export const DL_MODEL_DENSE_NAME = 'Dense Node'; +export const DL_MODEL_FLATTEN_NAME = 'Flatten Node'; +export const DL_MODEL_INPUT_NAME = 'Input Node'; +export const DL_MODEL_DENSE_COLOR = 'rgb(43, 161, 255)'; +export const DL_MODEL_INPUT_COLOR = 'rgb(105, 172, 61)'; +export const DL_MODEL_FLATTEN_COLOR = 'rgb(247, 173, 20)'; +export const DL_NODE_IN = 'In'; +export const DL_NODE_OUT = 'Out'; +export const DL_RESULT_LISTENER = 'result :::'; +export const MODEL_EXTENSION = '.py'; diff --git a/tensormap-client/src/constants/Urls.js b/tensormap-client/src/constants/Urls.js index c7ca4b3..c9edf3d 100644 --- a/tensormap-client/src/constants/Urls.js +++ b/tensormap-client/src/constants/Urls.js @@ -1,8 +1,8 @@ -export const HOME_URL = "/home"; -export const DATA_UPLOAD_URL = "/data-upload"; -export const DATA_PROCESS_URL = "/data-process"; -export const DEEP_LEARN_URL = "/deep-learning"; -export const TENSOR_MAP_URL = "https://github.com/scorelab/TensorMap" +export const HOME_URL = '/home'; +export const DATA_UPLOAD_URL = '/data-upload'; +export const DATA_PROCESS_URL = '/data-process'; +export const DEEP_LEARN_URL = '/deep-learning'; +export const TENSOR_MAP_URL = 'https://github.com/scorelab/TensorMap'; export const base_URL = 'http://127.0.0.1:5000/api/v1'; export const BACKEND_GET_ALL_FILES = '/data/upload/file'; export const BACKEND_GET_ALL_MODELS = '/model/model-list'; @@ -10,6 +10,6 @@ export const BACKEND_DOWNLOAD_CODE = '/model/code'; export const BACKEND_RUN_MODEL = '/model/run'; export const BACKEND_ADD_TARGET_FIELD = '/data/process/target'; export const BACKEND_FILE_UPLOAD = '/data/upload/file'; -export const WS_DL_RESULTS = "http://127.0.0.1:5000/dl-result"; -export const BACKEND_VALIDATE_MODEL = "/model/validate"; -export const BACKEND_GET_COV_MATRIX = "/data/process/data_metrics/"; +export const WS_DL_RESULTS = 'http://127.0.0.1:5000/dl-result'; +export const BACKEND_VALIDATE_MODEL = '/model/validate'; +export const BACKEND_GET_COV_MATRIX = '/data/process/data_metrics/'; diff --git a/tensormap-client/src/containers/DataProcess/DataProcess.js b/tensormap-client/src/containers/DataProcess/DataProcess.js index bf8c19a..35254cf 100644 --- a/tensormap-client/src/containers/DataProcess/DataProcess.js +++ b/tensormap-client/src/containers/DataProcess/DataProcess.js @@ -1,200 +1,207 @@ -import React, {Component} from 'react'; -import * as strings from "../../constants/Strings"; -import {Segment, Dropdown, Form, Button,Tab} from "semantic-ui-react"; +import React, { Component } from 'react'; +import { + Segment, Dropdown, Form, Button, Tab, +} from 'semantic-ui-react'; +import * as strings from '../../constants/Strings'; import ModalComponent from '../../components/shared/Modal'; import Metrics from '../../components/Process/Metrics'; import SelectFileModal from '../../components/Process/SelectFileModal'; -import { getAllFiles,setTargetField,getCovMatrix as getCorrMatrix } from '../../services/FileServices'; +import { getAllFiles, setTargetField, getCovMatrix as getCorrMatrix } from '../../services/FileServices'; class DataProcess extends Component { - - state = { - fileList: null, - selectedFile: null, - totalDetails: null, - showFieldsList: false, - fieldsList: null, - targetField: null, - disableButton: true, - targetAddedSuccessfully:false, - modalOpen:false, - corrMatrix:null, - dataTypes:null, - metrics:null - } - - panes = [ - { - menuItem: 'Metrics', - render: () => this.state.corrMatrix?:, - }, - { menuItem: 'View Dataset', render: () => Tab 2 Content }, - ] - - - componentDidMount() { - - - /* + state = { + fileList: null, + selectedFile: null, + totalDetails: null, + showFieldsList: false, + fieldsList: null, + targetField: null, + disableButton: true, + targetAddedSuccessfully: false, + modalOpen: false, + corrMatrix: null, + dataTypes: null, + metrics: null, + }; + + panes = [ + { + menuItem: 'Metrics', + render: () => (this.state.corrMatrix ? : ), + }, + { menuItem: 'View Dataset', render: () => Tab 2 Content }, + ]; + + componentDidMount() { + /* * In this react life cycle hook, file data is fetch from backend and added to state * * */ - getAllFiles() - .then( - response => { - const fileList = response.map((file,index)=>( - {"text": file.file_name +"."+ file.file_type, "value": file.file_id, "key":index} - )) - this.setState(prevState => ({ - ...prevState, - fileList:fileList, - totalDetails:response - })) - } - ) - - } - - fileSelectHandler = (event,val) => { + getAllFiles() + .then( + (response) => { + const fileList = response.map((file, index) => ( + { text: `${file.file_name}.${file.file_type}`, value: file.file_id, key: index } + )); + this.setState((prevState) => ({ + ...prevState, + fileList, + totalDetails: response, + })); + }, + ); + } + + fileSelectHandler = (event, val) => { + getCorrMatrix(val.value) + .then( + (response) => { + console.log(response); + this.setState({ + ...this.state, corrMatrix: response.correlation_matrix, dataTypes: response.data_types, metrics: response.metric, + }); + }, - getCorrMatrix(val.value) - .then( - response => { - console.log(response) - this.setState({...this.state, corrMatrix:response.correlation_matrix,dataTypes:response.data_types,metrics:response.metric}); - - } + ); + const promise = new Promise((resolve) => { + this.setState({ ...this.state, selectedFile: val.value, showFieldsList: true }, () => resolve()); + }); - ) - const promise = new Promise(resolve => { - this.setState({...this.state, selectedFile: val.value, showFieldsList:true }, () => resolve()); - }); + promise.then(() => { + const selectedFIleDetails = this.state.totalDetails.filter((item) => item.file_id === this.state.selectedFile); - promise.then(()=>{ - const selectedFIleDetails = this.state.totalDetails.filter(item => item.file_id === this.state.selectedFile); + this.setState({ + ...this.state, + fieldsList: selectedFIleDetails[0].fields.map( + (item, index) => ({ text: item, value: item, key: index }), + ), + }); + }); + }; - this.setState({...this.state, fieldsList: selectedFIleDetails[0].fields.map( - (item,index)=>({"text":item, "value":item, "key":index})) }); - }) - }; + fieldSelectHandler = (event, val) => { + this.setState({ ...this.state, targetField: val.value }, () => this.enableSubmitButton()); + }; - fieldSelectHandler = (event,val) => { - this.setState({...this.state, targetField:val.value}, ()=>this.enableSubmitButton()); - } - - /* + /* * Submission button enable only after the all the necessary fields added. * * */ - enableSubmitButton = () => { - if (this.state.selectedFile !== null && this.state.targetField !== null){ - this.setState({...this.state, disableButton:false}) - } + enableSubmitButton = () => { + if (this.state.selectedFile !== null && this.state.targetField !== null) { + this.setState({ ...this.state, disableButton: false }); } - - // Select the target field for a particular data file - setTargetFieldHandler = () => { - const { selectedFile, targetField } = this.state; - setTargetField(selectedFile, targetField) - .then(targetAddedSuccessfully => { + }; + + // Select the target field for a particular data file + setTargetFieldHandler = () => { + const { selectedFile, targetField } = this.state; + setTargetField(selectedFile, targetField) + .then((targetAddedSuccessfully) => { this.setState({ targetAddedSuccessfully }); this.modelOpen(); }) - .catch(error => { + .catch((error) => { console.error(error); this.setState({ targetAddedSuccessfully: false }); this.modelOpen(); }); - } + }; - /* + /* * Model related functions controls the feedback of the request * * */ - modelClose = () => { - this.setState({ ...this.state, modalOpen: false }); - } - - modelOpen = () => this.setState({ ...this.state, modalOpen: true }); + modelClose = () => { + this.setState({ ...this.state, modalOpen: false }); + }; - render() { + modelOpen = () => this.setState({ ...this.state, modalOpen: true }); - /* + render() { + /* * addedSuccessfully and errorInAddition are modals that will pop up after successful addition or failure. * * */ - const addedSuccessfully = ( - - ); - - const errorInAddition = ( - - ); - - /* + const addedSuccessfully = ( + + ); + + const errorInAddition = ( + + ); + + /* * Until a file is selected field list of a file is not showing * * */ - let fileFieldsList = + ); + + if (this.state.showFieldsList) { + fileFieldsList = ( + - - if (this.state.showFieldsList){ - fileFieldsList = - } - - return ( -
- - {(this.state.targetAddedSuccessfully)? addedSuccessfully : errorInAddition} - - {strings.PROCESS_SELECT_FILE_TITLE} - - {fileFieldsList} - - -
- ); + ); } + + return ( +
+ + {(this.state.targetAddedSuccessfully) ? addedSuccessfully : errorInAddition} + + + {strings.PROCESS_SELECT_FILE_TITLE} + + + {fileFieldsList} + + +
+ ); + } } export default DataProcess; diff --git a/tensormap-client/src/containers/DataUpload/DataUpload.js b/tensormap-client/src/containers/DataUpload/DataUpload.js index 4ca7035..970696c 100644 --- a/tensormap-client/src/containers/DataUpload/DataUpload.js +++ b/tensormap-client/src/containers/DataUpload/DataUpload.js @@ -1,72 +1,64 @@ -import React, {Component} from 'react'; -import { Grid, Segment, Divider, Dimmer, Loader } from 'semantic-ui-react'; -import FilesList from "../../components/Upload/FilesList/FilesList"; -import * as strings from "../../constants/Strings"; -import NewFile from "../../components/Upload/NewFile/NewFile"; -import { getAllFiles } from "../../services/FileServices" +import React, { useState, useEffect } from 'react'; +import { + Grid, Segment, Divider, Dimmer, Loader, +} from 'semantic-ui-react'; +import FilesList from '../../components/Upload/FilesList/FilesList'; +import * as strings from '../../constants/Strings'; +import NewFile from '../../components/Upload/NewFile/NewFile'; +import { getAllFiles } from '../../services/FileServices'; -class DataUpload extends Component { +function DataUpload() { + const [fileList, setFileList] = useState(null); - state = {fileList:null} - - componentDidMount() { - /* - * GET data from backend save them in the states => fileList - * - * */ - getAllFiles() - .then(response => { - const fileList = response.map(item => ({ - "SavedFileName": item.file_name, - "SavedFileType": item.file_type - })); - this.setState(prevState => ({ - ...prevState, - fileList:fileList })); - }) - .catch(error => { + useEffect(() => { + getAllFiles() + .then((response) => { + const updatedFileList = response.map((item) => ({ + SavedFileName: item.file_name, + SavedFileType: item.file_type, + })); + setFileList(updatedFileList); + }) + .catch((error) => { console.error('Error retrieving files:', error); }); - } - - render() { - - /* - * fileItem is a component that can represent as loading component and after file list is loaded to - * state, it will convert to proper file list - * - * */ + }, []); - let fileListItem = ( - - - {strings.UPLOAD_FILES_LOADING} - - - ); + let fileListItem = ( + + + + {strings.UPLOAD_FILES_LOADING} + + + + ); - if (this.state.fileList){ - fileListItem = ( - - ); - } + if (fileList) { + fileListItem = ; + } - return ( -
- - - {strings.UPLOAD_NEW_FILE_TITLE} - - - - {strings.UPLOAD_FILE_TITLE} - {fileListItem} - - - OR -
- ); - } + return ( +
+ + + + {strings.UPLOAD_NEW_FILE_TITLE} + + + + + + {strings.UPLOAD_FILE_TITLE} + + {fileListItem} + + + OR +
+ ); } export default DataUpload; diff --git a/tensormap-client/src/containers/DeepLearning/DeepLearning.js b/tensormap-client/src/containers/DeepLearning/DeepLearning.js index dfb44af..b1c2a99 100644 --- a/tensormap-client/src/containers/DeepLearning/DeepLearning.js +++ b/tensormap-client/src/containers/DeepLearning/DeepLearning.js @@ -1,25 +1,25 @@ import React from 'react'; import { Grid } from 'semantic-ui-react'; -import ResultPanel from "../../components/ResultPanel/ResultPanel"; +import ResultPanel from '../../components/ResultPanel/ResultPanel'; import Canvas from '../../components/DragAndDropCanvas/Canvas'; -const DeepLearning = () => { - return ( -
- - - - - - - - - - - - -
- ); +function DeepLearning() { + return ( +
+ + + + + + + + + + + + +
+ ); } export default DeepLearning; diff --git a/tensormap-client/src/containers/Home/Home.js b/tensormap-client/src/containers/Home/Home.js index 690b07f..1c9ba50 100644 --- a/tensormap-client/src/containers/Home/Home.js +++ b/tensormap-client/src/containers/Home/Home.js @@ -1,73 +1,75 @@ import React from 'react'; -import { Message, Segment, Grid, Header, Icon, Button } from 'semantic-ui-react'; -import { useHistory } from "react-router"; +import { + Message, Segment, Grid, Header, Icon, Button, +} from 'semantic-ui-react'; +import { useHistory } from 'react-router'; import * as urls from '../../constants/Urls'; import * as strings from '../../constants/Strings'; -const Home = () => { +function Home() { + const history = useHistory(); - const history = useHistory(); + const handleButtonUpload = () => { + history.push(urls.DATA_UPLOAD_URL); + }; - const handleButtonUpload = ()=> { - history.push(urls.DATA_UPLOAD_URL); - }; + const handleButtonNewProject = () => { + history.push(urls.DEEP_LEARN_URL); + }; - const handleButtonNewProject = ()=> { - history.push(urls.DEEP_LEARN_URL); - }; + const handleButtonGoToGit = () => { + window.location.replace(urls.TENSOR_MAP_URL); + }; - const handleButtonGoToGit = ()=> { - window.location.replace(urls.TENSOR_MAP_URL); - } + return ( +
+ - return ( -
- + - + + - - + + +
+ + Upload Data +
+ +
+ +
+ + Create new Project +
+ +
- - -
- - Upload Data -
- -
- - -
- - Create new Project -
- -
- - -
- - Contribute at: -
- -
-
-
-
-
- ); -}; + +
+ + Contribute at: +
+ +
+ + + +
+ ); +} export default Home; diff --git a/tensormap-client/src/index.js b/tensormap-client/src/index.js index dbc5e46..6d1524a 100644 --- a/tensormap-client/src/index.js +++ b/tensormap-client/src/index.js @@ -1,17 +1,16 @@ import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; -import 'semantic-ui-css/semantic.min.css' +import 'semantic-ui-css/semantic.min.css'; +import { RecoilRoot } from 'recoil'; import App from './App'; import reportWebVitals from './reportWebVitals'; -import { RecoilRoot } from 'recoil'; ReactDOM.render( , - document.getElementById('root') + document.getElementById('root'), ); - reportWebVitals(); diff --git a/tensormap-client/src/reportWebVitals.js b/tensormap-client/src/reportWebVitals.js index 5253d3a..bb47dbb 100644 --- a/tensormap-client/src/reportWebVitals.js +++ b/tensormap-client/src/reportWebVitals.js @@ -1,6 +1,8 @@ -const reportWebVitals = onPerfEntry => { +const reportWebVitals = (onPerfEntry) => { if (onPerfEntry && onPerfEntry instanceof Function) { - import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { + import('web-vitals').then(({ + getCLS, getFID, getFCP, getLCP, getTTFB, + }) => { getCLS(onPerfEntry); getFID(onPerfEntry); getFCP(onPerfEntry); diff --git a/tensormap-client/src/services/FileServices.js b/tensormap-client/src/services/FileServices.js index 476daeb..746c658 100644 --- a/tensormap-client/src/services/FileServices.js +++ b/tensormap-client/src/services/FileServices.js @@ -1,70 +1,63 @@ -import axios from "../shared/Axios"; -import * as urls from "../constants/Urls"; +import axios from '../shared/Axios'; +import * as urls from '../constants/Urls'; -export const getAllFiles = async () => { - return axios.get(urls.BACKEND_GET_ALL_FILES) - .then(resp => { - if (resp.data.success === true) { - return resp.data.data - } - return []; - }) - .catch(err=> { - console.error(err) - throw(err) - }) -}; +export const getAllFiles = async () => axios.get(urls.BACKEND_GET_ALL_FILES) + .then((resp) => { + if (resp.data.success === true) { + return resp.data.data; + } + return []; + }) + .catch((err) => { + console.error(err); + throw (err); + }); export const uploadFile = async (file) => { const formData = new FormData(); formData.append('data', file); return axios.post(urls.BACKEND_FILE_UPLOAD, formData, { - headers: { 'Content-Type': 'multipart/form-data' } + headers: { 'Content-Type': 'multipart/form-data' }, }) - .then(resp => { + .then((resp) => { if (resp.data.success === true) { return true; } return false; }) - .catch(err => { + .catch((err) => { console.error(err); - throw err + throw err; }); }; - export const setTargetField = async (fileId, targetField) => { const data = { file_id: fileId, - target: targetField + target: targetField, }; return axios.post(urls.BACKEND_ADD_TARGET_FIELD, data) - .then(resp => { + .then((resp) => { if (resp.data.success === true) { return true; } return false; }) - .catch(err => { + .catch((err) => { console.error(err.response.data.message); return false; }); }; - -export const getCovMatrix = async (file_id) => { - return axios.get(urls.BACKEND_GET_COV_MATRIX+file_id) - .then(resp => { +export const getCovMatrix = async (file_id) => axios.get(urls.BACKEND_GET_COV_MATRIX + file_id) + .then((resp) => { if (resp.data.success === true) { - return resp.data.data + return resp.data.data; } }) - .catch(err=> { - console.error(err) - throw(err) - }) - -} \ No newline at end of file + .catch((err) => { + console.error(err); + throw (err); + }); diff --git a/tensormap-client/src/services/ModelServices.js b/tensormap-client/src/services/ModelServices.js index 146c92b..7a43344 100644 --- a/tensormap-client/src/services/ModelServices.js +++ b/tensormap-client/src/services/ModelServices.js @@ -1,73 +1,65 @@ -import axios from "../shared/Axios"; -import * as urls from "../constants/Urls"; -import * as strings from "../constants/Strings"; +import axios from '../shared/Axios'; +import * as urls from '../constants/Urls'; +import * as strings from '../constants/Strings'; -export const validateModel = async (data) => { - return axios.post(urls.BACKEND_VALIDATE_MODEL, data) - .then(resp => { - return resp.data - }) - .catch(err => { - console.error(err); - if (err.response && err.response.data){ - return err.response.data - }else{ - return {success:false,message:"Unknown error occured"} - } - - }); - }; +export const validateModel = async (data) => axios.post(urls.BACKEND_VALIDATE_MODEL, data) + .then((resp) => resp.data) + .catch((err) => { + console.error(err); + if (err.response && err.response.data) { + return err.response.data; + } + return { success: false, message: 'Unknown error occured' }; + }); -export const getAllModels = async () => { - return axios.get(urls.BACKEND_GET_ALL_MODELS) - .then(resp => { - if (resp.data.success === true) { - return resp.data.data - } - return []; - }).catch(err =>{ - console.error(err); - throw(err) - }) - }; +export const getAllModels = async () => axios.get(urls.BACKEND_GET_ALL_MODELS) + .then((resp) => { + if (resp.data.success === true) { + return resp.data.data; + } + return []; + }).catch((err) => { + console.error(err); + throw (err); + }); -export const download_code = async (model_name) => { - const data = {"model_name": model_name} +export const download_code = async (model_name) => { + const data = { model_name }; return axios.post(urls.BACKEND_DOWNLOAD_CODE, data) - .then(resp => { - const link = document.createElement("a"); - link.href = window.URL.createObjectURL(new Blob([resp.data], { type: "application/octet-stream" })); - link.download = data.model_name + strings.MODEL_EXTENSION; + .then((resp) => { + const link = document.createElement('a'); + link.href = window.URL.createObjectURL(new Blob([resp.data], { type: 'application/octet-stream' })); + link.download = data.model_name + strings.MODEL_EXTENSION; - document.body.appendChild(link); + document.body.appendChild(link); - link.click(); + link.click(); - setTimeout(function () { + setTimeout(() => { window.URL.revokeObjectURL(link.href); document.body.removeChild(link); }, 200); }) - .catch(err => { + .catch((err) => { console.error(err); - throw err + throw err; }); }; export const runModel = async (modelName) => { const data = { - model_name: modelName + model_name: modelName, }; return axios.post(urls.BACKEND_RUN_MODEL, data) - .then(resp => { + .then((resp) => { if (resp.data.success === true) { return resp.data.message; } - console.log(resp.data.message) + console.log(resp.data.message); throw new Error(resp.data); }) - .catch(err => { - throw err - }) -} \ No newline at end of file + .catch((err) => { + throw err; + }); +}; diff --git a/tensormap-client/src/shared/Axios.js b/tensormap-client/src/shared/Axios.js index 962e790..1bff7aa 100644 --- a/tensormap-client/src/shared/Axios.js +++ b/tensormap-client/src/shared/Axios.js @@ -1,6 +1,6 @@ import axios from 'axios'; import * as urls from '../constants/Urls'; -const Axios = axios.create({ baseURL: urls.base_URL}); +const Axios = axios.create({ baseURL: urls.base_URL }); -export default Axios +export default Axios; diff --git a/tensormap-client/src/shared/atoms.js b/tensormap-client/src/shared/atoms.js index cd9ca1b..b3e57b9 100644 --- a/tensormap-client/src/shared/atoms.js +++ b/tensormap-client/src/shared/atoms.js @@ -1,6 +1,6 @@ -import {atom} from 'recoil' +import { atom } from 'recoil'; export const models = atom({ - key:"models", - default:[] -}) \ No newline at end of file + key: 'models', + default: [], +}); diff --git a/tensormap-server/environment.yml b/tensormap-server/environment.yml index 34ef96d..4f9136d 100644 --- a/tensormap-server/environment.yml +++ b/tensormap-server/environment.yml @@ -1,11 +1,11 @@ name: tensormap-server dependencies: - - python=3.7 + - python=3.8 - notebook - jupyterlab - ipywidgets - - numpy + - numpy=1.22.1 - pandas - flask - flask-cors diff --git a/tensormap-server/requirements.txt b/tensormap-server/requirements.txt index ee0232d..1fff0bd 100644 Binary files a/tensormap-server/requirements.txt and b/tensormap-server/requirements.txt differ diff --git a/tensormap-server/setup.sh b/tensormap-server/setup.sh old mode 100644 new mode 100755 index e30eef4..35eb843 --- a/tensormap-server/setup.sh +++ b/tensormap-server/setup.sh @@ -1,3 +1,9 @@ -conda env update --file environment.yml --prune +# Check if the "data" folder exists +if [ ! -d "data" ]; then + # If not, create the "data" folder + mkdir data +fi + +# Update Conda environment +conda env update --file environment.yml --prune -mkdir data