This is an automated email from the ASF dual-hosted git repository.

imesha pushed a commit to branch development
in repository https://gitbox.apache.org/repos/asf/oodt.git


The following commit(s) were added to refs/heads/development by this push:
     new b375681  Add File Manager NodeJS component and update OPSUI dashboard
     new cb77ee4  Merge pull request #112 from NGimhana
b375681 is described below

commit b375681f218190ca01e5e7670a4601632f9c62dc
Author: ngimhana <[email protected]>
AuthorDate: Sat Aug 24 16:18:43 2019 +0530

    Add File Manager NodeJS component and update OPSUI dashboard
---
 react-components/oodt_fm_plugin/package.json       |   5 +-
 .../src/components/Product/Product.js              | 427 ++++++++++++++-------
 .../oodt_fm_plugin/src/components/Product/index.js |   2 +-
 .../src/components/ProductIngest/ProductIngest.js  | 228 +++++++++++
 .../components/{Product => ProductIngest}/index.js |   4 +-
 .../ProductIngestWithMetaFile.js                   | 153 ++++++++
 .../index.js                                       |   4 +-
 .../src/components/ProductList/ProductList.js      | 403 +++++++++++++++++++
 .../src/components/ProductList/SearchBar.js        |  98 +++++
 .../src/components/ProductList/SimpleSnackBar.js   |  82 ++++
 .../components/{Product => ProductList}/index.js   |   4 +-
 .../oodt_fm_plugin/src/components/index.js         |   7 +-
 .../oodt_fm_plugin/src/constants/fmconnection.js   |   2 +-
 react-components/oodt_fm_plugin/src/index.js       |   2 +-
 react-components/oodt_opsui_sample_app/README.md   |  36 ++
 .../oodt_opsui_sample_app/package.json             |  36 ++
 .../oodt_opsui_sample_app/public/favicon.ico       | Bin 0 -> 3870 bytes
 .../public/images/oodt_logo.png                    | Bin 0 -> 28444 bytes
 .../oodt_opsui_sample_app/public/index.html        |  38 ++
 .../oodt_opsui_sample_app/public/manifest.json     |  15 +
 react-components/oodt_opsui_sample_app/src/App.js  | 141 +++++++
 .../oodt_opsui_sample_app/src/App.test.js          |   9 +
 .../src/components/OPSUIHome.js                    | 244 ++++++++++++
 .../src/components/SearchBar.js                    | 102 +++++
 .../src/components/listItems.js                    |  94 +++++
 .../oodt_opsui_sample_app/src/index.css            |  13 +
 .../oodt_opsui_sample_app/src/index.js             |  11 +
 .../oodt/cas/product/jaxrs/enums/ErrorType.java    |  68 ----
 28 files changed, 2007 insertions(+), 221 deletions(-)

