You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kylin.apache.org by ma...@apache.org on 2015/05/15 07:21:54 UTC

[25/52] [abbrv] incubator-kylin git commit: new model GUI

new model GUI


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

Branch: refs/heads/0.8.0
Commit: a2f4d320b6752333d0a7dafce064101943a7b757
Parents: 6fed6cb
Author: jiazhong <ji...@ebay.com>
Authored: Tue Mar 17 18:10:37 2015 +0800
Committer: honma <ho...@ebay.com>
Committed: Fri May 15 11:36:27 2015 +0800

----------------------------------------------------------------------
 .../apache/kylin/common/util/StringUtil.java    |   8 +-
 .../apache/kylin/metadata/MetadataManager.java  |  30 +-
 .../kylin/metadata/project/ProjectInstance.java |  36 +-
 .../kylin/metadata/project/ProjectManager.java  |  43 ++-
 .../kylin/rest/controller/ModelController.java  |   2 +-
 .../apache/kylin/rest/service/ModelService.java |  18 +-
 .../apache/kylin/rest/service/QueryService.java |  16 +-
 webapp/app/js/controllers/cube.js               |   4 +-
 webapp/app/js/controllers/cubeModel.js          |   4 +-
 webapp/app/js/controllers/modelDimensions.js    | 370 +------------------
 webapp/app/js/controllers/modelEdit.js          |  87 +++--
 webapp/app/js/controllers/modelSchema.js        |  66 +---
 webapp/app/js/controllers/projectMeta.js        |   2 -
 webapp/app/js/model/metaModel.js                | 100 ++---
 .../modelDesigner/conditions_settings.html      | 127 +++++++
 .../app/partials/modelDesigner/incremental.html |  94 -----
 .../modelDesigner/model_dimensions.html         | 339 +++--------------
 .../app/partials/modelDesigner/model_info.html  |   6 +-
 .../partials/modelDesigner/model_measures.html  | 156 +-------
 webapp/app/partials/models/model_edit.html      |   3 +-
 webapp/app/partials/models/model_schema.html    |  12 +-
 21 files changed, 455 insertions(+), 1068 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a2f4d320/common/src/main/java/org/apache/kylin/common/util/StringUtil.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/kylin/common/util/StringUtil.java b/common/src/main/java/org/apache/kylin/common/util/StringUtil.java
