You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kylin.apache.org by zh...@apache.org on 2016/12/09 03:49:51 UTC

kylin git commit: KYLIN 1875 update model designer

Repository: kylin
Updated Branches:
  refs/heads/KYLIN-1875 3e12fbb74 -> 2d2745067


KYLIN 1875 update model designer

Signed-off-by: zhongjian <ji...@163.com>


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

Branch: refs/heads/KYLIN-1875
Commit: 2d27450676aeb09736aa351f0a3bae76c71b63df
Parents: 3e12fbb
Author: chenzhx <34...@qq.com>
Authored: Fri Dec 9 11:44:35 2016 +0800
Committer: zhongjian <ji...@163.com>
Committed: Fri Dec 9 11:49:27 2016 +0800

----------------------------------------------------------------------
 webapp/app/index.html                           |   3 +
 webapp/app/js/controllers/cubeModel.js          | 191 +-------------
 .../js/controllers/modelConditionsSettings.js   |  84 ++++++
 webapp/app/js/controllers/modelDataModel.js     | 254 +++++++++++++++++++
 webapp/app/js/controllers/modelDimensions.js    |   6 +-
 webapp/app/js/controllers/modelEdit.js          | 100 +++-----
 webapp/app/js/controllers/modelMeasures.js      |  29 ++-
 webapp/app/js/services/tree.js                  |  48 +++-
 webapp/app/js/utils/utils.js                    |  24 +-
 .../modelDesigner/conditions_settings.html      |  57 ++---
 .../app/partials/modelDesigner/data_model.html  |  89 ++++---
 .../modelDesigner/model_dimensions.html         |   4 +-
 .../partials/modelDesigner/model_measures.html  |  59 +++--
 13 files changed, 585 insertions(+), 363 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/kylin/blob/2d274506/webapp/app/index.html
----------------------------------------------------------------------
diff --git a/webapp/app/index.html b/webapp/app/index.html
index ad881d5..13b54c8 100644
--- a/webapp/app/index.html
+++ b/webapp/app/index.html
@@ -187,6 +187,9 @@
 <!--New GUI-->
 <script src="js/controllers/modelSchema.js"></script>
 <script src="js/controllers/modelDimensions.js"></script>
+<script src="js/controllers/modelDataModel.js"></script>
+<script src="js/controllers/modelMeasures.js"></script>
+<script src="js/controllers/modelConditionsSettings.js"></script>
 <script src="js/controllers/modelRefresh.js"></script>
 <script src="js/controllers/modelEdit.js"></script>
 

http://git-wip-us.apache.org/repos/asf/kylin/blob/2d274506/webapp/app/js/controllers/cubeModel.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/controllers/cubeModel.js b/webapp/app/js/controllers/cubeModel.js
index b20a829..2c7de2c 100644
--- a/webapp/app/js/controllers/cubeModel.js
+++ b/webapp/app/js/controllers/cubeModel.js
@@ -18,8 +18,7 @@
 
 'use strict';
 