diff --git a/react-components/oodt_fm_plugin/package.json 
b/react-components/oodt_fm_plugin/package.json
index f81ce33..327ea3d 100644
--- a/react-components/oodt_fm_plugin/package.json
+++ b/react-components/oodt_fm_plugin/package.json
@@ -22,16 +22,19 @@
   "license": "Apache-2.0",
   "devDependencies": {
     "@babel/core": "^7.2.2",
+    "@babel/plugin-proposal-class-properties": "^7.4.0",
     "@babel/preset-env": "^7.2.3",
     "@babel/preset-react": "^7.0.0",
-    "@babel/plugin-proposal-class-properties": "^7.4.0",
     "babel-loader": "^8.0.5",
+    "prettier": "1.18.2",
     "webpack": "^4.28.3",
     "webpack-cli": "^3.2.0"
   },
   "dependencies": {
     "@material-ui/core": "^3.9.3",
+    "@material-ui/icons": "^4.2.0",
     "axios": "^0.18.0",
+    "clsx": "^1.0.4",
     "react": "^16.7.0",
     "react-dom": "^16.7.0",
     "prop-types": "latest"
diff --git a/react-components/oodt_fm_plugin/src/components/Product/Product.js 
b/react-components/oodt_fm_plugin/src/components/Product/Product.js
index c5acc2f..16f353b 100644
--- a/react-components/oodt_fm_plugin/src/components/Product/Product.js
+++ b/react-components/oodt_fm_plugin/src/components/Product/Product.js
@@ -15,170 +15,313 @@
  * limitations under the License.
  */
 
-import React, {Component} from "react";
-import Card from '@material-ui/core/Card';
-import CardContent from '@material-ui/core/CardContent';
-import Button from '@material-ui/core/Button';
-import Typography from '@material-ui/core/Typography';
-import {withStyles} from "@material-ui/core";
+import React, { Component } from "react";
+import Card from "@material-ui/core/Card";
+import CardContent from "@material-ui/core/CardContent";
+import Button from "@material-ui/core/Button";
+import Typography from "@material-ui/core/Typography";
+import { withStyles } from "@material-ui/core";
 import PropTypes from "prop-types";
-import {fmconnection} from "../../constants/fmconnection";
+import { fmconnection } from "../../constants/fmconnection";
 import Grid from "@material-ui/core/Grid";
 import Fab from "@material-ui/core/Fab";
 
 const styles = theme => ({
-    root: {
-        flexGrow: 1,
-        backgroundColor: theme.palette.background.paper,
-    },
-    card: {
-        minWidth: 275,
-        backgroundColor: "#dcdcdc",
-
-    },
-    bullet: {
-        display: 'inline-block',
-        margin: '0 2px',
-        transform: 'scale(0.8)',
-    },
-    title: {
-        fontSize: 14,
-
-    },
-    pos: {
-        marginBottom: 12,
-    },
+  root: {
+    flexGrow: 1,
+    backgroundColor: theme.palette.background.paper
+  },
+  card: {
+    minWidth: 275,
+    backgroundColor: "#dcdcdc"
+  },
+  bullet: {
+    display: "inline-block",
+    margin: "0 2px",
+    transform: "scale(0.8)"
+  },
+  title: {
+    fontSize: 14
+  },
+  pos: {
+    marginBottom: 12
+  }
 });
 
 class Product extends Component {
+  constructor(props) {
+    super(props);
+    this.loadProduct = this.loadProduct.bind(this);
+    this.removeProduct = this.removeProduct.bind(this);
+  }
 
+  state = {
+    productData: [],
+    productMetaDataFileLocation: [],
+    productMetaDataFileType: [],
+    productMetaDataMimeType: [],
+    productReferencesData: [],
+    productId: this.props.productId
+  };
 
-    constructor(props) {
-        super(props);
-    }
+  componentWillReceiveProps(productId) {
+    // check this.props vs nextProps and setState!
+    // do whatever you want.
+    this.setState({ productId: productId.productId });
+    this.loadProduct();
+  }
 
-    state = {
-        productData: [],
-        productMetaDataFileLocation:[],
-        productMetaDataFileType:[],
-        productMetaDataMimeType:[],
-        productReferencesData: [],
-        productId : this.props.productId,
-    };
+  render() {
+    const { classes } = this.props;
+    return (
+      <div className={classes.root}>
+        <Card className={classes.card}>
+          <Grid>
+            <Grid container spacing={24}>
+              <Grid item xs={3}>
+                <CardContent>
+                  <Typography variant="h6" color="textPrimary" gutterBottom>
+                    <strong>FILE INFO</strong>
+                  </Typography>
+                  <Typography
+                    variant="h6"
+                    style={{ fontSize: 15 }}
+                    color="textPrimary"
+                    gutterBottom
+                  >
+                    FILE NAME :{" "}
+                    <strong>{this.state.productData["name"]}</strong>
+                  </Typography>
+                  <Typography
+                    variant="h6"
+                    style={{ fontSize: 15 }}
+                    color="textPrimary"
+                    gutterBottom
+                  >
+                    PRODUCT ID : 
<strong>{this.state.productData["id"]}</strong>
+                  </Typography>
+                  <Typography
+                    variant="h6"
+                    style={{ fontSize: 15 }}
+                    color="textPrimary"
+                    gutterBottom
+                  >
+                    STRUCTURE :{" "}
+                    <strong>{this.state.productData["structure"]}</strong>
+                  </Typography>
+                  <Typography
+                    variant="h6"
+                    style={{ fontSize: 15 }}
+                    color="textPrimary"
+                    gutterBottom
+                  >
+                    TRANSFER STATUS :{" "}
+                    <strong>{this.state.productData["transferStatus"]}</strong>
+                  </Typography>
+                </CardContent>
+              </Grid>
 
-    render() {
+              <Grid item xs={3}>
+                <CardContent>
+                  <Typography variant="h6" color="textPrimary" gutterBottom>
+                    <strong>METADATA INFO</strong>
+                  </Typography>
+                  <Typography
+                    variant="h6"
+                    style={{ fontSize: 15 }}
+                    color="textPrimary"
+                    gutterBottom
+                  >
+                    <span style={{ color: "black" }}>FILE LOCATION</span> :{" 
"}
+                    <strong style={{ fontSize: 12 }}>
+                      {this.state.productMetaDataFileLocation["val"]}
+                    </strong>
+                  </Typography>
+                  <Typography
+                    variant="h6"
+                    style={{ fontSize: 15 }}
+                    color="textPrimary"
+                    gutterBottom
+                  >
+                    PRODUCT TYPE :{" "}
+                    
<strong>{this.state.productMetaDataFileType["val"]}</strong>
+                  </Typography>
+                  <Typography
+                    variant="h6"
+                    style={{ fontSize: 15 }}
+                    color="textPrimary"
+                    gutterBottom
+                  >
+                    MIME TYPE :{" "}
+                    <strong>{this.state.productMetaDataMimeType[0]}</strong>
+                  </Typography>
+                </CardContent>
+                {/*<Button style={{ background: "green" }}>*/}
+                {/*  <span style={{ color: "white" }}>View All 
Metadata</span>*/}
+                {/*</Button>*/}
+              </Grid>
 
-        const { classes } = this.props;
-        return(
-            <div className={classes.root}>
-            <Card className={classes.card}>
-
-            <Grid>
-            <Grid container spacing={24}>
-            <Grid item xs={3}>
-            <CardContent>
-            <Typography variant="h4" color="textPrimary" gutterBottom>
-        FILE INFO
-        </Typography>
-        <Typography variant="h6" color="textPrimary" gutterBottom>
-        FILE NAME : <strong>{this.state.productData["name"]}</strong>
-        </Typography>
-        <Typography variant="h6" color="textPrimary" gutterBottom>
-        PRODUCT ID : <strong>{this.state.productData["id"]}</strong>
-        </Typography>
-        <Typography variant="h6" color="textPrimary" gutterBottom>
-        STRUCTURE : <strong>{this.state.productData["structure"]}</strong>
-        </Typography>
-        <Typography variant="h6" color="textPrimary" gutterBottom>
-        TRANSFER STATUS : 
<strong>{this.state.productData["transferStatus"]}</strong>
-        </Typography>
-        </CardContent>
-        </Grid>
-
-        <Grid item xs={3}>
-            <CardContent>
-            <Typography variant="h4" color="textPrimary" gutterBottom>
-        <span style={{color:"black"}}>METADATA INFO</span>
-        </Typography>
-        <Typography variant="h6" color="textPrimary" gutterBottom>
-        <span style={{color:"black"}}>FILE LOCATION</span> : 
<strong>{this.state.productMetaDataFileLocation["val"]}</strong>
-        </Typography>
-        <Typography variant="h6" color="textPrimary" gutterBottom>
-        PRODUCT TYPE : 
<strong>{this.state.productMetaDataFileType["val"]}</strong>
-        </Typography>
-        <Typography variant="h6" color="textPrimary" gutterBottom>
-        MIME TYPE : <strong>{this.state.productMetaDataMimeType[0]}</strong>
-        </Typography>
-        </CardContent>
-        <Button style={{background:"green"}}><span 
style={{color:"white"}}>View All Metadata</span></Button>
-        </Grid>
-
-        <Grid item xs={3}>
-            <CardContent>
-            <Typography variant="h4" color="textPrimary" gutterBottom>
-        REFERENCE INFO
-        </Typography>
-        <Typography variant="h6" color="textPrimary" gutterBottom>
-        DATA STORE REF LOCATION : 
<strong>{this.state.productReferencesData["dataStoreReference"]}</strong>
-        </Typography>
-        <Typography variant="h6" color="textPrimary" gutterBottom>
-        FILE SIZE : 
<strong>{this.state.productReferencesData["fileSize"]}</strong>
-        </Typography>
-        <Typography variant="h6" color="textPrimary" gutterBottom>
-        ORIGINAL REFERENCE : 
<strong>{this.state.productReferencesData["originalReference"]}</strong>
-        </Typography>
-        </CardContent>
-        <Button style={{background:"green"}}><span 
style={{color:"white"}}>View All References</span></Button>
-        </Grid>
-
-        <Grid item xs={3}>
-            <CardContent>
-            <Typography variant="h6" color="textPrimary" gutterBottom>
-        <Fab  variant="extended" color="primary" 
style={{fontSize:20}}>Download File</Fab>
-        </Typography>
-        <Typography variant="h6" color="textPrimary" gutterBottom>
-        <Fab variant="extended" color="primary" style={{fontSize:20 
,background:"green"}}>View in File Manager</Fab>
-        </Typography>
-        <Typography variant="h6" color="textPrimary" gutterBottom>
-        <Fab variant="extended" color="secondary" style={{fontSize:20}}>Remove 
Record</Fab>
-        </Typography>
-        </CardContent>
-        </Grid>
-        </Grid>
-        </Grid>
+              <Grid item xs={3}>
+                <CardContent>
+                  <Typography variant="h6" color="textPrimary" gutterBottom>
+                    <strong>REFERENCE INFO</strong>
+                  </Typography>
+                  <Typography
+                    variant="h6"
+                    style={{ fontSize: 15 }}
+                    color="textPrimary"
+                    gutterBottom
+                  >
+                    DATA STORE REF LOCATION :{" "}
+                    <strong>
+                      {this.state.productReferencesData["dataStoreReference"]}
+                    </strong>
+                  </Typography>
+                  <Typography
+                    variant="h6"
+                    style={{ fontSize: 15 }}
+                    color="textPrimary"
+                    gutterBottom
+                  >
+                    FILE SIZE :{" "}
+                    <strong>
+                      {this.state.productReferencesData["fileSize"]}
+                    </strong>
+                  </Typography>
+                  <Typography
+                    variant="h6"
+                    style={{ fontSize: 15 }}
+                    color="textPrimary"
+                    gutterBottom
+                  >
+                    ORIGINAL REFERENCE :{" "}
+                    <strong>
+                      {this.state.productReferencesData["originalReference"]}
+                    </strong>
+                  </Typography>
+                </CardContent>
+                {/*<Button style={{ background: "green" }}>*/}
+                {/*  <span style={{ color: "white" }}>View All 
References</span>*/}
+                {/*</Button>*/}
+              </Grid>
 
+              <Grid item xs={3}>
+                <CardContent>
+                  <Typography
+                    variant="h6"
+                    style={{ fontSize: 15 }}
+                    color="textPrimary"
+                    gutterBottom
+                  >
+                    <Fab
+                      variant="extended"
+                      color="primary"
+                      style={{ fontSize: 20 }}
+                    >
+                      Download File
+                    </Fab>
+                  </Typography>
 
+                  <Typography
+                    variant="h6"
+                    style={{ fontSize: 15 }}
+                    color="textPrimary"
+                    gutterBottom
+                  >
+                    <Fab
+                      variant="extended"
+                      color="secondary"
+                      style={{ fontSize: 20 }}
+                      onClick={this.removeProduct}
+                    >
+                      Remove Record
+                    </Fab>
+                  </Typography>
+                </CardContent>
+              </Grid>
+            </Grid>
+          </Grid>
         </Card>
-        </div>
+      </div>
     );
-    }
+  }
 
-    componentDidMount() {
-        console.log(this.state.productId);
-        // Make a request for a product with a given ID
-        fmconnection.get("/product?productId=" +this.state.productId)
-
-            .then(res => {
-                this.setState({
-                    productData:res.data.product,
-                    
productMetaDataFileLocation:Object.values(res.data.product.metadata)[0][0],
-                    
productMetaDataFileType:Object.values(res.data.product.metadata)[0][1],
-                    
productMetaDataMimeType:Object.values(res.data.product.metadata)[0][7]["val"],
-                    
productReferencesData:res.data.product.references.reference,
-                });
-                console.log(this.state.productMetaDataFileLocation["val"]);
-                console.log(this.state.productMetaDataFileType["val"]);
-                console.log(this.state.productMetaDataMimeType[0]);
-
-            })
-            .catch(err=>{
-                console.log(err);
-            })
+  removeProduct() {
+    let result = confirm(
+      "Are you Sure to Remove the Product ?" + this.state.productId
+    );
+    if (result == true) {
+      fmconnection
+        .delete("/removeProduct?productId=" + this.state.productId)
+        .then(res => {
+          alert(
+            "Product sucessfully removed productID: " + this.state.productId
+          );
+          this.setState({ productId: "" });
+        });
+    } else {
     }
+  }
+
+  loadProduct() {
+    fmconnection
+      .get("/product?productId=" + this.state.productId)
+
+      .then(res => {
+        this.setState({
+          productData: res.data.product,
+          productMetaDataFileLocation: Object.values(
+            res.data.product.metadata
+          )[0][0],
+          productMetaDataFileType: Object.values(
+            res.data.product.metadata
+          )[0][1],
+          productMetaDataMimeType: Object.values(
+            res.data.product.metadata
+          )[0][7]["val"],
+          productReferencesData: res.data.product.references.reference
+        });
+        console.log(this.state.productMetaDataFileLocation["val"]);
+        console.log(this.state.productMetaDataFileType["val"]);
+        console.log(this.state.productMetaDastaMimeType[0]);
+      })
+      .catch(err => {
+        console.log(err);
+      });
+  }
+
+  componentDidMount() {
+    console.log(this.state.productId);
+    // Make a request for a product with a given ID
+    fmconnection
+      .get("/product?productId=" + this.state.productId)
+
+      .then(res => {
+        this.setState({
+          productData: res.data.product,
+          productMetaDataFileLocation: Object.values(
+            res.data.product.metadata
+          )[0][0],
+          productMetaDataFileType: Object.values(
+            res.data.product.metadata
+          )[0][1],
+          productMetaDataMimeType: Object.values(
+            res.data.product.metadata
+          )[0][7]["val"],
+          productReferencesData: res.data.product.references.reference
+        });
+        console.log(this.state.productMetaDataFileLocation["val"]);
+        console.log(this.state.productMetaDataFileType["val"]);
+        console.log(this.state.productMetaDastaMimeType[0]);
+      })
+      .catch(err => {
+        console.log(err);
+      });
+  }
 }
 
 Product.propTypes = {
-    classes: PropTypes.object.isRequired,
+  classes: PropTypes.object.isRequired
 };
 
 export default withStyles(styles)(Product);
diff --git a/react-components/oodt_fm_plugin/src/components/Product/index.js 
b/react-components/oodt_fm_plugin/src/components/Product/index.js
index 2e2501e..1289634 100644
--- a/react-components/oodt_fm_plugin/src/components/Product/index.js
+++ b/react-components/oodt_fm_plugin/src/components/Product/index.js
@@ -16,6 +16,6 @@
  */
 
 // Import the Product component from this folder and send it down to 
./components/index.js
-import Product from './Product';
+import Product from "./Product";
 
 export default Product;
diff --git 
a/react-components/oodt_fm_plugin/src/components/ProductIngest/ProductIngest.js 
b/react-components/oodt_fm_plugin/src/components/ProductIngest/ProductIngest.js
new file mode 100644
index 0000000..d9973f9
--- /dev/null
+++ 
b/react-components/oodt_fm_plugin/src/components/ProductIngest/ProductIngest.js
@@ -0,0 +1,228 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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, { Component } from "react";
+import { OutlinedInput, Paper, withStyles } from "@material-ui/core";
+import Typography from "@material-ui/core/Typography";
+import PropTypes from "prop-types";
+import TextField from "@material-ui/core/TextField";
+import Button from "@material-ui/core/Button";
+import { fmconnection } from "../../constants/fmconnection";
+import CircularProgress from "@material-ui/core/CircularProgress";
+
+import FormControl from "@material-ui/core/FormControl";
+import MenuItem from "@material-ui/core/MenuItem";
+import InputLabel from "@material-ui/core/InputLabel";
+import Select from "@material-ui/core/Select";
+import FormHelperText from "@material-ui/core/FormHelperText";
+import Input from "@material-ui/core/Input";
+
+const styles = theme => ({
+  root: {
+    flexGrow: 1,
+    backgroundColor: theme.palette.background.paper,
+    padding: 20
+  },
+  button: {
+    padding: 10,
+    margin: 20
+  },
+  textField: {
+    marginLeft: 2,
+    marginRight: 2
+  },
+  layout: {
+    display: "flex",
+    flexDirection: "row",
+    padding: 0
+  },
+  progress: {
+    margin: 2
+  },
+  formControl: {
+    margin: 1,
+    minWidth: 120
+  }
+});
+
+class ProductIngest extends Component {
+  constructor(props) {
+    super(props);
+    this.handleFile = this.handleFile.bind(this);
+    this.handleProductStructure = this.handleProductStructure.bind(this);
+    this.handleProductType = this.handleProductType.bind(this);
+    this.ingestProduct = this.ingestProduct.bind(this);
+  }
+
+  state = {
+    ingestedFile: null,
+    productId: "",
+    productType: "GenericFile",
+    productStructure: "Flat",
+    isIngested: false,
+    isIngestButtonClicked: false
+  };
+
+  handleFile(e) {
+    let file = e.target.files[0];
+    this.setState({ ingestedFile: file });
+  }
+
+  handleProductStructure(e) {
+    let productStructure = e.target.value;
+    this.setState({ productStructure: productStructure });
+  }
+
+  handleProductType(e) {
+    let productType = e.target.value;
+    this.setState({ productType: productType });
+    console.log(this.state.productType);
+  }
+
+  keyPress(e) {
+    if (e.keyCode === 13) {
+      console.log(e.target.value);
+      this.handleProductStructure();
+    }
+  }
+
+  ingestProduct() {
+    this.setState({ isIngested: false });
+    this.setState({ isIngestButtonClicked: true });
+
+    let product = this.state.ingestedFile;
+    let formData = new FormData();
+    formData.append("productFile", product);
+    fmconnection
+      .post(
+        "productWithFile?productType=" +
+          this.state.productType +
+          "&productStructure=" +
+          this.state.productStructure,
+        formData
+      )
+      .then(result => {
+        console.log(result);
+        this.setState({ productId: result.data });
+        this.setState({ isIngested: true });
+      })
+      .catch(error => {
+        console.log(error);
+        this.setState({ isIngested: false });
+        alert("Product Ingestion Failed : " + error);
+      });
+  }
+
+  render() {
+    const { classes } = this.props;
+
+    return (
+      <Paper className={classes.root}>
+        <Typography variant="h5" component="h3">
+          Product Ingest with Single File
+        </Typography>
+
+        <br />
+
+        <div className={classes.layout}>
+          <form>
+            <FormControl
+              variant="outlined"
+              className={classes.formControl}
+              style={{ width: "200px" }}
+            >
+              <InputLabel htmlFor="outlined-product-Type-simple">
+                Product Type
+              </InputLabel>
+              <Select
+                value={this.state.productType}
+                onChange={this.handleProductType}
+                input={
+                  <OutlinedInput
+                    labelWidth={100}
+                    name="Product Type"
+                    id="outlined-product-Type-simple"
+                  />
+                }
+              >
+                <MenuItem selected={true} value={"GenericFile"}>
+                  GenericFile
+                </MenuItem>
+                <MenuItem value={"LocationAwareProduct"}>
+                  LocationAwareProduct
+                </MenuItem>
+              </Select>
+            </FormControl>
+
+            <FormControl
+              variant="outlined"
+              className={classes.formControl}
+              style={{ width: "200px" }}
+            >
+              <InputLabel htmlFor="outlined-product-structure-simple">
+                Product Structure
+              </InputLabel>
+              <Select
+                value={this.state.productStructure}
+                onChange={this.handleProductStructure}
+                input={
+                  <OutlinedInput
+                    labelWidth={130}
+                    name="Product Structure"
+                    id="outlined-product-structure-simple"
+                  />
+                }
+              >
+                <MenuItem selected={true} value={"Flat"}>
+                  Flat
+                </MenuItem>
+              </Select>
+            </FormControl>
+          </form>
+
+          <input
+            className={classes.button}
+            type={"file"}
+            name={"fileToUpload"}
+            id={"fileToUpload"}
+            onChange={e => this.handleFile(e)}
+          />
+
+          <Button
+            variant="contained"
+            color="primary"
+            className={classes.button}
+            onClick={this.ingestProduct}
+          >
+            Ingest Product
+          </Button>
+
+          {this.state.isIngested === false &&
+            this.state.isIngestButtonClicked == true && <CircularProgress />}
+          {this.state.isIngested == true &&
+            alert("Successfully Ingested Product ID :" + this.state.productId)}
+        </div>
+      </Paper>
+    );
+  }
+}
+
+ProductIngest.propTypes = {
+  classes: PropTypes.object.isRequired
+};
+
+export default withStyles(styles)(ProductIngest);
diff --git a/react-components/oodt_fm_plugin/src/components/Product/index.js 
b/react-components/oodt_fm_plugin/src/components/ProductIngest/index.js
similarity index 92%
copy from react-components/oodt_fm_plugin/src/components/Product/index.js
copy to react-components/oodt_fm_plugin/src/components/ProductIngest/index.js
index 2e2501e..a9bd7c9 100644
--- a/react-components/oodt_fm_plugin/src/components/Product/index.js
+++ b/react-components/oodt_fm_plugin/src/components/ProductIngest/index.js
@@ -16,6 +16,6 @@
  */
 
 // Import the Product component from this folder and send it down to 
./components/index.js
-import Product from './Product';
+import ProductIngest from "./ProductIngest";
 
-export default Product;
+export default ProductIngest;
diff --git 
a/react-components/oodt_fm_plugin/src/components/ProductIngestWithMetaFile/ProductIngestWithMetaFile.js
 
b/react-components/oodt_fm_plugin/src/components/ProductIngestWithMetaFile/ProductIngestWithMetaFile.js
new file mode 100644
index 0000000..cd4748d
--- /dev/null
+++ 
b/react-components/oodt_fm_plugin/src/components/ProductIngestWithMetaFile/ProductIngestWithMetaFile.js
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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, { Component } from "react";
+import { Paper, withStyles } from "@material-ui/core";
+import Typography from "@material-ui/core/Typography";
+import PropTypes from "prop-types";
+import Button from "@material-ui/core/Button";
+import { fmconnection } from "../../constants/fmconnection";
+import CircularProgress from "@material-ui/core/CircularProgress";
+
+const styles = theme => ({
+  root: {
+    flexGrow: 1,
+    backgroundColor: theme.palette.background.paper,
+    padding: 20
+  },
+  button: {
+    padding: 10,
+    margin: 20
+  },
+  textField: {
+    marginLeft: 2,
+    marginRight: 2
+  },
+  layout: {
+    display: "flex",
+    flexDirection: "row",
+    padding: 0
+  }
+});
+
+class ProductIngestWithMetaFile extends Component {
+  constructor(props) {
+    super(props);
+    this.handleFile = this.handleFile.bind(this);
+    this.handleMetaFile = this.handleMetaFile.bind(this);
+    this.ingestProduct = this.ingestProduct.bind(this);
+  }
+
+  state = {
+    ingestedFile: null,
+    metaFile: null,
+    productId: "",
+    isIngested: false,
+    isIngestButtonClicked: false
+  };
+
+  handleFile(e) {
+    let file = e.target.files[0];
+    this.setState({ ingestedFile: file });
+  }
+
+  handleMetaFile(e) {
+    let metaFile = e.target.files[0];
+    this.setState({ metaFile: metaFile });
+  }
+
+  ingestProduct() {
+    this.setState({ isIngested: false });
+    this.setState({ isIngestButtonClicked: true });
+
+    let product = this.state.ingestedFile;
+    let metaProduct = this.state.metaFile;
+    let formData = new FormData();
+    formData.append("productFile", product);
+    formData.append("metadataFile", metaProduct);
+    fmconnection
+      .post("productWithMeta", formData)
+      .then(result => {
+        console.log(result);
+        this.setState({ productId: result.data });
+        this.setState({ isIngested: true });
+        alert("Sucessfully Ingested :ProductId " + result.data);
+      })
+      .catch(error => {
+        console.log(error);
+        this.setState({ isIngested: false });
+        alert("Exception Thrown " + error);
+      });
+  }
+
+  render() {
+    const { classes } = this.props;
+
+    return (
+      <Paper className={classes.root}>
+        <Typography variant="h5" component="h3">
+          Product Ingest with Meta File
+        </Typography>
+
+        <div className={classes.layout}>
+          <div>
+            <div>
+              <div>
+                <label>File</label>
+                <input
+                  className={classes.button}
+                  type={"file"}
+                  name={"fileToUpload"}
+                  id={"fileToUpload"}
+                  onChange={e => this.handleFile(e)}
+                />
+                <label>MetadataFile</label>
+                <input
+                  className={classes.button}
+                  type={"file"}
+                  name={"metaFileToUpload"}
+                  id={"metaFileToUpload"}
+                  onChange={e => this.handleMetaFile(e)}
+                />
+              </div>
+            </div>
+          </div>
+
+          <Button
+            variant="contained"
+            color="primary"
+            className={classes.button}
+            onClick={this.ingestProduct}
+          >
+            Ingest Product
+          </Button>
+
+          {this.state.isIngested === false &&
+            this.state.isIngestButtonClicked == true && <CircularProgress />}
+          {this.state.isIngested == true &&
+            alert("Sucessfully Ingested :ProductId  :" + this.state.productId)}
+        </div>
+      </Paper>
+    );
+  }
+}
+
+ProductIngestWithMetaFile.propTypes = {
+  classes: PropTypes.object.isRequired
+};
+
+export default withStyles(styles)(ProductIngestWithMetaFile);
diff --git a/react-components/oodt_fm_plugin/src/components/Product/index.js 
b/react-components/oodt_fm_plugin/src/components/ProductIngestWithMetaFile/index.js
similarity index 88%
copy from react-components/oodt_fm_plugin/src/components/Product/index.js
copy to 
react-components/oodt_fm_plugin/src/components/ProductIngestWithMetaFile/index.js
index 2e2501e..3bf6da6 100644
--- a/react-components/oodt_fm_plugin/src/components/Product/index.js
+++ 
b/react-components/oodt_fm_plugin/src/components/ProductIngestWithMetaFile/index.js
@@ -16,6 +16,6 @@
  */
 
 // Import the Product component from this folder and send it down to 
./components/index.js
-import Product from './Product';
+import ProductIngestWithMetaFile from "./ProductIngestWithMetaFile";
 
-export default Product;
+export default ProductIngestWithMetaFile;
diff --git 
a/react-components/oodt_fm_plugin/src/components/ProductList/ProductList.js 
b/react-components/oodt_fm_plugin/src/components/ProductList/ProductList.js
new file mode 100644
index 0000000..6ca462a
--- /dev/null
+++ b/react-components/oodt_fm_plugin/src/components/ProductList/ProductList.js
@@ -0,0 +1,403 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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, { Component } from "react";
+import { fmconnection } from "../../constants/fmconnection";
+import PropTypes from "prop-types";
+import { OutlinedInput, withStyles } from "@material-ui/core";
+import clsx from "clsx";
+import Button from "@material-ui/core/Button";
+import Grid from "@material-ui/core/Grid";
+import Paper from "@material-ui/core/Paper";
+import SimpleSnackBar from "./SimpleSnackBar";
+import FormControl from "@material-ui/core/FormControl";
+import InputLabel from "@material-ui/core/InputLabel";
+import Select from "@material-ui/core/Select";
+import MenuItem from "@material-ui/core/MenuItem";
+import CircularProgress from "@material-ui/core/CircularProgress";
+import Typography from "@material-ui/core/Typography";
+
+const styles = theme => ({
+  root: {
+    flexGrow: 1,
+    backgroundColor: theme.palette.background.paper
+  },
+  card: {
+    minWidth: 275,
+    backgroundColor: "#dcdcdc"
+  },
+  bullet: {
+    display: "inline-block",
+    margin: "0 2px",
+    transform: "scale(0.8)"
+  },
+  title: {
+    fontSize: 14
+  },
+  pos: {
+    marginBottom: 12
+  },
+  productcontainer: {
+    display: "flex",
+    flexDirection: "row",
+    padding: 0
+  },
+  paper: {
+    padding: 12,
+    display: "flex",
+    overflow: "auto",
+    flexDirection: "column"
+  },
+  fixedHeight: {
+    height: "auto"
+  },
+  formControl: {
+    margin: 1,
+    minWidth: 120
+  },
+  button: {
+    padding: 10,
+    margin: 20
+  }
+});
+
+class Product extends Component {
+  constructor(props) {
+    super(props);
+    this.setProductTypeName = this.setProductTypeName.bind(this);
+    this.loadProducts = this.loadProducts.bind(this);
+    this.loadNextProducts = this.loadNextProducts.bind(this);
+    this.loadPrevProducts = this.loadPrevProducts.bind(this);
+    this.onClick = this.onClick.bind(this);
+    this.handleProductType = this.handleProductType.bind(this);
+    this.searchProducts = this.searchProducts.bind(this);
+  }
+
+  state = {
+    productData: [],
+    productDetailsArray: [],
+    productFilesArray: [],
+    productFoldersArray: [],
+    productTypeName: "GenericFile",
+    selectedProductId: "",
+    currentProductPage: 1,
+    productTypeArray: [],
+    isSearchButtonClicked: true,
+    isTimedOut: true
+  };
+
+  setProductTypeName(productTypeName) {
+    this.setState({ productTypeName: productTypeName });
+  }
+
+  onClick(message) {
+    this.child.handleClick(message); // do stuff
+  }
+
+  loadProducts() {
+    this.setState({ productData: [] });
+    this.setState({ productDetailsArray: [] });
+    this.setState({ productFilesArray: [] });
+    this.setState({ productFoldersArray: [] });
+    fmconnection
+      .get("/products?productTypeName=" + this.state.productTypeName)
+
+      .then(res => {
+        this.setState({
+          productData: res.data.productPage
+        });
+        this.setState({
+          productDetailsArray: this.state.productData.products.product
+        });
+
+        this.getFiles();
+        this.getFolders();
+
+        // Snackbar for Request Success
+        this.onClick("Request Successful !!");
+      })
+      .catch(error => {
+        if (error.response) {
+          console.log(error.response.data);
+          this.onClick("404 - Couldn't Find Resource");
+        }
+      });
+  }
+
+  loadNextProducts() {
+    this.setState({ currentProductPage: this.state.currentProductPage + 1 });
+    this.setState({ productData: [] });
+    this.setState({ productDetailsArray: [] });
+    this.setState({ productFilesArray: [] });
+    this.setState({ productFoldersArray: [] });
+    fmconnection
+      .get(
+        "/products?productTypeName=" +
+          this.state.productTypeName +
+          "&currentProductPage=" +
+          this.state.currentProductPage
+      )
+
+      .then(res => {
+        this.setState({
+          productData: res.data.productPage
+        });
+        this.setState({
+          productDetailsArray: this.state.productData.products.product
+        });
+
+        this.getFiles();
+        this.getFolders();
+        // Snackbar for Request Success
+        this.onClick("Request Successful !!");
+      })
+      .catch(error => {
+        if (error.response) {
+          console.log(error.response.data);
+          this.onClick("404 - Couldn't Find Resource");
+        }
+      });
+  }
+
+  // Have to Implement
+  loadPrevProducts() {
+    this.setState({ currentProductPage: this.state.currentProductPage - 1 });
+    // this.setState({productData: []});
+    // this.setState({productDetailsArray: []});
+    // this.setState({productFilesArray: []});
+    // this.setState({productFoldersArray: []});
+    // fmconnection.get("/products?productTypeName=" + 
this.state.productTypeName+"&currentProductPage="+this.state.currentProductPage)
+    //
+    //     .then(res => {
+    //         this.setState({
+    //             productData: res.data.productPage,
+    //         });
+    //         this.setState({productDetailsArray: 
this.state.productData.products.product});
+    //
+    //         this.getFiles();
+    //         this.getFolders();
+    //         console.log(this.state.productDetailsArray);
+    //     })
+    //     .catch(err => {
+    //         console.log(err);
+    //     });
+  }
+
+  getFiles() {
+    let fileArray = [];
+    let fileTypesArray = [];
+    for (let i = 0; i < this.state.productDetailsArray.length; i++) {
+      if (this.state.productDetailsArray[i].structure === "Flat") {
+        fileArray.push(this.state.productDetailsArray[i]);
+        fileTypesArray.push(this.state.productDetailsArray[i].type);
+      }
+    }
+    this.setState({ productFilesArray: fileArray });
+    let uniqueFileTypes = [...new Set(fileTypesArray)];
+    this.setState({ productTypeArray: uniqueFileTypes });
+  }
+
+  getFolders() {
+    let folderArray = [];
+    for (let i = 0; i < this.state.productDetailsArray.length; i++) {
+      if (this.state.productDetailsArray[i].structure === "Hierarchical") {
+        folderArray.push(this.state.productDetailsArray[i]);
+      }
+    }
+    this.setState({ productFoldersArray: folderArray });
+  }
+
+  selectedItem(selectedProductId) {
+    this.setState({ selectedProductId: selectedProductId });
+    this.props.selectedProductId(this.state.selectedProductId);
+  }
+
+  handleProductType(e) {
+    let productTypeName = e.target.value;
+    this.setState({ productTypeName: productTypeName });
+    this.setState({ isSearchButtonClicked: false });
+    this.setState({ isTimedOut: false });
+  }
+
+  searchProducts() {
+    setTimeout(
+      function() {
+        this.setState({ isTimedOut: true });
+      }.bind(this),
+      3000
+    );
+    this.setState({ isSearchButtonClicked: true });
+    this.loadProducts();
+  }
+  render() {
+    const { classes } = this.props;
+
+    // Mapping Folder-products
+    let listFolderItems = this.state.productFoldersArray.map(product => (
+      <div className={classes.root}>
+        <Grid item xs={12} style={{ padding: 3 }}>
+          <Button variant={"outlined"} color={"inherit"}>
+            {product.name}
+          </Button>
+        </Grid>
+      </div>
+    ));
+
+    // Mapping File-products
+    let listFileItems = this.state.productFilesArray.map(product => (
+      <div className={classes.root}>
+        <Grid item xs={6} style={{ padding: 3 }}>
+          <Button
+            variant={"outlined"}
+            color={"inherit"}
+            onClick={() => {
+              this.selectedItem(product.id);
+            }}
+          >
+            {product.name}
+          </Button>
+        </Grid>
+      </div>
+    ));
+
+    // List Product Types
+    let listProductTypes = this.state.productTypeArray.map(productType => (
+      <MenuItem selected={false} value={productType}>
+        {productType}
+      </MenuItem>
+    ));
+
+    return (
+      <div className={classes.root}>
+        <Paper className={clsx(classes.paper, classes.fixedHeight)}>
+          {/*Success/Error Snackbar*/}
+          <SimpleSnackBar onRef={ref => (this.child = ref)} />
+
+          {/*SearchBar component for productTypeName Search*/}
+          {/*<SearchBar*/}
+          {/*  productTypeNameProp={this.setProductTypeName}*/}
+          {/*  loadProducts={this.loadProducts}*/}
+          {/*/>*/}
+
+          {/*Product Type Listing Component*/}
+
+          <FormControl variant="outlined" className={classes.formControl}>
+            <InputLabel htmlFor="outlined-product-Type-simple">
+              Product Type
+            </InputLabel>
+            <Select
+              value={this.state.productTypeName}
+              onChange={this.handleProductType}
+              input={
+                <OutlinedInput
+                  labelWidth={100}
+                  name="Product Type"
+                  id="outlined-product-Type-simple"
+                />
+              }
+              style={{ width: "400px" }}
+            >
+              <MenuItem selected={false} value={"Hello"}>
+                Hello
+              </MenuItem>
+              {listProductTypes}
+            </Select>
+            <Button
+              variant="contained"
+              color="primary"
+              className={classes.button}
+              onClick={this.searchProducts}
+            >
+              Search Products
+            </Button>
+          </FormControl>
+
+          {/*Load Folder Products*/}
+          <h4>Folders</h4>
+
+          {this.state.productFoldersArray.length === 0 &&
+            this.state.isSearchButtonClicked === true &&
+            this.state.isTimedOut === false && (
+              <div align={"center"}>
+                <CircularProgress />
+              </div>
+            )}
+
+          {this.state.productFoldersArray.length === 0 &&
+            this.state.isSearchButtonClicked === true &&
+            this.state.isTimedOut === true && (
+              <div align={"center"}>
+                <Typography variant={"h5"}>No Product Files Found 
!</Typography>
+              </div>
+            )}
+
+          {this.state.productFoldersArray.length > 0 && (
+            <Grid container spacing={3}>
+              {listFolderItems}
+            </Grid>
+          )}
+
+          {/*Load File Products*/}
+          <h4>Files</h4>
+
+          {this.state.productFilesArray.length === 0 &&
+            this.state.isSearchButtonClicked === true &&
+            this.state.isTimedOut === false && (
+              <div align={"center"}>
+                <CircularProgress />
+              </div>
+            )}
+
+          {this.state.productFilesArray.length === 0 &&
+            this.state.isSearchButtonClicked === true &&
+            this.state.isTimedOut === true && (
+              <div align={"center"}>
+                <Typography variant={"h5"}>No Product Files Found 
!</Typography>
+              </div>
+            )}
+
+          {this.state.productFilesArray.length > 0 && (
+            <Grid container spacing={3}>
+              {listFileItems}
+            </Grid>
+          )}
+
+          <Grid item xs={12} md={6}>
+            <Grid container spacing={1} direction="column" alignItems="center">
+              <Grid item>
+                <Button onClick={this.loadPrevProducts}>{"<<"}</Button>
+                <Button>{this.state.currentProductPage}</Button>
+                <Button onClick={this.loadNextProducts}>{">>"}</Button>
+              </Grid>
+            </Grid>
+          </Grid>
+        </Paper>
+      </div>
+    );
+  }
+
+  // Load productType = GenericFile on component Mounting
+  componentDidMount() {
+    this.loadProducts();
+  }
+}
+
+Product.propTypes = {
+  classes: PropTypes.object.isRequired
+};
+
+export default withStyles(styles)(Product);
diff --git 
a/react-components/oodt_fm_plugin/src/components/ProductList/SearchBar.js 
b/react-components/oodt_fm_plugin/src/components/ProductList/SearchBar.js
new file mode 100644
index 0000000..2cd6180
--- /dev/null
+++ b/react-components/oodt_fm_plugin/src/components/ProductList/SearchBar.js
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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, { Component } from "react";
+import Paper from "@material-ui/core/Paper";
+import InputBase from "@material-ui/core/InputBase";
+import IconButton from "@material-ui/core/IconButton";
+import SearchIcon from "@material-ui/icons/Search";
+import { withStyles } from "@material-ui/core";
+import PropTypes from "prop-types";
+
+const styles = theme => ({
+  root: {
+    padding: "2px 4px",
+    display: "flex",
+    alignItems: "center",
+    width: 400
+  },
+  input: {
+    marginLeft: 8,
+    flex: 1
+  },
+  iconButton: {
+    padding: 10
+  },
+  divider: {
+    width: 1,
+    height: 28,
+    margin: 4
+  }
+});
+
+class SearchBar extends Component {
+  constructor(props) {
+    super(props);
+    this.handleChange = this.handleChange.bind(this);
+    this.keyPress = this.keyPress.bind(this);
+    this.click = this.click.bind(this);
+  }
+
+  state = {
+    productTypeName: ""
+  };
+
+  handleChange(e) {
+    this.setState({ productTypeName: e.target.value });
+  }
+
+  keyPress(e) {
+    if (e.keyCode === 13) {
+      console.log(e.target.value);
+      this.props.productTypeNameProp(this.state.productTypeName);
+      this.click();
+    }
+  }
+
+  click() {
+    this.props.loadProducts();
+  }
+
+  render() {
+    const { classes } = this.props;
+    return (
+      <Paper className={classes.root}>
+        <InputBase
+          className={classes.input}
+          placeholder="Search Products by Product Type Name"
+          inputProps={{ "aria-label": "Search Products" }}
+          onKeyDown={this.keyPress}
+          onChange={this.handleChange}
+        />
+        <IconButton className={classes.iconButton} aria-label="Search">
+          <SearchIcon />
+        </IconButton>
+      </Paper>
+    );
+  }
+}
+
+SearchBar.propTypes = {
+  classes: PropTypes.object.isRequired
+};
+
+export default withStyles(styles)(SearchBar);
diff --git 
a/react-components/oodt_fm_plugin/src/components/ProductList/SimpleSnackBar.js 
b/react-components/oodt_fm_plugin/src/components/ProductList/SimpleSnackBar.js
new file mode 100644
index 0000000..6db9d8c
--- /dev/null
+++ 
b/react-components/oodt_fm_plugin/src/components/ProductList/SimpleSnackBar.js
@@ -0,0 +1,82 @@
+import React from "react";
+import Snackbar from "@material-ui/core/Snackbar";
+import IconButton from "@material-ui/core/IconButton";
+import CloseIcon from "@material-ui/icons/Close";
+import PropTypes from "prop-types";
+import { withStyles } from "@material-ui/core";
+
+const styles = theme => ({
+  close: {
+    padding: 20
+  }
+});
+
+class SimpleSnackBar extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      open: false,
+      messa: ""
+    };
+    this.handleClick = this.handleClick.bind(this);
+    this.handleClose = this.handleClose.bind(this);
+  }
+
+  handleClick(message) {
+    this.setState({ open: true });
+    this.setState({ messa: message });
+  }
+
+  handleClose(event, reason) {
+    if (reason === "clickaway") {
+      return;
+    }
+
+    this.setState({ open: false });
+  }
+
+  componentDidMount() {
+    this.props.onRef(this);
+  }
+  componentWillUnmount() {
+    this.props.onRef(null);
+  }
+
+  render() {
+    const { classes } = this.props;
+    return (
+      <div>
+        <Snackbar
+          anchorOrigin={{
+            vertical: "bottom",
+            horizontal: "left"
+          }}
+          open={this.state.open}
+          autoHideDuration={6000}
+          onClose={this.handleClose}
+          ContentProps={{
+            "aria-describedby": "message-id"
+          }}
+          message={<span id="message-id">{this.state.messa}</span>}
+          action={[
+            <IconButton
+              key="close"
+              aria-label="Close"
+              color="inherit"
+              className={classes.close}
+              onClick={this.handleClose}
+            >
+              <CloseIcon />
+            </IconButton>
+          ]}
+        />
+      </div>
+    );
+  }
+}
+
+SimpleSnackBar.propTypes = {
+  classes: PropTypes.object.isRequired
+};
+
+export default withStyles(styles)(SimpleSnackBar);
diff --git a/react-components/oodt_fm_plugin/src/components/Product/index.js 
b/react-components/oodt_fm_plugin/src/components/ProductList/index.js
similarity index 92%
copy from react-components/oodt_fm_plugin/src/components/Product/index.js
copy to react-components/oodt_fm_plugin/src/components/ProductList/index.js
index 2e2501e..325f50c 100644
--- a/react-components/oodt_fm_plugin/src/components/Product/index.js
+++ b/react-components/oodt_fm_plugin/src/components/ProductList/index.js
@@ -16,6 +16,6 @@
  */
 
 // Import the Product component from this folder and send it down to 
