You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kylin.apache.org by li...@apache.org on 2015/03/14 01:01:49 UTC

[04/50] [abbrv] incubator-kylin git commit: enhance cube wizard & KYLIN-622

enhance cube wizard & KYLIN-622


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

Branch: refs/heads/staging
Commit: 21dc31aa8b1dc27c9b5a78ecd3929ab2e0ff9e0f
Parents: 7564107
Author: jiazhong <ji...@ebay.com>
Authored: Thu Mar 5 20:37:11 2015 +0800
Committer: jiazhong <ji...@ebay.com>
Committed: Thu Mar 5 20:37:11 2015 +0800

----------------------------------------------------------------------
 .../kylin/metadata/model/PartitionDesc.java     |   3 +-
 webapp/app/js/controllers/admin.js              | 431 +++++++++----------
 webapp/app/js/controllers/cubeEdit.js           |  67 ++-
 webapp/app/js/controllers/cubeSchema.js         |  16 +-
 webapp/app/js/controllers/cubes.js              |  55 +--
 webapp/app/js/controllers/page.js               |   2 +-
 .../cubeDesigner/advanced_settings.html         |   2 +-
 .../app/partials/cubeDesigner/incremental.html  |   2 +
 webapp/app/partials/jobs/job_merge.html         |   2 +-
 webapp/app/partials/jobs/job_refresh.html       |   2 +-
 webapp/app/partials/jobs/job_submit.html        | 170 ++++----
 11 files changed, 400 insertions(+), 352 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/21dc31aa/metadata/src/main/java/org/apache/kylin/metadata/model/PartitionDesc.java
