LENS-1207 : Fix gaps in lens ui

Project: http://git-wip-us.apache.org/repos/asf/lens/repo
Commit: http://git-wip-us.apache.org/repos/asf/lens/commit/2de1b521
Tree: http://git-wip-us.apache.org/repos/asf/lens/tree/2de1b521
Diff: http://git-wip-us.apache.org/repos/asf/lens/diff/2de1b521

Branch: refs/heads/current-release-line
Commit: 2de1b5218aa4f1d21606e067c229752e9f2ffbdc
Parents: 77e7cc6
Author: Rajat Khandelwal <pro...@apache.org>
Authored: Tue Jul 19 17:23:29 2016 +0530
Committer: Amareshwari Sriramadasu <amareshw...@apache.org>
Committed: Tue Jul 19 17:23:29 2016 +0530

----------------------------------------------------------------------
 lens-ui/app/actions/LoginActions.js           |   5 +-
 lens-ui/app/adapters/AdhocQueryAdapter.js     |   9 +-
 lens-ui/app/adapters/AuthenticationAdapter.js |   3 +-
 lens-ui/app/app.js                            |   2 +-
 lens-ui/app/components/AdhocQueryComponent.js |   4 +-
 lens-ui/app/components/CubeSchemaComponent.js | 159 +++++++++++++++------
 lens-ui/app/components/CubeTreeComponent.js   |  13 +-
 lens-ui/app/components/DatabaseComponent.js   |  14 +-
 lens-ui/app/components/LoginComponent.js      |  12 +-
 lens-ui/app/components/QueryBoxComponent.js   |   2 +-
 lens-ui/app/components/TableTreeComponent.js  |  17 ++-
 lens-ui/app/stores/CubeStore.js               |   5 +-
 lens-ui/app/stores/DatabaseStore.js           |  10 --
 lens-ui/app/stores/UserStore.js               |  11 ++
 lens-ui/app/utils/ErrorParser.js              |  31 +---
 lens-ui/config.json                           |   4 +-
 lens-ui/package.json                          |   6 +-
 lens-ui/server.js                             |  14 +-
 18 files changed, 191 insertions(+), 130 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/2de1b521/lens-ui/app/actions/LoginActions.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/actions/LoginActions.js 