./components/index.js
-import Product from './Product';
+import ProductList from "./ProductList";
 
-export default Product;
+export default ProductList;
diff --git a/react-components/oodt_fm_plugin/src/components/index.js 
b/react-components/oodt_fm_plugin/src/components/index.js
index b4c8c0c..a235535 100644
--- a/react-components/oodt_fm_plugin/src/components/index.js
+++ b/react-components/oodt_fm_plugin/src/components/index.js
@@ -15,4 +15,9 @@
  * limitations under the License.
  */
 
-export { default as Product } from './Product';
+export { default as Product } from "./Product";
+export { default as ProductList } from "./ProductList";
+export { default as ProductIngest } from "./ProductIngest";
+export {
+  default as ProductIngestWithMetaFile
+} from "./ProductIngestWithMetaFile";
diff --git a/react-components/oodt_fm_plugin/src/constants/fmconnection.js 
b/react-components/oodt_fm_plugin/src/constants/fmconnection.js
index e3597d9..5f8a479 100644
--- a/react-components/oodt_fm_plugin/src/constants/fmconnection.js
+++ b/react-components/oodt_fm_plugin/src/constants/fmconnection.js
@@ -18,5 +18,5 @@
 import axios from "axios";
 
 export const fmconnection = axios.create({
-    baseURL: 'http://46.4.26.22:8012/fmprod/jaxrs',
+  baseURL: "http://"+window.location.hostname+":8080/cas_product_war/jaxrs/v2";
 });
