Repository: kylin Updated Branches: refs/heads/1.x-staging 75b6479fe -> 6a9a30085
KYLIN-1251 enable nav tree expand and hide funciton Project: http://git-wip-us.apache.org/repos/asf/kylin/repo Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/6a9a3008 Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/6a9a3008 Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/6a9a3008 Branch: refs/heads/1.x-staging Commit: 6a9a30085c2a3fad59bb0f95c54658c7544f0b9c Parents: 75b6479 Author: jian <[email protected]> Authored: Tue Jan 12 17:05:27 2016 +0800 Committer: jian <[email protected]> Committed: Tue Jan 12 17:05:58 2016 +0800 ---------------------------------------------------------------------- pom.xml | 3 +- webapp/app/index.html | 2 +- webapp/app/js/controllers/projectMeta.js | 14 +- .../app/js/directives/angular-tree-control.js | 227 +++++++++++++++++++ webapp/app/js/model/tableModel.js | 6 + .../partials/projects/project_table_tree.html | 1 + webapp/grunt.json | 1 - 7 files changed, 247 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/kylin/blob/6a9a3008/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index 7cb5847..374bac9 100644 --- a/pom.xml +++ b/pom.xml @@ -796,7 +796,8 @@ <!-- MIT license --> <exclude>webapp/app/css/AdminLTE.css</exclude> - + <exclude>webapp/app/js/directives/angular-tree-control.js</exclude> + <!--configuration file --> <exclude>webapp/app/routes.json</exclude> <exclude>webapp/bower.json</exclude> http://git-wip-us.apache.org/repos/asf/kylin/blob/6a9a3008/webapp/app/index.html ---------------------------------------------------------------------- diff --git a/webapp/app/index.html b/webapp/app/index.html index 1382df1..e44170c 100644 --- a/webapp/app/index.html +++ b/webapp/app/index.html @@ -79,7 +79,6 @@ <script src="components/angularLocalStorage/src/angularLocalStorage.js"></script> <script src="components/angular-base64/angular-base64.js"></script> <script src="components/ng-grid/build/ng-grid.js"></script> -<script src="components/angular-tree-control/angular-tree-control.js"></script> <script src="components/ace-builds/src-min-noconflict/ace.js"></script> <script src="components/ace-builds/src-noconflict/ext-language_tools.js"></script> <script src="components/ace-builds/src-min-noconflict/mode-json.js"></script> @@ -108,6 +107,7 @@ <script src="js/listeners.js"></script> <script src="js/filters/filter.js"></script> <script src="js/directives/directives.js"></script> +<script src="js/directives/angular-tree-control.js"></script> <script src="js/factories/graph.js"></script> <script src="js/services/cache.js"></script> <script src="js/services/message.js"></script> http://git-wip-us.apache.org/repos/asf/kylin/blob/6a9a3008/webapp/app/js/controllers/projectMeta.js ---------------------------------------------------------------------- diff --git a/webapp/app/js/controllers/projectMeta.js b/webapp/app/js/controllers/projectMeta.js index d34c414..925529d 100644 --- a/webapp/app/js/controllers/projectMeta.js +++ b/webapp/app/js/controllers/projectMeta.js @@ -23,6 +23,7 @@ KylinApp $scope.selectedSrcDb = []; $scope.selectedSrcTable = {}; $scope.treeOptions = { + dirSelectable:false, nodeChildren: "columns", injectClasses: { ul: "a1", @@ -38,6 +39,14 @@ KylinApp $scope.lastSelected = null; $scope.showSelected = function (table) { + if (angular.isUndefined(table.column_NAME)) { + $scope.selectedSrcTable = table; + } else { + $scope.selectedSrcTable.selectedSrcColumn = table; + } + } + + $scope.onDblClick = function (table) { if (!angular.isUndefined(table.table_NAME)){ var selectColumn = true; if (angular.isUndefined(table.column_NAME)) { @@ -46,7 +55,6 @@ KylinApp } else { $scope.selectedSrcTable.selectedSrcColumn = table; } - if($scope.lastSelected == table){ $scope.lastSelected = null; if(angular.isUndefined($scope.$parent.queryString)){ $scope.$parent.queryString=''; @@ -55,10 +63,8 @@ KylinApp $scope.$parent.queryString += (table.table_NAME + '.' + table.column_NAME + ' '); else $scope.$parent.queryString += (table.table_NAME + ' '); - } else { - $scope.lastSelected = table; - } } + } $scope.projectMetaLoad = function () { http://git-wip-us.apache.org/repos/asf/kylin/blob/6a9a3008/webapp/app/js/directives/angular-tree-control.js ---------------------------------------------------------------------- diff --git a/webapp/app/js/directives/angular-tree-control.js b/webapp/app/js/directives/angular-tree-control.js new file mode 100644 index 0000000..6a7d26c --- /dev/null +++ b/webapp/app/js/directives/angular-tree-control.js @@ -0,0 +1,227 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2013 Steve + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + (function ( angular ) { + 'use strict'; + + angular.module( 'treeControl', [] ) + .directive( 'treecontrol', ['$compile', function( $compile ) { + /** + * @param cssClass - the css class + * @param addClassProperty - should we wrap the class name with class="" + */ + function classIfDefined(cssClass, addClassProperty) { + if (cssClass) { + if (addClassProperty) + return 'class="' + cssClass + '"'; + else + return cssClass; + } + else + return ""; + } + + function ensureDefault(obj, prop, value) { + if (!obj.hasOwnProperty(prop)) + obj[prop] = value; + } + + return { + restrict: 'EA', + require: "treecontrol", + transclude: true, + scope: { + treeModel: "=", + selectedNode: "=?", + onSelection: "&", + options: "=?", + onDblclick: "&" + }, + controller: function( $scope ) { + function defaultIsSelectable() { + return true; + } + + $scope.options = $scope.options || {}; + ensureDefault($scope.options, "nodeChildren", "children"); + ensureDefault($scope.options, "dirSelectable", "true"); + ensureDefault($scope.options, "injectClasses", {}); + ensureDefault($scope.options.injectClasses, "ul", ""); + ensureDefault($scope.options.injectClasses, "li", ""); + ensureDefault($scope.options.injectClasses, "liSelected", ""); + ensureDefault($scope.options.injectClasses, "iExpanded", ""); + ensureDefault($scope.options.injectClasses, "iCollapsed", ""); + ensureDefault($scope.options.injectClasses, "iLeaf", ""); + ensureDefault($scope.options.injectClasses, "label", ""); + ensureDefault($scope.options.injectClasses, "labelSelected", ""); + ensureDefault($scope.options, "isSelectable", defaultIsSelectable); + ensureDefault($scope.options, "equality", function (a, b) { + if (a === undefined || b === undefined) + return false; + a = angular.copy(a); a[$scope.options.nodeChildren] = []; + b = angular.copy(b); b[$scope.options.nodeChildren] = []; + return angular.equals(a, b); + }); + + $scope.expandedNodes = {}; + $scope.parentScopeOfTree = $scope.$parent; + + $scope.headClass = function(node) { + var liSelectionClass = classIfDefined($scope.options.injectClasses.liSelected, false); + var injectSelectionClass = ""; + if (liSelectionClass && (this.$id == $scope.selectedScope)) + injectSelectionClass = " " + liSelectionClass; + if (!node[$scope.options.nodeChildren] || node[$scope.options.nodeChildren].length === 0) + return "tree-leaf" + injectSelectionClass + if ($scope.expandedNodes[this.$id]) + return "tree-expanded" + injectSelectionClass; + else + return "tree-collapsed" + injectSelectionClass; + }; + + $scope.iBranchClass = function() { + if ($scope.expandedNodes[this.$id]) + return classIfDefined($scope.options.injectClasses.iExpanded); + else + return classIfDefined($scope.options.injectClasses.iCollapsed); + }; + + $scope.nodeExpanded = function() { + return !!$scope.expandedNodes[this.$id]; + }; + + $scope.selectNodeHead = function() { + $scope.expandedNodes[this.$id] = ($scope.expandedNodes[this.$id] === undefined ? this.node : undefined); + }; + + $scope.selectNodeLabel = function( selectedNode ){ + if (selectedNode[$scope.options.nodeChildren] && selectedNode[$scope.options.nodeChildren].length > 0 && + (!$scope.options.dirSelectable||!$scope.options.isSelectable(selectedNode))) { + this.selectNodeHead(); + } + else { + $scope.selectedScope = this.$id; + $scope.selectedNode = selectedNode; + if ($scope.onSelection) + $scope.onSelection({node: selectedNode}); + } + }; + + $scope.dblClickNode = function(selectedNode){ + if($scope.onDblclick!=null){ + $scope.onDblclick({node:selectedNode}); + } + } + + $scope.selectedClass = function() { + var labelSelectionClass = classIfDefined($scope.options.injectClasses.labelSelected, false); + var injectSelectionClass = ""; + if (labelSelectionClass && (this.$id == $scope.selectedScope)) + injectSelectionClass = " " + labelSelectionClass; + + return (this.$id == $scope.selectedScope)?"tree-selected" + injectSelectionClass:""; + }; + + //tree template + var template = + '<ul '+classIfDefined($scope.options.injectClasses.ul, true)+'>' + + '<li ng-repeat="node in node.' + $scope.options.nodeChildren+'" ng-class="headClass(node)" '+classIfDefined($scope.options.injectClasses.li, true)+'>' + + '<i class="tree-branch-head" ng-class="iBranchClass()" ng-click="selectNodeHead(node)"></i>' + + '<i class="tree-leaf-head '+classIfDefined($scope.options.injectClasses.iLeaf, false)+'"></i>' + + '<div class="tree-label '+classIfDefined($scope.options.injectClasses.label, false)+'" ng-class="selectedClass()" ng-click="selectNodeLabel(node)" ng-dblclick="dblClickNode(node)" tree-transclude></div>' + + '<treeitem ng-if="nodeExpanded()"></treeitem>' + + '</li>' + + '</ul>'; + + return { + template: $compile(template) + } + }, + compile: function(element, attrs, childTranscludeFn) { + return function ( scope, element, attrs, treemodelCntr ) { + + scope.$watch("treeModel", function updateNodeOnRootScope(newValue) { + if (angular.isArray(newValue)) { + if (angular.isDefined(scope.node) && angular.equals(scope.node[scope.options.nodeChildren], newValue)) + return; + scope.node = {}; + scope.node[scope.options.nodeChildren] = newValue; + } + else { + if (angular.equals(scope.node, newValue)) + return; + scope.node = newValue; + } + }); + + //Rendering template for a root node + treemodelCntr.template( scope, function(clone) { + element.html('').append( clone ); + }); + // save the transclude function from compile (which is not bound to a scope as apposed to the one from link) + // we can fix this to work with the link transclude function with angular 1.2.6. as for angular 1.2.0 we need + // to keep using the compile function + scope.$treeTransclude = childTranscludeFn; + } + } + }; + }]) + .directive("treeitem", function() { + return { + restrict: 'E', + require: "^treecontrol", + link: function( scope, element, attrs, treemodelCntr) { + // Rendering template for the current node + treemodelCntr.template(scope, function(clone) { + element.html('').append(clone); + }); + } + } + }) + .directive("treeTransclude", function() { + return { + link: function(scope, element, attrs, controller) { + angular.forEach(scope.expandedNodes, function (node, id) { + if (scope.options.equality(node, scope.node)) { + scope.expandedNodes[scope.$id] = scope.node; + scope.expandedNodes[id] = undefined; + } + }); + if (scope.options.equality(scope.node, scope.selectedNode)) { + scope.selectNodeLabel(scope.node); + } + + // create a scope for the transclusion, whos parent is the parent of the tree control + scope.transcludeScope = scope.parentScopeOfTree.$new(); + scope.transcludeScope.node = scope.node; + scope.$on('$destroy', function() { + scope.transcludeScope.$destroy(); + }); + + scope.$treeTransclude(scope.transcludeScope, function(clone) { + element.empty(); + element.append(clone); + }); + } + } + }); +})( angular ); http://git-wip-us.apache.org/repos/asf/kylin/blob/6a9a3008/webapp/app/js/model/tableModel.js ---------------------------------------------------------------------- diff --git a/webapp/app/js/model/tableModel.js b/webapp/app/js/model/tableModel.js index ca9c47c..2b9c8ea 100755 --- a/webapp/app/js/model/tableModel.js +++ b/webapp/app/js/model/tableModel.js @@ -48,6 +48,12 @@ KylinApp.service('TableModel', function (ProjectModel, $q, TableService) { this.treeOptions = { nodeChildren: "columns", + isSelectable:function(node){ + if(node.id||node.uuid){//db + return true; + } + return false; + }, injectClasses: { ul: "a1", li: "a2", http://git-wip-us.apache.org/repos/asf/kylin/blob/6a9a3008/webapp/app/partials/projects/project_table_tree.html ---------------------------------------------------------------------- diff --git a/webapp/app/partials/projects/project_table_tree.html b/webapp/app/partials/projects/project_table_tree.html index ce53ddd..b409047 100644 --- a/webapp/app/partials/projects/project_table_tree.html +++ b/webapp/app/partials/projects/project_table_tree.html @@ -29,6 +29,7 @@ tree-model="selectedSrcDb" options="treeOptions" on-selection="showSelected(node)" + on-dblclick="onDblClick(node)" selected-node="selectedSrcTable"> {{node.name}} {{!!(node.type_NAME)?'(' + trimType(node.type_NAME) + ')' : ''}} </treecontrol> http://git-wip-us.apache.org/repos/asf/kylin/blob/6a9a3008/webapp/grunt.json ---------------------------------------------------------------------- diff --git a/webapp/grunt.json b/webapp/grunt.json index a9b072d..3605504 100755 --- a/webapp/grunt.json +++ b/webapp/grunt.json @@ -19,7 +19,6 @@ "app/components/angularLocalStorage/src/angularLocalStorage.js", "app/components/angular-base64/angular-base64.min.js", "app/components/ng-grid/build/ng-grid.js", - "app/components/angular-tree-control/angular-tree-control.js", "app/components/ace-builds/src-min-noconflict/ace.js", "app/components/ace-builds/src-min-noconflict/ext-language_tools.js", "app/components/ace-builds/src-min-noconflict/mode-json.js",
