Return-Path: X-Original-To: apmail-ignite-commits-archive@minotaur.apache.org Delivered-To: apmail-ignite-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id E5D7918C8A for ; Wed, 9 Dec 2015 05:10:40 +0000 (UTC) Received: (qmail 45818 invoked by uid 500); 9 Dec 2015 05:10:40 -0000 Delivered-To: apmail-ignite-commits-archive@ignite.apache.org Received: (qmail 45782 invoked by uid 500); 9 Dec 2015 05:10:40 -0000 Mailing-List: contact commits-help@ignite.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@ignite.apache.org Delivered-To: mailing list commits@ignite.apache.org Received: (qmail 45773 invoked by uid 99); 9 Dec 2015 05:10:40 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 09 Dec 2015 05:10:40 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 8DB2BE09AF; Wed, 9 Dec 2015 05:10:40 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: anovikov@apache.org To: commits@ignite.apache.org Message-Id: <42b08a2ada604a94b7dbce1652a5c989@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: ignite git commit: IGNITE-843 Migrate from ag-grid to ui-grid. Date: Wed, 9 Dec 2015 05:10:40 +0000 (UTC) Repository: ignite Updated Branches: refs/heads/ignite-843-rc2 4c36b82a8 -> da50f0c6c IGNITE-843 Migrate from ag-grid to ui-grid. Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/da50f0c6 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/da50f0c6 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/da50f0c6 Branch: refs/heads/ignite-843-rc2 Commit: da50f0c6cb3ce1e46ff63eafddd46a5a65f08a05 Parents: 4c36b82 Author: Andrey Authored: Wed Dec 9 12:09:41 2015 +0700 Committer: Andrey Committed: Wed Dec 9 12:10:29 2015 +0700 ---------------------------------------------------------------------- .../control-center-web/src/main/js/app/index.js | 5 +- .../control-center-web/src/main/js/config.js | 19 ++- .../main/js/controllers/caches-controller.js | 14 +- .../main/js/controllers/clusters-controller.js | 16 ++- .../src/main/js/controllers/common-module.js | 129 +------------------ .../main/js/controllers/metadata-controller.js | 14 +- .../src/main/js/controllers/sql-controller.js | 73 ++++++----- .../src/main/js/gulpfile.js/index.js | 5 +- .../src/main/js/gulpfile.js/tasks/connect.js | 1 + .../src/main/js/gulpfile.js/tasks/copy.js | 11 +- .../src/main/js/gulpfile.js/tasks/jade.js | 12 +- .../control-center-web/src/main/js/package.json | 20 ++- .../src/main/js/public/stylesheets/style.scss | 122 ++---------------- .../src/main/js/views/configuration/caches.jade | 2 +- .../main/js/views/configuration/clusters.jade | 2 +- .../src/main/js/views/configuration/igfs.jade | 2 +- .../js/views/configuration/metadata-load.jade | 8 +- .../main/js/views/configuration/metadata.jade | 4 +- .../main/js/views/configuration/summary.jade | 2 +- .../src/main/js/views/includes/controls.jade | 6 +- .../src/main/js/views/sql/sql.jade | 4 +- 21 files changed, 163 insertions(+), 308 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/da50f0c6/modules/control-center-web/src/main/js/app/index.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/app/index.js b/modules/control-center-web/src/main/js/app/index.js index 1305fa3..4174425 100644 --- a/modules/control-center-web/src/main/js/app/index.js +++ b/modules/control-center-web/src/main/js/app/index.js @@ -19,6 +19,7 @@ import jQuery from 'jquery' import _ from 'lodash' import ace from 'ace' import angular from 'angular'; +import pdfMake from 'pdfmake'; import 'angular-ui-router' import 'angular-strap' @@ -27,7 +28,7 @@ import 'angular-tree-control' import 'angular-smart-table' import 'angular-animate' import 'angular-sanitize' -import 'angular-ag-grid' +import 'angular-ui-grid' import 'angular-loading' import 'angular-drag-and-drop-lists' import 'angular-nvd3' @@ -42,7 +43,7 @@ import 'public/stylesheets/style.css!' import 'nvd3/build/nv.d3.css!' import 'angular-tree-control/css/tree-control-attribute.css!' import 'angular-tree-control/css/tree-control.css!' -import 'angular-ag-grid/dist/ag-grid.css!' +import 'angular-ui-grid/ui-grid.css!' import 'angular-loading/angular-loading.css!' import 'angular-motion/dist/angular-motion.css!' http://git-wip-us.apache.org/repos/asf/ignite/blob/da50f0c6/modules/control-center-web/src/main/js/config.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/config.js b/modules/control-center-web/src/main/js/config.js index fec475b..5f11590 100644 --- a/modules/control-center-web/src/main/js/config.js +++ b/modules/control-center-web/src/main/js/config.js @@ -24,12 +24,13 @@ System.config({ "angular-grid": "github:ceolter/ag-grid@2.3.5", "angular-loading": "github:darthwade/angular-loading@0.1.4", "angular-motion": "github:mgcrea/angular-motion@0.4.3", - "angular-nvd3": "github:krispo/angular-nvd3@1.0.4", + "angular-nvd3": "github:krispo/angular-nvd3@1.0.5", "angular-sanitize": "github:angular/bower-angular-sanitize@1.4.8", "angular-smart-table": "github:lorenzofox3/Smart-Table@2.1.5", "angular-strap": "github:akuznetsov-gridgain/angular-strap@fix-1852-2.3.6", "angular-tree-control": "github:wix/angular-tree-control@0.2.22", "angular-ui-ace": "github:angular-ui/ui-ace@0.2.3", + "angular-ui-grid": "github:angular-ui/bower-ui-grid@3.0.7", "angular-ui-router": "github:angular-ui/ui-router@0.2.15", "babel": "npm:babel-core@5.8.34", "babel-runtime": "npm:babel-runtime@5.8.34", @@ -40,12 +41,13 @@ System.config({ "core-js": "npm:core-js@1.2.6", "css": "github:systemjs/plugin-css@0.1.20", "file-saver": "github:eligrey/FileSaver.js@master", - "font-awesome": "npm:font-awesome@4.4.0", + "font-awesome": "npm:font-awesome@4.5.0", "jade": "github:johnsoftek/plugin-jade@0.5.1", "jquery": "github:components/jquery@2.1.4", "jszip": "github:Stuk/jszip@2.5.0", "lodash": "npm:lodash@3.10.1", "nvd3": "npm:nvd3@1.8.1", + "pdfmake": "github:bpampuch/pdfmake@0.1.20", "query-command-supported": "github:zenorocha/document.queryCommandSupported@1.0.0", "spinjs": "github:fgnass/spin.js@2.3.2", "github:akuznetsov-gridgain/angular-strap@fix-1852-2.3.6": { @@ -53,6 +55,9 @@ System.config({ "angular-motion": "github:mgcrea/angular-motion@0.4.3", "angular-sanitize": "github:angular/bower-angular-sanitize@1.4.8" }, + "github:angular-ui/bower-ui-grid@3.0.7": { + "pdfmake": "github:bpampuch/pdfmake@0.1.20" + }, "github:angular-ui/ui-ace@0.2.3": { "ace": "github:ajaxorg/ace-builds@1.2.2" }, @@ -81,7 +86,7 @@ System.config({ "assert": "npm:assert@1.3.0" }, "github:jspm/nodelibs-buffer@0.1.0": { - "buffer": "npm:buffer@3.5.2" + "buffer": "npm:buffer@3.5.4" }, "github:jspm/nodelibs-events@0.1.1": { "events": "npm:events@1.0.2" @@ -121,7 +126,7 @@ System.config({ "github:jspm/nodelibs-vm@0.1.0": { "vm-browserify": "npm:vm-browserify@0.0.4" }, - "github:krispo/angular-nvd3@1.0.4": { + "github:krispo/angular-nvd3@1.0.5": { "angular": "github:angular/bower-angular@1.4.8", "d3": "npm:d3@3.5.10", "nvd3": "npm:nvd3@1.8.1" @@ -177,12 +182,12 @@ System.config({ "npm:babel-runtime@5.8.34": { "process": "github:jspm/nodelibs-process@0.1.2" }, - "npm:buffer@3.5.2": { + "npm:buffer@3.5.4": { "base64-js": "npm:base64-js@0.0.8", "child_process": "github:jspm/nodelibs-child_process@0.1.0", "fs": "github:jspm/nodelibs-fs@0.1.2", "ieee754": "npm:ieee754@1.1.6", - "is-array": "npm:is-array@1.0.1", + "isarray": "npm:isarray@0.0.1", "process": "github:jspm/nodelibs-process@0.1.2" }, "npm:center-align@0.1.2": { @@ -240,7 +245,7 @@ System.config({ "fs": "github:jspm/nodelibs-fs@0.1.2", "process": "github:jspm/nodelibs-process@0.1.2" }, - "npm:font-awesome@4.4.0": { + "npm:font-awesome@4.5.0": { "css": "github:systemjs/plugin-css@0.1.20" }, "npm:graceful-readlink@1.0.1": { http://git-wip-us.apache.org/repos/asf/ignite/blob/da50f0c6/modules/control-center-web/src/main/js/controllers/caches-controller.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/controllers/caches-controller.js b/modules/control-center-web/src/main/js/controllers/caches-controller.js index 161f197..46a5339 100644 --- a/modules/control-center-web/src/main/js/controllers/caches-controller.js +++ b/modules/control-center-web/src/main/js/controllers/caches-controller.js @@ -127,6 +127,10 @@ consoleModule.controller('cachesController', [ statistics: {xml: '', java: '', allDefaults: true} }; + function _cacheLbl () { + return this.name + ', ' + _.result(_.find($scope.cacheModes, {value: this.cacheMode}), 'label') + ', ' + _.result(_.find($scope.atomicities, {value: this.atomicityMode}), 'label'); + } + $scope.required = function (field) { var backupItem = $scope.backupItem; @@ -241,6 +245,13 @@ consoleModule.controller('cachesController', [ var validFilter = $filter('metadatasValidation'); $scope.spaces = data.spaces; + + data.caches.forEach(function (cache) { + Object.defineProperty(cache, 'label', { + get: _cacheLbl + }); + }); + $scope.caches = data.caches; $scope.clusters = data.clusters; $scope.metadatas = _.sortBy(_.map(validFilter(data.metadatas, true, false), function (meta) { @@ -404,7 +415,8 @@ consoleModule.controller('cachesController', [ readFromBackup: true, copyOnRead: true, clusters: id && _.find($scope.clusters, {value: id}) ? [id] : [], - metadatas: id && _.find($scope.metadatas, {value: id}) ? [id] : [] + metadatas: id && _.find($scope.metadatas, {value: id}) ? [id] : [], + get label() { return angular.bind(this, _cacheLbl)(); } }; } http://git-wip-us.apache.org/repos/asf/ignite/blob/da50f0c6/modules/control-center-web/src/main/js/controllers/clusters-controller.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/controllers/clusters-controller.js b/modules/control-center-web/src/main/js/controllers/clusters-controller.js index d9a24ff..54e7534 100644 --- a/modules/control-center-web/src/main/js/controllers/clusters-controller.js +++ b/modules/control-center-web/src/main/js/controllers/clusters-controller.js @@ -169,6 +169,10 @@ consoleModule.controller('clustersController', [ $scope.clusters = []; + function _clusterLbl () { + return this.name + ', ' + _.result(_.find($scope.discoveries, {value: this.discovery.kind}), 'label'); + } + function selectFirstItem() { if ($scope.clusters.length > 0) $scope.selectItem($scope.clusters[0]); @@ -181,6 +185,12 @@ consoleModule.controller('clustersController', [ .success(function (data) { $scope.spaces = data.spaces; + data.clusters.forEach(function (cluster) { + Object.defineProperty(cluster, 'label', { + get: _clusterLbl + }); + }); + $scope.clusters = data.clusters; $scope.caches = _.map(data.caches, function (cache) { @@ -309,7 +319,7 @@ consoleModule.controller('clustersController', [ $common.showError(errMsg); }); }) - .error(function (errMsg) { + .catch(function (errMsg) { $common.showError(errMsg); }) .finally(function () { @@ -362,6 +372,10 @@ consoleModule.controller('clustersController', [ newItem.igfss = id && _.find($scope.igfss, {value: id}) ? [id] : []; newItem.space = $scope.spaces[0]._id; + Object.defineProperty(newItem, 'label', { + get: _clusterLbl + }); + return newItem; } http://git-wip-us.apache.org/repos/asf/ignite/blob/da50f0c6/modules/control-center-web/src/main/js/controllers/common-module.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/controllers/common-module.js b/modules/control-center-web/src/main/js/controllers/common-module.js index 1c4f242..ac8e418 100644 --- a/modules/control-center-web/src/main/js/controllers/common-module.js +++ b/modules/control-center-web/src/main/js/controllers/common-module.js @@ -17,7 +17,7 @@ var consoleModule = angular.module('ignite-web-console', [ - 'ngAnimate', 'ngSanitize', 'mgcrea.ngStrap', 'smart-table', 'ui.ace', 'treeControl', 'darthwade.dwLoading', 'agGrid', 'nvd3', 'dndLists' + 'ngAnimate', 'ngSanitize', 'mgcrea.ngStrap', 'smart-table', 'ui.ace', 'treeControl', 'darthwade.dwLoading', 'ui.grid', 'ui.grid.autoResize', 'ui.grid.exporter', 'nvd3', 'dndLists' /* ignite:modules */ , 'ignite-console' , 'ignite-console.navbar' @@ -1651,113 +1651,6 @@ consoleModule.service('ngCopy', ['$window', '$common', function ($window, $commo }; }]); -// Filter to decode name using map(value, label). -consoleModule.filter('displayValue', function () { - return function (v, m, dflt) { - var i = _.findIndex(m, function (item) { - return item.value === v; - }); - - if (i >= 0) { - return m[i].label; - } - - if (dflt) { - return dflt; - } - - return 'Unknown value'; - }; -}); - -consoleModule.filter('clustersSearch', function() { - var discoveries = { - 'Vm': 'static ips', - 'Multicast': 'multicast', - 'S3': 'aws s3', - 'Cloud': 'apache jclouds', - 'GoogleStorage': 'google cloud storage', - 'Jdbc': 'jdbc', - 'SharedFs': 'shared filesystem' - }; - - return function(array, query) { - if (!angular.isUndefined(array) && !angular.isUndefined(query) && !angular.isUndefined(query.$)) { - var filtredArray = []; - - var matchString = query.$.toLowerCase(); - - angular.forEach(array, function (row) { - var label = (row.name + ', ' + discoveries[row.discovery.kind]).toLowerCase(); - - if (label.indexOf(matchString) >= 0) - filtredArray.push(row); - }); - - return filtredArray; - } else - return array; - }; -}); - -consoleModule.filter('cachesSearch', function() { - return function(array, query) { - if (!angular.isUndefined(array) && !angular.isUndefined(query) && !angular.isUndefined(query.$)) { - var filtredArray = []; - - var matchString = query.$.toLowerCase(); - - angular.forEach(array, function (row) { - var label = (row.name + ', ' + row.cacheMode + ', ' + row.atomicityMode).toLowerCase(); - - if (label.indexOf(matchString) >= 0) - filtredArray.push(row); - }); - - return filtredArray; - } else - return array; - }; -}); - -consoleModule.filter('metadatasSearch', function() { - return function(array, query) { - if (!angular.isUndefined(array) && !angular.isUndefined(query) && !angular.isUndefined(query.$)) { - var filtredArray = []; - - var matchString = query.$.toLowerCase(); - - angular.forEach(array, function (row) { - if (row.valueType.toLowerCase().indexOf(matchString) >= 0) - filtredArray.push(row); - }); - - return filtredArray; - } else - return array; - }; -}); - -consoleModule.filter('schemasSearch', function() { - return function(array, query) { - if (!angular.isUndefined(array) && !angular.isUndefined(query) && !angular.isUndefined(query.$)) { - var filtredArray = []; - - var matchString = query.$.toLowerCase(); - - angular.forEach(array, function (row) { - var label = row.name.toLowerCase(); - - if (label.indexOf(matchString) >= 0) - filtredArray.push(row); - }); - - return filtredArray; - } else - return array; - }; -}); - consoleModule.filter('tablesSearch', function() { return function(array, query) { if (!angular.isUndefined(array) && !angular.isUndefined(query) && !angular.isUndefined(query.$)) { @@ -1778,26 +1671,6 @@ consoleModule.filter('tablesSearch', function() { }; }); -consoleModule.filter('igfssSearch', function() { - return function(array, query) { - if (!angular.isUndefined(array) && !angular.isUndefined(query) && !angular.isUndefined(query.$)) { - var filtredArray = []; - - var matchString = query.$.toLowerCase(); - - angular.forEach(array, function (row) { - var label = row.name.toLowerCase(); - - if (label.indexOf(matchString) >= 0) - filtredArray.push(row); - }); - - return filtredArray; - } else - return array; - }; -}); - // Filter metadata with key fields configuration. consoleModule.filter('metadatasValidation', ['$common', function ($common) { return function(metadatas, valid, invalid) { http://git-wip-us.apache.org/repos/asf/ignite/blob/da50f0c6/modules/control-center-web/src/main/js/controllers/metadata-controller.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/controllers/metadata-controller.js b/modules/control-center-web/src/main/js/controllers/metadata-controller.js index 35270d7..dd09a1a 100644 --- a/modules/control-center-web/src/main/js/controllers/metadata-controller.js +++ b/modules/control-center-web/src/main/js/controllers/metadata-controller.js @@ -358,15 +358,21 @@ consoleModule.controller('metadataController', [ $http.post('/api/v1/agent/metadata', $scope.preset) .success(function (tables) { - $scope.loadMeta.tables = tables; - $scope.loadMeta.action = 'tables'; - $scope.loadMeta.button = 'Save'; + tables.forEach(function (tbl) { + Object.defineProperty(tbl, 'label', { + get: function () { + return this.schema + '.' + this.tbl; + } + }); - _.forEach(tables, function (tbl) { tbl.use = $common.isDefined(_.find(tbl.cols, function (col) { return col.key; })); }); + + $scope.loadMeta.tables = tables; + $scope.loadMeta.action = 'tables'; + $scope.loadMeta.button = 'Save'; }) .error(function (errMsg) { $common.showError(errMsg); http://git-wip-us.apache.org/repos/asf/ignite/blob/da50f0c6/modules/control-center-web/src/main/js/controllers/sql-controller.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/controllers/sql-controller.js b/modules/control-center-web/src/main/js/controllers/sql-controller.js index 00f44e6..1070566 100644 --- a/modules/control-center-web/src/main/js/controllers/sql-controller.js +++ b/modules/control-center-web/src/main/js/controllers/sql-controller.js @@ -16,8 +16,8 @@ */ // Controller for SQL notebook screen. -consoleModule.controller('sqlController', function ($scope, $controller, $http, $timeout, $common, $confirm, - $interval, $modal, $popover, $loading, $location, $anchorScroll, $state) { +consoleModule.controller('sqlController', function ($animate, $scope, $controller, $http, $timeout, $common, $confirm, + $interval, $modal, $popover, $loading, $location, $anchorScroll, $state, uiGridExporterConstants) { // Initialize the super class and extend it. angular.extend(this, $controller('agent-download', {$scope: $scope})); @@ -42,7 +42,11 @@ consoleModule.controller('sqlController', function ($scope, $controller, $http, {value: 3600000, label: 'hours', short: 'h'} ]; - $scope.exportDropdown = [{ 'text': 'Export all', 'click': 'exportAll(paragraph)'}]; + $scope.exportDropdown = [ + { 'text': 'Export all', 'click': 'exportCsvAll(paragraph)' } + //{ 'text': 'Export all to CSV', 'click': 'exportCsvAll(paragraph)' }, + //{ 'text': 'Export all to PDF', 'click': 'exportPdfAll(paragraph)' } + ]; $scope.metadata = []; @@ -192,9 +196,19 @@ consoleModule.controller('sqlController', function ($scope, $controller, $http, }; Object.defineProperty(paragraph, 'gridOptions', { value: { - enableColResize: true, - columnDefs: [], - rowData: null + onRegisterApi: function(api) { + $animate.enabled(api.grid.element, false); + + this.api = api; + }, + enableGridMenu: false, + exporterMenuCsv: false, + exporterMenuPdf: false, + setRows: function(rows) { + this.height = Math.min(rows.length, 15) * 30 + 42 + 'px'; + + this.data = rows; + } }}); Object.defineProperty(paragraph, 'chartHistory', {value: []}); @@ -394,10 +408,6 @@ consoleModule.controller('sqlController', function ($scope, $controller, $http, if (paragraph.chart()) _chartApplySettings(paragraph, true); - else - setTimeout(function () { - paragraph.gridOptions.api.sizeColumnsToFit(); - }); }; $scope.resultEq = function(paragraph, result) { @@ -475,19 +485,16 @@ consoleModule.controller('sqlController', function ($scope, $controller, $http, if (_notObjectType(col.fieldTypeName)) paragraph.chartColumns.push({value: idx, type: col.fieldTypeName, label: col.fieldName, aggFx: $scope.aggregateFxs[0]}); - // Index for explain, execute and fieldName for scan. - var colValue = 'data[' + (paragraph.queryArgs.query ? idx : '"' + col.fieldName + '"') + ']'; - columnDefs.push({ - headerName: col.fieldName, + displayName: col.fieldName, headerTooltip: _fullColName(col), - valueGetter: $common.isJavaBuildInClass(col.fieldTypeName) ? colValue : 'JSON.stringify(' + colValue + ')', + field: paragraph.queryArgs.query ? '' + idx : col.fieldName, minWidth: 50 }); } }); - paragraph.gridOptions.api.setColumnDefs(columnDefs); + paragraph.gridOptions.columnDefs = columnDefs; if (paragraph.chartColumns.length > 0) { paragraph.chartColumns.push(TIME_LINE); @@ -512,10 +519,6 @@ consoleModule.controller('sqlController', function ($scope, $controller, $http, paragraph.chartColumns = []; _rebuildColumns(paragraph); - - setTimeout(function () { - paragraph.gridOptions.api.sizeColumnsToFit(); - }); }; function _retainColumns(allCols, curCols, acceptableType, xAxis, unwantedCols) { @@ -617,10 +620,7 @@ consoleModule.controller('sqlController', function ($scope, $controller, $http, else paragraph.rows = res.rows; - paragraph.gridOptions.api.setRowData(paragraph.rows); - - if (!refreshMode) - setTimeout(function () { paragraph.gridOptions.api.sizeColumnsToFit(); }); + paragraph.gridOptions.setRows(paragraph.rows); var chartHistory = paragraph.chartHistory; @@ -676,9 +676,6 @@ consoleModule.controller('sqlController', function ($scope, $controller, $http, }; var _showLoading = function (paragraph, enable) { - if (paragraph.table()) - paragraph.gridOptions.api.showLoading(enable); - paragraph.loading = enable; }; @@ -790,7 +787,7 @@ consoleModule.controller('sqlController', function ($scope, $controller, $http, _updateChartsWithData(paragraph, _chartDatum(paragraph)); } - paragraph.gridOptions.api.setRowData(res.rows); + paragraph.gridOptions.setRows(res.rows); _showLoading(paragraph, false); @@ -851,11 +848,17 @@ consoleModule.controller('sqlController', function ($scope, $controller, $http, $common.download('application/octet-stream;charset=utf-8', fileName, escape(csvContent)); }; - $scope.exportPage = function(paragraph) { + $scope.exportCsv = function(paragraph) { _export(paragraph.name + '.csv', paragraph.meta, paragraph.rows); + + //paragraph.gridOptions.api.exporter.csvExport(uiGridExporterConstants.ALL, uiGridExporterConstants.VISIBLE); }; - $scope.exportAll = function(paragraph) { + $scope.exportPdf = function(paragraph) { + paragraph.gridOptions.api.exporter.pdfExport(uiGridExporterConstants.ALL, uiGridExporterConstants.VISIBLE); + }; + + $scope.exportCsvAll = function(paragraph) { $http.post('/api/v1/agent/query/getAll', {query: paragraph.query, cacheName: paragraph.cacheName}) .success(function (item) { _export(paragraph.name + '-all.csv', item.meta, item.rows); @@ -865,6 +868,16 @@ consoleModule.controller('sqlController', function ($scope, $controller, $http, }); }; + $scope.exportPdfAll = function(paragraph) { + //$http.post('/api/v1/agent/query/getAll', {query: paragraph.query, cacheName: paragraph.cacheName}) + // .success(function (item) { + // _export(paragraph.name + '-all.csv', item.meta, item.rows); + // }) + // .error(function (errMsg) { + // $common.showError(errMsg); + // }); + }; + $scope.rateAsString = function (paragraph) { if (paragraph.rate && paragraph.rate.installed) { var idx = _.findIndex($scope.timeUnit, function (unit) { http://git-wip-us.apache.org/repos/asf/ignite/blob/da50f0c6/modules/control-center-web/src/main/js/gulpfile.js/index.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/gulpfile.js/index.js b/modules/control-center-web/src/main/js/gulpfile.js/index.js index 3c5c70c..cf287e5 100644 --- a/modules/control-center-web/src/main/js/gulpfile.js/index.js +++ b/modules/control-center-web/src/main/js/gulpfile.js/index.js @@ -17,6 +17,7 @@ var gulp = require('gulp'); var requireDir = require('require-dir'); +var sequence = require('gulp-sequence'); // Require all tasks in gulpfile.js/tasks, including subfolders. requireDir('./tasks', { recurse: true }); @@ -25,4 +26,6 @@ requireDir('./tasks', { recurse: true }); gulp.task('default', ['build']); // Build + watch + connect task. -gulp.task('watch', ['build', 'bundle:ignite:watch', 'bundle:legacy:watch', 'sass:watch', 'jade:watch', 'copy:watch', 'connect']); +gulp.task('watch', function (cb) { + return sequence('build', 'connect', ['bundle:ignite:watch', 'bundle:legacy:watch', 'sass:watch', 'jade:watch', 'copy:watch'])(cb); +}); http://git-wip-us.apache.org/repos/asf/ignite/blob/da50f0c6/modules/control-center-web/src/main/js/gulpfile.js/tasks/connect.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/gulpfile.js/tasks/connect.js b/modules/control-center-web/src/main/js/gulpfile.js/tasks/connect.js index b5886f4..2aa8006 100644 --- a/modules/control-center-web/src/main/js/gulpfile.js/tasks/connect.js +++ b/modules/control-center-web/src/main/js/gulpfile.js/tasks/connect.js @@ -20,6 +20,7 @@ var connect = require('gulp-connect'); var modrewrite = require('connect-modrewrite'); var options = { + livereload: true, root: './build', middleware: function (connect, opt) { return [modrewrite([ http://git-wip-us.apache.org/repos/asf/ignite/blob/da50f0c6/modules/control-center-web/src/main/js/gulpfile.js/tasks/copy.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/gulpfile.js/tasks/copy.js b/modules/control-center-web/src/main/js/gulpfile.js/tasks/copy.js index 07a4cd4..3786a50 100644 --- a/modules/control-center-web/src/main/js/gulpfile.js/tasks/copy.js +++ b/modules/control-center-web/src/main/js/gulpfile.js/tasks/copy.js @@ -52,7 +52,7 @@ var igniteModulePaths = [ ]; gulp.task('copy', function(cb) { - var tasks = ['copy:legacy', 'copy:fonts', 'copy:ignite_modules']; + var tasks = ['copy:legacy', 'copy:font-awesome', 'copy:ui-grid', 'copy:ignite_modules']; if (util.env.debug || util.env.sourcemaps) { tasks.push('copy:css'); @@ -75,10 +75,17 @@ gulp.task('copy:css', function(cb) { return gulp.src(cssPaths, {base: './'}).pipe(gulp.dest('./build')); }); -gulp.task('copy:fonts', function(cb) { +gulp.task('copy:font-awesome', function(cb) { return gulp.src('./node_modules/font-awesome/fonts/*', {base: './node_modules/font-awesome'}).pipe(gulp.dest('./build')); }); +gulp.task('copy:ui-grid', function(cb) { + return gulp.src(['jspm_packages/**/*-ui-grid@*/*.woff', + 'jspm_packages/**/*-ui-grid@*/*.svg', + 'jspm_packages/**/*-ui-grid@*/*.ttf', + 'jspm_packages/**/*-ui-grid@*/*.eot'], {base: './'}).pipe(gulp.dest('./build')); +}); + gulp.task('copy:ignite_modules', function(cb) { return gulp.src(igniteModulePaths).pipe(gulp.dest('./build/ignite_modules')); }); http://git-wip-us.apache.org/repos/asf/ignite/blob/da50f0c6/modules/control-center-web/src/main/js/gulpfile.js/tasks/jade.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/gulpfile.js/tasks/jade.js b/modules/control-center-web/src/main/js/gulpfile.js/tasks/jade.js index f58d70e..9082093 100644 --- a/modules/control-center-web/src/main/js/gulpfile.js/tasks/jade.js +++ b/modules/control-center-web/src/main/js/gulpfile.js/tasks/jade.js @@ -17,7 +17,8 @@ var gulp = require('gulp'); var gulpJade = require('gulp-jade'); -var gulpSequence = require('gulp-sequence'); +var sequence = require('gulp-sequence'); +var connect = require('gulp-connect'); var igniteModules = process.env.IGNITE_MODULES || './ignite_modules'; @@ -36,7 +37,7 @@ var jadeOptions = { }; gulp.task('jade', function(cb) { - return gulpSequence('jade:source', 'jade:ignite_modules')(cb) + return sequence('jade:source', 'jade:ignite_modules')(cb) }); gulp.task('jade:source', function (cb) { @@ -44,11 +45,14 @@ gulp.task('jade:source', function (cb) { }); gulp.task('jade:ignite_modules', function (cb) { - return gulp.src(igniteModulePaths).pipe(gulpJade(jadeOptions)).pipe(gulp.dest('./build/ignite_modules')); + return gulp.src(igniteModulePaths) + .pipe(gulpJade(jadeOptions)) + .pipe(gulp.dest('./build/ignite_modules')) + .pipe(connect.reload()); }); gulp.task('jade:watch', function (cb) { return gulp.watch([igniteModulePaths, paths], function(glob) { - gulpSequence('jade', 'inject:plugins:html')(cb) + sequence('jade', 'inject:plugins:html')(cb) }); }); http://git-wip-us.apache.org/repos/asf/ignite/blob/da50f0c6/modules/control-center-web/src/main/js/package.json ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/package.json b/modules/control-center-web/src/main/js/package.json index 0c87ecf..ae39b46 100644 --- a/modules/control-center-web/src/main/js/package.json +++ b/modules/control-center-web/src/main/js/package.json @@ -67,7 +67,6 @@ "dependencies": { "ace": "github:ajaxorg/ace-builds@^1.2.2", "angular": "github:angular/bower-angular@^1.4.8", - "angular-ag-grid": "github:ceolter/ag-grid@^2.3.5", "angular-animate": "github:angular/bower-angular-animate@^1.4.8", "angular-drag-and-drop-lists": "github:marceljuenemann/angular-drag-and-drop-lists@^1.3.0", "angular-loading": "github:darthwade/angular-loading@^0.1.4", @@ -78,6 +77,7 @@ "angular-strap": "github:akuznetsov-gridgain/angular-strap@fix-1852-2.3.6", "angular-tree-control": "github:wix/angular-tree-control@^0.2.22", "angular-ui-ace": "github:angular-ui/ui-ace@^0.2.3", + "angular-ui-grid": "github:angular-ui/bower-ui-grid@^3.0.7", "angular-ui-router": "github:angular-ui/ui-router@^0.2.15", "blob": "github:eligrey/Blob.js@master", "bootstrap-carousel": "github:twbs/bootstrap@^3.3.6", @@ -88,6 +88,7 @@ "jquery": "github:components/jquery@^2.1.4", "jszip": "github:Stuk/jszip@^2.5.0", "lodash": "npm:lodash@^3.10.1", + "pdfmake": "github:bpampuch/pdfmake@^0.1.20", "query-command-supported": "github:zenorocha/document.queryCommandSupported@^1.0.0" }, "devDependencies": { @@ -101,6 +102,18 @@ "format": "global", "main": "./dist/jszip" }, + "github:bpampuch/pdfmake@0.1.20": { + "format": "global", + "main": "vfs_fonts", + "shim": { + "vfs_fonts": { + "deps": [ + "./pdfmake" + ], + "exports": "pdfMake" + } + } + }, "github:zenorocha/document.queryCommandSupported@1.0.0": { "format": "global" }, @@ -191,6 +204,11 @@ "spinjs": "github:fgnass/spin.js@^2.3.2" } }, + "github:angular-ui/bower-ui-grid@3.0.7": { + "dependencies": { + "pdfmake": "github:bpampuch/pdfmake@^0.1.20" + } + }, "github:akuznetsov-gridgain/angular-strap@fix-1852-2.3.6": { "main": "dist/angular-strap.tpl", "dependencies": { http://git-wip-us.apache.org/repos/asf/ignite/blob/da50f0c6/modules/control-center-web/src/main/js/public/stylesheets/style.scss ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/public/stylesheets/style.scss b/modules/control-center-web/src/main/js/public/stylesheets/style.scss index d359ab5..7c9e010 100644 --- a/modules/control-center-web/src/main/js/public/stylesheets/style.scss +++ b/modules/control-center-web/src/main/js/public/stylesheets/style.scss @@ -1693,118 +1693,6 @@ treecontrol.tree-classic { min-height: 100px; } -.ag-bootstrap { - :focus { - outline: none; - } - - .ag-root { - } - - .ag-cell { - padding: 3px 6px; - border-right: 1px solid #ccc; - } - - .ag-pinned-header { - border-bottom: 2px solid $table-border-color; - } - - .ag-header-container { - border-bottom: 2px solid $table-border-color; - } - - .ag-header-cell { - text-align: left; - border-right: 1px solid #ccc - } - - .ag-header-group-cell { - border-right: 1px solid grey; - } - - .ag-header-group-cell-with-group { - border-bottom: 1px solid grey; - } - - .ag-header-cell-label { - padding: 5px; - font-weight: 700; - font-size: 13px; - } - - .ag-header-group-cell-label { - padding: 5px; - font-weight: bold; - } - - .ag-header-cell-menu-button { - padding: 2px; - margin-top: 4px; - border: 1px solid transparent; - border-radius: 3px; - box-sizing: content-box; /* When using bootstrap, box-sizing was set to 'border-box' */ - } - - .ag-header-cell-menu-button:hover { - border: 1px solid black; - } - - .ag-row-odd { - background-color: #f6f6f6; - } - - .ag-row-even { - background-color: white; - } - - .ag-body { - background-color: $table-bg; - } - - .ag-row-selected { - background-color: #B2DFEE; - /*background-color: #ECF1EF;*/ - } - - .ag-group-cell-entire-row { - background-color: #aaa; - } - - .ag-group-cell { - } - - .ag-filter-checkbox { - position: relative; - top: 2px; - left: 2px; - } - - .ag-filter-header-container { - border-bottom: 1px solid lightgrey; - } - - .ag-filter { - border: 1px solid black; - background-color: #f0f0f0; - } - - .ag-selection-checkbox { - margin-left: 4px; - } - - .ag-overlay-loading-wrapper { - background-color: rgba(255, 255, 255, 0.9); - } - - .ag-overlay-loading-center { - background-color: white; - border: 1px solid $ignite-darck-border-color; - border-radius: 10px; - padding: 10px; - } -} - .carousel-caption { position: relative; left: auto; @@ -1880,3 +1768,13 @@ treecontrol.tree-classic { float: none; } } + +.grid { + .ui-grid-menu-button { + margin-top: -1px; + } + + .ui-grid-column-menu-button-last-col { + margin-right: 10px + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/da50f0c6/modules/control-center-web/src/main/js/views/configuration/caches.jade ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/views/configuration/caches.jade b/modules/control-center-web/src/main/js/views/configuration/caches.jade index f063d05..dd32caf 100644 --- a/modules/control-center-web/src/main/js/views/configuration/caches.jade +++ b/modules/control-center-web/src/main/js/views/configuration/caches.jade @@ -38,7 +38,7 @@ include ../includes/controls div(dw-loading='loadingCachesScreen' dw-loading-options='{text: "Loading caches screen...", className: "page-loading-overlay"}') div(ng-show='ui.ready') hr - +main-table('Caches:', 'caches', 'cacheName', 'selectItem(row)', '{{$index + 1}}) {{row.name}}, {{row.cacheMode | displayValue:cacheModes:"Cache mode not set"}}, {{row.atomicityMode | displayValue:atomicities:"Cache atomicity not set"}}') + +main-table('Caches:', 'caches', 'cacheName', 'selectItem(row)', '{{$index + 1}}) {{row.label}}', 'label') .padding-top-dflt(bs-affix) .panel-tip-container(data-placement='bottom' bs-tooltip data-title='Create new cache') button.btn.btn-primary(id='new-item' ng-click='createItem()') Add cache http://git-wip-us.apache.org/repos/asf/ignite/blob/da50f0c6/modules/control-center-web/src/main/js/views/configuration/clusters.jade ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/views/configuration/clusters.jade b/modules/control-center-web/src/main/js/views/configuration/clusters.jade index 1fe4de6..f7e62d9 100644 --- a/modules/control-center-web/src/main/js/views/configuration/clusters.jade +++ b/modules/control-center-web/src/main/js/views/configuration/clusters.jade @@ -35,7 +35,7 @@ include ../includes/controls div(dw-loading='loadingClustersScreen' dw-loading-options='{text: "Loading clusters screen...", className: "page-loading-overlay"}') div(ng-show='ui.ready') hr - +main-table('Clusters:', 'clusters', 'clusterName', 'selectItem(row)', '{{$index + 1}}) {{row.name}}, {{row.discovery.kind | displayValue:discoveries:"Discovery not set"}}') + +main-table('Clusters:', 'clusters', 'clusterName', 'selectItem(row)', '{{$index + 1}}) {{row.label}}', 'label') .padding-top-dflt(bs-affix) .panel-tip-container(data-placement='bottom' bs-tooltip data-title='Create new cluster') button.btn.btn-primary(id='new-item' ng-click='createItem()') Add cluster http://git-wip-us.apache.org/repos/asf/ignite/blob/da50f0c6/modules/control-center-web/src/main/js/views/configuration/igfs.jade ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/views/configuration/igfs.jade b/modules/control-center-web/src/main/js/views/configuration/igfs.jade index 200ee73..199bf0d 100644 --- a/modules/control-center-web/src/main/js/views/configuration/igfs.jade +++ b/modules/control-center-web/src/main/js/views/configuration/igfs.jade @@ -34,7 +34,7 @@ include ../includes/controls div(dw-loading='loadingIgfsScreen' dw-loading-options='{text: "Loading IGFS screen...", className: "page-loading-overlay"}') div(ng-show='ui.ready') hr - +main-table('IGFS:', 'igfss', 'igfsName', 'selectItem(row)', '{{$index + 1}}) {{row.name}}') + +main-table('IGFS:', 'igfss', 'igfsName', 'selectItem(row)', '{{$index + 1}}) {{row.name}}', 'name') .padding-top-dflt(bs-affix) .panel-tip-container(data-placement='bottom' bs-tooltip data-title='Create new IGFS') button.btn.btn-primary(id='new-item' ng-click='createItem()') Add IGFS http://git-wip-us.apache.org/repos/asf/ignite/blob/da50f0c6/modules/control-center-web/src/main/js/views/configuration/metadata-load.jade ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/views/configuration/metadata-load.jade b/modules/control-center-web/src/main/js/views/configuration/metadata-load.jade index 57adb68..a6800d0 100644 --- a/modules/control-center-web/src/main/js/views/configuration/metadata-load.jade +++ b/modules/control-center-web/src/main/js/views/configuration/metadata-load.jade @@ -31,12 +31,12 @@ mixin chk(mdl, change, tip) .settings-row(ng-repeat='field in metadataDb') +form-row-custom(['col-xs-4 col-sm-3 col-md-3'], ['col-xs-8 col-sm-9 col-md-9'], 'preset') .metadata-content(ng-show='loadMeta.action == "schemas"') - table.table.metadata(st-table='loadMeta.displayedSchemas' st-safe-src='loadMeta.schemas' st-set-filter='schemasSearch') + table.table.metadata(st-table='loadMeta.displayedSchemas' st-safe-src='loadMeta.schemas') thead tr th.header(colspan='2') .col-sm-4.pull-right - input.form-control(type='text' st-search='' placeholder='Filter schemas...' ng-model='loadMeta.displayedSchemasFilter' ng-change='selectSchema()') + input.form-control(type='text' st-search='name' placeholder='Filter schemas...' ng-model='loadMeta.displayedSchemasFilter' ng-change='selectSchema()') tr th(width='50px') +chk('loadMeta.allSchemasSelected', 'selectAllSchemas()', 'Select all schemas') @@ -58,12 +58,12 @@ mixin chk(mdl, change, tip) label.required Package: span input.form-control(id='metadataLoadPackage' type="text" ng-model='ui.packageName' placeholder='Package for POJOs generation' bs-tooltip='' data-title='Package that will be used for POJOs generation' data-placement='top' data-trigger='hover') - table.table.metadata(st-table='loadMeta.displayedTables' st-safe-src='loadMeta.tables' st-set-filter='tablesSearch') + table.table.metadata(st-table='loadMeta.displayedTables' st-safe-src='loadMeta.tables') thead tr th.header(colspan='3') .col-sm-4.pull-right - input.form-control(type='text' st-search='' placeholder='Filter tables...' ng-model='loadMeta.displayedTablesFilter' ng-change='selectTable()') + input.form-control(type='text' st-search='label' placeholder='Filter tables...' ng-model='loadMeta.displayedTablesFilter' ng-change='selectTable()') tr th(width='50px') +chk('loadMeta.allTablesSelected', 'selectAllTables()', 'Select all tables') http://git-wip-us.apache.org/repos/asf/ignite/blob/da50f0c6/modules/control-center-web/src/main/js/views/configuration/metadata.jade ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/views/configuration/metadata.jade b/modules/control-center-web/src/main/js/views/configuration/metadata.jade index 9b779a6..b1bd498 100644 --- a/modules/control-center-web/src/main/js/views/configuration/metadata.jade +++ b/modules/control-center-web/src/main/js/views/configuration/metadata.jade @@ -38,7 +38,7 @@ include ../includes/controls div(ng-show='ui.ready') hr .padding-bottom-dflt(ng-show='metadatas && metadatas.length > 0') - table.links(st-set-filter='metadatasSearch' st-table='displayedRows' st-safe-src='metadatas') + table.links(st-table='displayedRows' st-safe-src='metadatas') thead tr th @@ -50,7 +50,7 @@ include ../includes/controls a.labelFormField(ng-if='ui.showValid' ng-click='toggleValid()') Key fields should be configured: {{(displayedRows | metadatasValidation:false:true).length}}  a.labelFormField(ng-if='!ui.showValid' ng-click='toggleValid()') Show all metadata: {{displayedRows.length}}  .col-sm-4 - input.form-control.pull-right(type='text' st-search='' placeholder='Filter metadatas...') + input.form-control.pull-right(type='text' st-search='valueType' placeholder='Filter metadatas...') tbody tr td http://git-wip-us.apache.org/repos/asf/ignite/blob/da50f0c6/modules/control-center-web/src/main/js/views/configuration/summary.jade ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/views/configuration/summary.jade b/modules/control-center-web/src/main/js/views/configuration/summary.jade index 35436f0..db057cb 100644 --- a/modules/control-center-web/src/main/js/views/configuration/summary.jade +++ b/modules/control-center-web/src/main/js/views/configuration/summary.jade @@ -60,7 +60,7 @@ mixin pojos(side) .padding-dflt(ng-if='clusters.length == 0') | You have no clusters configured. Please configure them   a(href='/configuration/clusters') here. - +main-table('Clusters:', 'clusters', 'clusterName', 'selectItem(row)', '{{$index + 1}}) {{row.name}}') + +main-table('Clusters:', 'clusters', 'clusterName', 'selectItem(row)', '{{$index + 1}}) {{row.name}}', 'name') div(ng-show='selectedItem && tableVisibleRow(displayedRows, selectedItem)' role='tab') .padding-top-dflt(ng-if='clusters.length > 0' bs-affix) button.btn.btn-primary(id='download' ng-click='downloadConfiguration()' bs-tooltip data-title='Download configuration' data-placement='bottom') Download http://git-wip-us.apache.org/repos/asf/ignite/blob/da50f0c6/modules/control-center-web/src/main/js/views/includes/controls.jade ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/views/includes/controls.jade b/modules/control-center-web/src/main/js/views/includes/controls.jade index 7e8461f..ff29533 100644 --- a/modules/control-center-web/src/main/js/views/includes/controls.jade +++ b/modules/control-center-web/src/main/js/views/includes/controls.jade @@ -481,15 +481,15 @@ mixin form-row-custom(lblClasses, fieldClasses, dataSource) .input-tip button#newIndexType.select-toggle.form-control(bs-select ng-model='field.newIndexType' data-placeholder='Select index type' bs-options="item.value as item.label for item in indexType" tabindex='0' on-enter=btnVisibleAndSave on-escape='tableReset()') -mixin main-table(title, rows, focusId, click, rowTemplate) +mixin main-table(title, rows, focusId, click, rowTemplate, searchField) .padding-bottom-dflt(ng-show='#{rows} && #{rows}.length > 0') - table.links(st-set-filter='#{rows}Search' st-table='displayedRows' st-safe-src='#{rows}') + table.links(st-table='displayedRows' st-safe-src='#{rows}') thead tr th lable.labelHeader.labelFormField #{title} .col-sm-3.pull-right(style='padding: 0') - input.form-control(type='text' st-search='' placeholder='Filter #{rows}...') + input.form-control(type='text' st-search='#{searchField}' placeholder='Filter #{rows}...') tbody tr td http://git-wip-us.apache.org/repos/asf/ignite/blob/da50f0c6/modules/control-center-web/src/main/js/views/sql/sql.jade ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/views/sql/sql.jade b/modules/control-center-web/src/main/js/views/sql/sql.jade index a63cf20..bc4dae8 100644 --- a/modules/control-center-web/src/main/js/views/sql/sql.jade +++ b/modules/control-center-web/src/main/js/views/sql/sql.jade @@ -152,10 +152,10 @@ mixin chart-settings(mdl) +result-toolbar .col-xs-4 .btn-group.pull-right(ng-disabled='paragraph.loading') - button.btn.btn-primary.fieldButton(ng-click='exportPage(paragraph)' bs-tooltip data-title='{{actionTooltip(paragraph, "export", false)}}') Export + button.btn.btn-primary.fieldButton(ng-click='exportCsv(paragraph)' bs-tooltip data-title='{{actionTooltip(paragraph, "export", false)}}') Export button.btn.btn-primary(id='export-item-dropdown' data-toggle='dropdown' data-container='body' bs-dropdown='exportDropdown' data-placement='bottom-right') span.caret - .sql-table.ag-bootstrap(ag-grid='paragraph.gridOptions') + .grid(ui-grid='paragraph.gridOptions' ui-grid-auto-resize ui-grid-exporter ng-style='{ height: paragraph.gridOptions.height }') div(ng-show='paragraph.chart() && paragraph.nonEmpty()') div(ng-show='paragraph.queryExecute()') +chart-settings