diff --git a/react-components/oodt_fm_plugin/src/index.js 
b/react-components/oodt_fm_plugin/src/index.js
index 3dc3ab3..a4cef6b 100644
--- a/react-components/oodt_fm_plugin/src/index.js
+++ b/react-components/oodt_fm_plugin/src/index.js
@@ -17,4 +17,4 @@
 
 // Export all the explicitly exported components, this file will contain our
 // components when built by webpack and sent off to the world.
-export * from './components';
\ No newline at end of file
+export * from "./components";
diff --git a/react-components/oodt_opsui_sample_app/README.md 
b/react-components/oodt_opsui_sample_app/README.md
new file mode 100644
index 0000000..7aa963c
--- /dev/null
+++ b/react-components/oodt_opsui_sample_app/README.md
@@ -0,0 +1,36 @@
+This project was bootstrapped with [Create React 
App](https://github.com/facebook/create-react-app).
+
+## Available Scripts
+
+In the project directory, you can run:
+
+### `npm start`
+
+Runs the app in the development mode.<br>
+Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
+
+The page will reload if you make edits.<br>
+You will also see any lint errors in the console.
+
+### `npm test`
+
+Launches the test runner in the interactive watch mode.<br>
+See the section about [running 
tests](https://facebook.github.io/create-react-app/docs/running-tests) for more 
information.
+
+### `npm run build`
+
+Builds the app for production to the `build` folder.<br>
+It correctly bundles React in production mode and optimizes the build for the 
best performance.
+
+The build is minified and the filenames include the hashes.<br>
+Your app is ready to be deployed!
+
+See the section about 
[deployment](https://facebook.github.io/create-react-app/docs/deployment) for 
more information.
+
+### Deployment
+
+This section has moved here: 
https://facebook.github.io/create-react-app/docs/deployment
+
+### `npm run build` fails to minify
+
+This section has moved here: 
https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify
diff --git a/react-components/oodt_opsui_sample_app/package.json 
b/react-components/oodt_opsui_sample_app/package.json
new file mode 100644
index 0000000..669e93b
--- /dev/null
+++ b/react-components/oodt_opsui_sample_app/package.json
@@ -0,0 +1,36 @@
+{
+  "name": "oodt_opsui_sample_app",
+  "version": "0.1.0",
+  "private": true,
+  "dependencies": {
+    "react": "^16.8.6",
+    "react-dom": "^16.8.6",
+    "react-scripts": "3.0.1",
+    "@material-ui/core": "latest",
+    "@material-ui/icons": "^4.2.0",
+    "axios": "^0.19.0",
+    "clsx": "^1.0.4",
+    "react-router-dom": "^5.0.1"
+  },
+  "scripts": {
+    "start": "react-scripts start",
+    "build": "react-scripts build",
+    "test": "react-scripts test",
+    "eject": "react-scripts eject"
+  },
+  "eslintConfig": {
+    "extends": "react-app"
+  },
+  "browserslist": {
+    "production": [
+      ">0.2%",
+      "not dead",
+      "not op_mini all"
+    ],
+    "development": [
+      "last 1 chrome version",
+      "last 1 firefox version",
+      "last 1 safari version"
+    ]
+  }
+}
diff --git a/react-components/oodt_opsui_sample_app/public/favicon.ico 
b/react-components/oodt_opsui_sample_app/public/favicon.ico
new file mode 100644
index 0000000..a11777c
Binary files /dev/null and 
b/react-components/oodt_opsui_sample_app/public/favicon.ico differ
diff --git a/react-components/oodt_opsui_sample_app/public/images/oodt_logo.png 
b/react-components/oodt_opsui_sample_app/public/images/oodt_logo.png
new file mode 100644
index 0000000..dda5ca2
Binary files /dev/null and 
b/react-components/oodt_opsui_sample_app/public/images/oodt_logo.png differ
diff --git a/react-components/oodt_opsui_sample_app/public/index.html 
b/react-components/oodt_opsui_sample_app/public/index.html
new file mode 100644
index 0000000..08d1712
--- /dev/null
+++ b/react-components/oodt_opsui_sample_app/public/index.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8" />
+<!--    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />-->
+    <meta name="viewport" content="width=device-width, initial-scale=1" />
+<!--    <meta name="theme-color" content="#000000" />-->
+    <!--
+      manifest.json provides metadata used when your web app is installed on a
+      user's mobile device or desktop. See 
https://developers.google.com/web/fundamentals/web-app-manifest/
+    -->
+<!--    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />-->
+    <!--
+      Notice the use of %PUBLIC_URL% in the tags above.
+      It will be replaced with the URL of the `public` folder during the build.
+      Only files inside the `public` folder can be referenced from the HTML.
+
+      Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
+      work correctly both with client-side routing and a non-root public URL.
+      Learn how to configure a non-root public URL by running `npm run build`.
+    -->
+    <title>OODT-OPSUI</title>
+  </head>
+  <body>
+    <noscript>You need to enable JavaScript to run this app.</noscript>
+    <div id="root"></div>
+    <!--
+      This HTML file is a template.
+      If you open it directly in the browser, you will see an empty page.
+
+      You can add webfonts, meta tags, or analytics to this file.
+      The build step will place the bundled scripts into the <body> tag.
+
+      To begin the development, run `npm start` or `yarn start`.
+      To create a production bundle, use `npm run build` or `yarn build`.
+    -->
+  </body>
+</html>
diff --git a/react-components/oodt_opsui_sample_app/public/manifest.json 
b/react-components/oodt_opsui_sample_app/public/manifest.json
new file mode 100644
index 0000000..1f2f141
--- /dev/null
+++ b/react-components/oodt_opsui_sample_app/public/manifest.json
@@ -0,0 +1,15 @@
+{
+  "short_name": "React App",
+  "name": "Create React App Sample",
+  "icons": [
+    {
+      "src": "favicon.ico",
+      "sizes": "64x64 32x32 24x24 16x16",
+      "type": "image/x-icon"
+    }
+  ],
+  "start_url": ".",
+  "display": "standalone",
+  "theme_color": "#000000",
+  "background_color": "#ffffff"
+}
diff --git a/react-components/oodt_opsui_sample_app/src/App.js 
b/react-components/oodt_opsui_sample_app/src/App.js
new file mode 100644
index 0000000..282d097
--- /dev/null
+++ b/react-components/oodt_opsui_sample_app/src/App.js
@@ -0,0 +1,141 @@
+import React, { Component } from "react";
+import { BrowserRouter, Switch, Route } from "react-router-dom";
+import {
+  ProductList,
+  Product,
+  ProductIngest,
+  ProductIngestWithMetaFile
+} from "oodt_fm_plugin_sample";
+import OPSUIHome from "./components/OPSUIHome";
+import SearchBar from "./components/SearchBar";
+// import { WorkflowList } from "oodt_wm_plugin_sample";
+import Paper from "@material-ui/core/Paper";
+import Typography from "@material-ui/core/Typography";
+import Switch1 from "@material-ui/core/Switch";
+import axios from "axios";
+
+class MyApp extends Component {
+  constructor(props) {
+    super(props);
+    this.setSelectedProductId = this.setSelectedProductId.bind(this);
+    this.handleChange = this.handleChange.bind(this);
+    // this.timeOut = this.timeOut.bind(this);
+  }
+
+  state = {
+    selectedProductId: "",
+    checkedA: false
+  };
+
+  setSelectedProductId(productId) {
+    this.setState({ selectedProductId: productId });
+    console.log(this.state.selectedProductId);
+  }
+
+  componentDidMount() {
+    this.handleChange();
+    // this.timeOut()
+  }
+
+  handleChange(){
+    axios
+      .get("http://"+ window.location.hostname 
+":8080/cas_product_war/jaxrs/v2/fmprodstatus")
+      .then(result => {
+        console.log(result.data.FMStatus.serverUp);
+        if (result.data.FMStatus.serverUp) {
+          this.setState({ checkedA: true });
+        }
+      })
+      .catch(error => {});
+  };
+
+  // timeOut() {
+  //   setInterval(function () {
+  //     axios
+  //     .get("http://localhost:8080/cas_product_war/jaxrs/v2/fmprodstatus";)
+  //     .then(result => {
+  //       console.log(result.data.FMStatus.serverUp);
+  //       if (result.data.FMStatus.serverUp) {
+  //         this.setState({ checkedA: true });
+  //       }
+  //     })
+  //     .catch(error => {});
+  //
+  //   }, 10000);
+  // }
+  render() {
+    return (
+      <BrowserRouter>
+        <OPSUIHome>
+          <Switch>
+            <Route
+              exact
+              path={"/"}
+              render={() => (
+                <div>
+                  <h1>Dashboard</h1>
+                  <Paper
+                    style={{
+                      flexGrow: 1,
+                      backgroundColor: "white",
+                      padding: 20
+                    }}
+                  >
+                    <Typography variant="h5" component="h3">
+                      File Manager Status
+                      <Switch1
+                        disabled={true}
+                        checked={this.state.checkedA}
+                        onChange={this.handleChange}
+                      />
+                    </Typography>
+                  </Paper>
+                </div>
+              )}
+            />
+
+            <Route
+              path={"/products"}
+              render={() => (
+                <ProductList selectedProductId={this.setSelectedProductId} />
+              )}
+            />
+
+            <Route
+              path={"/productIngest"}
+              render={() => (
+                <div>
+                  <ProductIngest />
+                  <br />
+                  <ProductIngestWithMetaFile />
+                </div>
+              )}
+            />
+
+            <Route
+              path={"/product"}
+              render={() => (
+                <div>
+                  <SearchBar setSelectedProductId={this.setSelectedProductId} 
/>
+                  <br />
+                  <Product productId={this.state.selectedProductId} />
+                </div>
+              )}
+            />
+
+            <Route
+              path={"/workflows"}
+              render={() => (
+                <div>
+                  {/*<WorkflowList />*/}
+                </div>
+              )}
+            />
+          </Switch>
+        </OPSUIHome>
+      </BrowserRouter>
+    );
+  }
+}
+
+export default MyApp;
diff --git a/react-components/oodt_opsui_sample_app/src/App.test.js 
b/react-components/oodt_opsui_sample_app/src/App.test.js
new file mode 100644
index 0000000..a754b20
--- /dev/null
+++ b/react-components/oodt_opsui_sample_app/src/App.test.js
@@ -0,0 +1,9 @@
+import React from 'react';
+import ReactDOM from 'react-dom';
+import App from './App';
+
+it('renders without crashing', () => {
+  const div = document.createElement('div');
+  ReactDOM.render(<App />, div);
+  ReactDOM.unmountComponentAtNode(div);
+});
diff --git a/react-components/oodt_opsui_sample_app/src/components/OPSUIHome.js 
b/react-components/oodt_opsui_sample_app/src/components/OPSUIHome.js
new file mode 100644
index 0000000..1eee37b
--- /dev/null
+++ b/react-components/oodt_opsui_sample_app/src/components/OPSUIHome.js
@@ -0,0 +1,244 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 clsx from 'clsx';
+import {withStyles} from '@material-ui/core/styles';
+import CssBaseline from '@material-ui/core/CssBaseline';
+import Drawer from '@material-ui/core/Drawer';
+import AppBar from '@material-ui/core/AppBar';
+import Toolbar from '@material-ui/core/Toolbar';
+import List from '@material-ui/core/List';
+import Typography from '@material-ui/core/Typography';
+import Divider from '@material-ui/core/Divider';
+import IconButton from '@material-ui/core/IconButton';
+import Container from '@material-ui/core/Container';
+import MenuIcon from '@material-ui/icons/Menu';
+import {fmMenuListItems,wmMenuListItems} from './listItems';
+import ChevronLeftIcon from '@material-ui/icons/ChevronLeft';
+import {Link} from "react-router-dom";
+
+import ListItem from "@material-ui/core/ListItem";
+import ListItemIcon from "@material-ui/core/ListItemIcon";
+import DashboardIcon from "@material-ui/icons/Dashboard";
+import ListItemText from "@material-ui/core/ListItemText";
+import PropTypes from "prop-types";
+
+
+const drawerWidth = 240;
+
+const styles = (theme => ({
+    root: {
+        display: 'flex',
+    },
+    toolbar: {
+        paddingRight: 24, // keep right padding when drawer closed
+    },
+    toolbarIcon: {
+        display: 'flex',
+        alignItems: 'center',
+        justifyContent: 'flex-end',
+        padding: '0 8px',
+        ...theme.mixins.toolbar,
+    },
+    appBar: {
+        zIndex: theme.zIndex.drawer + 1,
+        transition: theme.transitions.create(['width', 'margin'], {
+            easing: theme.transitions.easing.sharp,
+            duration: theme.transitions.duration.leavingScreen,
+        }),
+    },
+    appBarShift: {
+        marginLeft: drawerWidth,
+        width: `calc(100% - ${drawerWidth}px)`,
+        transition: theme.transitions.create(['width', 'margin'], {
+            easing: theme.transitions.easing.sharp,
+            duration: theme.transitions.duration.enteringScreen,
+        }),
+    },
+    menuButton: {
+        marginRight: 36,
+    },
+    menuButtonHidden: {
+        display: 'none',
+    },
+    title: {
+        flexGrow: 1,
+    },
+    drawerPaper: {
+        position: 'relative',
+        whiteSpace: 'nowrap',
+        width: drawerWidth,
+        transition: theme.transitions.create('width', {
+            easing: theme.transitions.easing.sharp,
+            duration: theme.transitions.duration.enteringScreen,
+        }),
+    },
+    drawerPaperClose: {
+        overflowX: 'hidden',
+        transition: theme.transitions.create('width', {
+            easing: theme.transitions.easing.sharp,
+            duration: theme.transitions.duration.leavingScreen,
+        }),
+        width: theme.spacing(7),
+        [theme.breakpoints.up('sm')]: {
+            width: theme.spacing(9),
+        },
+    },
+    appBarSpacer: theme.mixins.toolbar,
+    content: {
+        flexGrow: 1,
+        height: '100vh',
+        overflow: 'auto',
+    },
+    container: {
+        paddingTop: theme.spacing(4),
+        paddingBottom: theme.spacing(4),
+    },
+    paper: {
+        padding: theme.spacing(2),
+        display: 'flex',
+        overflow: 'auto',
+        flexDirection: 'column',
+    },
+    fixedHeight: {
+        height: 'auto',
+    },
+    logo: {
+        color: 'blue',
+        textAlign: 'center'
+    },
+    button: {
+        color: 'yellow',
+    },
+}));
+
+
+class OPSUIHome extends React.Component {
+
+    constructor(props) {
+        super(props);
+        this.state = {
+            open: true,
+            selectedProductId: '',
+        };
+        this.setSelectedProductId=this.setSelectedProductId.bind(this);
+    }
+
+    handleDrawerOpen = () => {
+        this.setState({open: true});
+    };
+
+    handleDrawerClose = () => {
+        this.setState({open: false});
+    };
+
+
+    testFunction = () => {
+        console.log("Hello");
+    };
+
+
+    setSelectedProductId(productId) {
+        this.setState({selectedProductId: productId});
+    };
+
+
+    render() {
+        const {classes} = this.props;
+
+        return (
+            <div className={classes.root}>
+                <CssBaseline/>
+                <AppBar position="absolute" className={clsx(classes.appBar, 
this.state.open && classes.appBarShift)}>
+                    <Toolbar className={classes.toolbar}>
+                        <IconButton
+                            edge="start"
+                            color="inherit"
+                            aria-label="Open drawer"
+                            onClick={this.handleDrawerOpen}
+                            className={clsx(classes.menuButton, 
this.state.open && classes.menuButtonHidden)}
+                        >
+                            <MenuIcon/>
+                        </IconButton>
+                        <Typography component="h1" variant="h6" 
color="inherit" noWrap className={classes.title}>
+                            Apache OODT - OPSUI
+                        </Typography>
+
+                    </Toolbar>
+                </AppBar>
+                <Drawer variant="permanent" className={classes.logo}
+                        classes={{paper: clsx(classes.drawerPaper, 
!this.state.open && classes.drawerPaperClose),}}
+                        open={this.state.open}>
+                    <div>
+                        <IconButton onClick={this.handleDrawerClose}>
+                            <div>
+                                <img src="/images/oodt_logo.png" alt="Apache 
OODT Logo" width="110px"/>
+                            </div>
+                            <ChevronLeftIcon/>
+                        </IconButton>
+
+                    </div>
+
+                    {/*Main Menu List*/}
+                    {/*<List>{mainListItems}</List>*/}
+                    <List>
+                        <div>
+
+
+                            {/*Status of OPSUI*/}
+                            <ListItem button component={Link} to={"/"} >
+                                {/*onClick={this.testFunction.bind(this)}*/}
+                                <ListItemIcon>
+                                    <DashboardIcon/>
+                                </ListItemIcon>
+                                <ListItemText primary="Dashboard"/>
+                            </ListItem>
+                        </div>
+                    </List>
+
+                    <Divider/>
+
+
+                    {/*FileManager Menu List*/}
+                    <List>{fmMenuListItems}</List>
+                    <Divider/>
+
+                    {/*Workflow Manager Menu List*/}
+                    <List>{wmMenuListItems}</List>
+
+                </Drawer>
+                <main className={classes.content}>
+                    <div className={classes.appBarSpacer}/>
+                    <Container maxWidth="lg" className={classes.container}>
+                        {this.props.children}
+
+                    </Container>
+
+                </main>
+
+            </div>
+        );
+    }
+}
+
+
+OPSUIHome.propTypes = {
+    classes: PropTypes.object.isRequired,
+};
+
+export default withStyles(styles)(OPSUIHome);
\ No newline at end of file
diff --git a/react-components/oodt_opsui_sample_app/src/components/SearchBar.js 
b/react-components/oodt_opsui_sample_app/src/components/SearchBar.js
new file mode 100644
index 0000000..4a417b3
--- /dev/null
+++ b/react-components/oodt_opsui_sample_app/src/components/SearchBar.js
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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, {Component} from 'react';
+import Paper from '@material-ui/core/Paper';
+import InputBase from '@material-ui/core/InputBase';
+import IconButton from '@material-ui/core/IconButton';
+import SearchIcon from '@material-ui/icons/Search';
+import {withStyles} from "@material-ui/core";
+import {PropTypes} from "prop-types";
+
+
+const styles = theme => ({
+    root: {
+        padding: '2px 4px',
+        display: 'flex',
+        alignItems: 'center',
+        width: 400,
+    },
+    input: {
+        marginLeft: 8,
+        flex: 1,
+    },
+    iconButton: {
+        padding: 10,
+    },
+    divider: {
+        width: 1,
+        height: 28,
+        margin: 4,
+    },
+});
+
+class SearchBar extends Component {
+
+    constructor(props) {
+        super(props);
+        this.handleChange = this.handleChange.bind(this);
+        this.keyPress = this.keyPress.bind(this);
+        // this.click = this.click.bind(this);
+    }
+
+    state = {
+        selectedProductId: '',
+    };
+
+    handleChange(e) {
+        this.setState({ selectedProductId: e.target.value });
+    }
+
+    keyPress(e){
+        if(e.keyCode === 13){
+            console.log(e.target.value);
+            this.props.setSelectedProductId(this.state.selectedProductId);
+            // this.click();
+        }
+    }
+
+    // click() {
+    //     this.props.loadProducts();
+    // }
+
+    render(){
+        const { classes } = this.props;
+        return (
+            <Paper className={classes.root}>
+                <InputBase
+                    className={classes.input}
+                    placeholder="Search Products by Product Id"
+                    inputProps={{ 'aria-label': 'Search Products' }}
+                    onKeyDown={this.keyPress} onChange={this.handleChange}
+                />
+                <IconButton className={classes.iconButton} aria-label="Search" 
>
+                    <SearchIcon />
+                </IconButton>
+            </Paper>
+        );
+    }
+
+
+}
+
+
+SearchBar.propTypes = {
+    classes: PropTypes.object.isRequired,
+};
+
+export default withStyles(styles)(SearchBar);
diff --git a/react-components/oodt_opsui_sample_app/src/components/listItems.js 
b/react-components/oodt_opsui_sample_app/src/components/listItems.js
new file mode 100644
index 0000000..1ee820b
--- /dev/null
+++ b/react-components/oodt_opsui_sample_app/src/components/listItems.js
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 ListItem from '@material-ui/core/ListItem';
+import ListItemIcon from '@material-ui/core/ListItemIcon';
+import ListItemText from '@material-ui/core/ListItemText';
+import ListSubheader from '@material-ui/core/ListSubheader';
+import DashboardIcon from '@material-ui/icons/Dashboard';
+import NoteAddIcon from '@material-ui/icons/NoteAdd';
+import StorageIcon from '@material-ui/icons/Storage';
+import FindInPage from '@material-ui/icons/FindInPage';
+import {Link} from "react-router-dom";
+
+
+
+export const mainListItems = (
+
+
+
+    <div>
+        {/*Status of OPSUI*/}
+        <ListItem button>
+            <ListItemIcon>
+                <DashboardIcon />
+            </ListItemIcon>
+            <ListItemText primary="Dashboard" />
+        </ListItem>
+    </div>
+);
+
+
+
+export const fmMenuListItems = (
+    <div>
+
+        <ListSubheader>File Manager</ListSubheader>
+
+        {/*Product Ingesting*/}
+        <ListItem button component={Link} to={"/productIngest"}>
+            <ListItemIcon>
+                <NoteAddIcon/>
+            </ListItemIcon>
+            <ListItemText primary="Product Ingest" />
+        </ListItem>
+
+        {/*Product Browser*/}
+        <ListItem button component={Link} to={"/products"}>
+            <ListItemIcon>
+                <StorageIcon />
+            </ListItemIcon>
+            <ListItemText primary="Product Browser" />
+        </ListItem>
+
+        {/*Product Search*/}
+        <ListItem button component={Link} to={"/product"}>
+            <ListItemIcon>
+                <FindInPage/>
+            </ListItemIcon>
+            <ListItemText primary="Product Search" />
+        </ListItem>
+
+    </div>
+
+);
+
+
+export const wmMenuListItems = (
+    <div>
+        <ListSubheader>WorkFlow Manager</ListSubheader>
+
+      {/*Workflow Browser*/}
+      <ListItem button component={Link} to={"/workflows"}>
+        <ListItemIcon>
+          <StorageIcon />
+        </ListItemIcon>
+        <ListItemText primary="Workflow Browser" />
+      </ListItem>
+    </div>
+);
\ No newline at end of file
diff --git a/react-components/oodt_opsui_sample_app/src/index.css 
b/react-components/oodt_opsui_sample_app/src/index.css
new file mode 100644
index 0000000..4a1df4d
--- /dev/null
+++ b/react-components/oodt_opsui_sample_app/src/index.css
@@ -0,0 +1,13 @@
+body {
+  margin: 0;
+  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", 
"Oxygen",
+    "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
+    sans-serif;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+code {
+  font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
+    monospace;
+}
diff --git a/react-components/oodt_opsui_sample_app/src/index.js 
b/react-components/oodt_opsui_sample_app/src/index.js
new file mode 100644
index 0000000..8110e69
--- /dev/null
+++ b/react-components/oodt_opsui_sample_app/src/index.js
@@ -0,0 +1,11 @@
+import React from 'react';
+import ReactDOM from 'react-dom';
+import App from './App';
+// import * as serviceWorker from './serviceWorker';
+
+ReactDOM.render(<App />, document.getElementById('root'));
+
+// If you want your app to work offline and load faster, you can change
+// unregister() to register() below. Note this comes with some pitfalls.
+// Learn more about service workers: https://bit.ly/CRA-PWA
+// serviceWorker.unregister();
diff --git 
a/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/enums/ErrorType.java
 
b/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/enums/ErrorType.java
deleted file mode 100644
index 2a2339b..0000000
--- 
a/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/enums/ErrorType.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with this
- * work for additional information regarding copyright ownership.  The ASF
- * licenses this file to you 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.
- */
-
-package org.apache.oodt.cas.product.jaxrs.enums;
-
-/**
- * This is the Enumeration file for storing HTTP Exception types. Use these 
constants instead of
- * hardcoding errors in REST API implementations
- *
- * @author ngimhana (Nadeeshan Gimhana)
- */
-public enum ErrorType {
-  BAD_REQUEST_EXCEPTION("Malformed message"),
-  BAD_REQUEST_EXCEPTION_REFERENCE_RESOURCE(
-      "This URL requires a productId query parameter with a product ID value,"
-          + " e.g. /reference?productId=1787a257-df87-11e2-8a2d-e3f6264e86c5"),
-
-  BAD_REQUEST_EXCEPTION_PRODUCT_RESOURCE(
-      "Failed to load resource: the server responded with a status of 400"),
-  BAD_REQUEST_EXCEPTION_DATASET_RESOURCE(
-      "This URL requires a productTypeId query parameter and either a "
-          + "product type ID value or 'ALL' for all product types"),
-
-  BAD_REQUEST_EXCEPTION_TRANSFER_RESOURCE(
-      "This URL requires a dataStoreRef query parameter "
-          + "and a data store reference value, e.g. 
/transfer?dataStoreRef=file:/repository/test.txt/test.txt"),
-
-  INTERNAL_SERVER_ERROR("General Server Error"),
-
-  NOT_FOUND_EXCEPTION("Couldn’t find resource"),
-  NOT_FOUND_EXCEPTION_TRANSFER_RESOURCE(
-      "Unable to find a current file transfer status for data store reference: 
"),
-
-  CAS_PRODUCT_EXCEPTION_FILEMGR_CLIENT_UNAVILABLE(
-      "Unable to get the file manager client from the servlet context."),
-  CAS_PRODUCT_EXCEPTION_FILEMGR_WORKING_DIR_UNAVILABLE(
-      "Unable to get the file manager's" + " working directory from the 
servlet context.");
-
-  private String errorType;
-
-  ErrorType(String errorType) {
-    this.errorType = errorType;
-  }
-
-  /** @return the errorType */
-  public String getErrorType() {
-    return errorType;
-  }
-
-  /** @param errorType the errorType to set */
-  public void setErrorType(String errorType) {
-    this.errorType = errorType;
-  }
-}

Reply via email to