index 2d7b170..f4aed14 100644
--- a/common/src/main/java/org/apache/kylin/common/util/StringUtil.java
+++ b/common/src/main/java/org/apache/kylin/common/util/StringUtil.java
@@ -50,9 +50,11 @@ public class StringUtil {
     }
 
     public static void toUpperCaseArray(String[] source, String[] target) {
-        for (int i = 0; i < source.length; i++) {
-            if (source[i] != null) {
-                target[i] = source[i].toUpperCase();
+        if(source!=null) {
+            for (int i = 0; i < source.length; i++) {
+                if (source[i] != null) {
+                    target[i] = source[i].toUpperCase();
+                }
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a2f4d320/metadata/src/main/java/org/apache/kylin/metadata/MetadataManager.java
----------------------------------------------------------------------
diff --git a/metadata/src/main/java/org/apache/kylin/metadata/MetadataManager.java b/metadata/src/main/java/org/apache/kylin/metadata/MetadataManager.java
index 9d489e2..ea03933 100644
--- a/metadata/src/main/java/org/apache/kylin/metadata/MetadataManager.java
+++ b/metadata/src/main/java/org/apache/kylin/metadata/MetadataManager.java
@@ -27,6 +27,8 @@ import java.util.Map.Entry;
 import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.kylin.metadata.model.TableDesc;
+import org.apache.kylin.metadata.project.ProjectInstance;
+import org.apache.kylin.metadata.project.ProjectManager;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -253,7 +255,6 @@ public class MetadataManager {
         ResourceStore store = getStore();
         TableDesc t = store.getResource(path, TableDesc.class, TABLE_SERIALIZER);
         if (t == null) {
-            logger.error("Didn't load table at " + path);
             return null;
         }
         t.init();
@@ -283,7 +284,24 @@ public class MetadataManager {
     }
 
     public List<DataModelDesc> getModels() {
-        return new ArrayList<DataModelDesc>(dataModelDescMap.values());
+        return new ArrayList<>(dataModelDescMap.values());
+    }
+
+    public List<DataModelDesc> getModels(String projectName){
+        ProjectInstance projectInstance =  ProjectManager.getInstance(config).getProject(projectName);
+        HashSet<DataModelDesc> ret = new HashSet<>();
+        if (projectInstance != null) {
+            for (String modelName : projectInstance.getModels()) {
+                DataModelDesc model = getDataModelDesc(modelName);
+                if (null != model) {
+                    ret.add(model);
+                } else {
+                    logger.error("Failed to load model" + modelName);
+                }
+            }
+        }
+
+        return new ArrayList<>(ret);
     }
 
 
@@ -322,12 +340,12 @@ public class MetadataManager {
         }
     }
 
-    public DataModelDesc createDataModelDesc(DataModelDesc dataModelDesc) throws IOException {
-        String name = dataModelDesc.getName();
+    public DataModelDesc createDataModelDesc(DataModelDesc desc,String projectName,String owner) throws IOException {
+        String name = desc.getName();
         if (dataModelDescMap.containsKey(name))
             throw new IllegalArgumentException("DataModelDesc '" + name + "' already exists");
-
-        return saveDataModelDesc(dataModelDesc);
+        ProjectManager.getInstance(config).updateModelToProject(name,projectName,owner);
+        return saveDataModelDesc(desc);
     }
 
     public DataModelDesc updateDataModelDesc(DataModelDesc desc) throws IOException {

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a2f4d320/metadata/src/main/java/org/apache/kylin/metadata/project/ProjectInstance.java
----------------------------------------------------------------------
diff --git a/metadata/src/main/java/org/apache/kylin/metadata/project/ProjectInstance.java b/metadata/src/main/java/org/apache/kylin/metadata/project/ProjectInstance.java
index 096d2ac..387f735 100644
--- a/metadata/src/main/java/org/apache/kylin/metadata/project/ProjectInstance.java
+++ b/metadata/src/main/java/org/apache/kylin/metadata/project/ProjectInstance.java
@@ -68,6 +68,9 @@ public class ProjectInstance extends RootPersistentEntity {
     @JsonProperty("realizations")
     private List<RealizationEntry> realizationEntries;
 
+    @JsonProperty("models")
+    private List<String> models;
+
     public String getResourcePath() {
         return concatResourcePath(name);
     }
@@ -83,7 +86,7 @@ public class ProjectInstance extends RootPersistentEntity {
         return project.toUpperCase();
     }
 
-    public static ProjectInstance create(String name, String owner, String description, List<RealizationEntry> realizationEntries) {
+    public static ProjectInstance create(String name, String owner, String description, List<RealizationEntry> realizationEntries,List<String> models) {
         ProjectInstance projectInstance = new ProjectInstance();
 
         projectInstance.updateRandomUuid();
@@ -96,7 +99,10 @@ public class ProjectInstance extends RootPersistentEntity {
             projectInstance.setRealizationEntries(realizationEntries);
         else
             projectInstance.setRealizationEntries(Lists.<RealizationEntry> newArrayList());
-
+        if (models != null)
+            projectInstance.setModels(models);
+        else
+            projectInstance.setModels(new ArrayList<String>());
         return projectInstance;
     }
 
@@ -231,6 +237,32 @@ public class ProjectInstance extends RootPersistentEntity {
         this.realizationEntries = entries;
     }
 
+    public List<String> getModels() {
+        return models;
+    }
+
+    public boolean containsModel(String modelName) {
+        modelName = modelName.toUpperCase();
+        return models!=null&&models.contains(modelName);
+    }
+
+    public void setModels(List<String> models) { this.models = models; }
+
+    public void addModel(String modelName) {
+        modelName = modelName.toUpperCase();
+        if(this.getModels()==null){
+            this.setModels(new ArrayList<String>());
+        }
+        this.getModels().add(modelName);
+    }
+
+    public void removeModel(String modelName){
+        modelName = modelName.toUpperCase();
+        if(this.getModels()!=null) {
+            this.getModels().remove(modelName);
+        }
+    }
+
     public void init() {
         if (name == null)
             name = ProjectInstance.DEFAULT_PROJECT_NAME;

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a2f4d320/metadata/src/main/java/org/apache/kylin/metadata/project/ProjectManager.java
----------------------------------------------------------------------
diff --git a/metadata/src/main/java/org/apache/kylin/metadata/project/ProjectManager.java b/metadata/src/main/java/org/apache/kylin/metadata/project/ProjectManager.java
index 33d0867..fb2d298 100644
--- a/metadata/src/main/java/org/apache/kylin/metadata/project/ProjectManager.java
+++ b/metadata/src/main/java/org/apache/kylin/metadata/project/ProjectManager.java
@@ -164,7 +164,7 @@ public class ProjectManager {
 
         ProjectInstance currentProject = getProject(projectName);
         if (currentProject == null) {
-            currentProject = ProjectInstance.create(projectName, owner, description, null);
+            currentProject = ProjectInstance.create(projectName, owner, description, null,null);
         } else {
             throw new IllegalStateException("The project named " + projectName + "already exists");
         }
@@ -220,6 +220,36 @@ public class ProjectManager {
         }
     }
 
+    public boolean isModelInProject(String projectName, String modelName) {
+        return this.getProject(projectName).containsModel(modelName);
+    }
+
+    public ProjectInstance updateModelToProject(String modelName, String newProjectName, String owner) throws IOException {
+        removeModelFromProjects(modelName);
+
+        return addModelToProject(modelName, newProjectName, owner);
+    }
+
+    public void removeModelFromProjects(String modelName) throws IOException {
+        for (ProjectInstance projectInstance : findProjects(modelName)) {
+            projectInstance.removeModel(modelName);
+
+            saveResource(projectInstance);
+        }
+    }
+
+    private ProjectInstance addModelToProject(String modelName, String project, String user) throws IOException {
+        String newProjectName = ProjectInstance.getNormalizedProjectName(project);
+        ProjectInstance newProject = getProject(newProjectName);
+        if (newProject == null) {
+            newProject = this.createProject(newProjectName, user, "This is a project automatically added when adding model " + modelName);
+        }
+        newProject.addModel(modelName);
+        saveResource(newProject);
+
+        return newProject;
+    }
+
     public ProjectInstance moveRealizationToProject(RealizationType type, String realizationName, String newProjectName, String owner) throws IOException {
         removeRealizationsFromProjects(type, realizationName);
         return addRealizationToProject(type, realizationName, newProjectName, owner);
@@ -288,6 +318,17 @@ public class ProjectManager {
         return result;
     }
 
+    private List<ProjectInstance> findProjects(String modelName) {
+        List<ProjectInstance> projects = new ArrayList<ProjectInstance>();
+        for (ProjectInstance projectInstance : projectMap.values()) {
+            if (projectInstance.containsModel(modelName)) {
+                projects.add(projectInstance);
+            }
+        }
+
+        return projects;
+    }
+
     public List<TableDesc> listDefinedTables(String project) throws IOException {
         return l2Cache.listDefinedTables(norm(project));
     }

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a2f4d320/server/src/main/java/org/apache/kylin/rest/controller/ModelController.java
----------------------------------------------------------------------
diff --git a/server/src/main/java/org/apache/kylin/rest/controller/ModelController.java b/server/src/main/java/org/apache/kylin/rest/controller/ModelController.java
index 97a5d32..ce53474 100644
--- a/server/src/main/java/org/apache/kylin/rest/controller/ModelController.java
+++ b/server/src/main/java/org/apache/kylin/rest/controller/ModelController.java
@@ -123,7 +123,7 @@ public class ModelController extends BasicController {
 
         String descData = JsonUtil.writeValueAsIndentString(modelDesc);
         modelRequest.setModelDescData(descData);
-
+        modelRequest.setSuccessful(true);
         return modelRequest;
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a2f4d320/server/src/main/java/org/apache/kylin/rest/service/ModelService.java
----------------------------------------------------------------------
diff --git a/server/src/main/java/org/apache/kylin/rest/service/ModelService.java b/server/src/main/java/org/apache/kylin/rest/service/ModelService.java
index 093efe3..e423c37 100644
--- a/server/src/main/java/org/apache/kylin/rest/service/ModelService.java
+++ b/server/src/main/java/org/apache/kylin/rest/service/ModelService.java
@@ -19,7 +19,6 @@
 package org.apache.kylin.rest.service;
 
 
-import org.apache.kylin.job.exception.JobException;
 import org.apache.kylin.metadata.model.DataModelDesc;
 import org.apache.kylin.metadata.project.ProjectInstance;
 import org.apache.kylin.rest.constant.Constant;
@@ -29,10 +28,10 @@ import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PostFilter;
 import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.stereotype.Component;
 
 import java.io.IOException;
-import java.net.UnknownHostException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -56,9 +55,8 @@ public class ModelService extends BasicService {
         if (null == project) {
             models = getMetadataManager().getModels();
         } else {
-            //TO-DO
-//            models = listAllModels(projectName);
-            models=Collections.emptyList();
+            models = getMetadataManager().getModels(projectName);
+            project.getModels();
         }
 
         List<DataModelDesc> filterModels = new ArrayList();
@@ -97,9 +95,10 @@ public class ModelService extends BasicService {
             throw new InternalErrorException("The model named " + desc.getName() + " already exists");
         }
         DataModelDesc createdDesc = null;
-        createdDesc = getMetadataManager().createDataModelDesc(desc);
-//        ProjectInstance project = getProjectManager().getProject(projectName);
-//        accessService.inherit(createdDesc, project);
+        String owner = SecurityContextHolder.getContext().getAuthentication().getName();
+        createdDesc = getMetadataManager().createDataModelDesc(desc,projectName,owner);
+        ProjectInstance project = getProjectManager().getProject(projectName);
+        accessService.inherit(desc, project);
         return createdDesc;
     }
 
@@ -108,7 +107,8 @@ public class ModelService extends BasicService {
     public DataModelDesc updateModelAndDesc(DataModelDesc desc, String newProjectName) throws IOException {
         DataModelDesc existingModel = getMetadataManager().getDataModelDesc(desc.getName());
         if (existingModel == null) {
-            getMetadataManager().createDataModelDesc(desc);
+            String owner = SecurityContextHolder.getContext().getAuthentication().getName();
+            getMetadataManager().createDataModelDesc(desc,newProjectName,owner);
         } else {
             getMetadataManager().updateDataModelDesc(desc);
         }

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a2f4d320/server/src/main/java/org/apache/kylin/rest/service/QueryService.java
----------------------------------------------------------------------
diff --git a/server/src/main/java/org/apache/kylin/rest/service/QueryService.java b/server/src/main/java/org/apache/kylin/rest/service/QueryService.java
index 027202d..8f81d2d 100644
--- a/server/src/main/java/org/apache/kylin/rest/service/QueryService.java
+++ b/server/src/main/java/org/apache/kylin/rest/service/QueryService.java
@@ -28,16 +28,7 @@ import java.sql.SQLException;
 import java.sql.Statement;
 import java.sql.Time;
 import java.sql.Timestamp;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 
 import javax.sql.DataSource;
 
@@ -60,6 +51,7 @@ import org.apache.kylin.rest.request.SQLRequest;
 import org.apache.kylin.rest.response.SQLResponse;
 import org.apache.kylin.rest.util.QueryUtil;
 import org.apache.kylin.rest.util.Serializer;
+import org.h2.util.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.security.access.AccessDeniedException;
@@ -280,7 +272,9 @@ public class QueryService extends BasicService {
         Connection conn = null;
         ResultSet columnMeta = null;
         List<TableMeta> tableMetas = null;
-
+        if(StringUtils.isNullOrEmpty(project)){
+            return Collections.emptyList();
+        }
         try {
             DataSource dataSource = getOLAPDataSource(project);
             conn = dataSource.getConnection();

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a2f4d320/webapp/app/js/controllers/cube.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/controllers/cube.js b/webapp/app/js/controllers/cube.js
index 607706d..2765a45 100755
--- a/webapp/app/js/controllers/cube.js
+++ b/webapp/app/js/controllers/cube.js
@@ -18,12 +18,12 @@
 
 'use strict';
 
-KylinApp.controller('CubeCtrl', function ($scope, AccessService, MessageService, CubeService, TableService, CubeGraphService, UserService,SweetAlert) {
+KylinApp.controller('CubeCtrl', function ($scope, AccessService, MessageService, CubeService, TableService, GraphService, UserService,SweetAlert) {
     $scope.newAccess = null;
     $scope.state = {jsonEdit: false};
 
     $scope.buildGraph = function (cube) {
-        CubeGraphService.buildTree(cube);
+       GraphService.buildTree(cube);
     };
 
     $scope.getCubeSql = function (cube) {

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a2f4d320/webapp/app/js/controllers/cubeModel.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/controllers/cubeModel.js b/webapp/app/js/controllers/cubeModel.js
index fc2cca8..cfe0f1c 100644
--- a/webapp/app/js/controllers/cubeModel.js
+++ b/webapp/app/js/controllers/cubeModel.js
@@ -18,13 +18,13 @@
 
 'use strict';
 
-KylinApp.controller('CubeModelCtrl', function ($scope, $modal,cubeConfig,ModelService,MetaModel,SweetAlert,CubeGraphService,$log) {
+KylinApp.controller('CubeModelCtrl', function ($scope, $modal,cubeConfig,ModelService,MetaModel,SweetAlert,GraphService,$log) {
 
     //copy model for show Json in model tab list
     $scope.modelJson = angular.copy($scope.model);
 
     $scope.buildGraph = function (model) {
-        CubeGraphService.buildTree(model);
+        GraphService.buildTree(model);
     };
 
     $scope.cubeConfig = cubeConfig;

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a2f4d320/webapp/app/js/controllers/modelDimensions.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/controllers/modelDimensions.js b/webapp/app/js/controllers/modelDimensions.js
index aa197e6..c89e6a6 100644
--- a/webapp/app/js/controllers/modelDimensions.js
+++ b/webapp/app/js/controllers/modelDimensions.js
@@ -28,375 +28,45 @@ KylinApp.controller('ModelDimensionsCtrl', function ($scope, $modal,MetaModel) {
 
     // Available tables cache: 1st is the fact table, next are lookup tables.
     $scope.availableTables = [];
-
-
-    /**
-     * Helper func to get columns that dimensions based on, three cases:
-     * 1. normal dimension: column array.
-     * 2. hierarchy dimension: column array, the array index is the hierarchy level.
-     * 3. derived dimension: derived columns array.
-     * TODO new cube schema change
-     */
-    var dimCols = function (dim) {
-        var referredCols = [];
-
-        // Case 3.
-        if (dim.derived && dim.derived.length) {
-            referredCols = referredCols.concat(dim.derived);
-        }
-
-        // Case 2.
-        if (dim.hierarchy && dim.column.length) {
-            referredCols = referredCols.concat(dim.column);
-        }
-
-        // Case 1.
-        if (!dim.derived && !dim.hierarchy) {
-            referredCols.push(dim.column);
-        }
-
-        return referredCols;
-    };
+    $scope.dimensions=[];
 
     // Dump available columns plus column table name, whether is from lookup table.
     $scope.initColumns = function () {
         var factTable = $scope.model.fact_table;
 
-        // At first dump the columns of fact table.
-        var cols = $scope.getColumnsByTable(factTable);
-
-        // Initialize selected available.
-        var factAvailable = {};
-        var factSelectAvailable = {};
-
-        for (var i = 0; i < cols.length; i++) {
-            cols[i].table = factTable;
-            cols[i].isLookup = false;
-
-            factAvailable[cols[i].name] = cols[i];
-
-            // Default not selected and not disabled.
-            factSelectAvailable[cols[i].name] = {selected: false, disabled: false};
-        }
-
-        $scope.availableColumns[factTable] = factAvailable;
-        $scope.selectedColumns[factTable] = factSelectAvailable;
-        $scope.availableTables.push(factTable);
-
-        // Then dump each lookup tables.
+        $scope.availableTables.push($scope.model.fact_table);
         var lookups = $scope.model.lookups;
-
         for (var j = 0; j < lookups.length; j++) {
-            var cols2 = $scope.getColumnsByTable(lookups[j].table);
-
-            // Initialize selected available.
-            var lookupAvailable = {};
-            var lookupSelectAvailable = {};
-
-            for (var k = 0; k < cols2.length; k++) {
-                cols2[k].table = lookups[j].table;
-                cols2[k].isLookup = true;
-
-                lookupAvailable[cols2[k].name] = cols2[k];
-
-                // Default not selected and not disabled.
-                lookupSelectAvailable[cols2[k].name] = {selected: false, disabled: false};
-            }
-
-            $scope.availableColumns[lookups[j].table] = lookupAvailable;
-            $scope.selectedColumns[lookups[j].table] = lookupSelectAvailable;
             $scope.availableTables.push(lookups[j].table);
         }
-    };
 
-    // Check column status: selected or disabled based on current cube dimensions.
-    $scope.initColumnStatus = function () {
-        angular.forEach($scope.model.dimensions, function (dim) {
-            var cols = dimCols(dim);
-
-            angular.forEach(cols, function (colName) {
-                $scope.selectedColumns[dim.table][colName] = {selected: true, disabled: true};
-            });
-        });
-    };
+//        init dimension only when dimen
+//        if(!$scope.model.dimensions.length){
 
-    // Initialize data for columns widget in auto-gen when add/edit cube.
-    if ($scope.state.mode == 'edit') {
-        $scope.initColumns();
-    }
+            for(var i = 0;i<$scope.availableTables.length;i++){
+                var tableInUse = _.some($scope.model.dimensions,function(item){
+                    return item.table == $scope.availableTables[i];
+                });
 
-    // Initialize params for add/edit dimension.
-    $scope.dimState = {
-        editing: false,
-        editingIndex: -1,
-        filter: ''
-    };
-
-    // Init the dimension, dimension name default as the column key. TODO new cube schema change.
-    var Dimension = function (table, selectedCols, dimType) {
-        var origin = {name: '', table: table,hierarchy:false,derived:null,column:null};
-
-        switch (dimType) {
-            case 'normal':
-                // Default name as 1st column name.
-                if (table && selectedCols.length) {
-                    origin.name = table + '.' + selectedCols[0];
-                }
-
-                origin.column = selectedCols;
-                break;
-
-            case 'derived':
-                if (table && selectedCols.length) {
-                    origin.name = table + '_derived';
-                }
-
-                origin.derived = selectedCols;
-                break;
-
-            case 'hierarchy':
-                if (table && selectedCols.length) {
-                    origin.name = table + '_hierarchy';
+                if(!tableInUse){
+                    $scope.model.dimensions.push(new Dimension($scope.availableTables[i]));
                 }
-
-                origin.hierarchy = true;
-                origin.column = selectedCols;
-                break;
-        }
-
-        return origin;
-    };
-
-    // Since old schema may be both derived and hierarchy. TODO new cube schema change.
-    $scope.getDimType = function (dim) {
-        var types = [];
-
-        if (dim.derived && dim.derived.length) {
-            types.push('derived');
-        }
-
-        if (dim.hierarchy && dim.column.length) {
-            types.push('hierarchy');
-        }
-
-        if (!types.length) {
-            types.push('normal');
-        }
-
-        return types;
-    };
-
-    var dimList = $scope.model.dimensions;
-
-    // Open add/edit dimension modal.
-    $scope.openDimModal = function (dimType) {
-        var modalInstance = $modal.open({
-            templateUrl: 'addEditDimension.html',
-            controller: cubeDimModalCtrl,
-            backdrop: 'static',
-            scope: $scope,
-            resolve: {
-                dimType: function () {
-                    // For old schema compatibility, convert into array here. TODO new cube schema change.
-                    return angular.isArray(dimType) ? dimType : [dimType];
-                }
-            }
-        });
-
-        modalInstance.result.then(function () {
-            if (!$scope.dimState.editing) {
-                $scope.doneAddDim();
-            } else {
-                $scope.doneEditDim();
             }
+//        }
 
-        }, function () {
-            $scope.cancelDim();
-        });
-    };
-
-    // Controller for cube dimension add/edit modal.
-    var cubeDimModalCtrl = function ($scope, $modalInstance, dimType) {
-        $scope.dimType = dimType;
-
-        $scope.ok = function () {
-            $modalInstance.close();
-        };
-
-        $scope.cancel = function () {
-            $modalInstance.dismiss('cancel');
-        };
-    };
-
-    $scope.addDim = function (dimType) {
-        $scope.newDimension = Dimension('', [], dimType);
-
-        $scope.openDimModal(dimType);
-    };
-
-    $scope.editDim = function (dim) {
-        $scope.dimState.editingIndex = dimList.indexOf(dim);
-        $scope.dimState.editing = true;
-
-        // Make a copy of model will be editing.
-        $scope.newDimension = angular.copy(dim);
-
-        $scope.openDimModal($scope.getDimType(dim));
-    };
-
-    $scope.doneAddDim = function () {
-        // Push new dimension which bound user input data.
-        dimList.push(angular.copy($scope.newDimension));
-
-        $scope.resetParams();
-    };
-
-    $scope.doneEditDim = function () {
-        // Copy edited model to destination model.
-        angular.copy($scope.newDimension, dimList[$scope.dimState.editingIndex]);
-
-        $scope.resetParams();
-    };
-
-    $scope.cancelDim = function () {
-        $scope.resetParams();
-    };
-
-    $scope.removeDim = function (dim) {
-        dimList.splice(dimList.indexOf(dim), 1);
-    };
-
-    $scope.resetParams = function () {
-        $scope.dimState.editing = false;
-        $scope.dimState.editingIndex = -1;
-
-        $scope.newDimension = {};
-    };
-
-    // Open auto-gen dimension modal.
-    $scope.openAutoGenModal = function (dimType) {
-        // Init columns status.
-        $scope.initColumnStatus();
-
-        var modalInstance = $modal.open({
-            templateUrl: 'autoGenDimension.html',
-            controller: cubeAutoGenDimModalCtrl,
-            backdrop: 'static',
-            scope: $scope
-        });
-
-        modalInstance.result.then(function () {
-            $scope.autoGenDims();
-        }, function () {
-            $scope.resetGenDims();
-        });
-    };
-
-    // Controller for cube dimension auto-gen modal.
-    var cubeAutoGenDimModalCtrl = function ($scope, $modalInstance) {
-        $scope.ok = function () {
-            $modalInstance.close();
-        };
-
-        $scope.cancel = function () {
-            $modalInstance.dismiss('cancel');
-        };
-    };
-
-    // Helper func to get the selected status in auto gen.
-    $scope.getSelectedCols = function () {
-        var selectedCols = {};
-
-        angular.forEach($scope.selectedColumns, function (value, table) {
-            angular.forEach(value, function (status, colName) {
-                if (status.selected && !status.disabled) {
-                    if (!selectedCols[table]) {
-                        selectedCols[table] = [];
-                    }
-
-                    selectedCols[table].push(colName);
-                }
-            });
-        });
-
-        return selectedCols;
-    };
-
-    // Auto generate dimensions.
-    $scope.autoGenDims = function () {
-        var selectedCols = $scope.getSelectedCols();
-
-        angular.forEach(selectedCols, function (cols, table) {
-            if ($scope.model.fact_table == table) {
-                // Fact table: for each selected column, create one normal dimension.
-                for (var i = 0; i < cols.length; i++) {
-                    dimList.push(Dimension(table, [cols[i]], 'normal'));
-                }
-            } else {
-                // Per lookup table, create one derived dimension for all its selected columns;
-                if (cols.length) {
-                    dimList.push(Dimension(table, cols, 'derived'));
-                }
-            }
-        });
-    };
+        // At first dump the columns of fact table.
+//        var cols = $scope.getColumnsByTable(factTable);
 
-    // Just reset the selected status of columns.
-    $scope.resetGenDims = function () {
-        var selectedCols = $scope.getSelectedCols();
 
-        angular.forEach(selectedCols, function (cols, table) {
-            for (var i = 0; i < cols.length; i++) {
-                $scope.selectedColumns[table][cols[i]].selected = false;
-            }
-        });
     };
 
-    // Check whether there is column conflicts.
-    $scope.dimConflicts = [];
-
-    $scope.$watch('cubeMetaFrame.dimensions', function (newVal, oldVal) {
-        if (!newVal || !newVal.length) {
-            return;
-        }
-
-        var referredCols = {};
-
-        angular.forEach(newVal, function (curDim) {
-            var table = curDim.table;
-            var cols = dimCols(curDim);
-
-            for (var i = 0; i < cols.length; i++) {
-                var key = table + '.' + cols[i];
-
-                if (!referredCols[key]) {
-                    referredCols[key] = [];
-                }
-
-                referredCols[key].push({id: curDim.id, name: curDim.name});
-            }
-        });
-
-        var conflicts = [];
-
-        angular.forEach(referredCols, function (dims, key) {
-            if (dims.length > 1) {
-                // More than 1 dimensions has referred this column.
-                var colInfo = key.split('.');
-                conflicts.push({table: colInfo[0], column: colInfo[1], dims: dims});
-            }
-        });
-
-        $scope.dimConflicts = conflicts;
-    }, true);
-
-
+    var Dimension = function(table){
+        this.table = table;
+        this.columns = [];
+    }
 
+    // Initialize data for columns widget in auto-gen when add/edit cube.
     if ($scope.state.mode == 'edit') {
-        $scope.$on('$destroy', function () {
-           // $scope.dimensionsAdapter();
-            // Emit dimensions edit event in order to re-generate row key.
-            $scope.$emit('DimensionsEdited');
-        });
-    }
+        $scope.initColumns();
+    };
 });

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a2f4d320/webapp/app/js/controllers/modelEdit.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/controllers/modelEdit.js b/webapp/app/js/controllers/modelEdit.js
index 2741d2c..38290f7 100644
--- a/webapp/app/js/controllers/modelEdit.js
+++ b/webapp/app/js/controllers/modelEdit.js
@@ -19,8 +19,7 @@
 'use strict';
 
 
-KylinApp.controller('ModelEditCtrl', function ($scope, $q, $routeParams, $location, $templateCache, $interpolate, MessageService, TableService, CubeDescService, CubeService, loadingRequest, SweetAlert,$log,cubeConfig,CubeDescModel,ModelDescService,MetaModel,TableModel) {
-    $scope.cubeConfig = cubeConfig;
+KylinApp.controller('ModelEditCtrl', function ($scope, $q, $routeParams, $location, $templateCache, $interpolate, MessageService, TableService, CubeDescService, ModelService, loadingRequest, SweetAlert,$log,cubeConfig,CubeDescModel,ModelDescService,MetaModel,TableModel,ProjectService,ProjectModel) {
     //add or edit ?
     var absUrl = $location.absUrl();
     $scope.modelMode = absUrl.indexOf("/models/add")!=-1?'addNewModel':absUrl.indexOf("/models/edit")!=-1?'editExistModel':'default';
@@ -57,12 +56,16 @@ KylinApp.controller('ModelEditCtrl', function ($scope, $q, $routeParams, $locati
 
     // ~ Define data
     $scope.state = {
-        "modelSchema": ""
+        "modelSchema": "",
+        mode:'edit',
+        modelName: $scope.routeParams.modelName,
+        project:$scope.projectModel.selectedProject
     };
 
     // ~ init
     if ($scope.isEdit = !!$routeParams.modelName) {
-        ModelDescService.get({model_name: $routeParams.modelName}, function (model) {
+        var modelName = $routeParams.modelName;
+        ModelDescService.get({model_name: modelName}, function (model) {
                     if (model) {
                         $scope.model = model;
                         //use
@@ -74,19 +77,43 @@ KylinApp.controller('ModelEditCtrl', function ($scope, $q, $routeParams, $locati
                         }
                     }
                 });
+        //init project
+            ProjectService.list({}, function (projects) {
+                $scope.projects = projects;
+                if (modelName) {
+                    var projName = null;
+                    if(ProjectModel.getSelectedProject()){
+                        projName=ProjectModel.getSelectedProject();
+                    }else{
+                        angular.forEach($scope.projects, function (project, index) {
+                            angular.forEach(project.models, function (unit, index) {
+                                if (!projName && unit === modelName) {
+                                    projName = project.name;
+                                }
+                            });
+                        });
+                    }
 
-    } else {
-        $scope.model = MetaModel.createNew();;
-    }
+                    if(!ProjectModel.getSelectedProject()){
+                        ProjectModel.setSelectedProject(projName);
+                        TableModel.aceSrcTbLoaded();
+                    }
 
-    // ~ public methods
-    $scope.aceChanged = function () {
-    };
+                    $scope.state.project = projName;
+                }
+
+                angular.forEach($scope.projects, function (project, index) {
+                    $scope.listAccess(project, 'ProjectInstance');
+                });
+            });
 
-    $scope.aceLoaded = function(){
-    };
 
-    $scope.prepareCube = function () {
+    } else {
+        MetaModel.initModel();
+        $scope.model = MetaModel.getMetaModel();
+    }
+
+    $scope.prepareModel = function () {
         // generate column family
 
         if ($scope.model.partition_desc.partition_date_column&&($scope.model.partition_desc.partition_date_start|$scope.model.partition_desc.partition_date_start==0)) {
@@ -102,22 +129,22 @@ KylinApp.controller('ModelEditCtrl', function ($scope, $q, $routeParams, $locati
 
         }
         $scope.state.modelSchema = angular.toJson($scope.model, true);
-        $scope.state.project = $scope.projectModel.selectedProject;
+//        $scope.state.project = $scope.projectModel.selectedProject;
 
     };
 
-    $scope.cubeResultTmpl = function (notification) {
+    $scope.modelResultTmpl = function (notification) {
         // Get the static notification template.
-        var tmpl = notification.type == 'success' ? 'cubeResultSuccess.html' : 'cubeResultError.html';
+        var tmpl = notification.type == 'success' ? 'modelResultSuccess.html' : 'modelResultError.html';
         return $interpolate($templateCache.get(tmpl))(notification);
     };
 
     $scope.saveModel = function (design_form) {
 
         try {
-            angular.fromJson($scope.state.cubeSchema);
+            angular.fromJson($scope.state.modelSchema);
         } catch (e) {
-            SweetAlert.swal('Oops...', 'Invalid cube json format..', 'error');
+            SweetAlert.swal('Oops...', 'Invalid model json format..', 'error');
             return;
         }
 
@@ -134,10 +161,10 @@ KylinApp.controller('ModelEditCtrl', function ($scope, $q, $routeParams, $locati
                 loadingRequest.show();
 
                 if ($scope.isEdit) {
-                    CubeService.update({}, {modelDescData:$scope.state.modelSchema, modelName: $routeParams.modelName, project: $scope.state.project}, function (request) {
+                    ModelService.update({}, {modelDescData:$scope.state.modelSchema, modelName: $routeParams.modelName, project: $scope.state.project}, function (request) {
                         if (request.successful) {
                             $scope.state.modelSchema = request.modelSchema;
-                            MessageService.sendMsg($scope.cubeResultTmpl({'text':'Updated the cube successfully.',type:'success'}), 'success', {}, true, 'top_center');
+                            MessageService.sendMsg($scope.modelResultTmpl({'text':'Updated the model successfully.',type:'success'}), 'success', {}, true, 'top_center');
 
                             if (design_form) {
                                 design_form.$invalid = true;
@@ -146,7 +173,7 @@ KylinApp.controller('ModelEditCtrl', function ($scope, $q, $routeParams, $locati
                             $scope.saveModelRollBack();
                                 var message =request.message;
                                 var msg = !!(message) ? message : 'Failed to take action.';
-                                MessageService.sendMsg($scope.cubeResultTmpl({'text':msg,'schema':$scope.state.modelSchema}), 'error', {}, true, 'top_center');
+                                MessageService.sendMsg($scope.modelResultTmpl({'text':msg,'schema':$scope.state.modelSchema}), 'error', {}, true, 'top_center');
                         }
                         //end loading
                         loadingRequest.hide();
@@ -156,23 +183,23 @@ KylinApp.controller('ModelEditCtrl', function ($scope, $q, $routeParams, $locati
                         if(e.data&& e.data.exception){
                             var message =e.data.exception;
                             var msg = !!(message) ? message : 'Failed to take action.';
-                            MessageService.sendMsg($scope.cubeResultTmpl({'text':msg,'schema':$scope.state.modelSchema}), 'error', {}, true, 'top_center');
+                            MessageService.sendMsg($scope.modelResultTmpl({'text':msg,'schema':$scope.state.modelSchema}), 'error', {}, true, 'top_center');
                         } else {
-                            MessageService.sendMsg($scope.cubeResultTmpl({'text':'Failed to take action.','schema':$scope.state.modelSchema}), 'error', {}, true, 'top_center');
+                            MessageService.sendMsg($scope.modelResultTmpl({'text':'Failed to take action.','schema':$scope.state.modelSchema}), 'error', {}, true, 'top_center');
                         }
                         loadingRequest.hide();
                     });
                 } else {
-                    CubeService.save({}, {cubeDescData: $scope.state.cubeSchema,modelDescData:$scope.state.modelSchema, project: $scope.state.project}, function (request) {
+                    ModelService.save({}, {modelDescData:$scope.state.modelSchema, project: $scope.state.project}, function (request) {
                         if(request.successful) {
                             $scope.state.modelSchema = request.modelSchema;
 
-                            MessageService.sendMsg($scope.cubeResultTmpl({'text':'Created the cube successfully.',type:'success'}), 'success', {}, true, 'top_center');
+                            MessageService.sendMsg($scope.modelResultTmpl({'text':'Created the model successfully.',type:'success'}), 'success', {}, true, 'top_center');
                         } else {
                             $scope.saveModelRollBack();
                             var message =request.message;
                             var msg = !!(message) ? message : 'Failed to take action.';
-                            MessageService.sendMsg($scope.cubeResultTmpl({'text':msg,'schema':$scope.state.modelSchema}), 'error', {}, true, 'top_center');
+                            MessageService.sendMsg($scope.modelResultTmpl({'text':msg,'schema':$scope.state.modelSchema}), 'error', {}, true, 'top_center');
                         }
 
                         //end loading
@@ -183,9 +210,9 @@ KylinApp.controller('ModelEditCtrl', function ($scope, $q, $routeParams, $locati
                         if (e.data && e.data.exception) {
                             var message =e.data.exception;
                             var msg = !!(message) ? message : 'Failed to take action.';
-                            MessageService.sendMsg($scope.cubeResultTmpl({'text':msg,'schema':$scope.state.modelSchema}), 'error', {}, true, 'top_center');
+                            MessageService.sendMsg($scope.modelResultTmpl({'text':msg,'schema':$scope.state.modelSchema}), 'error', {}, true, 'top_center');
                         } else {
-                            MessageService.sendMsg($scope.cubeResultTmpl({'text':"Failed to take action.",'schema':$scope.state.modelSchema}), 'error', {}, true, 'top_center');
+                            MessageService.sendMsg($scope.modelResultTmpl({'text':"Failed to take action.",'schema':$scope.state.modelSchema}), 'error', {}, true, 'top_center');
                         }
                         //end loading
                         loadingRequest.hide();
@@ -207,6 +234,10 @@ KylinApp.controller('ModelEditCtrl', function ($scope, $q, $routeParams, $locati
         }
     };
 
+    $scope.removeTableDimensions = function(tableIndex){
+        $scope.model.dimensions.splice(tableIndex,1);
+    }
+
     $scope.$watch('projectModel.selectedProject', function (newValue, oldValue) {
         if(!newValue){
             return;

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a2f4d320/webapp/app/js/controllers/modelSchema.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/controllers/modelSchema.js b/webapp/app/js/controllers/modelSchema.js
index 112507e..198a9a3 100644
--- a/webapp/app/js/controllers/modelSchema.js
+++ b/webapp/app/js/controllers/modelSchema.js
@@ -32,7 +32,7 @@ KylinApp.controller('ModelSchemaCtrl', function ($scope, QueryService, UserServi
         {title: 'Data Model', src: 'partials/modelDesigner/data_model.html', isComplete: false},
         {title: 'Dimensions', src: 'partials/modelDesigner/model_dimensions.html', isComplete: false},
         {title: 'Measures', src: 'partials/modelDesigner/model_measures.html', isComplete: false},
-        {title: 'Refresh Setting', src: 'partials/modelDesigner/incremental.html', isComplete: false}
+        {title: 'Settings', src: 'partials/modelDesigner/conditions_settings.html', isComplete: false}
     ];
 
     $scope.curStep = $scope.wizardSteps[0];
@@ -58,70 +58,6 @@ KylinApp.controller('ModelSchemaCtrl', function ($scope, QueryService, UserServi
         return $scope.userService.hasRole('ROLE_ADMIN') || $scope.hasPermission(project,$scope.permissions.ADMINISTRATION.mask);
     };
 
-    $scope.addNewMeasure = function (measure) {
-        $scope.newMeasure = (!!measure)? measure:CubeDescModel.createMeasure();
-    };
-
-    $scope.clearNewMeasure = function () {
-        $scope.newMeasure = null;
-    };
-
-    $scope.saveNewMeasure = function () {
-        if ($scope.cubeMetaFrame.measures.indexOf($scope.newMeasure) === -1) {
-            $scope.cubeMetaFrame.measures.push($scope.newMeasure);
-        }
-        $scope.newMeasure = null;
-    };
-
-    //map right return type for param
-    $scope.measureReturnTypeUpdate = function(){
-        if($scope.newMeasure.function.expression!=="COUNT_DISTINCT"){
-
-            var column = $scope.newMeasure.function.parameter.value;
-            var colType = $scope.getColumnType(column, $scope.metaModel.model.fact_table); // $scope.getColumnType defined in cubeEdit.js
-
-
-            switch($scope.newMeasure.function.expression){
-                case "SUM":
-                    if(colType==="smallint"||colType==="int"||colType==="bigint"){
-                        $scope.newMeasure.function.returntype= 'bigint';
-                    }else{
-                        $scope.newMeasure.function.returntype= 'decimal';
-                    }
-                    break;
-                case "MIN":
-                case "MAX":
-                    $scope.newMeasure.function.returntype = colType;
-                    break;
-                case "COUNT":
-                    $scope.newMeasure.function.returntype = "bigint";
-                    break;
-                default:
-                    $scope.newMeasure.function.returntype = "";
-                    break;
-            }
-        }
-    }
-
-    $scope.addNewRowkeyColumn = function () {
-        $scope.cubeMetaFrame.rowkey.rowkey_columns.push({
-            "column": "",
-            "length": 0,
-            "dictionary": "true",
-            "mandatory": false
-        });
-    };
-
-    $scope.addNewAggregationGroup = function () {
-        $scope.cubeMetaFrame.rowkey.aggregation_groups.push([]);
-    };
-
-    $scope.refreshAggregationGroup = function (list, index, aggregation_groups) {
-        if (aggregation_groups) {
-            list[index] = aggregation_groups;
-        }
-    };
-
     $scope.removeElement = function (arr, element) {
         var index = arr.indexOf(element);
         if (index > -1) {

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a2f4d320/webapp/app/js/controllers/projectMeta.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/controllers/projectMeta.js b/webapp/app/js/controllers/projectMeta.js
index d1ba98a..aa35d03 100644
--- a/webapp/app/js/controllers/projectMeta.js
+++ b/webapp/app/js/controllers/projectMeta.js
@@ -78,9 +78,7 @@ KylinApp
 
 
         $scope.$watch('projectModel.selectedProject', function (newValue, oldValue) {
-            if(newValue){
                 $scope.projectMetaLoad();
-            }
         });
 
         $scope.trimType = function(typeName){

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a2f4d320/webapp/app/js/model/metaModel.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/model/metaModel.js b/webapp/app/js/model/metaModel.js
index 74714d9..28e9f69 100644
--- a/webapp/app/js/model/metaModel.js
+++ b/webapp/app/js/model/metaModel.js
@@ -21,58 +21,74 @@
  */
 KylinApp.service('MetaModel',function(){
 
-    var _this = this;
     //data model when edit model
-    this.name=null;
-    this.fact_table=null;
-    this.lookups=[];
-    this.filter_condition=null;
-    this.capacity=null;
-    this.dimensions=[];
-    this.metrics=[];
-    this.partition_desc = {
-        "partition_date_column" : '',
-        "partition_date_start" : 0,
-        "partition_type" : 'APPEND'
+    this.model={
+        name: null,
+        fact_table: null,
+        lookups: [],
+        filter_condition:null,
+        capacity:null,
+        dimensions:[],
+        metrics:[],
+        "partition_desc" : {
+            "partition_date_column" : '',
+            "partition_date_start" : 0,
+            "partition_type" : 'APPEND'
+        },
+        last_modified:0
     };
-    this.last_modified=0;
+
 
     this.setMetaModel =function(model){
-        _this.name = model.name;
-        _this.fact_table = model.fact_table;
-        _this.lookups =model.lookups;
-        _this.filter_condition = model.filter_condition;
-        _this.capacity = model.capacity;
-        _this.partition_desc = model.partition_desc;
-        _this.last_modified = model.last_modified;
-        _this.metrics  = model.metrics;
-        _this.dimensions = model.dimensions;
+        var _model = {};
+        _model.name = model.name;
+        _model.fact_table = model.fact_table;
+        _model.lookups =model.lookups;
+        _model.filter_condition = model.filter_condition;
+        _model.capacity = model.capacity;
+        _model.dimensions = model.dimensions;
+        _model.metrics = model.metrics;
+        _model.partition_desc = model.partition_desc;
+        _model.last_modified = model.last_modified;
+        this.model = _model;
+    };
+
+    this.initModel = function(){
+        this.model = this.createNew();
+    }
+
+    this.getMetaModel = function(){
+        return this.model;
+    };
+
+    this.setFactTable = function(fact_table) {
+        this.model.fact_table =fact_table;
     };
 
 
     this.converDateToGMT = function(){
-        if(this.partition_desc&&this.partition_desc.partition_date_start){
-            this.partition_desc.partition_date_start+=new Date().getTimezoneOffset()*60000;
+        if(this.model.partition_desc&&this.model.partition_desc.partition_date_start){
+            this.model.partition_desc.partition_date_start+=new Date().getTimezoneOffset()*60000;
         }
     };
     //
     this.createNew = function () {
-            var metaModel = {
-                name: '',
-                fact_table: '',
-                lookups: [],
-                filter_condition:'',
-                capacity:'MEDIUM',
-                dimensions:[],
-                metrics:[],
-                "partition_desc" : {
-                    "partition_date_column" : '',
-                    "partition_date_start" : 0,
-                    "partition_type" : 'APPEND'
-                },
-                last_modified:0
-            };
+        var metaModel = {
+            name: '',
+            fact_table: '',
+            lookups: [],
+            filter_condition:'',
+            capacity:'MEDIUM',
+            dimensions:[],
+            metrics:[],
+            "partition_desc" : {
+                "partition_date_column" : '',
+                "partition_date_start" : 0,
+                "partition_type" : 'APPEND'
+            },
+            last_modified:0
+        };
 
-            return metaModel;
-        }
-})
+        return metaModel;
+    }
+})
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a2f4d320/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
new file mode 100644
index 0000000..7994fa1
--- /dev/null
+++ b/webapp/app/partials/modelDesigner/conditions_settings.html
@@ -0,0 +1,127 @@
+<!--
+* 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.
+-->
+
+<div ng-controller="CubeRefreshCtrl">
+<div class="row">
+    <div class="col-xs-8">
+
+        <!--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="model.partition_desc.partition_type"
+                        ng-options="ddt as ddt for ddt in cubeConfig.cubePartitionTypes">
+                        <option value=""></option>
+                    </select>
+                    <span ng-if="state.mode=='view'">{{model.partition_desc.partition_type}}</span>
+                </div>
+            </div>
+        </div>
+
+        <!--Partition Column-->
+        <div class="form-group">
+            <div class="row">
+                <label class="control-label col-xs-12 col-sm-3 no-padding-right font-color-default"><b>Partition Date Column</b></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-required="model.partition_desc.partition_date_start"
+                            ng-model="model.partition_desc.partition_date_column"
+                            ng-if="state.mode=='edit'"
+                            data-placement=""
+                            ng-options="model.fact_table+'.'+columns.name as model.fact_table+'.'+columns.name for columns in getPartitonColumns(model.fact_table)" >
+                        <option value="">--Select Partition Column--</option>
+                    </select>
+                    <p class="text-red"  ng-if="state.mode=='edit'">(data format in column should be 'YYYY-MM-DD')</p>
+                    <span ng-if="state.mode=='view'">
+                        {{!!(model.partition_desc.partition_date_column)?model.partition_desc.partition_date_column: ''}}</span>
+                </div>
+            </div>
+        </div>
+
+        <!--Data Range Start-->
+        <div class="form-group">
+            <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="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'&&model.partition_desc.partition_date_column">{{(model.partition_desc.partition_date_start)|reverseToGMT0 }}</span>
+                </div>
+            </div>
+        </div>
+
+        <!--Filter Condition-->
+        <div class="form-group">
+            <div class="row">
+                <label class="control-label col-xs-12 col-sm-3 no-padding-right font-color-default"><b>Filter</b></label>
+                <div class="col-xs-12 col-sm-6">
+
+                    <!--edit mode-->
+                    <div class="form-group" ng-if="state.mode=='edit'"
+                         style="font-family:'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro'">
+                        <label for="filter_condition"
+                               style="color: #930f80;"><b>WHERE</b></label>
+                        <textarea id="filter_condition" type="text"
+                                  style="height:150px"
+                                  class="form-control box-default"
+                                  placeholder="Please input WHERE clause without typing 'WHERE'"
+                                  ng-model="model.filter_condition">
+                        </textarea>
+                    </div>
+
+                    <!--view mode-->
+                    <div class="form-group row" ng-if="state.mode=='view'"
+                         style="font-family:'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro'">
+                        <div ng-if="model.filter_condition" class="col-md-11 col-md-offset-1">
+                            <p style="color: #930f80;"><b>WHERE</b></p>
+                            <span>{{model.filter_condition}}</span>
+                        </div>
+                    </div>
+
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <div class="col-xs-4">
+        <div class="box box-solid">
+            <div class="box-header">
+                <h4 class="box-title">Tips</h4>
+            </div>
+            <div class="box-body">
+                <div class="row">
+                    <div class="col-xs-12">
+                        <ol class="text-info">
+                            <li>Not required,leave as default if this cube always need full build</li>
+                            <li>Partition column will select 'date' or 'string' type column from fact table</li>
+                            <li>If column selected,please indicate start date to just pull certain data from source</li>
+                        </ol>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+</div>

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a2f4d320/webapp/app/partials/modelDesigner/incremental.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/modelDesigner/incremental.html b/webapp/app/partials/modelDesigner/incremental.html
deleted file mode 100644
index 3238b1c..0000000
--- a/webapp/app/partials/modelDesigner/incremental.html
+++ /dev/null
@@ -1,94 +0,0 @@
-<!--
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements.  See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership.  The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License.  You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
--->
-
-<div ng-controller="ModelRefreshCtrl">
-<div class="row">
-    <div class="col-xs-8">
-
-        <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="model.partition_desc.partition_type"
-                        ng-options="ddt as ddt for ddt in cubeConfig.cubePartitionTypes">
-                        <option value=""></option>
-                    </select>
-                    <span ng-if="state.mode=='view'">{{model.partition_desc.partition_type}}</span>
-                </div>
-            </div>
-        </div>
-
-        <!--Partition Column-->
-        <div class="form-group">
-            <div class="row">
-                <label class="control-label col-xs-12 col-sm-3 no-padding-right font-color-default"><b>Partition Date Column</b></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-required="model.partition_desc.partition_date_start"
-                            ng-model="model.partition_desc.partition_date_column"
-                            ng-if="state.mode=='edit'"
-                            data-placement=""
-                            ng-options="model.fact_table+'.'+columns.name as model.fact_table+'.'+columns.name for columns in getPartitonColumns(model.fact_table)" >
-                        <option value="">--Select Partition Column--</option>
-                    </select>
-                    <p class="text-red"  ng-if="state.mode=='edit'">(data format in column should be 'YYYY-MM-DD')</p>
-                    <span ng-if="state.mode=='view'">
-                        {{!!(model.partition_desc.partition_date_column)?model.partition_desc.partition_date_column: ''}}</span>
-                </div>
-            </div>
-        </div>
-
-        <!--Data Range Start-->
-        <div class="form-group">
-            <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="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'&&model.partition_desc.partition_date_column">{{(model.partition_desc.partition_date_start)|reverseToGMT0 }}</span>
-                </div>
-            </div>
-        </div>
-    </div>
-
-    <div class="col-xs-4">
-        <div class="box box-solid">
-            <div class="box-header">
-                <h4 class="box-title">Tips</h4>
-            </div>
-            <div class="box-body">
-                <div class="row">
-                    <div class="col-xs-12">
-                        <ol class="text-info">
-                            <li>Not required,leave as default if cube always need full build</li>
-                            <li>Partition column will select 'date' or 'string' type column from fact table</li>
-                            <li>If column selected,please indicate start date to just pull certain data from source</li>
-                        </ol>
-                    </div>
-                </div>
-            </div>
-        </div>
-    </div>
-</div>
-</div>

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a2f4d320/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 8be67d1..cd529d9 100644
--- a/webapp/app/partials/modelDesigner/model_dimensions.html
+++ b/webapp/app/partials/modelDesigner/model_dimensions.html
@@ -20,24 +20,8 @@
 
 <!-- Dimensions Summary -->
 <div class="dataTables_wrapper form-inline no-footer">
-    <div class="row">
-        <div class="col-xs-6" ng-if="state.mode=='edit'">
-            <div class="btn-group">
-                <button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown">
-                    <i class="fa fa-plus"></i> Add Dimension <span class="ace-icon fa fa-caret-down icon-on-right"></span>
-                </button>
-                <ul class="dropdown-menu" role="menu">
-                    <li><a ng-click="addDim('normal')">Normal</a></li>
-                    <li><a ng-click="addDim('hierarchy')">Hierarchy</a></li>
-                    <li><a ng-click="addDim('derived')">Derived</a></li>
-                </ul>
-            </div>
-            <button type="button" class="btn btn-default" ng-disabled="!model.fact_table.length"
-                    ng-click="openAutoGenModal()">
-                <i class="fa fa-building-o"></i> Auto Generator
-            </button>
-        </div>
-        <div class="col-xs-6" ng-if="state.mode!='edit'">
+    <div class="row"  ng-if="state.mode=='view'">
+        <div class="col-xs-6">
             <b>Dimensions</b>
         </div>
         <div class="col-xs-6">
@@ -47,15 +31,14 @@
             </span>
         </div>
     </div>
-    <table class="table table-striped table-hover" ng-if="model.dimensions.length > 0">
+
+     <!-- VIEW MODE -->
+    <table class="table table-striped table-hover" ng-if="state.mode=='view'&&model.dimensions.length > 0">
         <thead>
             <tr>
                 <th>ID</th>
-                <th>Name</th>
                 <th>Table Name</th>
-                <th>Type</th>
-                <th></th>
-                <th ng-if="state.mode=='edit'">Actions</th>
+                <th>Columns</th>
             </tr>
         </thead>
         <tbody class="cube-dimension">
@@ -66,289 +49,55 @@
                 </td>
                 <!--Name -->
                 <td>
-                    <span>{{dimension.name}}</span>
+                    <span>{{dimension.table}}</span>
                 </td>
                 <!--Table Name -->
                 <td>
-                    <span tooltip="{{dimension.table == model.fact_table ? 'Fact Table' : 'Lookup Table'}}">{{dimension.table}}</span>
+                    <span>{{dimension.columns}}</span>
                 </td>
-                <!--Type-->
-                <td>
-                    <span class="label label-primary" ng-repeat="t in getDimType(dimension)">{{t}}</span>
+            </tr>
+        </tbody>
+    </table>
+
+    <div  ng-if="state.mode=='edit'" class="form-group model-dimension-edit" style="width: 100%">
+        <h4 style="margin-left:42px">Dimensions</h4>
+        <table style="margin-left:42px; width:92%"
+               ng-if="model.dimensions.length > 0"
+               class="table table-hover list">
+            <tr class="row">
+                <th class="col-xs-1">ID</th>
+                <th class="col-xs-1">Table Name</th>
+                <th class="col-xs-9">Columns</th>
+                <th class="col-xs-1"></th>
+            </tr>
+
+            <tr ng-repeat="dimension in model.dimensions" class="row">
+                <td class="col-xs-1">
+                    <!-- ID -->
+                    <b>{{($index + 1)}}</b>
                 </td>
-                <!--Columns-->
-                <td  style="word-wrap:break-word;word-break:break-all;">
-                    <div ng-repeat="t in getDimType(dimension)">
-                        <div ng-switch="t">
-                            <dl class="dl-horizontal" ng-switch-when="hierarchy">
-                                <dt>Hierarchy</dt>
-                                <dd>{{dimension.column}}</dd>
-                            </dl>
-                            <dl class="dl-horizontal" ng-switch-when="derived">
-                                <dt>Derived</dt>
-                                <dd>{{dimension.derived}}</dd>
-                            </dl>
-                            <dl class="dl-horizontal" ng-switch-when="normal">
-                                <dt>Column</dt>
-                                <dd>{{dimension.columns}}</dd>
-                            </dl>
-                        </div>
-                    </div>
+                <td class="col-xs-1">
+                        {{dimension.table}}
                 </td>
-                <td ng-if="state.mode=='edit'">
-                    <!--edit button-->
+                <td class="col-xs-9">
+                    <!-- Dimensions -->
+                    <select ng-if="state.mode=='edit'" style="width: 100%"
+                            ng-model="model.dimensions[$index].columns" required chosen multiple
+                            ng-change=""
+                            ng-options="column.name as column.name for column in getColumnsByTable(dimension.table)">
+                        <option value=""></option>
+                    </select>
+                </td>
+                <td class="col-xs-1">
                     <button class="btn btn-xs btn-info"
-                            ng-click="editDim(dimension)"><i class="fa fa-pencil"></i>
-                    </button>
-                    <!-- remove button-->
-                    <button class="btn btn-xs btn-danger"
-                            ng-click="removeDim(dimension)"><i class="fa fa-trash-o"></i>
+                            ng-click="removeTableDimensions($index)"><i
+                            class="fa fa-minus"></i>
                     </button>
                 </td>
             </tr>
-        </tbody>
-    </table>
-</div>
-
-<div class="space-16"></div>
-<div class="callout callout-warning dimensions-conflict-area" ng-if="dimConflicts.length">
-    <h4>There are following columns defined in multiple dimensions. <small>This is not recommended!</small></h4>
-    <div class="row" ng-repeat="c in dimConflicts">
-        <div class="col-xs-3">
-            <code>{{c.table}}.{{c.column}}</code>
-        </div>
-        <div class="col-xs-3">
-            <ul class="list-unstyled">
-                <li ng-repeat="d in c.dims">{{d.id}} - {{d.name}}</li>
-            </ul>
-        </div>
-    </div>
-</div>
-
-<!-- Edit Dimension Form -->
-<script type="text/ng-template" id="addEditDimension.html">
-    <div class="modal-header">
-        <h4 class="box-title lighter">{{dimState.editing ? 'Edit' : 'Add'}} Dimension
-            <span class="label label-primary" ng-repeat="t in dimType">{{t}}</span>
-        </h4>
-    </div>
-    <div class="modal-body">
-        <ng-form name="edit_dim_form">
-        <div class="row">
-            <div class="col-xs-8">
-                <!--Name-->
-                <div class="form-group">
-                    <div class="row">
-                        <label class="col-xs-12 col-sm-3 control-label no-padding-right font-color-default"><b>Name</b></label>
-                        <div class="col-xs-12 col-sm-6">
-                            <input type="text" placeholder="Name.." class="form-control" name="dim_name"
-                                   tooltip="dimension name.." tooltip-trigger="focus"
-                                   ng-model="newDimension.name" required />
-                        </div>
-                        <div class="col-xs-12 col-sm-3">
-                            <div class="text-warning" ng-if="edit_dim_form.dim_name.$error.required  && edit_dim_form.dim_name.$dirty">
-                                The Dimension Name is required.
-                            </div>
-                        </div>
-                    </div>
-                </div>
-
-                <!--Table Name: derived dimension only allows lookup tables-->
-                <div class="form-group">
-                    <div class="row">
-                        <label class="control-label col-xs-12 col-sm-3 no-padding-right font-color-default"><b>Table Name</b></label>
-                        <div class="col-xs-12 col-sm-6" ng-if="dimType.indexOf('derived') >= 0">
-                            <select class="form-control" required="true" chosen data-placeholder="Select a lookup table"
-                                    ng-model="newDimension.table" ng-options="table for table in availableTables.slice(1)">
-                                <option value=""></option>
-                            </select>
-                        </div>
-                        <div class="col-xs-12 col-sm-6" ng-if="dimType.indexOf('derived') == -1">
-                            <select class="form-control" required="true" chosen data-placeholder="Select a table"
-                                    ng-model="newDimension.table" ng-options="table for table in availableTables">
-                                <option value=""></option>
-                            </select>
-                        </div>
-                        <div class="col-xs-12 col-sm-3">
-                            <div class="text-info" ng-if="dimType.indexOf('derived') >= 0">
-                                Derived dimension only comes from lookup table.
-                            </div>
-                        </div>
-                    </div>
-                </div>
-
-                <!--Normal Dimension: choose one column-->
-                <div class="form-group" ng-if="dimType.indexOf('normal') >= 0">
-                    <div class="row">
-                        <label class="control-label col-xs-12 col-sm-3 no-padding-right font-color-default"><b>Column Name</b></label>
-                        <div class="col-xs-12 col-sm-6">
-                            <select class="form-control" required="true" chosen data-placeholder="Select a column"
-                                    ng-model="newDimension.column[0]" ng-options="column.name as column.name for column in getColumnsByTable(newDimension.table)">
-                                <option value=""></option>
-                            </select>
-                        </div>
-                    </div>
-                </div>
+        </table>
 
-                <!--Hierarchy Dimension-->
-                <div class="form-group" ng-if="dimType.indexOf('hierarchy') >= 0">
-                    <div class="row">
-                        <div class="col-sm-6 col-sm-offset-3">
-                            <div ui-sortable="{containment: 'parent', placeholder: 'hierarchy-item-placeholder', forcePlaceholderSize: true, opacity: 0.8}"
-                                 ng-model="newDimension.column" class="hierarchy-container">
-                                <div ng-repeat="hierarchyIndex in [] | range: newDimension.column.length" class="hierarchy-item">
-                                    <div class="row">
-                                        <div class="col-xs-2">
-                                            <span class="badge">{{$index + 1}}</span>
-                                        </div>
-                                        <div class="col-xs-8">
-                                            <select chosen style="width: 100%"
-                                                    data-placeholder="Dimension Hierarchy Column"
-                                                    ng-model="newDimension.column[$index]"
-                                                    ng-options="columns.name as columns.name for columns in getColumnsByTable(newDimension.table)" >
-                                                <option value="">-- Select Column --</option>
-                                            </select>
-                                        </div>
-                                        <div class="col-xs-2">
-                                            <button type="button" class="pull-right btn btn-xs btn-danger" style="cursor: pointer " tooltip="Delete"
-                                                    ng-click="newDimension.column.splice($index, 1);">
-                                                <i class="fa fa-trash-o"></i>
-                                            </button>
-                                        </div>
-                                    </div>
-                                </div>
-                            </div>
 
-                            <div class="space-8"></div>
-
-                            <div class="row">
-                                <div class="col-xs-4">
-                                    <button class="btn btn-xs btn-info"
-                                            ng-click="newDimension.column.push('');">
-                                        <i class="fa fa-plus"></i> New Hierarchy</button>
-                                </div>
-                                <div class="col-xs-8">
-                                    <p class="help-block">Drag level into the order you prefer.</p>
-                                </div>
-                            </div>
-                        </div>
-                    </div>
-                </div>
-
-                <!--Derived Dimension-->
-                <div ng-if="dimType.indexOf('derived') >= 0">
-                    <div class="form-group">
-                        <div class="row">
-                            <div class="col-sm-6 col-sm-offset-3">
-                                <div ng-repeat="derived in newDimension.derived track by $index">
-                                    <div>
-                                        <select chosen style="width: 80%;" data-placeholder="Derived Columns.."
-                                                ng-model="newDimension.derived[$index]"
-                                                ng-options="columns.name as columns.name for columns in getColumnsByTable(newDimension.table)" >
-                                            <option value=""></option>
-                                        </select>
-                                        <button class="pull-right btn btn-xs btn-danger" style="cursor: pointer " tooltip="Delete"
-                                                ng-click="newDimension.derived.splice($index, 1);">
-                                            <i class="fa fa-trash-o"></i>
-                                        </button>
-                                        <div class="space-4"></div>
-                                    </div>
-                                </div>
-                                <button class="btn btn-xs btn-info" ng-click="newDimension.derived.push('');">
-                                    <i class="fa fa-plus"></i> New Derived</button>
-                            </div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-
-            <!--Tips-->
-            <div class="col-xs-4">
-                <div class="box box-solid">
-                    <div class="box-header">
-                        <h4 class="box-title">Tips</h4>
-                    </div>
-                    <div class="box-body">
-                        <div class="row">
-                            <div class="col-xs-12">
-                                <ol class="text-info">
-                                    <li>Type in any input box for auto suggestion</li>
-                                    <li>Pick up Fact Table from Star Schema Tables first</li>
-                                    <li>Data Type should match with Hive Table's Data Type</li>
-                                    <li>Join Type have to be same as will be used in query</li>
-                                    <li>Using Hierarchy to inherit one dimension another</li>
-                                    <li>Using Derived for One-One relationship between columns, like ID and Name</li>
-                                </ol>
-                            </div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-        </div>
-        </ng-form>
-    </div>
-    <div class="modal-footer">
-        <button class="btn btn-primary" ng-disabled="edit_dim_form.$invalid" ng-click="ok()">OK</button>
-        <button class="btn btn-warning" ng-click="cancel()">Cancel</button>
-    </div>
-</script>
-
-
-<script type="text/ng-template" id="autoGenDimension.html">
-    <div class="modal-header">
-        <h4 class="box-title lighter">Auto Generate Dimensions <small>This is a helper for you to batch generate dimensions.</small></h4>
-    </div>
-    <div class="modal-body">
-        <div class="row">
-            <div class="col-xs-8">
-                <div class="box box-solid">
-                    <div class="box-header"><h4>Columns</h4></div>
-                    <div class="box-body">
-                        <ul class="list-unstyled columns-region">
-                            <li ng-repeat="table in availableTables track by $index">
-                                <h5 class="table-name-underline">
-                                    <b>{{table}}</b>{{$index == 0 ? ' [Fact Table]' : ' [Lookup Table]'}}
-                                </h5>
-                                <ul class="list-unstyled">
-                                    <li ng-repeat="col in availableColumns[table] track by col.table + '.' + col.name">
-                                        <label>
-                                            <input type="checkbox" ng-model="selectedColumns[table][col.name].selected"
-                                                   ng-disabled="selectedColumns[table][col.name].disabled">
-                                            {{col.name}}
-                                        </label>
-                                    </li>
-                                </ul>
-                            </li>
-                        </ul>
-                    </div>
-                </div>
-            </div>
-
-            <!--Tips-->
-            <div class="col-xs-4">
-                <div class="box box-solid">
-                    <div class="box-header">
-                        <h4 class="box-title">Auto Generate Rules</h4>
-                    </div>
-                    <div class="box-body">
-                        <div class="row">
-                            <div class="col-xs-12">
-                                <ol class="text-info">
-                                    <li>Column is disabled once there is already a dimension referred this column.</li>
-                                    <li>In fact table: one normal dimension will be auto generated per column.</li>
-                                    <li>In lookup table: one derived dimension will be auto generated for all the selected columns.</li>
-                                </ol>
-                            </div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-        </div>
-    </div>
-    <div class="modal-footer">
-        <button class="btn btn-primary" ng-disabled="" ng-click="ok()">OK</button>
-        <button class="btn btn-warning" ng-click="cancel()">Cancel</button>
-    </div>
-</script>
+</div>
 
 </div>

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a2f4d320/webapp/app/partials/modelDesigner/model_info.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/modelDesigner/model_info.html b/webapp/app/partials/modelDesigner/model_info.html
index d91a0f0..9b9e786 100644
--- a/webapp/app/partials/modelDesigner/model_info.html
+++ b/webapp/app/partials/modelDesigner/model_info.html
@@ -29,7 +29,7 @@
                 </label>
                 <div class="col-xs-12 col-sm-6">
                     <input ng-if="state.mode=='edit'" name="project_name" type="text" class="form-control"
-                           ng-model="model.project" disabled/>
+                           ng-model="state.project"/>
                     <span ng-if="state.mode=='view'">
                         {{model.project}}
                     </span>
@@ -37,11 +37,11 @@
             </div>
         </div>
 
-        <!--Cube Name-->
+        <!--Model Name-->
         <div class="form-group">
             <div class="row">
                 <label class="col-xs-12 col-sm-3 control-label no-padding-right font-color-default">
-                    <b>Cube Name</b>
+                    <b>Model Name</b>
                 </label>
                 <div class="col-xs-12 col-sm-6">
                     <input ng-if="state.mode=='edit'" name="model_name" type="text" class="form-control"