-KylinApp.controller('CubeModelCtrl', function ($location,$scope, $modal,cubeConfig,MetaModel,SweetAlert,ModelGraphService,$log,TableModel,ModelService,loadingRequest,modelsManager) {
-
+KylinApp.controller('CubeModelCtrl', function ($location,$scope, $modal,cubeConfig,MetaModel,SweetAlert,ModelGraphService,$log,TableModel,ModelService,loadingRequest,modelsManager,VdmUtil) {
     $scope.modelsManager = modelsManager;
 
     $scope.buildGraph = function (model) {
@@ -45,193 +44,5 @@ KylinApp.controller('CubeModelCtrl', function ($location,$scope, $modal,cubeConf
     };
 
     $scope.cubeConfig = cubeConfig;
-    var DataModel = function () {
-        return {
-            name: '',
-            fact_table: '',
-            lookups: []
-        };
-    };
-
-    var Lookup = function () {
-        return {
-            table: '',
-            join: {
-                type: '',
-                primary_key: [],
-                foreign_key: [],
-                isCompatible:[],
-                pk_type:[],
-                fk_type:[]
-            }
-        };
-    };
-
-    // Initialize params.
-    $scope.lookupState = {
-        editing: false,
-        editingIndex: -1,
-        filter: ''
-    };
-
-    $scope.newLookup = Lookup();
-
-    var lookupList = modelsManager.selectedModel.lookups;
-
-    $scope.openLookupModal = function () {
-        var modalInstance = $modal.open({
-            templateUrl: 'dataModelLookupTable.html',
-            controller: cubeModelLookupModalCtrl,
-            backdrop: 'static',
-            scope: $scope
-        });
-        modalInstance.result.then(function () {
-            if (!$scope.lookupState.editing) {
-                $scope.doneAddLookup();
-            } else {
-                $scope.doneEditLookup();
-            }
-
-        }, function () {
-            $scope.cancelLookup();
-        });
-    };
-
-    // Controller for cube model lookup modal.
-    var cubeModelLookupModalCtrl = function ($scope, $modalInstance) {
-        $scope.ok = function () {
-            $modalInstance.close();
-        };
-
-        $scope.cancel = function () {
-            $modalInstance.dismiss('cancel');
-        };
-    };
-
-    $scope.editLookup = function (lookup) {
-        $scope.lookupState.editingIndex = lookupList.indexOf(lookup);
-        $scope.lookupState.editing = true;
-
-        // Make a copy of model will be editing.
-        $scope.newLookup = angular.copy(lookup);
-
-        $scope.openLookupModal();
-    };
-
-    $scope.doneAddLookup = function () {
-        // Push newLookup which bound user input data.
-        lookupList.push(angular.copy($scope.newLookup));
-
-        $scope.resetParams();
-    };
-
-    $scope.doneEditLookup = function () {
-        // Copy edited model to destination model.
-        angular.copy($scope.newLookup, lookupList[$scope.lookupState.editingIndex]);
-
-        $scope.resetParams();
-    };
-
-    $scope.cancelLookup = function () {
-        $scope.resetParams();
-    };
-
-        $scope.removeLookup = function (lookup) {
-            var dimExist = _.some(modelsManager.selectedModel.dimensions,function(item,index){
-                return item.table===lookup.table;
-            });
-            if(dimExist) {
-                SweetAlert.swal({
-                    title: '',
-                    text: "Once it's removed, all relative dimensions will be removed. Are you sure to remove the lookup table?",
-                    type: '',
-                    showCancelButton: true,
-                    confirmButtonColor: '#DD6B55',
-                    confirmButtonText: "Yes",
-                    closeOnConfirm: true
-                }, function (isConfirm) {
-                    if (isConfirm) {
-                        for (var i = modelsManager.selectedModel.dimensions.length - 1; i >= 0; i--) {
-                            if (modelsManager.selectedModel.dimensions[i].table === lookup.table) {
-                                modelsManager.selectedModel.dimensions.splice(i, 1);
-                            }
-                        }
-                        lookupList.splice(lookupList.indexOf(lookup), 1);
-                    }
-                });
-            }else{
-                lookupList.splice(lookupList.indexOf(lookup), 1);
-            }
-        };
-
-
-    $scope.changeKey = function(index){
-         var fact_table = modelsManager.selectedModel.fact_table;
-         var lookup_table = $scope.newLookup.table;
-         var pk_column = $scope.newLookup.join.primary_key[index];
-         var fk_column = $scope.newLookup.join.foreign_key[index];
-         if(pk_column!=='null'&&fk_column!=='null'){
-             $scope.newLookup.join.pk_type[index] = TableModel.getColumnType(pk_column,lookup_table);
-             $scope.newLookup.join.fk_type[index] = TableModel.getColumnType(fk_column,fact_table);
-            if($scope.newLookup.join.pk_type[index]!==$scope.newLookup.join.fk_type[index]){
-               $scope.newLookup.join.isCompatible[index]=false;
-            }else{
-               $scope.newLookup.join.isCompatible[index]=true;
-            }
-
-         }
-    }
-
-    $scope.addNewJoin = function(){
-        $scope.newLookup.join.primary_key.push("null");
-        $scope.newLookup.join.foreign_key.push("null");
-        $scope.newLookup.join.fk_type.push("null");
-        $scope.newLookup.join.pk_type.push("null");
-        $scope.newLookup.join.isCompatible.push(true);
-    };
-
-    $scope.removeJoin = function($index){
-        $scope.newLookup.join.primary_key.splice($index,1);
-        $scope.newLookup.join.foreign_key.splice($index,1);
-        $scope.newLookup.join.fk_type.splice($index,1);
-        $scope.newLookup.join.pk_type.splice($index,1);
-        $scope.newLookup.join.isCompatible.splice($index,1);
-    };
-
-    $scope.resetParams = function () {
-        $scope.lookupState.editing = false;
-        $scope.lookupState.editingIndex = -1;
-        $scope.newLookup = Lookup();
-    };
-
-    $scope.checkLookupForm = function(){
-            var errors = [];
-            // null validate
-            for(var i = 0;i<$scope.newLookup.join.primary_key.length;i++){
-                if($scope.newLookup.join.primary_key[i]==='null'){
-                    errors.push("Primary Key can't be null.");
-                    break;
-                }
-            }
-            for(var i = 0;i<$scope.newLookup.join.foreign_key.length;i++){
-                if($scope.newLookup.join.foreign_key[i]==='null'){
-                    errors.push("Foreign Key can't be null.");
-                    break;
-                }
-            }
-
-            var errorInfo = "";
-            angular.forEach(errors,function(item){
-                errorInfo+="\n"+item;
-            });
-            if(errors.length){
-//                SweetAlert.swal('Warning!', errorInfo, '');
-                SweetAlert.swal('', errorInfo, 'warning');
-                return false;
-            }else{
-                return true;
-            }
-
-    };
 
 });

http://git-wip-us.apache.org/repos/asf/kylin/blob/2d274506/webapp/app/js/controllers/modelConditionsSettings.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/controllers/modelConditionsSettings.js b/webapp/app/js/controllers/modelConditionsSettings.js
new file mode 100644
index 0000000..b3e4998
--- /dev/null
+++ b/webapp/app/js/controllers/modelConditionsSettings.js
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+
+/**
+ * Created by jiazhong on 2015/3/13.
+ */
+
+'use strict';
+
+KylinApp.controller('ModelConditionsSettingsCtrl', function ($scope, $modal,MetaModel,modelsManager,VdmUtil) {
+  $scope.modelsManager = modelsManager;
+  $scope.availableFactTables = [];
+  $scope.selectedTables={fact:VdmUtil.getNameSpaceAliasName($scope.modelsManager.selectedModel.partition_desc.partition_date_column)}
+  $scope.availableFactTables.push(VdmUtil.removeNameSpace($scope.modelsManager.selectedModel.fact_table));
+  var joinTable = $scope.modelsManager.selectedModel.lookups;
+  for (var j = 0; j < joinTable.length; j++) {
+    if(joinTable[j].kind=='FACT'){
+      $scope.availableFactTables.push(joinTable[j].alias);
+    }
+  }
+  $scope.isFormatEdit = {editable:false};
+  var judgeFormatEditable = function(dateColumn){
+    if(dateColumn == null){
+      $scope.isFormatEdit.editable = false;
+      return;
+    }
+    var column = _.filter($scope.getColumnsByAlias(VdmUtil.getNameSpaceAliasName(dateColumn)),function(_column){
+      var columnName=VdmUtil.getNameSpaceAliasName(dateColumn)+"."+_column.name;
+      if(dateColumn == columnName){
+        return _column;
+      }
+    });
+
+    var data_type = column[0].datatype;
+    if(data_type ==="bigint" ||data_type ==="int" ||data_type ==="integer"){
+      $scope.isFormatEdit.editable = false;
+      $scope.modelsManager.selectedModel.partition_desc.partition_date_format='yyyyMMdd';
+      $scope.partitionColumn.hasSeparateTimeColumn=false;
+      $scope.modelsManager.selectedModel.partition_desc.partition_time_column=null;
+      $scope.modelsManager.selectedModel.partition_desc.partition_time_format=null;
+
+      return;
+    }
+
+    $scope.isFormatEdit.editable = true;
+    return;
+
+  };
+  $scope.partitionChange = function (dateColumn) {
+    judgeFormatEditable(dateColumn);
+  };
+  $scope.partitionColumn ={
+      "hasSeparateTimeColumn" : false
+  }
+
+  if (($scope.state.mode=='edit')&&($scope.isEdit = !!$scope.route.params)) {
+    if($scope.modelsManager.selectedModel.partition_desc.partition_time_column){
+      $scope.partitionColumn.hasSeparateTimeColumn = true;
+    }
+    judgeFormatEditable($scope.modelsManager.selectedModel.partition_desc.partition_date_column);
+  }
+
+
+  $scope.toggleHasSeparateColumn = function(){
+    if($scope.partitionColumn.hasSeparateTimeColumn == false){
+      $scope.modelsManager.selectedModel.partition_desc.partition_time_column = null;
+    }
+  }
+});

http://git-wip-us.apache.org/repos/asf/kylin/blob/2d274506/webapp/app/js/controllers/modelDataModel.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/controllers/modelDataModel.js b/webapp/app/js/controllers/modelDataModel.js
new file mode 100644
index 0000000..d17af91
--- /dev/null
+++ b/webapp/app/js/controllers/modelDataModel.js
@@ -0,0 +1,254 @@
+/*
+ * 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.
+*/
+
+'use strict';
+
+KylinApp.controller('ModelDataModelCtrl', function ($location,$scope, $modal,cubeConfig,MetaModel,SweetAlert,ModelGraphService,$log,TableModel,ModelService,loadingRequest,modelsManager,VdmUtil) {
+    $scope.modelsManager = modelsManager;
+    $scope.init = function (){
+      $scope.rootFactTable=$scope.modelsManager.selectedModel.fact_table;
+      $scope.aliasTableMap[VdmUtil.removeNameSpace($scope.modelsManager.selectedModel.fact_table)]=$scope.modelsManager.selectedModel.fact_table;
+      $scope.tableAliasMap[$scope.modelsManager.selectedModel.fact_table]=VdmUtil.removeNameSpace($scope.modelsManager.selectedModel.fact_table);
+      $scope.aliasName.push(VdmUtil.removeNameSpace($scope.modelsManager.selectedModel.fact_table));
+      angular.forEach($scope.modelsManager.selectedModel.lookups,function(joinTable){
+         $scope.aliasTableMap[joinTable.alias]=joinTable.table;
+         $scope.tableAliasMap[joinTable.table]=joinTable.alias;
+         $scope.aliasName.push(joinTable.alias);
+      });
+    }
+    if($scope.state.mode=='edit'){
+      $scope.init();
+    }
+
+    $scope.cubeConfig = cubeConfig;
+    var DataModel = function () {
+        return {
+            name: '',
+            fact_table: '',
+            lookups: []
+        };
+    };
+
+    var Lookup = function () {
+        return {
+            table: '',
+            alias: '',
+            joinTable:'',
+            kind:'LOOKUP',
+            join: {
+                type: '',
+                primary_key: [],
+                foreign_key: [],
+                isCompatible:[],
+                pk_type:[],
+                fk_type:[]
+            }
+        };
+    };
+
+    // Initialize params.
+    $scope.lookupState = {
+        editing: false,
+        editingIndex: -1,
+        filter: ''
+    };
+
+    $scope.newLookup = Lookup();
+
+    var lookupList = modelsManager.selectedModel.lookups;
+
+    $scope.openLookupModal = function () {
+        var modalInstance = $modal.open({
+            templateUrl: 'dataModelLookupTable.html',
+            controller: cubeModelLookupModalCtrl,
+            backdrop: 'static',
+            scope: $scope
+        });
+        modalInstance.result.then(function () {
+            if (!$scope.lookupState.editing) {
+                $scope.doneAddLookup();
+            } else {
+                $scope.doneEditLookup();
+            }
+
+        }, function () {
+            $scope.cancelLookup();
+        });
+    };
+
+    // Controller for cube model lookup modal.
+    var cubeModelLookupModalCtrl = function ($scope, $modalInstance) {
+        $scope.ok = function () {
+            $modalInstance.close();
+        };
+
+        $scope.cancel = function () {
+            $modalInstance.dismiss('cancel');
+        };
+    };
+
+    $scope.editLookup = function (lookup) {
+        $scope.lookupState.editingIndex = lookupList.indexOf(lookup);
+        $scope.lookupState.editing = true;
+
+        // Make a copy of model will be editing.
+        $scope.newLookup = angular.copy(lookup);
+        $scope.newLookup.joinTable=VdmUtil.getNameSpaceTopName($scope.newLookup.join.foreign_key[0]);
+        $scope.openLookupModal();
+    };
+
+    $scope.doneAddLookup = function () {
+        // Push newLookup which bound user input data.
+        $scope.aliasTableMap[$scope.newLookup.alias]=$scope.newLookup.table;
+        $scope.tableAliasMap[$scope.newLookup.table]=$scope.newLookup.alias;
+        $scope.aliasName.push($scope.newLookup.alias);
+        lookupList.push(angular.copy($scope.newLookup));
+
+        $scope.resetParams();
+    };
+
+    $scope.doneEditLookup = function () {
+        // Copy edited model to destination model.
+        $scope.aliasTableMap[VdmUtil.removeNameSpace($scope.modelsManager.selectedModel.fact_table)]=$scope.modelsManager.selectedModel.fact_table;
+        $scope.aliasName=[VdmUtil.removeNameSpace($scope.modelsManager.selectedModel.fact_table)];
+        angular.copy($scope.newLookup, lookupList[$scope.lookupState.editingIndex]);
+        angular.forEach(lookupList,function(joinTable){
+          $scope.aliasName.push(joinTable.alias);
+          $scope.aliasTableMap[joinTable.alias]=joinTable.table;
+         // $scope.tableAliasMap[joinTable.alias]=joinTable.table;
+        });
+
+        $scope.resetParams();
+    };
+    $scope.changeFactTable = function () {
+        delete $scope.aliasTableMap[VdmUtil.removeNameSpace($scope.modelsManager.selectedModel.fact_table)];
+        $scope.aliasTableMap[VdmUtil.removeNameSpace($scope.rootFactTable)]=$scope.rootFactTable;
+        delete $scope.tableAliasMap[$scope.modelsManager.selectedModel.fact_table];
+        $scope.tableAliasMap[$scope.rootFactTable]=VdmUtil.removeNameSpace($scope.rootFactTable);
+        $scope.aliasName.splice($scope.aliasName.indexOf(VdmUtil.removeNameSpace($scope.modelsManager.selectedModel.fact_table)),1);
+        $scope.aliasName.push(VdmUtil.removeNameSpace($scope.rootFactTable));
+        $scope.modelsManager.selectedModel.fact_table=$scope.rootFactTable;
+    }
+    $scope.changeJoinTable = function () {
+        $scope.newLookup.alias=$scope.newLookup.table;
+    }
+    $scope.cancelLookup = function () {
+        $scope.resetParams();
+    };
+
+    $scope.removeLookup = function (lookup) {
+        var dimExist = _.some(modelsManager.selectedModel.dimensions,function(item,index){
+            return item.alias===lookup.alias;
+        });
+        if(dimExist) {
+            SweetAlert.swal({
+                 title: '',
+                 text: "Once it's removed, all relative dimensions will be removed. Are you sure to remove the lookup table?",
+                 type: '',
+                 showCancelButton: true,
+                 confirmButtonColor: '#DD6B55',
+                 confirmButtonText: "Yes",
+                 closeOnConfirm: true
+            }, function (isConfirm) {
+                if (isConfirm) {
+                    for (var i = modelsManager.selectedModel.dimensions.length - 1; i >= 0; i--) {
+                        if (modelsManager.selectedModel.dimensions[i].alias === lookup.alias) {
+                            modelsManager.selectedModel.dimensions.splice(i, 1);
+                        }
+                    }
+                    lookupList.splice(lookupList.indexOf(lookup), 1);
+                }
+            });
+        }else{
+            lookupList.splice(lookupList.indexOf(lookup), 1);
+        }
+    };
+    $scope.changeAlias = function (){
+    }
+
+    $scope.changeKey = function(index){
+         var join_table = $scope.newLookup.jointable;
+         var lookup_table = $scope.newLookup.table;
+         var pk_column = $scope.newLookup.join.primary_key[index];
+         var fk_column = $scope.newLookup.join.foreign_key[index];
+         if(pk_column!=='null'&&fk_column!=='null'){
+             $scope.newLookup.join.pk_type[index] = TableModel.getColumnType(pk_column,lookup_table);
+             $scope.newLookup.join.fk_type[index] = TableModel.getColumnType(fk_column,join_table);
+            if($scope.newLookup.join.pk_type[index]!==$scope.newLookup.join.fk_type[index]){
+               $scope.newLookup.join.isCompatible[index]=false;
+            }else{
+               $scope.newLookup.join.isCompatible[index]=true;
+            }
+
+         }
+    }
+
+    $scope.addNewJoin = function(){
+        $scope.newLookup.join.primary_key.push("null");
+        $scope.newLookup.join.foreign_key.push("null");
+        $scope.newLookup.join.fk_type.push("null");
+        $scope.newLookup.join.pk_type.push("null");
+        $scope.newLookup.join.isCompatible.push(true);
+    };
+
+    $scope.removeJoin = function($index){
+        $scope.newLookup.join.primary_key.splice($index,1);
+        $scope.newLookup.join.foreign_key.splice($index,1);
+        $scope.newLookup.join.fk_type.splice($index,1);
+        $scope.newLookup.join.pk_type.splice($index,1);
+        $scope.newLookup.join.isCompatible.splice($index,1);
+    };
+
+    $scope.resetParams = function () {
+        $scope.lookupState.editing = false;
+        $scope.lookupState.editingIndex = -1;
+        $scope.newLookup = Lookup();
+    };
+
+    $scope.checkLookupForm = function(){
+            var errors = [];
+            // null validate
+            for(var i = 0;i<$scope.newLookup.join.primary_key.length;i++){
+                if($scope.newLookup.join.primary_key[i]==='null'){
+                    errors.push("Primary Key can't be null.");
+                    break;
+                }
+            }
+            for(var i = 0;i<$scope.newLookup.join.foreign_key.length;i++){
+                if($scope.newLookup.join.foreign_key[i]==='null'){
+                    errors.push("Foreign Key can't be null.");
+                    break;
+                }
+            }
+
+            var errorInfo = "";
+            angular.forEach(errors,function(item){
+                errorInfo+="\n"+item;
+            });
+            if(errors.length){
+//                SweetAlert.swal('Warning!', errorInfo, '');
+                SweetAlert.swal('', errorInfo, 'warning');
+                return false;
+            }else{
+                return true;
+            }
+
+    };
+
+
+});

http://git-wip-us.apache.org/repos/asf/kylin/blob/2d274506/webapp/app/js/controllers/modelDimensions.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/controllers/modelDimensions.js b/webapp/app/js/controllers/modelDimensions.js
index 1b0e889..3f8a55b 100644
--- a/webapp/app/js/controllers/modelDimensions.js
+++ b/webapp/app/js/controllers/modelDimensions.js
@@ -18,7 +18,7 @@
 
 'use strict';
 
-KylinApp.controller('ModelDimensionsCtrl', function ($scope, $modal,MetaModel,modelsManager) {
+KylinApp.controller('ModelDimensionsCtrl', function ($scope, $modal,MetaModel,modelsManager,VdmUtil) {
     $scope.modelsManager = modelsManager;
 
     // Available columns list derived from cube data model.
@@ -34,10 +34,10 @@ KylinApp.controller('ModelDimensionsCtrl', function ($scope, $modal,MetaModel,mo
     // Dump available columns plus column table name, whether is from lookup table.
     $scope.initColumns = function () {
 
-        $scope.availableTables.push(modelsManager.selectedModel.fact_table);
+        $scope.availableTables.push(VdmUtil.removeNameSpace($scope.modelsManager.selectedModel.fact_table));
         var lookups = modelsManager.selectedModel.lookups;
         for (var j = 0; j < lookups.length; j++) {
-            $scope.availableTables.push(lookups[j].table);
+            $scope.availableTables.push(lookups[j].alias);
         }
 
         for(var i = 0;i<$scope.availableTables.length;i++){

http://git-wip-us.apache.org/repos/asf/kylin/blob/2d274506/webapp/app/js/controllers/modelEdit.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/controllers/modelEdit.js b/webapp/app/js/controllers/modelEdit.js
index 2f1b35e..4d1e12c 100644
--- a/webapp/app/js/controllers/modelEdit.js
+++ b/webapp/app/js/controllers/modelEdit.js
@@ -22,6 +22,10 @@
 KylinApp.controller('ModelEditCtrl', function ($scope, $q, $routeParams, $location, $templateCache, $interpolate, MessageService, TableService, CubeDescService, ModelService, loadingRequest, SweetAlert,$log,cubeConfig,CubeDescModel,ModelDescService,MetaModel,TableModel,ProjectService,ProjectModel,modelsManager,VdmUtil) {
     //add or edit ?
     var absUrl = $location.absUrl();
+    $scope.tableAliasMap={};
+    $scope.aliasTableMap={};
+    $scope.aliasName=[];
+    $scope.route={params:$routeParams.modelName};
     $scope.modelMode = absUrl.indexOf("/models/add")!=-1?'addNewModel':absUrl.indexOf("/models/edit")!=-1?'editExistModel':'default';
 
     if($scope.modelMode=="addNewModel"&&ProjectModel.selectedProject==null){
@@ -30,11 +34,10 @@ KylinApp.controller('ModelEditCtrl', function ($scope, $q, $routeParams, $locati
     }
 
     $scope.modelsManager = modelsManager;
-
     $scope.cubeConfig = cubeConfig;
 
-    $scope.getPartitonColumns = function(tableName){
-        var columns = _.filter($scope.getColumnsByTable(tableName),function(column){
+    $scope.getPartitonColumns = function(alias){
+        var columns = _.filter($scope.getColumnsByAlias(alias),function(column){
             return column.datatype==="date"||column.datatype==="timestamp"||column.datatype==="string"||column.datatype.startsWith("varchar")||column.datatype==="bigint"||column.datatype==="int"||column.datatype==="integer";
         });
         return columns;
@@ -56,9 +59,17 @@ KylinApp.controller('ModelEditCtrl', function ($scope, $q, $routeParams, $locati
         });
         return temp;
     };
-
-    $scope.getColumnType = function (_column,table){
-        var columns = $scope.getColumnsByTable(table);
+    $scope.getColumnsByAlias = function (aliasName) {
+        var temp = [];
+        angular.forEach(TableModel.selectProjectTables, function (table) {
+            if (table.name == $scope.aliasTableMap[aliasName]) {
+                temp = table.columns;
+            }
+        });
+        return temp;
+    };
+    $scope.getColumnType = function (_column,alias){
+        var columns = $scope.getColumnsByAlias(alias);
         var type;
         angular.forEach(columns,function(column){
             if(_column === column.name){
@@ -69,38 +80,6 @@ KylinApp.controller('ModelEditCtrl', function ($scope, $q, $routeParams, $locati
         return type;
     };
 
-  $scope.isFormatEditable = false;
-  var judgeFormatEditable = function(dateColumn){
-
-    if(dateColumn == null){
-      $scope.isFormatEditable = false;
-      return;
-    }
-    var column = _.filter($scope.getColumnsByTable($scope.modelsManager.selectedModel.fact_table),function(_column){
-      var columnName=$scope.modelsManager.selectedModel.fact_table+"."+_column.name;
-      if(dateColumn == columnName)
-        return _column;
-    });
-
-    var data_type = column[0].datatype;
-    if(data_type ==="bigint" ||data_type ==="int" ||data_type ==="integer"){
-      $scope.isFormatEditable = false;
-      $scope.modelsManager.selectedModel.partition_desc.partition_date_format='yyyyMMdd';
-      $scope.partitionColumn.hasSeparateTimeColumn=false;
-      $scope.modelsManager.selectedModel.partition_desc.partition_time_column=null;
-      $scope.modelsManager.selectedModel.partition_desc.partition_time_format=null;
-
-      return;
-    }
-
-    $scope.isFormatEditable = true;
-    return;
-
-  };
-  $scope.partitionChange = function (dateColumn) {
-    judgeFormatEditable(dateColumn);
-  };
-
     // ~ Define data
     $scope.state = {
         "modelSchema": "",
@@ -109,46 +88,27 @@ KylinApp.controller('ModelEditCtrl', function ($scope, $q, $routeParams, $locati
         project:$scope.projectModel.selectedProject
     };
 
-    $scope.partitionColumn ={
-      "hasSeparateTimeColumn" : false
-    }
-    // ~ init
     if ($scope.isEdit = !!$routeParams.modelName) {
-
-        var modelName = $routeParams.modelName;
-        ModelDescService.query({model_name: modelName}, function (model) {
-                    if (model) {
-                        modelsManager.selectedModel = model;
-
-                        if($scope.modelsManager.selectedModel.partition_desc.partition_time_column){
-                          $scope.partitionColumn.hasSeparateTimeColumn = true;
-                        }
-                        modelsManager.selectedModel.project = ProjectModel.getProjectByCubeModel(modelName);
-
-                        if(!ProjectModel.getSelectedProject()){
-                            ProjectModel.setSelectedProject(modelsManager.selectedModel.project);
-                        }
-
-                        TableModel.aceSrcTbLoaded().then(function(){
-                          judgeFormatEditable($scope.modelsManager.selectedModel.partition_desc.partition_date_column);
-                        });
-                    }
-                });
+      var modelName = $routeParams.modelName;
+      ModelDescService.query({model_name: modelName}, function (model) {
+        if (model) {
+          modelsManager.selectedModel = model;
+          if($scope.modelsManager.selectedModel.partition_desc.partition_time_column){
+            $scope.partitionColumn.hasSeparateTimeColumn = true;
+          }
+          modelsManager.selectedModel.project = ProjectModel.getProjectByCubeModel(modelName);
+          if(!ProjectModel.getSelectedProject()){
+            ProjectModel.setSelectedProject(modelsManager.selectedModel.project);
+          }
+        }
+      });
         //init project
-
     } else {
         MetaModel.initModel();
         modelsManager.selectedModel = MetaModel.getMetaModel();
         modelsManager.selectedModel.project = ProjectModel.getSelectedProject();
     }
 
-
-    $scope.toggleHasSeparateColumn = function(){
-      if($scope.partitionColumn.hasSeparateTimeColumn == false){
-        $scope.modelsManager.selectedModel.partition_desc.partition_time_column = null;
-      }
-    }
-
     $scope.prepareModel = function () {
         // generate column family
         $scope.state.project = modelsManager.selectedModel.project;

http://git-wip-us.apache.org/repos/asf/kylin/blob/2d274506/webapp/app/js/controllers/modelMeasures.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/controllers/modelMeasures.js b/webapp/app/js/controllers/modelMeasures.js
index 01cd35a..342f341 100644
--- a/webapp/app/js/controllers/modelMeasures.js
+++ b/webapp/app/js/controllers/modelMeasures.js
@@ -22,6 +22,31 @@
 
 'use strict';
 
-KylinApp.controller('ModelMeasuresCtrl', function ($scope) {
-
+KylinApp.controller('ModelMeasuresCtrl', function ($scope, $modal,MetaModel,modelsManager,VdmUtil) {
+    $scope.modelsManager = modelsManager;
+    $scope.availableFactTables = [];
+    $scope.selectedFactTables = {};
+    $scope.availableFactTables.push(VdmUtil.removeNameSpace($scope.modelsManager.selectedModel.fact_table));
+    var joinTable = $scope.modelsManager.selectedModel.lookups;
+    for (var j = 0; j < joinTable.length; j++) {
+        if(joinTable[j].kind=='FACT'){
+          $scope.availableFactTables.push(joinTable[j].alias);
+        }
+    }
+    angular.forEach($scope.modelsManager.selectedModel.metrics,function(metric){
+       $scope.selectedFactTables[VdmUtil.getNameSpaceAliasName(metric)]=$scope.selectedFactTables[VdmUtil.getNameSpaceAliasName(metric)]||[];
+       $scope.selectedFactTables[VdmUtil.getNameSpaceAliasName(metric)].push(metric);
+    });
+    $scope.changeColumns = function (table){
+       angular.forEach($scope.selectedFactTables[table],function(column){
+          if($scope.modelsManager.selectedModel.metrics.indexOf(column)==-1){
+             $scope.modelsManager.selectedModel.metrics.push(column);
+          }
+       });
+       angular.forEach($scope.modelsManager.selectedModel.metrics,function(metric){
+          if($scope.selectedFactTables[VdmUtil.getNameSpaceAliasName(metric)].indexOf(metric)==-1){
+            $scope.modelsManager.selectedModel.metrics.splice($scope.modelsManager.selectedModel.metrics.indexOf(metric),1);
+          }
+       });
+    }
 });

http://git-wip-us.apache.org/repos/asf/kylin/blob/2d274506/webapp/app/js/services/tree.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/services/tree.js b/webapp/app/js/services/tree.js
index acc4626..3b444c6 100755
--- a/webapp/app/js/services/tree.js
+++ b/webapp/app/js/services/tree.js
@@ -16,8 +16,9 @@
  * limitations under the License.
 */
 
-KylinApp.service('ModelGraphService', function () {
-
+KylinApp.service('ModelGraphService', function (VdmUtil) {
+    var tablesNodeList=[];
+    var aliasList=[];
     var margin = {top: 20, right: 100, bottom: 20, left: 100},
         width = 1100 - margin.right - margin.left,
         height = 600;
@@ -37,31 +38,52 @@ KylinApp.service('ModelGraphService', function () {
             .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
 
         var graphData = {
-            "type": "fact",
-            "name": model.fact_table,
+            "type": "FACT",
+            "name": VdmUtil.removeNameSpace(model.fact_table),
             "children": []
         };
-
+        tablesNodeList.push(graphData);
+        aliasList.push(graphData.name);
         model.graph = (!!model.graph) ? model.graph : {};
 
-      angular.forEach(model.lookups, function (lookup, index) {
-        if (lookup.join && lookup.join.primary_key.length > 0) {
+        angular.forEach(model.lookups, function (lookup, index) {
+          if (lookup.join && aliasList.indexOf(lookup.alias)==-1) {
+            var  dimensionNode={
+                "type": lookup.kind,
+                "name": lookup.alias,
+                "join": lookup.join,
+                "children": [],
+                "_children": []
+              }
+              aliasList.push(dimensionNode.name);
+              tablesNodeList.push(dimensionNode);
+            }
+
+        });
+        angular.forEach(model.lookups, function (lookup) {
+           if (lookup.join && lookup.join.primary_key.length > 0) {
+                  VdmUtil.getNameSpaceAliasName(lookup.join.primary_key[0]);
+                  VdmUtil.getNameSpaceAliasName(lookup.join.foreign_key[0]);
+           }
+        });
+
 
-          var dimensionNode;
+/* Loop through the graphData.children array to find out: If the LKP table is already existed *//*
 
-          /* Loop through the graphData.children array to find out: If the LKP table is already existed */
           for(var j = 0; j < graphData.children.length; j++ ) {
-            if(graphData.children[j].name == lookup.table){
+            if(graphData.children[j].name == lookup.alias){
               dimensionNode = graphData.children[j];
               break;
             }
           }
 
-          /* If not existed, create dimensionNode and push it */
+          */
+/* If not existed, create dimensionNode and push it *//*
+
           if(j == graphData.children.length) {
             dimensionNode = {
               "type": "dimension",
-              "name": lookup.table,
+              "name": lookup.alias,
               "join": lookup.join,
               "children": [],
               "_children": []
@@ -73,7 +95,7 @@ KylinApp.service('ModelGraphService', function () {
           }
 
         }
-      });
+*/
 
       angular.forEach(model.dimensions, function (dimension, index) {
         // for dimension on lookup table

http://git-wip-us.apache.org/repos/asf/kylin/blob/2d274506/webapp/app/js/utils/utils.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/utils/utils.js b/webapp/app/js/utils/utils.js
index 0875e52..1da840e 100644
--- a/webapp/app/js/utils/utils.js
+++ b/webapp/app/js/utils/utils.js
@@ -140,7 +140,27 @@ KylinApp.factory('VdmUtil', function ($modal, $timeout, $location, $anchorScroll
         return obj;
       }
       return angular.toJson(filterData(newObj),true);
-    }
-
+    },
+    removeNameSpace:function(str){
+      if(str){
+         return str.replace(/([^.\s]+\.)+/,'');
+      }else{
+        return '';
+      }
+    },
+    getNameSpaceTopName:function(str){
+      if(str){
+         return str.replace(/(\.[^.]+)/,'');
+      }else{
+        return '';
+      }
+    },
+    getNameSpaceAliasName:function(str){
+      if(str){
+         return str.replace(/\.[^.]+$/,'');
+      }else{
+        return '';
+      }
+    },
   }
 });

http://git-wip-us.apache.org/repos/asf/kylin/blob/2d274506/webapp/app/partials/modelDesigner/conditions_settings.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/modelDesigner/conditions_settings.html b/webapp/app/partials/modelDesigner/conditions_settings.html
index 6e7a883..6820b60 100644
--- a/webapp/app/partials/modelDesigner/conditions_settings.html
+++ b/webapp/app/partials/modelDesigner/conditions_settings.html
@@ -15,52 +15,44 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 -->
-
-<div class="row">
+<div ng-controller="ModelConditionsSettingsCtrl">
+  <div class="row">
     <div class="col-xs-12">
       <ng-form name="forms.model_setting_form" novalidate>
 
         <h3>Partition</h3>
         <div class="box-body">
-        <!--Cube Partition Type-->
-          <div class="form-group" ng-hide="true">
-              <div class="row">
-                  <label class="control-label col-xs-12 col-sm-3 no-padding-right font-color-default"><b>Partition Type</b></label>
-                  <div class="col-xs-12 col-sm-6">
-                      <select class="form-control"
-                          ng-if="state.mode=='edit'"
-                          chosen ng-model="modelsManager.selectedModel.partition_desc.partition_type"
-                          ng-options="ddt as ddt for ddt in cubeConfig.cubePartitionTypes">
-                          <option value=""></option>
-                      </select>
-                      <span ng-if="state.mode=='view'">{{modelsManager.selectedModel.partition_desc.partition_type}}</span>
-                  </div>
-              </div>
-          </div>
-
           <!--Partition Column-->
           <div class="form-group">
               <div class="row middle-popover">
                   <label class="control-label col-xs-12 col-sm-3 no-padding-right font-color-default"><b>Partition Date Column</b> <i kylinpopover placement="right" title="Partition Date Column" template="partitionTip.html" class="fa fa-info-circle"></i></label>
-                  <div class="col-xs-12 col-sm-6">
-
-                      <select style="width: 100%" chosen data-placeholder="e.g. DEFAULT.TEST_KYLIN_FACT.CAL_DT"
-                              ng-model="modelsManager.selectedModel.partition_desc.partition_date_column"
-                              ng-if="state.mode=='edit'" ng-change="partitionChange(modelsManager.selectedModel.partition_desc.partition_date_column)"
+                  <div class="col-xs-12 col-sm-6" ng-if="state.mode=='edit'">
+                      <select style="width: 45%" chosen data-placeholder="e.g. DEFAULT.TEST_KYLIN_FACT.CAL_DT"
+                              ng-model="selectedTables.fact"
                               data-placement=""
-                              ng-options="modelsManager.selectedModel.fact_table+'.'+columns.name as modelsManager.selectedModel.fact_table+'.'+columns.name for columns in getPartitonColumns(modelsManager.selectedModel.fact_table)" >
-                          <option value="">--Select Partition Column--</option>
+                              ng-options="alias as alias for alias in availableFactTables" >
+                          <option value="">--Select Partition Table--</option>
                       </select>
-                      <!--<small class="text-info" ng-show="state.mode=='edit'">(Column Type should be DATE or TIMESTAMP Type)</small>-->
 
-                      <span ng-if="state.mode=='view'">
-                          {{!!(modelsManager.selectedModel.partition_desc.partition_date_column)?modelsManager.selectedModel.partition_desc.partition_date_column: ''}}</span>
+                      <select style="width: 45%" chosen data-placeholder="e.g. DEFAULT.TEST_KYLIN_FACT.CAL_DT"
+                            ng-model="modelsManager.selectedModel.partition_desc.partition_date_column"
+                            ng-change="partitionChange(modelsManager.selectedModel.partition_desc.partition_date_column)"
+                            data-placement=""
+                            ng-options="selectedTables.fact+'.'+columns.name as columns.name for columns in getPartitonColumns(selectedTables.fact)" >
+                      <option value="">--Select Partition Column--</option>
+                    </select>
+                      <!--<small class="text-info" ng-show="state.mode=='edit'">(Column Type should be DATE or TIMESTAMP Type)</small>-->
+                  </div>
+                  <div class="col-xs-12 col-sm-6" ng-if="state.mode=='view'">
+                     <span >
+                          {{!!(modelsManager.selectedModel.partition_desc.partition_date_column)?modelsManager.selectedModel.partition_desc.partition_date_column: ''}}
+                     </span>
                   </div>
               </div>
           </div>
 
           <!--Date Format-->
-          <div class="form-group"  ng-if="(state.mode=='edit') || (state.mode=='view')">
+          <div class="form-group" >
             <div class="row">
               <label class="control-label col-xs-12 col-sm-3 no-padding-right font-color-default"><b>Date Format</b></label>
               <div class="col-xs-12 col-sm-6">
@@ -68,7 +60,7 @@
                         ng-required="modelsManager.selectedModel.partition_desc.partition_date_format"
                         ng-model="modelsManager.selectedModel.partition_desc.partition_date_format"
                         ng-if="state.mode=='edit'"
-                        ng-disabled="isFormatEditable!==true"
+                        ng-disabled="$parent.isFormatEdit.editable!==true"
                         data-placement=""
                         ng-options="ddt as ddt for ddt in cubeConfig.partitionDateFormatOpt">
                   <option value="">--Select Date Format--</option>
@@ -79,7 +71,7 @@
           </div>
 
           <!--Date Format-->
-          <div class="form-group middle-popover" ng-if="isFormatEditable==true">
+          <div class="form-group middle-popover" ng-if="isFormatEdit.editable==true">
             <div class="row">
               <label class="control-label col-xs-12 col-sm-3 no-padding-right font-color-default"><b>Has a separate "time of the day" column ?</b>  <i kylinpopover placement="right" title="Separate Time Column" template="separateTimeColumnTip.html" class="fa fa-info-circle"></i></label>
               <div class="col-xs-12 col-sm-6">
@@ -160,8 +152,8 @@
         </div>
        </ng-form>
     </div>
+  </div>
 </div>
-
 <script type="text/ng-template" id="partitionTip.html">
     <ol>
       <li>Partition date column not required,leave as default if cube always need full build</Li>
@@ -183,3 +175,4 @@
 <script type="text/ng-template" id="separateTimeColumnTip.html">
   <p>For cases where fact table saves date and hour at two columns (KYLIN-1427)</p>
 </script>
+

http://git-wip-us.apache.org/repos/asf/kylin/blob/2d274506/webapp/app/partials/modelDesigner/data_model.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/modelDesigner/data_model.html b/webapp/app/partials/modelDesigner/data_model.html
index ace977f..82be964 100644
--- a/webapp/app/partials/modelDesigner/data_model.html
+++ b/webapp/app/partials/modelDesigner/data_model.html
@@ -16,7 +16,7 @@
 * limitations under the License.
 -->
 
-<div ng-controller="CubeModelCtrl">
+<div ng-controller="ModelDataModelCtrl">
     <ng-form name="forms.data_model_form">
 
     <!-- Fact Table Name -->
@@ -26,9 +26,9 @@
                 <b>Fact Table</b>
             </label>
             <div class="col-xs-12 col-sm-6" ng-class="{'has-error':forms.data_model_form.table_name.$invalid && (forms.data_model_form.table_name.$dirty||forms.data_model_form.$submitted)}">
-              <select chosen ng-model="modelsManager.selectedModel.fact_table" ng-if="state.mode=='edit'"
+              <select chosen ng-model="$parent.rootFactTable" ng-if="state.mode=='edit'"
                       ng-options="table.name as table.name for table in tableModel.selectProjectTables"
-                      style="width:100%;"
+                      style="width:100%;" ng-change="changeFactTable()"
                       name="table_name"
                       ng-required="true"
                       data-placeholder="Fact Table Name"
@@ -37,7 +37,7 @@
               </select>
 
                 <small class="help-block" ng-show="forms.data_model_form.innerform.typeahead.$error.required && (forms.data_model_form.innerform.typeahead.$dirty||forms.data_model_form.$submitted)">The fact table is required</small>
-                <span ng-if="state.mode=='view'">{{modelsManager.selectedModel.fact_table}}</span>
+                <span ng-if="state.mode=='view'">{{$parent.rootFactTable}}</span>
             </div>
         </div>
     </div>
@@ -48,11 +48,11 @@
             <div class="col-xs-6" ng-if="state.mode=='edit'">
                 <button type="button" class="btn btn-primary" ng-disabled="!modelsManager.selectedModel.fact_table.length"
                         ng-click="openLookupModal()">
-                    <i class="fa fa-plus"></i> Add Lookup Table
+                    <i class="fa fa-plus"></i> Add Join Table
                 </button>
             </div>
             <div class="col-xs-6" ng-if="state.mode!='edit'">
-                <b>{{modelsManager.selectedModel.lookups.length ? 'Lookup Tables' : 'No Lookup Tables'}}</b>
+                <b>{{modelsManager.selectedModel.lookups.length ? 'Join Tables' : 'No Join Tables'}}</b>
             </div>
             <div class="col-xs-6">
                 <span class="pull-right input-icon input-icon-right nav-search" style="margin-left: 22px;" ng-if="modelsManager.selectedModel.lookups.length">
@@ -66,19 +66,24 @@
             <tr>
                 <th>ID</th>
                 <th>Table Name</th>
+                <th>Table Kind</th>
                 <th>Join Type</th>
                 <th>Join Condition</th>
                 <th ng-if="state.mode=='edit'">Actions</th>
             </tr>
             </thead>
             <tbody>
-            <tr ng-repeat="lookup in modelsManager.selectedModel.lookups | filter:lookupState.filter track by $index">
+            <tr ng-repeat="lookup in modelsManager.selectedModel.lookups | filter:lookupState.filter">
                 <td>
                     <b>{{$index + 1}}</b>
                 </td>
                 <!-- Table Name -->
                 <td>
-                    <span tooltip="Lookup Table Name">{{lookup.table}}</span>
+                    <span>{{lookup.alias}}</span>
+                </td>
+                <!-- Table Kind -->
+                <td>
+                    <span>{{lookup.kind}}</span>
                 </td>
                 <!-- Join Type -->
                 <td>
@@ -88,7 +93,7 @@
                 <td>
                     <ul class="list-unstyled">
                         <li ng-repeat="pk in lookup.join.primary_key track by $index">
-                            <code>{{modelsManager.selectedModel.fact_table + '.' + lookup.join.foreign_key[$index]}} = {{lookup.table + '.' + pk}}</code>
+                            <code>{{lookup.join.foreign_key[$index]}} = {{pk}}</code>
                         </li>
                     </ul>
                 </td>
@@ -108,7 +113,7 @@
     </div>
     </ng-form>
 
-    <!-- Add Lookup Table Form -->
+    <!-- Add Join Table Form -->
     <script type="text/ng-template" id="dataModelLookupTable.html">
         <div class="modal-header">
             <h4 class="box-title lighter">{{lookupState.editing ? 'Edit' : 'Add'}} Lookup</h4>
@@ -117,28 +122,45 @@
             <div class="row">
                 <div class="col-xs-8">
                     <ng-form name="lookup_form">
-                    <!--Table Name-->
-                    <div class="form-group">
+                      <div class="form-group">
                         <div class="row">
-                            <label class="control-label col-xs-12 col-sm-3 no-padding-right font-color-default"><b>Lookup Table Name</b></label>
-                            <div ng-class="{'has-error':lookup_form.table_name.$invalid && (lookup_form.table_name.$dirty||forms.model_info_form.$submitted)}">
-                                <div class="col-xs-12 col-sm-6">
-                                  <select chosen ng-model="newLookup.table"
-                                          ng-options="table.name as table.name for table in tableModel.selectProjectTables"
-                                          style="width:100%;"
-                                          name="table_name"
-                                          ng-required="true"
-                                          data-placeholder="Lookup Table Name"
-                                          class="chosen-select">
-                                    <option value=""> -- Select Lookup Table -- </option>
-                                  </select>
+                          <div class="col-xs-9">
+                            <div>
+                              <select chosen ng-model="newLookup.joinTable" style="width: 45%"
+                                      ng-options="table as table for table in aliasName"
+                                      name="table_name"
+                                      ng-required="true"
+                                      data-placeholder="Join Table Name"
+                                      class="chosen-select">
+                                <option value=""> &#45;&#45; Select Join Table &#45;&#45; </option>
+                              </select>
+                              <small class="help-block" ng-show="lookup_form.table_name.$invalid && (lookup_form.table_name.$dirty||forms.model_info_form.$submitted)">Table name required</small>
+                              <b>&nbsp;</b>
+                              <select chosen ng-model="newLookup.table" style="width: 45%"
+                                      ng-options="table.name as table.name for table in tableModel.selectProjectTables"
+                                      name="table_name"
+                                      ng-required="true"  ng-change="changeJoinTable()"
+                                      data-placeholder="Join Table Name"
+                                      class="chosen-select">
+                                <option value=""> &#45;&#45; Select Join Table &#45;&#45; </option>
+                              </select>
+                              <small class="help-block" ng-show="lookup_form.table_name.$invalid && (lookup_form.table_name.$dirty||forms.model_info_form.$submitted)">Table name required</small>
 
-                                    <small class="help-block" ng-show="lookup_form.table_name.$invalid && (lookup_form.table_name.$dirty||forms.model_info_form.$submitted)">Table name required</small>
-                                </div>
+                            </div>
+                            <div class="space-4"></div>
+                            <small class="help-block red" ng-show="newLookup.join.isCompatible[$index]==false"><i class="fa fa-exclamation-triangle"></i> <b>Column Type incompatible {{newLookup.join.foreign_key[$index]}}[{{newLookup.join.fk_type[$index]}}], {{newLookup.join.primary_key[$index]}} [{{newLookup.join.pk_type[$index]}}]</b></small>
+                          </div>
+                        </div>
+                      </div>
+                    <div class="form-group">
+                        <div class="row">
+                            <label class="col-sm-3 control-label font-color-default"><b>Alias</b></label>
+                            <div class="col-sm-6">
+                              <input type="text" class="form-control " placeholder="Input Table Alias" ng-required="true"
+                                     ng-model="newLookup.alias" ng-change="changeAlias()" ng-disabled="">
                             </div>
                         </div>
                     </div>
-
                     <!--Join Type and Columns-->
                     <div class="form-group">
                         <div class="row">
@@ -153,18 +175,27 @@
                     </div>
                     <div class="form-group">
                         <div class="row">
+                          <label class="col-sm-3 control-label font-color-default"><b>Table Type</b></label>
+                          <div class="col-sm-6">
+                            <label> <input type="radio" ng-model="newLookup.kind" value="FACT" > Fact Table </label>
+                            <label> <input type="radio" ng-model="newLookup.kind" value="LOOKUP"> Lookup Table </label>
+                          </div>
+                        </div>
+                    </div>
+                    <div class="form-group">
+                        <div class="row">
                             <div class="col-xs-9">
                                 <div ng-repeat="joinIndex in [] | range: newLookup.join.primary_key.length">
                                     <div>
                                         <select style="width: 45%" chosen data-placeholder="Fact Table Column"
                                                 ng-model="newLookup.join.foreign_key[$index]"  ng-change="changeKey($index)"
-                                                ng-options="columns.name as columns.name for columns in getColumnsByTable(modelsManager.selectedModel.fact_table)" >
+                                                ng-options="newLookup.joinTable+'.'+columns.name as columns.name for columns in getColumnsByAlias(newLookup.joinTable)" >
                                             <option value=""></option>
                                         </select>
                                         <b>=</b>
                                         <select style="width: 45%" chosen data-placeholder="Lookup Table Column"
                                                 ng-model="newLookup.join.primary_key[$index]"  ng-change="changeKey($index)"
-                                                ng-options="columns.name as columns.name for columns in getColumnsByTable(newLookup.table)" >
+                                                ng-options="newLookup.alias+'.'+columns.name as columns.name for columns in getColumnsByTable(newLookup.table)" >
                                             <option value=""></option>
                                         </select>
                                         <button class="pull-right btn btn-xs btn-danger" style="cursor: pointer" tooltip="Delete"

http://git-wip-us.apache.org/repos/asf/kylin/blob/2d274506/webapp/app/partials/modelDesigner/model_dimensions.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/modelDesigner/model_dimensions.html b/webapp/app/partials/modelDesigner/model_dimensions.html
index f767b9d..6249521 100644
--- a/webapp/app/partials/modelDesigner/model_dimensions.html
+++ b/webapp/app/partials/modelDesigner/model_dimensions.html
@@ -70,13 +70,13 @@
                     </td>
                     <td class="col-xs-9">
                       <ui-select
-                        ng-if="state.mode=='edit'" style="width: 100%"
+                        style="width: 100%"
                         autofocus="true"
                         close-on-select="false"
                         ng-model="modelsManager.selectedModel.dimensions[$index].columns" multiple>
                         <ui-select-match placeholder="Select Column...">{{$item.name}}</ui-select-match>
                         <ui-select-choices
-                          repeat="column.name as column in getColumnsByTable(dimension.table) | filter:$select.search">
+                          repeat="column.name as column in getColumnsByAlias(dimension.table) | filter:$select.search">
                           {{column.name}}
                         </ui-select-choices>
                       </ui-select>

http://git-wip-us.apache.org/repos/asf/kylin/blob/2d274506/webapp/app/partials/modelDesigner/model_measures.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/modelDesigner/model_measures.html b/webapp/app/partials/modelDesigner/model_measures.html
index 20c73c3..f34e3fb 100644
--- a/webapp/app/partials/modelDesigner/model_measures.html
+++ b/webapp/app/partials/modelDesigner/model_measures.html
@@ -17,10 +17,10 @@
 -->
 
 <!-- Measures Summary -->
-<ng-form name="forms.model_measure_form" novalidate>
-<div class="dataTables_wrapper form-inline no-footer">
-
-    <table ng-if="state.mode=='view'&&modelsManager.selectedModel.metrics.length > 0" class="table table-striped table-hover">
+<div ng-controller="ModelMeasuresCtrl">
+  <ng-form name="forms.model_measure_form" novalidate>
+    <div class="dataTables_wrapper form-inline no-footer">
+      <table ng-if="state.mode=='view'&&modelsManager.selectedModel.metrics.length > 0" class="table table-striped table-hover">
         <thead>
             <tr>
                 <th>ID</th>
@@ -39,23 +39,42 @@
                 </td>
             </tr>
         </tbody>
-    </table>
-    <div  ng-if="state.mode=='edit'" class="form-group" style="width: 100%">
+      </table>
+      <div  ng-if="state.mode=='edit'" class="form-group" style="width: 100%">
         <h4 style="margin-left:42px">Select measure columns</h4>
-      <ui-select
-        close-on-select="false"
-        ng-if="state.mode=='edit'"
-        style="width: 100%"
-        autofocus="true"
-        ng-model="modelsManager.selectedModel.metrics" multiple>
-        <ui-select-match placeholder="Select Column...">{{$item.name}}</ui-select-match>
-          <ui-select-choices
-            repeat="measure.name as measure in getColumnsByTable(modelsManager.selectedModel.fact_table) | filter:$select.search">
-            {{measure.name}}
-          </ui-select-choices>
-      </ui-select>
+        <table style="margin-left:42px; width:92%"
+               class="table table-hover list">
+          <tr class="row">
+            <th class="col-xs-1">ID</th>
+            <th class="col-xs-2">Table Name</th>
+            <th class="col-xs-9">Columns</th>
+          </tr>
 
+          <tr  class="row" ng-repeat="table in availableFactTables ">
+            <td class="col-xs-1">
+              <!-- ID -->
+              <b>{{($index + 1)}}</b>
+            </td>
+            <td class="col-xs-2">
+              {{table}}
+            </td>
+            <td class="col-xs-9">
+              <ui-select
+                close-on-select="false"
+                ng-if="state.mode=='edit'"
+                style="width: 100%" ng-change="changeColumns(table)"
+                autofocus="true"
+                ng-model="selectedFactTables[table]" multiple>
+                <ui-select-match placeholder="Select Column...">{{$item.name}}</ui-select-match>
+                <ui-select-choices
+                  repeat="table+'.'+measure.name as measure in getColumnsByAlias(table) | filter:$select.search">
+                  {{measure.name}}
+                </ui-select-choices>
+              </ui-select>
+            </td>
+          </tr>
+        </table>
+      </div>
     </div>
+  </ng-form>
 </div>
-
-</ng-form>