b/lens-ui/app/actions/LoginActions.js
index 3cb39d0..5c57087 100644
--- a/lens-ui/app/actions/LoginActions.js
+++ b/lens-ui/app/actions/LoginActions.js
@@ -22,8 +22,8 @@ import AppConstants from '../constants/AppConstants';
 import AuthenticationAdapter from '../adapters/AuthenticationAdapter';
 
 let LoginActions = {
-  authenticate (email, password) {
-    AuthenticationAdapter.authenticate(email, password)
+  authenticate (email, password, database) {
+    AuthenticationAdapter.authenticate(email, password, database)
       .then(function (response) {
 
         // authenticating user right away
@@ -31,6 +31,7 @@ let LoginActions = {
           actionType: AppConstants.AUTHENTICATION_SUCCESS,
           payload: {
             email: email,
+            database: database,
             secretToken: response
           }
         });

http://git-wip-us.apache.org/repos/asf/lens/blob/2de1b521/lens-ui/app/adapters/AdhocQueryAdapter.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/adapters/AdhocQueryAdapter.js 
b/lens-ui/app/adapters/AdhocQueryAdapter.js
index 9d4b416..a54274f 100644
--- a/lens-ui/app/adapters/AdhocQueryAdapter.js
+++ b/lens-ui/app/adapters/AdhocQueryAdapter.js
@@ -52,7 +52,12 @@ let AdhocQueryAdapter = {
 
   getCubes (secretToken) {
     let url = baseUrl + urls.getCubes;
-    return BaseAdapter.get(url + '?sessionid=' + secretToken);
+    let postURL = "?";
+    if (Config.cubes_type) {
+      postURL += "type=" + Config.cubes_type + "&"
+    }
+    postURL += "sessionid=" + secretToken;
+    return BaseAdapter.get(url + postURL);
   },
 
   getCubeDetails (secretToken, cubeName) {
@@ -212,7 +217,7 @@ let AdhocQueryAdapter = {
   },
 
   getParams (secretToken, query) {
-    let url = baseUrl + urls.parameters;
+    let url = baseUrl + urls.parameters + '?sessionid=' + secretToken;
 
     let formData = new FormData();
     formData.append('query', query);

http://git-wip-us.apache.org/repos/asf/lens/blob/2de1b521/lens-ui/app/adapters/AuthenticationAdapter.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/adapters/AuthenticationAdapter.js 
b/lens-ui/app/adapters/AuthenticationAdapter.js
index 15c196b..1effb14 100644
--- a/lens-ui/app/adapters/AuthenticationAdapter.js
+++ b/lens-ui/app/adapters/AuthenticationAdapter.js
@@ -38,12 +38,13 @@ let sessionconf = `<?xml version="1.0" encoding="UTF-8"?>
                   </conf>`;
 
 let AuthenticationAdapter = {
-  authenticate (email, password) {
+  authenticate (email, password, database) {
 
     // preparing data as API accepts multipart/form-data :(
     var formData = new FormData();
     formData.append('username', email);
     formData.append('password', password || "");
+    formData.append('database', database|| "default");
     formData.append('sessionconf', sessionconf);
 
     return BaseAdapter.post(authUrl, formData, {

http://git-wip-us.apache.org/repos/asf/lens/blob/2de1b521/lens-ui/app/app.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/app.js b/lens-ui/app/app.js
index 07d9acf..18237d2 100644
--- a/lens-ui/app/app.js
+++ b/lens-ui/app/app.js
@@ -45,7 +45,7 @@ let routes = (
       <Route name='savedqueries' handler={SavedQueries}/>
       <Route name='result' path='/results/:handle' 
handler={QueryDetailResult}/>
     </Route>
-    <Route name='schema' path='schema/:databaseName/' handler={AdhocQuery} >
+    <Route name='schema' path='schema/' handler={AdhocQuery} >
       <Route name='cubeschema' path='cube/:cubeName' handler={CubeSchema}/>
       <Route name='tableschema' path='table/:tableName'
              handler={TableSchema}/>

http://git-wip-us.apache.org/repos/asf/lens/blob/2de1b521/lens-ui/app/components/AdhocQueryComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/AdhocQueryComponent.js 
b/lens-ui/app/components/AdhocQueryComponent.js
index aae823c..ff68beb 100644
--- a/lens-ui/app/components/AdhocQueryComponent.js
+++ b/lens-ui/app/components/AdhocQueryComponent.js
@@ -28,11 +28,11 @@ class AdhocQuery extends React.Component {
   render () {
     return (
       <section className='row'>
-        <div className='col-md-4'>
+        <div className='col-md-2'>
           <Sidebar {...this.props}/>
         </div>
 
-        <div className='col-md-8'>
+        <div className='col-md-10'>
           <QueryBox {...this.props}/>
 
           <RouteHandler/>

http://git-wip-us.apache.org/repos/asf/lens/blob/2de1b521/lens-ui/app/components/CubeSchemaComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/CubeSchemaComponent.js 
b/lens-ui/app/components/CubeSchemaComponent.js
index dbb4cbc..9c23b9f 100644
--- a/lens-ui/app/components/CubeSchemaComponent.js
+++ b/lens-ui/app/components/CubeSchemaComponent.js
@@ -1,21 +1,21 @@
 /**
-* 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.
-*/
+ * 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';
 
@@ -24,11 +24,11 @@ import UserStore from '../stores/UserStore';
 import AdhocQueryActions from '../actions/AdhocQueryActions';
 import Loader from '../components/LoaderComponent';
 
-function getCubes (database) {
+function getCubes(database) {
   return CubeStore.getCubes(database);
 }
 
-function constructMeasureTable (cubeName, measures) {
+function constructMeasureTable(cubeName, measures) {
   let table = measures.map((measure) => {
     if (typeof(measure) == "string") {
       return (
@@ -40,9 +40,8 @@ function constructMeasureTable (cubeName, measures) {
       return (
         <tr key={cubeName + '|' + measure.name}>
           <td>{ measure.name }</td>
-          <td>{ measure._type }</td>
-          <td>{ measure.default_aggr }</td>
           <td>{ measure.display_string }</td>
+          <td>{ measure.description }</td>
         </tr>
       );
     }
@@ -57,11 +56,9 @@ function constructMeasureTable (cubeName, measures) {
     header = (
       <tr>
         <th>Name</th>
-        <th>Type</th>
-        <th>Default Aggr</th>
+        <th>Display String</th>
         <th>Description</th>
       </tr>
-
     );
   }
 
@@ -76,9 +73,9 @@ function constructMeasureTable (cubeName, measures) {
   );
 }
 
-function constructDimensionTable (cubeName, dimensions) {
+function constructDimensionTable(cubeName, dimensions) {
   let table = dimensions.map((dimension) => {
-    if (typeof(dimension) =="string") {
+    if (typeof(dimension) == "string") {
       return (
         <tr key={cubeName + '|' + dimension}>
           <td>{ dimension}</td>
@@ -88,12 +85,11 @@ function constructDimensionTable (cubeName, dimensions) {
       return (
         <tr key={cubeName + '|' + dimension.name}>
           <td>{ dimension.name }</td>
-          <td>{ dimension._type }</td>
-          <td>{ dimension.ref_spec && dimension.ref_spec.chain_ref_column &&
-          dimension.ref_spec.chain_ref_column.dest_table }</td>
-          <td>{ dimension.ref_spec && dimension.ref_spec.chain_ref_column &&
-          dimension.ref_spec.chain_ref_column.ref_col }</td>
+          <td>{ dimension.display_string }</td>
           <td>{ dimension.description }</td>
+          <td>{ dimension.chain_ref_column ? 
dimension.chain_ref_column.map((ref) => {
+            return ref.chain_name + "." + ref.ref_col
+          }).join("  ") : ""}</td>
         </tr>
       );
     }
@@ -104,20 +100,89 @@ function constructDimensionTable (cubeName, dimensions) {
     </tr>
   );
   if (typeof(dimensions[0]) != "string") {
-    header =  (
+    header = (
       <tr>
         <th>Name</th>
-        <th>Type</th>
-        <th>Destination Table</th>
-        <th>Column</th>
+        <th>Display String</th>
         <th>Description</th>
+        <th>Source</th>
       </tr>
     );
   }
   return (
     <div className='table-responsive'>
       <table className='table table-striped'>
-        <caption className='bg-primary text-center'>Dimensions</caption>
+        <caption className='bg-primary text-center'>Dim-Attributes</caption>
+        <thead>{header}</thead>
+        <tbody>{table}</tbody>
+      </table>
+    </div>
+  );
+}
+
+function constructJoinChainTable(cubeName, join_chains) {
+  let table = join_chains.map((join_chain) => {
+    return (
+      <tr key={cubeName + '|' + join_chain.name}>
+        <td>{ join_chain.name }</td>
+        <td>{ <pre> {
+          join_chain.paths.path.map((path) => {
+            return path.edges.edge.map((edge) => {
+              return edge.from.table + "." + edge.from.column + "=" + 
edge.to.table + "." + edge.to.column
+            }).join("->")
+          }).join("\n ")
+        }
+          </pre>
+        }</td>
+      </tr>
+    );
+  });
+  let header = (
+    <tr>
+      <th>Name</th>
+      <th>Paths</th>
+    </tr>
+  );
+  return (
+    <div className='table-responsive'>
+      <table className='table table-striped'>
+        <caption className='bg-primary text-center'>Join Chains</caption>
+        <thead>{header}</thead>
+        <tbody>{table}</tbody>
+      </table>
+    </div>
+  );
+}
+
+function constructExpressionTable(cubeName, expressions) {
+  let table = expressions.map((expression) => {
+    return (
+      <tr key={cubeName + '|' + expression.name}>
+        <td>{ expression.name }</td>
+        <td>{ expression.display_string }</td>
+        <td>{ expression.description }</td>
+        <td>{ <pre> {
+          expression.expr_spec.map((expr_spec) => {
+            return expr_spec.expr;
+          }).join("\n ")
+        }
+          </pre>
+        }</td>
+      </tr>
+    );
+  });
+  let header = (
+    <tr>
+      <th>Name</th>
+      <th>Display String</th>
+      <th>Description</th>
+      <th>Expressions</th>
+    </tr>
+  );
+  return (
+    <div className='table-responsive'>
+      <table className='table table-striped'>
+        <caption className='bg-primary text-center'>Join Chains</caption>
         <thead>{header}</thead>
         <tbody>{table}</tbody>
       </table>
@@ -127,7 +192,7 @@ function constructDimensionTable (cubeName, dimensions) {
 
 // TODO add prop checking.
 class CubeSchema extends React.Component {
-  constructor (props) {
+  constructor(props) {
     super(props);
     this.state = {cube: {}, database: props.params.databaseName};
     this._onChange = this._onChange.bind(this);
@@ -136,21 +201,21 @@ class CubeSchema extends React.Component {
       .getCubeDetails(UserStore.getUserDetails().secretToken, 
props.params.databaseName, props.params.cubeName);
   }
 
-  componentDidMount () {
+  componentDidMount() {
     CubeStore.addChangeListener(this._onChange);
   }
 
-  componentWillUnmount () {
+  componentWillUnmount() {
     CubeStore.removeChangeListener(this._onChange);
   }
 
-  componentWillReceiveProps (props) {
+  componentWillReceiveProps(props) {
     // TODO are props updated automatically, unlike state?
     let cubeName = props.params.cubeName;
     let cube = getCubes(props.params.databaseName)[cubeName];
 
     if (cube.isLoaded) {
-      this.setState({ cube: cube, database: props.params.database });
+      this.setState({cube: cube, database: props.params.database});
       return;
     }
 
@@ -158,15 +223,15 @@ class CubeSchema extends React.Component {
       .getCubeDetails(UserStore.getUserDetails().secretToken, 
props.params.databaseName, cubeName);
 
     // empty the previous state
-    this.setState({ cube: {}, database: props.params.databaseName });
+    this.setState({cube: {}, database: props.params.databaseName});
   }
 
-  render () {
+  render() {
     let schemaSection;
 
     // this will be empty if it's the first time so show a loader
     if (!this.state.cube.isLoaded) {
-      schemaSection = <Loader size='8px' margin='2px' />;
+      schemaSection = <Loader size='8px' margin='2px'/>;
     } else {
       // if we have cube state
       let cube = this.state.cube;
@@ -182,6 +247,8 @@ class CubeSchema extends React.Component {
           <div>
             { constructMeasureTable(cube.name, cube.measures) }
             { constructDimensionTable(cube.name, cube.dimensions) }
+            { cube.join_chains && constructJoinChainTable(cube.name, 
cube.join_chains) }
+            { cube.expressions && constructExpressionTable(cube.name, 
cube.expressions) }
           </div>
         );
       }
@@ -196,7 +263,7 @@ class CubeSchema extends React.Component {
           <div className='panel-heading'>
             <h3 className='panel-title'>Schema Details: &nbsp;
               <strong className='text-primary'>
-                 {this.props.params.cubeName}
+                {this.props.params.cubeName}
               </strong>
             </h3>
           </div>
@@ -209,7 +276,7 @@ class CubeSchema extends React.Component {
     );
   }
 
-  _onChange () {
+  _onChange() {
     this.setState({cube: 
getCubes(this.props.params.databaseName)[this.props.params.cubeName]});
   }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/2de1b521/lens-ui/app/components/CubeTreeComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/CubeTreeComponent.js 
b/lens-ui/app/components/CubeTreeComponent.js
index 702fa36..e106a4c 100644
--- a/lens-ui/app/components/CubeTreeComponent.js
+++ b/lens-ui/app/components/CubeTreeComponent.js
@@ -33,7 +33,7 @@ import '../styles/css/tree.css';
 
 function getCubeData () {
   return {
-    cubes: CubeStore.getCubes(DatabaseStore.currentDatabase())
+    cubes: CubeStore.getCubes(UserStore.currentDatabase())
   };
 }
 
@@ -45,12 +45,17 @@ class CubeTree extends React.Component {
     // comes with React.createClass, using constructor is the new
     // idiomatic way
     // 
https://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html
-    this.state = {database: props.database, cubes: [], loading: true, 
isCollapsed: false };
+    this.state = {cubes: CubeStore.getCubes(UserStore.currentDatabase()), 
loading: false, isCollapsed: false };
 
     // no autobinding with ES6 so doing it manually, see link below
     // 
https://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html#autobinding
     this._onChange = this._onChange.bind(this);
     this.toggle = this.toggle.bind(this);
+    if (!this.state.cubes) {
+      this.state.cubes = this.state.cubes || [];
+      this.state.loading = true;
+      AdhocQueryActions.getCubes(UserStore.getUserDetails().secretToken, 
UserStore.currentDatabase());
+    }
   }
 
   componentDidMount () {
@@ -84,7 +89,7 @@ class CubeTree extends React.Component {
 
       let dimensionLabel = <Link to='cubeschema' params={{databaseName: 
this.state.database, cubeName: cubeName}}
         query={{type: 'dimensions'}}>
-          <span className='quiet'>Dimensions</span>
+          <span className='quiet'>Dim-Attributes</span>
         </Link>;
       return (
         <TreeView key={cube.name + '|' + i} nodeLabel={label}
@@ -101,7 +106,7 @@ class CubeTree extends React.Component {
             }) : null }
           </TreeView >
 
-          <TreeView key={cube.name + '|dimensions'} nodeLabel={dimensionLabel}
+          <TreeView key={cube.name + '|dim attributes'} 
nodeLabel={dimensionLabel}
             defaultCollapsed={!cube.isLoaded}>
             { cube.dimensions ? cube.dimensions.map(dimension => {
               return (

http://git-wip-us.apache.org/repos/asf/lens/blob/2de1b521/lens-ui/app/components/DatabaseComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/DatabaseComponent.js 
b/lens-ui/app/components/DatabaseComponent.js
index 15a4e46..362a018 100644
--- a/lens-ui/app/components/DatabaseComponent.js
+++ b/lens-ui/app/components/DatabaseComponent.js
@@ -26,6 +26,7 @@ import UserStore from '../stores/UserStore';
 import Loader from '../components/LoaderComponent';
 import CubeTree from './CubeTreeComponent';
 import TableTree from './TableTreeComponent';
+import Config from 'config.json';
 
 function getDatabases () {
   return DatabaseStore.getDatabases();
@@ -38,24 +39,23 @@ class DatabaseComponent extends React.Component {
       databases: [],
       loading: true,
       isCollapsed: false,
-      selectedDatabase: props.params.databaseName,
+      selectedDatabase: UserStore.getUserDetails().database
     };
     this._onChange = this._onChange.bind(this);
     this.toggle = this.toggle.bind(this);
     this.setDatabase = this.setDatabase.bind(this);
 
     AdhocQueryActions.getDatabases(UserStore.getUserDetails().secretToken);
-    if (this.state.selectedDatabase) {
-      this.setDatabase(this.state.selectedDatabase);
-    }
   }
 
   componentDidMount () {
     DatabaseStore.addChangeListener(this._onChange);
+    UserStore.addChangeListener(this._onChange);
   }
 
   componentWillUnmount () {
     DatabaseStore.removeChangeListener(this._onChange);
+    UserStore.removeChangeListener(this._onChange);
   }
 
   render () {
@@ -92,7 +92,6 @@ class DatabaseComponent extends React.Component {
         <strong>Sorry, we couldn&#39;t find any databases.</strong>
       </div>);
     }
-
     return (<div>
         {databaseComponent}
         {
@@ -104,7 +103,7 @@ class DatabaseComponent extends React.Component {
           </div>
         }
         {
-          this.state.selectedDatabase &&
+          this.state.selectedDatabase && Config.display_tables &&
           <div>
             <hr style={{marginTop: '10px', marginBottom: '10px'}}/>
             <TableTree key={this.state.selectedDatabase}
@@ -117,7 +116,7 @@ class DatabaseComponent extends React.Component {
   }
 
   _onChange () {
-    this.setState({ databases: getDatabases(), loading: false });
+    this.setState({ databases: getDatabases(), loading: false, 
selectedDatabase:  UserStore.currentDatabase() });
   }
 
   toggle () {
@@ -132,7 +131,6 @@ class DatabaseComponent extends React.Component {
       dbName = event.target.value;
     }
     AdhocQueryActions.setDatabase(UserStore.getUserDetails().secretToken, 
dbName);
-    this.setState({databases: getDatabases(), selectedDatabase: dbName, 
loading: false});
   }
 }
 

http://git-wip-us.apache.org/repos/asf/lens/blob/2de1b521/lens-ui/app/components/LoginComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/LoginComponent.js 
b/lens-ui/app/components/LoginComponent.js
index 23b3bb9..0a81414 100644
--- a/lens-ui/app/components/LoginComponent.js
+++ b/lens-ui/app/components/LoginComponent.js
@@ -32,8 +32,8 @@ class Login extends React.Component {
     this._onChange = this._onChange.bind(this);
     this.state = {
       error: UserStore.isUserLoggedIn(),
-      password_required: Config.password_required
     };
+    this.props.db = Config.default_database || "default";
   }
 
   componentDidMount () {
@@ -48,11 +48,13 @@ class Login extends React.Component {
     event.preventDefault();
     var email = this.refs.email.getDOMNode().value;
     var pass = this.refs.pass.getDOMNode().value;
-
-    LoginActions.authenticate(email, pass);
+    var db = this.refs.db.getDOMNode().value || 
this.refs.db.getDOMNode().placeholder;
+    LoginActions.authenticate(email, pass, db);
   }
 
   render () {
+    var { router } = this.context;
+    var db = router.getCurrentQuery().db || router.getCurrentQuery().database 
|| this.props.db;
     return (
       <section className='row' style={{margin: 'auto'}}>
         <form className='form-signin' onSubmit={this.handleSubmit}>
@@ -63,7 +65,9 @@ class Login extends React.Component {
           <label htmlFor='inputPassword' className='sr-only'>Password</label>
           <input ref='pass' type='password' id='inputPassword'
             className='form-control' placeholder='Password'
-                 required={this.state.password_required} 
disabled={!this.state.password_required}/>
+                 required={Config.password_required} 
disabled={!Config.password_required}/>
+          <input ref='db' id='inputDatabase'
+                 className='form-control' placeholder={db}/>
           <button className='btn btn-primary btn-block'
             type='submit'>Sign in</button>
           {this.state.error && (

http://git-wip-us.apache.org/repos/asf/lens/blob/2de1b521/lens-ui/app/components/QueryBoxComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/QueryBoxComponent.js 
b/lens-ui/app/components/QueryBoxComponent.js
index 30eb643..49b999f 100644
--- a/lens-ui/app/components/QueryBoxComponent.js
+++ b/lens-ui/app/components/QueryBoxComponent.js
@@ -393,7 +393,7 @@ class QueryBox extends React.Component {
 
   _onChangeCubeStore () {
     // cubes
-    let cubes = CubeStore.getCubes(DatabaseStore.currentDatabase()); // hashmap
+    let cubes = CubeStore.getCubes(UserStore.currentDatabase()); // hashmap
     Object.keys(cubes).forEach((cubeName) => {
       let cube = cubes[cubeName];
       codeMirrorHints[cubeName] = [];

http://git-wip-us.apache.org/repos/asf/lens/blob/2de1b521/lens-ui/app/components/TableTreeComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/TableTreeComponent.js 
b/lens-ui/app/components/TableTreeComponent.js
index 9a8351e..fb04912 100644
--- a/lens-ui/app/components/TableTreeComponent.js
+++ b/lens-ui/app/components/TableTreeComponent.js
@@ -80,7 +80,6 @@ class TableTree extends React.Component {
       page: 0,
       loading: true,
       isCollapsed: false,
-      database: props.database
     };
     this._onChange = this._onChange.bind(this);
     this.prevPage = this.prevPage.bind(this);
@@ -88,18 +87,18 @@ class TableTree extends React.Component {
     this.toggle = this.toggle.bind(this);
     this.validateClickEvent = this.validateClickEvent.bind(this);
 
-    if (!TableStore.getTables(props.database)) {
+    if (!TableStore.getTables(UserStore.currentDatabase())) {
       AdhocQueryActions
-        .getTables(UserStore.getUserDetails().secretToken, props.database);
+        .getTables(UserStore.getUserDetails().secretToken, 
UserStore.currentDatabase());
     } else {
-      let state = getState(1, '', props.database);
+      let state = getState(1, '', UserStore.currentDatabase());
       this.state = state;
 
       // on page refresh only a single table is fetched, and hence we need to
       // fetch others too.
-      if (!TableStore.areTablesCompletelyFetched(props.database)) {
+      if (!TableStore.areTablesCompletelyFetched(UserStore.currentDatabase())) 
{
         AdhocQueryActions
-          .getTables(UserStore.getUserDetails().secretToken, props.database);
+          .getTables(UserStore.getUserDetails().secretToken, 
UserStore.currentDatabase());
       }
     }
   }
@@ -122,7 +121,7 @@ class TableTree extends React.Component {
     // construct tree
     let tableTreeInternal = this.state.tables.map(table => {
       let label = (<Link to='tableschema' params={{databaseName: 
this.state.database, tableName: table.name}}
-                         title={table.name} query={{database: 
this.props.database}}>
+                         title={table.name} query={{database: 
UserStore.currentDatabase()}}>
         {table.name}</Link>);
       return (
         <TreeView key={table.name} nodeLabel={label}
@@ -209,7 +208,7 @@ class TableTree extends React.Component {
   _onChange (page) {
     // so that page doesn't reset to beginning
     page = page || this.state.page || 1;
-    this.setState(getState(page, filterString, this.props.database));
+    this.setState(getState(page, filterString, UserStore.currentDatabase()));
   }
 
   getDetails (tableName, database) {
@@ -247,7 +246,7 @@ class TableTree extends React.Component {
   validateClickEvent (e) {
     if (e.target && e.target.nodeName === 'DIV' &&
       e.target.nextElementSibling.nodeName === 'A') {
-      this.getDetails(e.target.nextElementSibling.textContent, 
this.props.database);
+      this.getDetails(e.target.nextElementSibling.textContent, 
UserStore.currentDatabase());
     }
   }
 

http://git-wip-us.apache.org/repos/asf/lens/blob/2de1b521/lens-ui/app/stores/CubeStore.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/stores/CubeStore.js b/lens-ui/app/stores/CubeStore.js
index 4441e54..2648311 100644
--- a/lens-ui/app/stores/CubeStore.js
+++ b/lens-ui/app/stores/CubeStore.js
@@ -52,12 +52,15 @@ function receiveCubeDetails (payload) {
   cubes[payload.database][cubeDetails.name] = 
cubes[payload.database][cubeDetails.name] || { name: cubeDetails.name, 
isLoaded: false };
   cubes[payload.database][cubeDetails.name].measures = measures;
   cubes[payload.database][cubeDetails.name].dimensions = dimensions;
+  if (cubeDetails.type == 'x_base_cube') {
+    cubes[payload.database][cubeDetails.name].join_chains = 
cubeDetails.join_chains.join_chain;
+    cubes[payload.database][cubeDetails.name].expressions = 
cubeDetails.expressions.expression;
+  }
   cubes[payload.database][cubeDetails.name].isLoaded = true;
 }
 
 let CHANGE_EVENT = 'change';
 var cubes = {};
-var currentDatabase = null;
 let CubeStore = assign({}, EventEmitter.prototype, {
   getCubes (currentDatabase) {
     return cubes[currentDatabase];

http://git-wip-us.apache.org/repos/asf/lens/blob/2de1b521/lens-ui/app/stores/DatabaseStore.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/stores/DatabaseStore.js 
b/lens-ui/app/stores/DatabaseStore.js
index a18e986..4feef5e 100644
--- a/lens-ui/app/stores/DatabaseStore.js
+++ b/lens-ui/app/stores/DatabaseStore.js
@@ -23,8 +23,6 @@ import assign from 'object-assign';
 import { EventEmitter } from 'events';
 
 function receiveDatabases (payload) {
-  databases = [];
-
   databases = payload.databases.stringList &&
     payload.databases.stringList.elements &&
     payload.databases.stringList.elements.slice();
@@ -32,14 +30,10 @@ function receiveDatabases (payload) {
 
 let CHANGE_EVENT = 'change';
 var databases = [];
-var currentDatabase = null;
 let DatabaseStore = assign({}, EventEmitter.prototype, {
   getDatabases () {
     return databases;
   },
-  currentDatabase() {
-    return currentDatabase;
-  },
   emitChange () {
     this.emit(CHANGE_EVENT);
   },
@@ -59,10 +53,6 @@ AppDispatcher.register((action) => {
       receiveDatabases(action.payload);
       DatabaseStore.emitChange();
       break;
-    case AdhocQueryConstants.SELECT_DATABASE:
-      currentDatabase = action.payload.database;
-      DatabaseStore.emitChange();
-      break;
   }
 });
 

http://git-wip-us.apache.org/repos/asf/lens/blob/2de1b521/lens-ui/app/stores/UserStore.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/stores/UserStore.js b/lens-ui/app/stores/UserStore.js
index 1d7e5d4..bd53f91 100644
--- a/lens-ui/app/stores/UserStore.js
+++ b/lens-ui/app/stores/UserStore.js
@@ -19,6 +19,8 @@
 
 import AppDispatcher from '../dispatcher/AppDispatcher';
 import AppConstants from '../constants/AppConstants';
+import AdhocQueryConstants from '../constants/AdhocQueryConstants';
+
 import assign from 'object-assign';
 import { EventEmitter } from 'events';
 
@@ -35,6 +37,7 @@ function authenticateUser (details) {
   userDetails = {
     isUserLoggedIn: true,
     email: details.email,
+    database: details.database || "default",
     // creating the session string which is passed with every request
     secretToken: `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
       <lensSessionHandle>
@@ -88,6 +91,9 @@ var UserStore = assign({}, EventEmitter.prototype, {
   getUserDetails () {
     return userDetails;
   },
+  currentDatabase() {
+    return userDetails.database || "default";
+  },
 
   logout () {
     unauthenticateUser();
@@ -115,6 +121,11 @@ AppDispatcher.register((action) => {
       UserStore.emitChange();
       break;
 
+    case AdhocQueryConstants.SELECT_DATABASE:
+      userDetails.database = action.payload.database;
+      UserStore.emitChange();
+      break;
+
     case AppConstants.AUTHENTICATION_FAILED:
       unauthenticateUser(action.payload);
 

http://git-wip-us.apache.org/repos/asf/lens/blob/2de1b521/lens-ui/app/utils/ErrorParser.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/utils/ErrorParser.js b/lens-ui/app/utils/ErrorParser.js
index 8bd0d90..a7fa5b2 100644
--- a/lens-ui/app/utils/ErrorParser.js
+++ b/lens-ui/app/utils/ErrorParser.js
@@ -18,35 +18,10 @@
 */
 
 let ErrorParser = {
-  getMessage (errorXML) {
-    let errors = [];
-
-    errors = Array.prototype.slice.call(errorXML.getElementsByTagName('error'))
-      .map(error => {
-        return {
-          code: error.getElementsByTagName('code')[0].textContent,
-          message: error.getElementsByTagName('message')[0].textContent
-        };
-      })
-      .sort((a, b) => {
-        return parseInt(a.code, 10) - parseInt(b.code, 10);
-      })
-      // removes duplicate error messages
-      .filter((item, pos, array) => {
-        return !pos || (item.code != (array[pos - 1] && array[pos - 1].code));
-      })
-      // removes not so helpful `Internal Server Error`
-      .filter(error => {
-        return error.code != 1001;
-      });
-
-    if (errors && errors.length == 0) {
-      errors[0] = {};
-      errors[0].code = 500;
-      errors[0].message = 'Oh snap! Something went wrong. Please try again 
later.';
+  getMessage (error) {
+    if (error && error.lensAPIResult && error.lensAPIResult.error) {
+      return [error.lensAPIResult.error]
     }
-
-    return errors;
   }
 };
 

http://git-wip-us.apache.org/repos/asf/lens/blob/2de1b521/lens-ui/config.json
----------------------------------------------------------------------
diff --git a/lens-ui/config.json b/lens-ui/config.json
index bebc7e5..d067e08 100644
--- a/lens-ui/config.json
+++ b/lens-ui/config.json
@@ -1,5 +1,7 @@
 {
   "isPersistent": true,
   "baseURL": "/serverproxy/",
-  "password_required" : true
+  "password_required" : false,
+  "display_tables":false,
+  "cubes_type":"base"
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/2de1b521/lens-ui/package.json
----------------------------------------------------------------------
diff --git a/lens-ui/package.json b/lens-ui/package.json
index 0ed3db1..c90c91e 100644
--- a/lens-ui/package.json
+++ b/lens-ui/package.json
@@ -3,8 +3,9 @@
   "description": "An exemplary front end solution for Apache LENS.",
   "main": "app/app.js",
   "scripts": {
-    "start": "NODE_ENV=production node_modules/webpack/bin/webpack.js -p && 
lensserver='http://0.0.0.0:9999/lensapi/' port=8082 node server.js",
-    "dev": "lensserver='http://0.0.0.0:9999/lensapi/' port=8082 node server.js 
& node_modules/webpack/bin/webpack.js --watch",
+    "start": "NODE_ENV=production node_modules/webpack/bin/webpack.js -p && 
nohup node server.js &",
+    "stop": "killall -15 lens-ui-server",
+    "dev": "node server.js lens-ui-server & 
node_modules/webpack/bin/webpack.js --watch",
     "deploy": "NODE_ENV=production node_modules/webpack/bin/webpack.js -p"
   },
   "dependencies": {
@@ -30,6 +31,7 @@
     "react": "^0.13.3",
     "react-bootstrap": "0.25.1",
     "react-router": "^0.13.3",
+    "react-sidebar": "~1.1.0",
     "react-treeview": "^0.3.12",
     "react-widgets": "^2.8.0",
     "serve-favicon": "~2.2.1"

http://git-wip-us.apache.org/repos/asf/lens/blob/2de1b521/lens-ui/server.js
----------------------------------------------------------------------
diff --git a/lens-ui/server.js b/lens-ui/server.js
index c8920f3..0cff513 100644
--- a/lens-ui/server.js
+++ b/lens-ui/server.js
@@ -27,18 +27,17 @@ var app = express();
 var httpProxy = require('http-proxy');
 var proxy = httpProxy.createProxyServer();
 
-var port = process.env['port'] || 8082;
+var port = process.env.npm_config_port || 8082;
 
 app.use(logger('dev'));
 app.use(cookieParser());
-
 process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';
-process.env['lensserver'] = process.env['lensserver'] || 
'http://0.0.0.0:9999/lensapi/';
-if (!process.env['lensserver']) {
+process.env.npm_config_lensserver = process.env.npm_config_lensserver || 
'http://0.0.0.0:9999/lensapi/';
+if (!process.env.npm_config_lensserver) {
   throw new Error('Specify LENS Server address in `lensserver` argument');
 }
-
-console.log('Using this as your LENS Server Address: ', 
process.env['lensserver']);
+process.title = "lens-ui-server";
+console.log('Using this as your LENS Server Address: ', 
process.env.npm_config_lensserver);
 console.log('If this seems wrong, please edit `lensserver` argument in 
package.json. Do not forget to append http://\n');
 
 app.use(session({
@@ -62,7 +61,7 @@ app.get('/target/assets/*', function (req, res) {
 app.all('/serverproxy/*', function (req, res) {
   req.url = req.url.replace('serverproxy', '');
   proxy.web(req, res, {
-    target: process.env['lensserver']
+    target: process.env.npm_config_lensserver
   }, function (e) {
     console.error('Proxy Error: ', e);
   });
@@ -71,7 +70,6 @@ app.all('/serverproxy/*', function (req, res) {
 app.get('*', function (req, res) {
   res.end(fs.readFileSync(__dirname + '/index.html'));
 });
-
 var server = app.listen(port, function (err) {
   if (err) throw err;
 

Reply via email to