----------------------------------------------------------------------
diff --git a/metadata/src/main/java/org/apache/kylin/metadata/model/PartitionDesc.java b/metadata/src/main/java/org/apache/kylin/metadata/model/PartitionDesc.java
index b079734..3b3fe94 100644
--- a/metadata/src/main/java/org/apache/kylin/metadata/model/PartitionDesc.java
+++ b/metadata/src/main/java/org/apache/kylin/metadata/model/PartitionDesc.java
@@ -23,6 +23,7 @@ import java.util.Map;
 import com.fasterxml.jackson.annotation.JsonAutoDetect;
 import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.kylin.common.util.StringSplitter;
 
 /**
@@ -47,7 +48,7 @@ public class PartitionDesc {
     private TblColRef partitionDateColumnRef;
 
     public void init(Map<String, Map<String, TblColRef>> columnMap) {
-        if (null != partitionDateColumn) {
+        if (StringUtils.isNotEmpty(partitionDateColumn)) {
             partitionDateColumn = partitionDateColumn.toUpperCase();
 
             String[] columns = StringSplitter.split(partitionDateColumn, ".");

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/21dc31aa/webapp/app/js/controllers/admin.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/controllers/admin.js b/webapp/app/js/controllers/admin.js
index 17ad0b0..a15411a 100644
--- a/webapp/app/js/controllers/admin.js
+++ b/webapp/app/js/controllers/admin.js
@@ -1,216 +1,215 @@
-/*
- * 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('AdminCtrl', function ($scope,AdminService, CacheService, TableService,loadingRequest, MessageService, $modal,SweetAlert) {
-    $scope.configStr = "";
-    $scope.envStr = "";
-
-    $scope.getEnv = function(){
-        AdminService.env({}, function(env){
-            $scope.envStr = env.env;
-            MessageService.sendMsg('Server environment get successfully', 'success', {});
-//            SweetAlert.swal('Success!', 'Server environment get successfully', 'success');
-        },function(e){
-            if(e.data&& e.data.exception){
-                var message =e.data.exception;
-                var msg = !!(message) ? message : 'Failed to take action.';
-                SweetAlert.swal('Oops...', msg, 'error');
-            }else{
-                SweetAlert.swal('Oops...', "Failed to take action.", 'error');
-            }
-        });
-    }
-
-    $scope.getConfig = function(){
-        AdminService.config({}, function(config){
-            $scope.configStr = config.config;
-            MessageService.sendMsg('Server config get successfully', 'success', {});
-        },function(e){
-            if(e.data&& e.data.exception){
-                var message =e.data.exception;
-                var msg = !!(message) ? message : 'Failed to take action.';
-                SweetAlert.swal('Oops...', msg, 'error');
-            }else{
-                SweetAlert.swal('Oops...', "Failed to take action.", 'error');
-            }
-        });
-    }
-
-    $scope.reloadMeta = function(){
-        SweetAlert.swal({
-            title: '',
-            text: 'Are you sure to reload metadata and clean cache?',
-            type: '',
-            showCancelButton: true,
-            confirmButtonColor: '#DD6B55',
-            confirmButtonText: "Yes",
-            closeOnConfirm: true
-        }, function(isConfirm) {
-            if(isConfirm){
-                CacheService.clean({}, function () {
-                    SweetAlert.swal('Success!', 'Cache reload successfully', 'success');
-                },function(e){
-                    if(e.data&& e.data.exception){
-                        var message =e.data.exception;
-                        var msg = !!(message) ? message : 'Failed to take action.';
-                        SweetAlert.swal('Oops...', msg, 'error');
-                    }else{
-                        SweetAlert.swal('Oops...', "Failed to take action.", 'error');
-                    }
-                });
-            }
-
-        });
-    }
-
-    $scope.calCardinality = function (tableName) {
-        $modal.open({
-            templateUrl: 'calCardinality.html',
-            controller: CardinalityGenCtrl,
-            resolve: {
-                tableName: function () {
-                    return tableName;
-                },
-                scope: function () {
-                    return $scope;
-                }
-            }
-        });
-    }
-
-    $scope.cleanStorage = function(){
-        SweetAlert.swal({
-            title: '',
-            text: 'Are you sure to clean up unused HDFS and HBase space?',
-            type: '',
-            showCancelButton: true,
-            confirmButtonColor: '#DD6B55',
-            confirmButtonText: "Yes",
-            closeOnConfirm: true
-        }, function(isConfirm) {
-            if(isConfirm){
-            AdminService.cleanStorage({}, function () {
-                SweetAlert.swal('Success!', 'Storage cleaned successfully!', 'success');
-            },function(e){
-                if(e.data&& e.data.exception){
-                    var message =e.data.exception;
-                    var msg = !!(message) ? message : 'Failed to take action.';
-                    SweetAlert.swal('Oops...', msg, 'error');
-                }else{
-                    SweetAlert.swal('Oops...', "Failed to take action.", 'error');
-                }
-            });
-            }
-        });
-    }
-
-    $scope.disableCache = function(){
-        SweetAlert.swal({
-            title: '',
-            text: 'Are you sure to disable query cache?',
-            type: '',
-            showCancelButton: true,
-            confirmButtonColor: '#DD6B55',
-            confirmButtonText: "Yes",
-            closeOnConfirm: true
-        }, function(isConfirm) {
-            if(isConfirm){
-            AdminService.updateConfig({}, {key: 'kylin.query.cache.enabled',value:false}, function () {
-                SweetAlert.swal('Success!', 'Cache disabled successfully!', 'success');
-            },function(e){
-                if(e.data&& e.data.exception){
-                    var message =e.data.exception;
-                    var msg = !!(message) ? message : 'Failed to take action.';
-                    SweetAlert.swal('Oops...', msg, 'error');
-                }else{
-                    SweetAlert.swal('Oops...', "Failed to take action.", 'error');
-                }
-            });
-            }
-
-        });
-
-    }
-
-    $scope.toSetConfig = function(){
-        $modal.open({
-            templateUrl: 'updateConfig.html',
-            controller: updateConfigCtrl,
-            resolve: {
-            }
-        });
-    }
-
-    var CardinalityGenCtrl = function ($scope, $modalInstance, tableName, MessageService) {
-        $scope.tableName = tableName;
-        $scope.delimiter = 0;
-        $scope.format = 0;
-        $scope.cancel = function () {
-            $modalInstance.dismiss('cancel');
-        };
-        $scope.calculate = function () {
-            $modalInstance.dismiss();
-            loadingRequest.show();
-            TableService.genCardinality({tableName: $scope.tableName}, {delimiter: $scope.delimiter, format: $scope.format}, function (result) {
-                loadingRequest.hide();
-                SweetAlert.swal('Success!', 'Cardinality job was calculated successfully. . Click Refresh button ...', 'success');
-            },function(e){
-                loadingRequest.hide();
-                console.log(e);
-                if(e.data&& e.data.exception){
-                    var message =e.data.exception;
-                    var msg = !!(message) ? message : 'Failed to take action.';
-                    SweetAlert.swal('Oops...', msg, 'error');
-                }else{
-                    SweetAlert.swal('Oops...', "Failed to take action.", 'error');
-                }
-            });
-        }
-    };
-
-    var updateConfigCtrl = function ($scope, $modalInstance, AdminService, MessageService) {
-        $scope.state = {
-            key:null,
-            value:null
-        };
-        $scope.cancel = function () {
-            $modalInstance.dismiss('cancel');
-        };
-        $scope.update = function () {
-
-
-                AdminService.updateConfig({}, {key: $scope.state.key, value: $scope.state.value}, function (result) {
-                    SweetAlert.swal('Success!', 'Config updated successfully!', 'success');
-                    $modalInstance.dismiss();
-                },function(e){
-                    if(e.data&& e.data.exception){
-                        var message =e.data.exception;
-                        var msg = !!(message) ? message : 'Failed to take action.';
-                        SweetAlert.swal('Oops...', msg, 'error');
-                    }else{
-                        SweetAlert.swal('Oops...', "Failed to take action.", 'error');
-                    }
-                });
-                }
-    };
-
-    $scope.getEnv();
-    $scope.getConfig();
-});
+/*
+ * 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('AdminCtrl', function ($scope,AdminService, CacheService, TableService,loadingRequest, MessageService, $modal,SweetAlert) {
+    $scope.configStr = "";
+    $scope.envStr = "";
+
+    $scope.getEnv = function(){
+        AdminService.env({}, function(env){
+            $scope.envStr = env.env;
+            MessageService.sendMsg('Server environment get successfully', 'success', {});
+//            SweetAlert.swal('Success!', 'Server environment get successfully', 'success');
+        },function(e){
+            if(e.data&& e.data.exception){
+                var message =e.data.exception;
+                var msg = !!(message) ? message : 'Failed to take action.';
+                SweetAlert.swal('Oops...', msg, 'error');
+            }else{
+                SweetAlert.swal('Oops...', "Failed to take action.", 'error');
+            }
+        });
+    }
+
+    $scope.getConfig = function(){
+        AdminService.config({}, function(config){
+            $scope.configStr = config.config;
+            MessageService.sendMsg('Server config get successfully', 'success', {});
+        },function(e){
+            if(e.data&& e.data.exception){
+                var message =e.data.exception;
+                var msg = !!(message) ? message : 'Failed to take action.';
+                SweetAlert.swal('Oops...', msg, 'error');
+            }else{
+                SweetAlert.swal('Oops...', "Failed to take action.", 'error');
+            }
+        });
+    }
+
+    $scope.reloadMeta = function(){
+        SweetAlert.swal({
+            title: '',
+            text: 'Are you sure to reload metadata and clean cache?',
+            type: '',
+            showCancelButton: true,
+            confirmButtonColor: '#DD6B55',
+            confirmButtonText: "Yes",
+            closeOnConfirm: true
+        }, function(isConfirm) {
+            if(isConfirm){
+                CacheService.clean({}, function () {
+                    SweetAlert.swal('Success!', 'Cache reload successfully', 'success');
+                },function(e){
+                    if(e.data&& e.data.exception){
+                        var message =e.data.exception;
+                        var msg = !!(message) ? message : 'Failed to take action.';
+                        SweetAlert.swal('Oops...', msg, 'error');
+                    }else{
+                        SweetAlert.swal('Oops...', "Failed to take action.", 'error');
+                    }
+                });
+            }
+
+        });
+    }
+
+    $scope.calCardinality = function (tableName) {
+        $modal.open({
+            templateUrl: 'calCardinality.html',
+            controller: CardinalityGenCtrl,
+            resolve: {
+                tableName: function () {
+                    return tableName;
+                },
+                scope: function () {
+                    return $scope;
+                }
+            }
+        });
+    }
+
+    $scope.cleanStorage = function(){
+        SweetAlert.swal({
+            title: '',
+            text: 'Are you sure to clean up unused HDFS and HBase space?',
+            type: '',
+            showCancelButton: true,
+            confirmButtonColor: '#DD6B55',
+            confirmButtonText: "Yes",
+            closeOnConfirm: true
+        }, function(isConfirm) {
+            if(isConfirm){
+            AdminService.cleanStorage({}, function () {
+                SweetAlert.swal('Success!', 'Storage cleaned successfully!', 'success');
+            },function(e){
+                if(e.data&& e.data.exception){
+                    var message =e.data.exception;
+                    var msg = !!(message) ? message : 'Failed to take action.';
+                    SweetAlert.swal('Oops...', msg, 'error');
+                }else{
+                    SweetAlert.swal('Oops...', "Failed to take action.", 'error');
+                }
+            });
+            }
+        });
+    }
+
+    $scope.disableCache = function(){
+        SweetAlert.swal({
+            title: '',
+            text: 'Are you sure to disable query cache?',
+            type: '',
+            showCancelButton: true,
+            confirmButtonColor: '#DD6B55',
+            confirmButtonText: "Yes",
+            closeOnConfirm: true
+        }, function(isConfirm) {
+            if(isConfirm){
+            AdminService.updateConfig({}, {key: 'kylin.query.cache.enabled',value:false}, function () {
+                SweetAlert.swal('Success!', 'Cache disabled successfully!', 'success');
+            },function(e){
+                if(e.data&& e.data.exception){
+                    var message =e.data.exception;
+                    var msg = !!(message) ? message : 'Failed to take action.';
+                    SweetAlert.swal('Oops...', msg, 'error');
+                }else{
+                    SweetAlert.swal('Oops...', "Failed to take action.", 'error');
+                }
+            });
+            }
+
+        });
+
+    }
+
+    $scope.toSetConfig = function(){
+        $modal.open({
+            templateUrl: 'updateConfig.html',
+            controller: updateConfigCtrl,
+            resolve: {
+            }
+        });
+    }
+
+    var CardinalityGenCtrl = function ($scope, $modalInstance, tableName, MessageService) {
+        $scope.tableName = tableName;
+        $scope.delimiter = 0;
+        $scope.format = 0;
+        $scope.cancel = function () {
+            $modalInstance.dismiss('cancel');
+        };
+        $scope.calculate = function () {
+            $modalInstance.dismiss();
+            loadingRequest.show();
+            TableService.genCardinality({tableName: $scope.tableName}, {delimiter: $scope.delimiter, format: $scope.format}, function (result) {
+                loadingRequest.hide();
+                SweetAlert.swal('Success!', 'Cardinality job was calculated successfully. . Click Refresh button ...', 'success');
+            },function(e){
+                loadingRequest.hide();
+                if(e.data&& e.data.exception){
+                    var message =e.data.exception;
+                    var msg = !!(message) ? message : 'Failed to take action.';
+                    SweetAlert.swal('Oops...', msg, 'error');
+                }else{
+                    SweetAlert.swal('Oops...', "Failed to take action.", 'error');
+                }
+            });
+        }
+    };
+
+    var updateConfigCtrl = function ($scope, $modalInstance, AdminService, MessageService) {
+        $scope.state = {
+            key:null,
+            value:null
+        };
+        $scope.cancel = function () {
+            $modalInstance.dismiss('cancel');
+        };
+        $scope.update = function () {
+
+
+                AdminService.updateConfig({}, {key: $scope.state.key, value: $scope.state.value}, function (result) {
+                    SweetAlert.swal('Success!', 'Config updated successfully!', 'success');
+                    $modalInstance.dismiss();
+                },function(e){
+                    if(e.data&& e.data.exception){
+                        var message =e.data.exception;
+                        var msg = !!(message) ? message : 'Failed to take action.';
+                        SweetAlert.swal('Oops...', msg, 'error');
+                    }else{
+                        SweetAlert.swal('Oops...', "Failed to take action.", 'error');
+                    }
+                });
+                }
+    };
+
+    $scope.getEnv();
+    $scope.getConfig();
+});

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/21dc31aa/webapp/app/js/controllers/cubeEdit.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/controllers/cubeEdit.js b/webapp/app/js/controllers/cubeEdit.js
index 35df8a3..e903f65 100755
--- a/webapp/app/js/controllers/cubeEdit.js
+++ b/webapp/app/js/controllers/cubeEdit.js
@@ -95,7 +95,6 @@ KylinApp.controller('CubeEditCtrl', function ($scope, $q, $routeParams, $locatio
                         //should run only one time
                         if(model.partition_desc&&model.partition_desc.partition_date_start)
                         {
-                            //$scope.metaModel.partition_desc.partition_date_start+=new Date().getTimezoneOffset()*60000;
                             MetaModel.converDateToGMT();
                         }
                     }
@@ -259,10 +258,11 @@ KylinApp.controller('CubeEditCtrl', function ($scope, $q, $routeParams, $locatio
     function reGenerateRowKey(){
         $log.log("reGen rowkey & agg group");
         var tmpRowKeyColumns = [];
-        var tmpAggregationItems = [];
-        var hierarchyItems = [];
+        var tmpAggregationItems = [];//put all aggregation item
+        var hierarchyItemArray = [];//put all hierarchy items
         angular.forEach($scope.cubeMetaFrame.dimensions, function (dimension, index) {
 
+           //derived column
             if(dimension.derived&&dimension.derived.length){
                 var lookup = _.find($scope.metaModel.model.lookups,function(lookup){return lookup.table==dimension.table});
                 angular.forEach(lookup.join.foreign_key, function (fk, index) {
@@ -284,7 +284,8 @@ KylinApp.controller('CubeEditCtrl', function ($scope, $q, $routeParams, $locatio
                 })
 
             }
-            else if (dimension.column&&dimension.column.length==1) {
+            //normal column
+            else if (dimension.column&&!dimension.hierarchy&&dimension.column.length==1) {
                 for (var i = 0; i < tmpRowKeyColumns.length; i++) {
                     if(tmpRowKeyColumns[i].column == dimension.column[0])
                         break;
@@ -299,7 +300,9 @@ KylinApp.controller('CubeEditCtrl', function ($scope, $q, $routeParams, $locatio
                     tmpAggregationItems.push(dimension.column[0]);
                 }
             }
+            // hierarchy
             if(dimension.hierarchy && dimension.column.length){
+                var hierarchyUnit = [];
                 angular.forEach(dimension.column, function (hier_column, index) {
                     for (var i = 0; i < tmpRowKeyColumns.length; i++) {
                         if(tmpRowKeyColumns[i].column == hier_column)
@@ -314,10 +317,13 @@ KylinApp.controller('CubeEditCtrl', function ($scope, $q, $routeParams, $locatio
                         });
                         tmpAggregationItems.push(hier_column);
                     }
-                    if(hierarchyItems.indexOf(hier_column)==-1){
-                        hierarchyItems.push(hier_column);
+                    if(hierarchyUnit.indexOf(hier_column)==-1){
+                      hierarchyUnit.push(hier_column);
                     }
                 });
+              if(hierarchyUnit.length){
+                hierarchyItemArray.push(hierarchyUnit);
+              }
             }
 
         });
@@ -362,6 +368,8 @@ KylinApp.controller('CubeEditCtrl', function ($scope, $q, $routeParams, $locatio
 
         if($scope.cubeMode==="addNewCube"){
 
+          if(!tmpAggregationItems.length) return;
+
             var newUniqAggregationItem = [];
             angular.forEach(tmpAggregationItems, function (item, index) {
                 if(newUniqAggregationItem.indexOf(item)==-1){
@@ -369,12 +377,51 @@ KylinApp.controller('CubeEditCtrl', function ($scope, $q, $routeParams, $locatio
                 }
             });
 
-            var unHierarchyItems = increasedData(hierarchyItems,newUniqAggregationItem);
+          var hierarchyItems = [];
+          for(var m=0;m<hierarchyItemArray.length;m++){
+            for(var n=0;n<hierarchyItemArray[m].length;n++){
+              hierarchyItems.push(hierarchyItemArray[m][n]);
+            }
+          }
+          var unHierarchyItems = increasedData(hierarchyItems,newUniqAggregationItem);
 //            hierarchyItems
-            var increasedDataGroups = sliceGroupItemToGroups(unHierarchyItems);
-            if(hierarchyItems.length){
-                increasedDataGroups.push(hierarchyItems);
+          var increasedDataGroups = sliceGroupItemToGroups(unHierarchyItems);
+          var lastAggregationGroup = increasedDataGroups.length===0?[]:increasedDataGroups[increasedDataGroups.length-1];
+          if(lastAggregationGroup.length<10){
+            if(lastAggregationGroup.length+hierarchyItemArray.length<=10){
+              lastAggregationGroup = lastAggregationGroup.concat(hierarchyItems);
+              if(increasedDataGroups.length==0){
+                increasedDataGroups[0]=lastAggregationGroup;
+              }else{
+                increasedDataGroups[increasedDataGroups.length-1]=lastAggregationGroup;
+              }
+            }
+            else{
+              var spareLength = 10-lastAggregationGroup.length;
+              var partialHierarchy =lastAggregationGroup.concat(hierarchyItemArray.slice(0,spareLength));
+              //add hierarchy to last group and make sure length less than 10
+              lastAggregationGroup = lastAggregationGroup.concat(partialHierarchy);
+              var spareHierarchy = hierarchyItemArray.slice(spareLength+1,hierarchyItemArray.length-1);
+              if(spareHierarchy.length){
+                lastAggregationGroup.push(spareHierarchy);
+              }
+              increasedDataGroups[increasedDataGroups.length-1]=lastAggregationGroup;
             }
+          }
+          else{
+            if(hierarchyItemArray.length<=10){
+              increasedDataGroups.push(hierarchyItems);
+            }else{
+              var partialHierarchy =lastAggregationGroup.concat(hierarchyItemArray.slice(0,10));
+              //add hierarchy to last group and make sure length less than 10
+              increasedDataGroups.push(partialHierarchy);
+              var spareHierarchy = hierarchyItemArray.slice(11,hierarchyItemArray.length-1);
+              if(spareHierarchy.length){
+                increasedDataGroups.push(spareHierarchy);
+              }
+            }
+          }
+
 
             //! here get the latest aggregation groups,only effect when add newCube
             $scope.cubeMetaFrame.rowkey.aggregation_groups = increasedDataGroups;

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/21dc31aa/webapp/app/js/controllers/cubeSchema.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/controllers/cubeSchema.js b/webapp/app/js/controllers/cubeSchema.js
index 9654ac7..b0de094 100755
--- a/webapp/app/js/controllers/cubeSchema.js
+++ b/webapp/app/js/controllers/cubeSchema.js
@@ -61,22 +61,14 @@ KylinApp.controller('CubeSchemaCtrl', function ($scope, QueryService, UserServic
             //init model
             ModelService.get({model_name: $scope.cubeMetaFrame.model_name}, function (model) {
                 if (model) {
-//                    $scope.metaModel = MetaModel;
-
                     $scope.metaModel.model = model;
 
-                    // add model ref for cube
-                    angular.forEach(CubeList.cubes,function(cube){
-                        if(cube.name===$scope.cubeMetaFrame.name||cube.descriptor===$scope.cubeMetaFrame.name){
-                          cube.model = model;
-                        }
-                    });
                     //convert GMT mills ,to make sure partition date show GMT Date
                     //should run only one time
-                    if($scope.metaModel.model.partition_desc&&$scope.metaModel.model.partition_desc.partition_date_start)
-                    {
-                        $scope.metaModel.model.partition_desc.partition_date_start+=new Date().getTimezoneOffset()*60000;
-                    }
+                    //if($scope.metaModel.model.partition_desc&&$scope.metaModel.model.partition_desc.partition_date_start)
+                    //{
+                    //    $scope.metaModel.model.partition_desc.partition_date_start+=new Date().getTimezoneOffset()*60000;
+                    //}
                 }
             });
 

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/21dc31aa/webapp/app/js/controllers/cubes.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/controllers/cubes.js b/webapp/app/js/controllers/cubes.js
index 35266a4..df86816 100755
--- a/webapp/app/js/controllers/cubes.js
+++ b/webapp/app/js/controllers/cubes.js
@@ -83,7 +83,11 @@ KylinApp
                 CubeDescService.get({cube_name: cube.name}, {}, function (detail) {
                     if (detail.length > 0&&detail[0].hasOwnProperty("name")) {
                         cube.detail = detail[0];
-                        defer.resolve(cube.detail);
+                        ModelService.get({model_name: cube.detail.model_name}, function (model) {
+                          cube.model = model
+                          defer.resolve(cube.detail);
+                       });
+
                     }else{
                         SweetAlert.swal('Oops...', "No cube detail info loaded.", 'error');
                     }
@@ -326,43 +330,46 @@ KylinApp
         };
 
         $scope.startRefresh = function (cube) {
-            $scope.loadDetail(cube);
-
-            $modal.open({
-                templateUrl: 'jobRefresh.html',
-                controller: jobSubmitCtrl,
-                resolve: {
-                    cube: function () {
-                        return cube;
-                    },
-                    buildType: function () {
-                        return 'BUILD';
-                    }
-                }
+            $scope.loadDetail(cube).then(function(){
+              $modal.open({
+                  templateUrl: 'jobRefresh.html',
+                  controller: jobSubmitCtrl,
+                  resolve: {
+                      cube: function () {
+                          return cube;
+                      },
+                      buildType: function () {
+                          return 'BUILD';
+                      }
+                  }
+              });
             });
+
         };
 
         $scope.startMerge = function (cube) {
-            $scope.loadDetail(cube);
-
-            $modal.open({
+            $scope.loadDetail(cube).then(function(){
+              $modal.open({
                 templateUrl: 'jobMerge.html',
                 controller: jobSubmitCtrl,
                 resolve: {
-                    cube: function () {
-                        return cube;
-                    },
-                    buildType: function () {
-                        return 'MERGE';
-                    }
+                  cube: function () {
+                    return cube;
+                  },
+                  buildType: function () {
+                    return 'MERGE';
+                  }
                 }
+              });
             });
         }
     });
 
 var jobSubmitCtrl = function ($scope, $modalInstance, CubeService, MessageService, $location, cube,MetaModel, buildType,SweetAlert,loadingRequest) {
     $scope.cube = cube;
-    $scope.metaModel = MetaModel;
+    $scope.metaModel={
+      model:cube.model
+    }
     $scope.jobBuildRequest = {
         buildType: buildType,
         startTime: 0,

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/21dc31aa/webapp/app/js/controllers/page.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/controllers/page.js b/webapp/app/js/controllers/page.js
index a382b97..6cc2762 100644
--- a/webapp/app/js/controllers/page.js
+++ b/webapp/app/js/controllers/page.js
@@ -180,7 +180,7 @@ KylinApp.controller('PageCtrl', function ($scope, $q, AccessService,$modal, $loc
 
     $scope.$watch('projectModel.selectedProject', function (newValue, oldValue) {
         if(newValue!=oldValue){
-            $log.log("project updated in page controller,from:"+oldValue+" To:"+newValue);
+            //$log.log("project updated in page controller,from:"+oldValue+" To:"+newValue);
             $cookieStore.put("project",$scope.projectModel.selectedProject);
         }
 

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/21dc31aa/webapp/app/partials/cubeDesigner/advanced_settings.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/cubeDesigner/advanced_settings.html b/webapp/app/partials/cubeDesigner/advanced_settings.html
index e9b533a..e29e6a4 100755
--- a/webapp/app/partials/cubeDesigner/advanced_settings.html
+++ b/webapp/app/partials/cubeDesigner/advanced_settings.html
@@ -163,4 +163,4 @@
                 ng-click="addNewRowkeyColumn()" ng-show="state.mode=='edit'">New Rowkey Column<i class="fa fa-plus"></i></button>
     </div>
 </div>
-</div>
\ No newline at end of file
+</div>

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/21dc31aa/webapp/app/partials/cubeDesigner/incremental.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/cubeDesigner/incremental.html b/webapp/app/partials/cubeDesigner/incremental.html
index b3bf34e..6f40371 100755
--- a/webapp/app/partials/cubeDesigner/incremental.html
+++ b/webapp/app/partials/cubeDesigner/incremental.html
@@ -60,9 +60,11 @@
             <div class="row">
                 <label class="control-label col-xs-12 col-sm-3 no-padding-right font-color-default"><b>Start Date</b></label>
                 <div class="col-xs-12 col-sm-6">
+                  <!--edit model will convert in MetaModel.converDateToGMT-->
                     <input type="text" class="form-control" datepicker-popup="yyyy-MM-dd"
                            ng-model="metaModel.model.partition_desc.partition_date_start" ng-if="state.mode=='edit'"
                            placeholder="Click to choose start date..." is-open="opened" />
+                  <!--vier model will convert use filter-->
                     <span ng-if="state.mode=='view'&&metaModel.model.partition_desc.partition_date_column">{{(metaModel.model.partition_desc.partition_date_start)|reverseToGMT0 }}</span>
                 </div>
             </div>

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/21dc31aa/webapp/app/partials/jobs/job_merge.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/jobs/job_merge.html b/webapp/app/partials/jobs/job_merge.html
index 123c702..c55b280 100644
--- a/webapp/app/partials/jobs/job_merge.html
+++ b/webapp/app/partials/jobs/job_merge.html
@@ -129,4 +129,4 @@
             Submit
         </button>
     </div>
-</script>
\ No newline at end of file
+</script>

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/21dc31aa/webapp/app/partials/jobs/job_refresh.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/jobs/job_refresh.html b/webapp/app/partials/jobs/job_refresh.html
index 9b70ea8..89705e0 100644
--- a/webapp/app/partials/jobs/job_refresh.html
+++ b/webapp/app/partials/jobs/job_refresh.html
@@ -96,4 +96,4 @@
                 ng-disabled="!(jobBuildRequest.startTime >= 0 && jobBuildRequest.endTime > 0)">Submit
         </button>
     </div>
-</script>
\ No newline at end of file
+</script>

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/21dc31aa/webapp/app/partials/jobs/job_submit.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/jobs/job_submit.html b/webapp/app/partials/jobs/job_submit.html
index b3f917b..1036dee 100644
--- a/webapp/app/partials/jobs/job_submit.html
+++ b/webapp/app/partials/jobs/job_submit.html
@@ -1,85 +1,85 @@
-<!--
-* 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.
--->
-
-<script type="text/ng-template" id="jobSubmit.html">
-    <div class="modal-header">
-        <h4 tooltip="submit">CUBE BUILD CONFIRM</h4>
-    </div>
-    <div class="modal-body" style="background-color: white">
-        <div ng-if="metaModel.model.partition_desc.partition_date_column" class="row">
-            <div class="col-md-2"></div>
-            <div class="col-md-8">
-                <div class="row">
-                    <table class="table table-striped list"
-                           ng-if="(cube.segments | filter: {status: 'NEW'}).length == 0">
-                        <tbody>
-                        <tr>
-                            <td>PARTITION DATE COLUMN</td>
-                            <td>{{metaModel.model.partition_desc.partition_date_column}}</td>
-                        </tr>
-                        <tr>
-                            <td>Start Date (Include)</td>
-                            <td>
-                                <!--no need convert UTC again-->
-                                <div ng-if="cube.segments.length == 0">
-                                    {{jobBuildRequest.startTime =
-                                    (!!metaModel.model.partition_desc.partition_date_start)?metaModel.model.partition_desc.partition_date_start:0
-                                    | reverseToGMT0 }}
-                                </div>
-                                <div ng-if="cube.segments.length > 0">
-                                    <!--no need to convert-->
-                                    <div ng-if="metaModel.model.partition_desc.partition_type=='APPEND'">
-                                        {{ jobBuildRequest.startTime = cube.segments[cube.segments.length-1].date_range_end| reverseToGMT0 }}
-                                    </div>
-                                    <!--<div ng-if="metaModel.model.partition_desc.cube_partition_type=='UPDATE_INSERT'">-->
-                                        <!--&lt;!&ndash;<datepicker ng-model="jobBuildRequest.startTime" show-weeks="true"&ndash;&gt;-->
-                                                    <!--&lt;!&ndash;required class="well well-sm"></datepicker>&ndash;&gt;-->
-                                        <!--<input type="text" datepicker-popup="yyyy-MM-dd" class="input-sm" style="width: 98%"-->
-                                               <!--ng-model="jobBuildRequest.startTime"-->
-                                               <!--placeholder="Click to choose START date..." is-open="opened" />-->
-                                    <!--</div>-->
-                                </div>
-                            </td>
-                        </tr>
-                        <tr>
-                            <td>End Date (Exclude)</td>
-                            <td>
-                                <input type="text" datepicker-popup="yyyy-MM-dd" class="input-sm" style="width: 98%"
-                                       ng-model="jobBuildRequest.endTime"
-                                       placeholder="Click to choose END date..." is-open="opened" />
-                            </td>
-                        </tr>
-                        </tbody>
-                    </table>
-
-                    <div ng-if="(cube.segments|filter: {status: 'NEW'}).length > 0">
-                        <span class="text-warning">There exists a build request of this cube, the job may be running or error. If you need a new build, please wait for its complete or discard it.</span>
-                    </div>
-                </div>
-                <div ng-if="message">
-                    <span class="text-warning">{{message}}</span>
-                </div>
-            </div>
-            <div class="col-md-2"></div>
-        </div>
-    </div>
-    <div class="modal-footer">
-        <button class="btn btn-success" ng-click="updateDate();rebuild(true)" ng-disabled="jobBuildRequest.endTime<=0">Submit</button>
-        <button class="btn btn-primary" ng-click="cancel()">Close</button>
-    </div>
-</script>
\ No newline at end of file
+<!--
+* 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.
+-->
+
+<script type="text/ng-template" id="jobSubmit.html">
+    <div class="modal-header">
+        <h4 tooltip="submit">CUBE BUILD CONFIRM</h4>
+    </div>
+    <div class="modal-body" style="background-color: white">
+        <div ng-if="metaModel.model.partition_desc.partition_date_column" class="row">
+            <div class="col-md-2"></div>
+            <div class="col-md-8">
+                <div class="row">
+                    <table class="table table-striped list"
+                           ng-if="(cube.segments | filter: {status: 'NEW'}).length == 0">
+                        <tbody>
+                        <tr>
+                            <td>PARTITION DATE COLUMN</td>
+                            <td>{{metaModel.model.partition_desc.partition_date_column}}</td>
+                        </tr>
+                        <tr>
+                            <td>Start Date (Include)</td>
+                            <td>
+                                <!--no need convert UTC again-->
+                                <div ng-if="cube.segments.length == 0">
+                                    {{jobBuildRequest.startTime =
+                                    (!!metaModel.model.partition_desc.partition_date_start)?metaModel.model.partition_desc.partition_date_start:0
+                                    | reverseToGMT0 }}
+                                </div>
+                                <div ng-if="cube.segments.length > 0">
+                                    <!--no need to convert-->
+                                    <div ng-if="metaModel.model.partition_desc.partition_type=='APPEND'">
+                                        {{ jobBuildRequest.startTime = cube.segments[cube.segments.length-1].date_range_end| reverseToGMT0 }}
+                                    </div>
+                                    <!--<div ng-if="metaModel.model.partition_desc.cube_partition_type=='UPDATE_INSERT'">-->
+                                        <!--&lt;!&ndash;<datepicker ng-model="jobBuildRequest.startTime" show-weeks="true"&ndash;&gt;-->
+                                                    <!--&lt;!&ndash;required class="well well-sm"></datepicker>&ndash;&gt;-->
+                                        <!--<input type="text" datepicker-popup="yyyy-MM-dd" class="input-sm" style="width: 98%"-->
+                                               <!--ng-model="jobBuildRequest.startTime"-->
+                                               <!--placeholder="Click to choose START date..." is-open="opened" />-->
+                                    <!--</div>-->
+                                </div>
+                            </td>
+                        </tr>
+                        <tr>
+                            <td>End Date (Exclude)</td>
+                            <td>
+                                <input type="text" datepicker-popup="yyyy-MM-dd" class="input-sm" style="width: 98%"
+                                       ng-model="jobBuildRequest.endTime"
+                                       placeholder="Click to choose END date..." is-open="opened" />
+                            </td>
+                        </tr>
+                        </tbody>
+                    </table>
+
+                    <div ng-if="(cube.segments|filter: {status: 'NEW'}).length > 0">
+                        <span class="text-warning">There exists a build request of this cube, the job may be running or error. If you need a new build, please wait for its complete or discard it.</span>
+                    </div>
+                </div>
+                <div ng-if="message">
+                    <span class="text-warning">{{message}}</span>
+                </div>
+            </div>
+            <div class="col-md-2"></div>
+        </div>
+    </div>
+    <div class="modal-footer">
+        <button class="btn btn-success" ng-click="updateDate();rebuild(true)" ng-disabled="jobBuildRequest.endTime<=0">Submit</button>
+        <button class="btn btn-primary" ng-click="cancel()">Close</button>
+    </div>
+</script>