Pipeline view and status view functionality 09/9309/1
authorjosephthaliath <jo.thaliath@samsung.com>
Tue, 18 Oct 2022 09:57:00 +0000 (15:27 +0530)
committerjosephthaliath <jo.thaliath@samsung.com>
Tue, 18 Oct 2022 09:58:40 +0000 (15:28 +0530)
Issue-Id: AIMLFW-2

Signed-off-by: josephthaliath <jo.thaliath@samsung.com>
Change-Id: Ib750d927071443823ae14f378372d0979486225d

src/components/home/HomePage.js [new file with mode: 0644]
src/components/home/pipelines/UploadPipeline.js [new file with mode: 0644]
src/components/home/status/Checkbox.js [new file with mode: 0644]
src/components/home/status/Popup.js [new file with mode: 0644]
src/components/home/status/StatusPageRows.js [new file with mode: 0644]
src/components/home/status/StepsState.css [new file with mode: 0644]
src/components/home/status/StepsState.js [new file with mode: 0644]
src/components/home/status/TrainingJobInfo.js [new file with mode: 0644]

diff --git a/src/components/home/HomePage.js b/src/components/home/HomePage.js
new file mode 100644 (file)
index 0000000..a3f0749
--- /dev/null
@@ -0,0 +1,53 @@
+// ==================================================================================
+
+//        Copyright (c) 2022 Samsung Electronics Co., Ltd. All Rights Reserved.
+
+//    Licensed under the Apache License, Version 2.0 (the "License");
+//    you may not use this file except in compliance with the License.
+//    You may obtain a copy of the License at
+
+//           http://www.apache.org/licenses/LICENSE-2.0
+
+//    Unless required by applicable law or agreed to in writing, software
+//    distributed under the License is distributed on an "AS IS" BASIS,
+//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//    See the License for the specific language governing permissions and
+//    limitations under the License.
+
+// ==================================================================================
+
+import React from 'react';
+import CreateTrainingJob from './create/CreateTrainingJob';
+import StatusPageRows from './status/StatusPageRows';
+import UploadPipelineForm from './pipelines/UploadPipeline'
+import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
+import NavbarComponent from './navbar/NavbarComponent';
+
+class HomePage extends React.Component {
+
+  render() {
+      return (
+        <>
+          <Router>
+            <NavbarComponent />
+            <Switch>
+              <Route path='/' exact component={Home} />
+              <Route path='/TrainingJob/CreateTrainingJob' exact component={CreateTrainingJob} />
+              <Route path='/TrainingJob/TrainingJobsStatus' exact component={StatusPageRows} />
+              <Route path='/TrainingJob/Pipeline' exact component={UploadPipelineForm} />
+            </Switch>
+          </Router>
+        </>
+      );
+  }
+}
+
+export default HomePage;
+
+
+class Home extends React.Component{
+  render() {
+    return <></>;
+  }
+}
+
diff --git a/src/components/home/pipelines/UploadPipeline.js b/src/components/home/pipelines/UploadPipeline.js
new file mode 100644 (file)
index 0000000..ba4f530
--- /dev/null
@@ -0,0 +1,131 @@
+// ==================================================================================
+
+//        Copyright (c) 2022 Samsung Electronics Co., Ltd. All Rights Reserved.
+
+//    Licensed under the Apache License, Version 2.0 (the "License");
+//    you may not use this file except in compliance with the License.
+//    You may obtain a copy of the License at
+
+//           http://www.apache.org/licenses/LICENSE-2.0
+
+//    Unless required by applicable law or agreed to in writing, software
+//    distributed under the License is distributed on an "AS IS" BASIS,
+//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//    See the License for the specific language governing permissions and
+//    limitations under the License.
+
+// ==================================================================================
+
+import React from 'react'
+import Form from 'react-bootstrap/Form'
+import Button from 'react-bootstrap/Button'
+import axios from 'axios';
+import * as CONSTANTS from '../common/Constants' 
+
+class UploadPipelineForm extends React.Component {
+  constructor(props) {
+    super(props);
+
+    this.state = {
+      fileName: '',
+      plName: '',
+      UCMgr_baseUrl: CONSTANTS.UCMgr_baseUrl
+    }
+    this.handleInputChange = this.handleInputChange.bind(this);
+  }
+
+  handleInputChange(event) {
+    console.log(event)
+    this.setState({
+      fileName: event.target.files[0]
+    })
+    console.log('handleInputChange',this.fileName)
+  }
+
+  handlePlNameChange = (event) => {
+    this.setState({
+      plName: event.target.value
+    })
+  }
+
+
+
+  resetFrom = (event)=> {
+    this.setState({   
+      fileName: '',
+      plName: '',     
+    })
+    console.log(this.state)
+    event.target.value = null;
+  }
+
+  handleSubmit = event => {
+    const data = new FormData()
+    data.append('file', this.state.fileName)
+    
+    let url =  this.state.UCMgr_baseUrl + "/pipelines/" + this.state.plName + "/upload";
+
+    //Option-3
+    axios.post(url,data
+      ).then(res => {
+        console.log('Pipeline  responsed ', res)
+        console.log('Status  responsed ', res.status)
+        if(res.status === 200) {
+          console.log('Pipeline uploaded ', res.status)
+          alert(res.data.result)
+          this.resetFrom(event)
+          
+        } else {
+          console.log('Upload pipeline error:' , res)
+        }
+      })
+      .catch(error => {
+        console.log('Error in uploading pipeline',error.response)
+        alert("Pipeline upload failed: " + error.response.data.result)
+      })
+      .then(function () {
+        // always executed
+      })
+
+      console.log('something')
+      event.preventDefault();
+  }
+
+  handleCreatePipeline  = event => {
+    console.log('handleCreatePipeline clicked..', event)
+    window.open(CONSTANTS.notebook_url + '/tree', "_blank")
+  }
+
+  render() {
+    return (
+    <>
+    <div className="upload-pl-form" >
+
+    <Button variant="success" size="sm"  onClick={e => this.handleCreatePipeline(e)} >
+        Create Pipeline
+    </Button>{' '}
+
+      <Form  onSubmit={this.handleSubmit}>
+        <Form.Group controlId="plName">
+          <Form.Label>Pipeline Name*</Form.Label>
+          <Form.Control type="input"
+            value={this.state.plName}
+            onChange={this.handlePlNameChange}
+            placeholder="" 
+            required/>
+        </Form.Group>
+
+      <input type="file" className="form-control"
+            name="upload_file" onChange={this.handleInputChange} />
+
+      <Button type="submit" > Upload </Button>
+
+      </Form>
+      </div>
+    </>
+
+    );
+  }
+}
+
+export default UploadPipelineForm;
\ No newline at end of file
diff --git a/src/components/home/status/Checkbox.js b/src/components/home/status/Checkbox.js
new file mode 100644 (file)
index 0000000..c2a19ff
--- /dev/null
@@ -0,0 +1,37 @@
+// ==================================================================================
+
+//        Copyright (c) 2022 Samsung Electronics Co., Ltd. All Rights Reserved.
+
+//    Licensed under the Apache License, Version 2.0 (the "License");
+//    you may not use this file except in compliance with the License.
+//    You may obtain a copy of the License at
+
+//           http://www.apache.org/licenses/LICENSE-2.0
+
+//    Unless required by applicable law or agreed to in writing, software
+//    distributed under the License is distributed on an "AS IS" BASIS,
+//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//    See the License for the specific language governing permissions and
+//    limitations under the License.
+
+// ==================================================================================
+
+import React from 'react'
+
+export const Checkbox = React.forwardRef(
+    ({ indeterminate, ...rest }, ref) => {
+      const defaultRef = React.useRef()
+      const resolvedRef = ref || defaultRef
+  
+      React.useEffect(() => {
+        resolvedRef.current.indeterminate = indeterminate
+      }, [resolvedRef, indeterminate])
+  
+      return (
+        <>
+          <input type="checkbox" ref={resolvedRef} {...rest} />
+        </>
+      )
+    }
+  )
+  
\ No newline at end of file
diff --git a/src/components/home/status/Popup.js b/src/components/home/status/Popup.js
new file mode 100644 (file)
index 0000000..1d8add9
--- /dev/null
@@ -0,0 +1,40 @@
+// ==================================================================================
+
+//        Copyright (c) 2022 Samsung Electronics Co., Ltd. All Rights Reserved.
+
+//    Licensed under the Apache License, Version 2.0 (the "License");
+//    you may not use this file except in compliance with the License.
+//    You may obtain a copy of the License at
+
+//           http://www.apache.org/licenses/LICENSE-2.0
+
+//    Unless required by applicable law or agreed to in writing, software
+//    distributed under the License is distributed on an "AS IS" BASIS,
+//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//    See the License for the specific language governing permissions and
+//    limitations under the License.
+
+// ==================================================================================
+
+
+import React from 'react';
+import {Modal} from 'react-bootstrap';
+
+function Popup(props){
+  return (
+    <>
+      <Modal show={props.show} onHide={props.onHide} size={props.hasOwnProperty('size') ? props.size : 'medium'} centered>
+          <Modal.Header closeButton>
+              <Modal.Title>
+                  {props.title}
+              </Modal.Title>
+          </Modal.Header>
+          <Modal.Body>
+              {props.children}
+          </Modal.Body>
+      </Modal>
+    </>
+  );
+}
+
+export default Popup;
\ No newline at end of file
diff --git a/src/components/home/status/StatusPageRows.js b/src/components/home/status/StatusPageRows.js
new file mode 100644 (file)
index 0000000..713dbf9
--- /dev/null
@@ -0,0 +1,194 @@
+// ==================================================================================
+
+//        Copyright (c) 2022 Samsung Electronics Co., Ltd. All Rights Reserved.
+
+//    Licensed under the Apache License, Version 2.0 (the "License");
+//    you may not use this file except in compliance with the License.
+//    You may obtain a copy of the License at
+
+//           http://www.apache.org/licenses/LICENSE-2.0
+
+//    Unless required by applicable law or agreed to in writing, software
+//    distributed under the License is distributed on an "AS IS" BASIS,
+//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//    See the License for the specific language governing permissions and
+//    limitations under the License.
+
+// ==================================================================================
+
+import React, { useMemo, useState, useEffect } from 'react';
+import BTable from 'react-bootstrap/Table';
+import Button from 'react-bootstrap/Button';
+import { useTable, useRowSelect } from 'react-table';
+import {UCMgr_baseUrl} from '../common/Constants'; 
+import axios from 'axios';
+import { Checkbox } from './Checkbox';
+import Popup from './Popup';
+import TrainingJobInfo from './TrainingJobInfo';
+import StepsState from './StepsState';
+
+const StatusPageRows = () => {
+
+  const [trainingJobs, setTrainingJobs] = useState([])
+
+  const [stepsStatePopup, setStepsStatePopup] = useState(false);
+  const [stepsStateTrainingJobAndVersion, setStepsStateTrainingJobNameAndVersion] = useState(null);
+  const closeStepsStatePopup = () => setStepsStatePopup(false);
+
+  const [infoPopup, setInfoPopup] = useState(false);
+  const [infoTrainingJobAndVersion, setInfoTrainingJobNameAndVersion] = useState(null);
+  const closeInfoPopup = () => setInfoPopup(false);
+
+  useEffect(() => {
+    console.log('useEffect');
+    fetchTrainingJobs();
+    const timer = setInterval(async ()=>{
+      fetchTrainingJobs();
+    }, 5000);
+    return ()=>clearInterval(timer);
+  }, []);
+
+
+
+  const fetchTrainingJobs = async () => {
+    console.log('fetchTrainingJobs UCMgr_baseUrl', UCMgr_baseUrl)
+    try {    
+      const result = await axios.get(`${UCMgr_baseUrl}/trainingjobs/latest`);
+      console.log('fetchTrainingJobs Result', result);
+      console.log('Training Jobs  are --> ', result.data.trainingjobs)
+      setTrainingJobs(result.data.trainingjobs);
+      
+    } catch (e) {
+      console.error(e)
+    }
+  }
+   
+
+  const handleStepStateClick = (trainingjob_name, version) => {
+    setStepsStateTrainingJobNameAndVersion({
+      trainingjob_name : trainingjob_name,
+      version : version
+    });
+    setStepsStatePopup(true);
+  };
+  
+  const handleInfoClick = (trainingjob_name, version) => {
+    setInfoTrainingJobNameAndVersion({
+      trainingjob_name : trainingjob_name,
+      version : version
+    });
+    setInfoPopup(true);
+  };
+
+  const columns = useMemo(() => [
+    {
+      id: 'selection',
+      Header: ({ getToggleAllRowsSelectedProps }) => (
+        <div>
+          <Checkbox {...getToggleAllRowsSelectedProps()} />
+        </div>
+      ),
+      Cell: ({ row }) => (
+        <div>
+          <Checkbox {...row.getToggleRowSelectedProps()} />
+        </div>
+      ),
+    },
+    {
+      id : 'trainingjob_name',
+      Header : 'Training Job Name',
+      accessor : 'trainingjob_name'
+    },
+    {
+      id : 'version',
+      Header : 'Version',
+      accessor : 'version'
+    },
+    {
+      id : 'overall_status',
+      Header : 'Overall Status',
+      accessor : row => row.overall_status === 'IN_PROGRESS' ? 'IN PROGRESS' : row.overall_status
+    },
+    {
+      id : 'stepsState',
+      Header : 'Detailed Status',
+      Cell : ({row}) => {
+        return (
+          <Button variant="info" onClick={() => handleStepStateClick(row.original.trainingjob_name, row.original.version)}>Detailed Status</Button>
+        );   
+      }
+    },
+    {
+      id : 'info',
+      Header : 'Info',
+      Cell : ({row}) => {
+        return (
+          <Button variant="info" onClick={() => handleInfoClick(row.original.trainingjob_name, row.original.version)}>Info</Button>
+        );   
+      }
+    }
+  ], []);
+  const data =  useMemo(() => trainingJobs, [trainingJobs]);
+
+  const {
+    getTableProps,
+    headerGroups, 
+    rows, 
+    prepareRow,
+    selectedFlatRows,
+    toggleAllRowsSelected
+  } = useTable(
+        {
+          columns,
+          data,
+          autoResetSelectedRows : false
+        },
+        useRowSelect
+      )
+  return (  
+    <>
+
+
+      <BTable className="Status_table" responsive striped bordered hover size="sm"  {...getTableProps()}>
+
+        <thead>
+          {headerGroups.map(headerGroup => (
+            <tr {...headerGroup.getHeaderGroupProps()}>
+              {headerGroup.headers.map(column => (
+                <th {...column.getHeaderProps()}>
+                  {column.render('Header')}
+                </th>
+              ))}
+            </tr>
+          ))}
+        </thead>
+
+        <tbody>
+          {rows.map((row, i) => {
+            prepareRow(row)
+            return (
+              <tr {...row.getRowProps()}>
+                {row.cells.map(cell => {
+                  return (
+                    <th {...cell.getCellProps()}>
+                      {cell.render('Cell')}
+                    </th>
+                  )
+                })}
+              </tr>
+            )
+          })}
+        </tbody>
+      </BTable>
+      <Popup size="sm" show={stepsStatePopup} onHide={closeStepsStatePopup} title="Detailed Status">
+          <StepsState trainingjob_name_and_version={stepsStateTrainingJobAndVersion}></StepsState>
+      </Popup>
+      <Popup show={infoPopup} onHide={closeInfoPopup} title="Training Job Info">
+        <TrainingJobInfo trainingjob_name_and_version={infoTrainingJobAndVersion}/>
+      </Popup>
+    </>
+  );
+}
+
+export default StatusPageRows;
diff --git a/src/components/home/status/StepsState.css b/src/components/home/status/StepsState.css
new file mode 100644 (file)
index 0000000..c382efd
--- /dev/null
@@ -0,0 +1,65 @@
+ /* ==================================================================================
+
+        Copyright (c) 2022 Samsung Electronics Co., Ltd. All Rights Reserved.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+           http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+ ================================================================================== */
+.step-progressbar-wrapper{
+   
+}
+
+.state{
+    background-color: white;
+    border: 2px solid black;
+    height: 30px;
+    width: 30px;
+    border-radius: 50%;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+}
+
+.step{
+    max-width: 400px;
+}
+
+.step-progress-bar-box{
+    display: flex;
+    align-items: center;
+    column-gap: 20px;
+    border: 2px solid pink;
+    padding: 10px;
+}
+
+.step-progress-bar-box-line{
+    border-right: 3px solid black;
+    height: 50px;
+    width: 50%;
+}
+
+.container-for-step-progress-bar-box-line-and-message{
+    display: flex;
+    column-gap: 20px;
+}
+
+.step-progress-bar-box-line-messsage{
+    display: flex;
+    justify-content: center;
+    align-items: center;
+}
+
+
+
+
diff --git a/src/components/home/status/StepsState.js b/src/components/home/status/StepsState.js
new file mode 100644 (file)
index 0000000..b1ae15b
--- /dev/null
@@ -0,0 +1,109 @@
+// ==================================================================================
+
+//        Copyright (c) 2022 Samsung Electronics Co., Ltd. All Rights Reserved.
+
+//    Licensed under the Apache License, Version 2.0 (the "License");
+//    you may not use this file except in compliance with the License.
+//    You may obtain a copy of the License at
+
+//           http://www.apache.org/licenses/LICENSE-2.0
+
+//    Unless required by applicable law or agreed to in writing, software
+//    distributed under the License is distributed on an "AS IS" BASIS,
+//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//    See the License for the specific language governing permissions and
+//    limitations under the License.
+
+// ==================================================================================
+
+import React, { useEffect, useState } from 'react';
+import axios from "axios";
+import './StepsState.css';
+import { UCMgr_baseUrl } from '../common/Constants';
+
+const StepsState = (props) => {
+    const [boxesState, setBoxesState] = useState([]);
+    const [connectionsState, setConnectionsState] = useState([]);
+    const [boxes, setBoxes] = useState([]);
+    useEffect(()=>{
+        const periodicTask = async () => {
+            let res = null;
+            try{
+                res = await axios.get(`${UCMgr_baseUrl}/trainingjobs/${props.trainingjob_name_and_version.trainingjob_name}/${props.trainingjob_name_and_version.version}/steps_state`);
+            }
+            catch(error){
+                console.log(error);
+            }
+            const json_from_backend = res.data;
+            console.log(`response for ${UCMgr_baseUrl}/trainingjobs/${props.trainingjob_name_and_version.trainingjob_name}/${props.trainingjob_name_and_version.version}/steps_state` , res);
+            const newBoxesState = [];
+            const newConnectionsState = [];
+            const newBoxes = ['Data extraction' , 'Training', 'Trained Model'];
+            
+
+            newBoxesState.push(json_from_backend.DATA_EXTRACTION);
+            newBoxesState.push(json_from_backend.TRAINING);
+            newBoxesState.push(json_from_backend.TRAINED_MODEL);
+            if(json_from_backend.hasOwnProperty('DEPLOYMENT')){
+                newBoxesState.push(json_from_backend.DEPLOYMENT);
+                newBoxes.push('Deployment');
+            }
+            setBoxesState(newBoxesState);
+            setBoxes(newBoxes);
+
+            newConnectionsState.push(json_from_backend.DATA_EXTRACTION_AND_TRAINING);
+            newConnectionsState.push(json_from_backend.TRAINING_AND_TRAINED_MODEL);
+            if(json_from_backend.hasOwnProperty('TRAINED_MODEL_AND_DEPLOYMENT')){
+                newConnectionsState.push(json_from_backend.TRAINED_MODEL_AND_DEPLOYMENT);
+            }
+            setConnectionsState(newConnectionsState);
+        };
+        periodicTask();
+        const timer = setInterval( async () => {
+            periodicTask();   
+        }, 5000);
+        return () => clearInterval(timer);
+    
+        
+    },[props.trainingjob_name_and_version]);
+
+    return (    
+        <div className='step-progressbar-wrapper'>
+            {
+                boxes.map((item, index) => {
+                    return (
+                        <div key={index}>
+                            <div   className='step-progress-bar-box'>
+                                <div className='state'>
+                                    {boxesState[index] === 'NOT_STARTED' ? index + 1 : 
+                                     boxesState[index] === 'FINISHED' ? '✔' :
+                                     boxesState[index] === 'FAILED' ? '❌' :
+                                     '⌛'}
+                                </div>
+                                <div className='step'>
+                                    {item}
+                                </div>
+                            </div>  
+                            { index + 1 !== boxes.length &&
+                                
+                                <div className='container-for-step-progress-bar-box-line-and-message'>
+                                    <div className='step-progress-bar-box-line'/>
+                                    <div className='step-progress-bar-box-line-messsage'>
+                                        {
+                                            connectionsState[index] === 'NOT_STARTED' ? 'Not started' :
+                                            connectionsState[index] === 'FINISHED' ? '✔ Finished' :
+                                            connectionsState[index] === 'FAILED' ? '❌ Failed' :
+                                            '⌛ In progress'
+                                        }
+                                    </div>
+                                </div>
+                            }
+                        </div>
+                    )
+                })   
+            }
+        </div>
+    );
+};
+
+export default StepsState;
\ No newline at end of file
diff --git a/src/components/home/status/TrainingJobInfo.js b/src/components/home/status/TrainingJobInfo.js
new file mode 100644 (file)
index 0000000..2b81a5c
--- /dev/null
@@ -0,0 +1,147 @@
+// ==================================================================================
+
+//        Copyright (c) 2022 Samsung Electronics Co., Ltd. All Rights Reserved.
+
+//    Licensed under the Apache License, Version 2.0 (the "License");
+//    you may not use this file except in compliance with the License.
+//    You may obtain a copy of the License at
+
+//           http://www.apache.org/licenses/LICENSE-2.0
+
+//    Unless required by applicable law or agreed to in writing, software
+//    distributed under the License is distributed on an "AS IS" BASIS,
+//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//    See the License for the specific language governing permissions and
+//    limitations under the License.
+
+// ==================================================================================
+
+import React, { useEffect, useState } from 'react';
+import { Form } from 'react-bootstrap';
+import axios from 'axios';
+import { UCMgr_baseUrl } from '../common/Constants';
+import {convertToCommaSeparatedString, getDatalakeNameWithoutConversion} from '../common/CommonMethods';
+
+const TrainingJobInfo = (props) => {
+    const [trainingJobName, setTrainingJobName] = useState("");
+    const [version, setVersion] = useState("");
+    const [description, setDescription] = useState("");
+    const [featureNames, setFeatureNames] = useState("");
+    const [pipeLineName, setPipelineName] = useState("");
+    const [experimentName, setExperimentName] = useState("");
+    const [featureFilter, setFeatureFilter] = useState("");
+    const [hyperParameters, setHyperParameters] = useState("");
+    const [metrics, setMetrics] = useState("");
+    const [enableVersioning, setEnableVersioning] = useState(false);
+    const [pipelineVersion, setPipelineVersion] = useState("");
+    const [datalakeSource, setDatalakeSource] = useState("");
+    const [modelUrl, setModelUrl] = useState("");
+    const [_measurement, set_measurement] = useState("");
+    const [bucket, setBucket] = useState("");
+
+    useEffect(()=>{
+        try{
+            axios.get(`${UCMgr_baseUrl}/trainingjobs/${props.trainingjob_name_and_version.trainingjob_name}/${props.trainingjob_name_and_version.version}`)
+            .then(response => {
+                console.log(`response for ${UCMgr_baseUrl}/trainingjobs/${props.trainingjob_name_and_version.trainingjob_name}/${props.trainingjob_name_and_version.version}`, response);
+                console.log(response.data);
+                setTrainingJobName(response.data.trainingjob.trainingjob_name);
+                setVersion(response.data.trainingjob.version);
+                setDescription(response.data.trainingjob.description);
+                setFeatureNames(response.data.trainingjob.feature_list);
+                setPipelineName(response.data.trainingjob.pipeline_name);
+                setExperimentName(response.data.trainingjob.experiment_name);
+                setFeatureFilter(response.data.trainingjob.query_filter);
+                setHyperParameters(convertToCommaSeparatedString(response.data.trainingjob.arguments));
+                setMetrics(response.data.trainingjob.accuracy);
+                setEnableVersioning(response.data.trainingjob.enable_versioning);
+                setPipelineVersion(response.data.trainingjob.pipeline_version === response.data.trainingjob.pipeline_name ? "1" : response.data.trainingjob.pipeline_version);
+                setDatalakeSource(getDatalakeNameWithoutConversion(response.data.trainingjob.datalake_source));
+                setModelUrl(response.data.trainingjob.model_url);
+                set_measurement(response.data.trainingjob._measurement);
+                setBucket(response.data.trainingjob.bucket);
+            })
+            .catch(error => {
+                console.log(error);
+            });
+        }
+        catch(error){
+            console.log(error);
+        }
+    },[props.trainingjob_name_and_version]);
+
+
+    return (
+        <>
+            <Form>
+                <Form.Group controlId="ucName">
+                    <Form.Label>Training Job Name</Form.Label>
+                    <Form.Control type="text" value={trainingJobName} readOnly/>
+                </Form.Group>
+                <Form.Group controlId="version">
+                    <Form.Label>Version</Form.Label>
+                    <Form.Control type="text" value={version} readOnly />
+                </Form.Group>
+                <Form.Group controlId="description">
+                    <Form.Label>Description</Form.Label>
+                    <Form.Control type="text" value={description} readOnly />
+                </Form.Group>
+                <Form.Group controlId="featureNames">
+                    <Form.Label>Feature Names</Form.Label>
+                    <Form.Control type="text" value={featureNames} readOnly />
+                </Form.Group>
+                <Form.Group controlId="pipelineName">
+                    <Form.Label>Pipeline Name</Form.Label>
+                    <Form.Control type="text" value={pipeLineName} readOnly />
+                </Form.Group>
+                <Form.Group controlId="experimentName">
+                    <Form.Label>Experiment Name</Form.Label>
+                    <Form.Control type="text" value={experimentName} readOnly />
+                </Form.Group>
+                <Form.Group controlId="featureFilter">
+                    <Form.Label>Feature Filter</Form.Label>
+                    <Form.Control type="text" value={featureFilter} readOnly />
+                </Form.Group>
+                <Form.Group controlId="hyperParameters">
+                    <Form.Label>Hyper Parameters</Form.Label>
+                    <Form.Control type="text" value={hyperParameters} readOnly />
+                </Form.Group>
+                <Form.Group controlId="metrics">
+                    <Form.Label>Metrics</Form.Label>
+                    <Form.Control type="text" value={metrics} readOnly />
+                </Form.Group>
+                <Form.Group id="enableVersioning">
+                    <Form.Check type="checkbox" label="Enable versioning"
+                    checked={enableVersioning} readOnly/>
+                </Form.Group>
+                <Form.Group controlId="pipelineVersion">
+                    <Form.Label>Pipeline Version</Form.Label>
+                    <Form.Control type="text" value={pipelineVersion} readOnly />
+                </Form.Group>
+                <Form.Group controlId="datalakeSource">
+                    <Form.Label>Datalake Source</Form.Label>
+                    <Form.Control type="text" value={datalakeSource} readOnly />
+                </Form.Group>
+                {
+                    datalakeSource === "Influx DB" &&
+                        <>
+                            <Form.Group controlId="_measurement">
+                                <Form.Label>_measurement</Form.Label>
+                                <Form.Control type="text" value={_measurement} readOnly />
+                            </Form.Group>
+                            <Form.Group controlId="bucket">
+                                <Form.Label>bucket</Form.Label>
+                                <Form.Control type="text" value={bucket} readOnly />
+                            </Form.Group>
+                        </>
+                }
+                <Form.Group controlId="modelUrl">
+                    <Form.Label>Model URL</Form.Label>
+                    <Form.Control type="text" value={modelUrl} readOnly />
+                </Form.Group>
+            </Form>
+        </>
+    );
+}
+
+export default TrainingJobInfo;
\ No newline at end of file