mirror of
https://github.com/getredash/redash.git
synced 2025-12-25 01:03:20 -05:00
[#138] QueryEditCtrl cleanup
This commit is contained in:
@@ -17,6 +17,15 @@ angular.module('redash', [
|
||||
]).config(['$routeProvider', '$locationProvider', '$compileProvider', 'growlProvider',
|
||||
function($routeProvider, $locationProvider, $compileProvider, growlProvider) {
|
||||
|
||||
function newQuery(Query) {
|
||||
return new Query({
|
||||
query: "",
|
||||
name: "New Query",
|
||||
ttl: -1,
|
||||
user: currentUser
|
||||
});
|
||||
}
|
||||
|
||||
function getQuery(Query, $q, $route) {
|
||||
var defer = $q.defer();
|
||||
|
||||
@@ -42,6 +51,14 @@ angular.module('redash', [
|
||||
controller: 'QueriesCtrl',
|
||||
reloadOnSearch: false
|
||||
});
|
||||
$routeProvider.when('/queries/new', {
|
||||
templateUrl: '/views/query.html',
|
||||
controller: 'QueryEditCtrl',
|
||||
reloadOnSearch: false,
|
||||
resolve: {
|
||||
'query': ['Query', newQuery]
|
||||
}
|
||||
});
|
||||
$routeProvider.when('/queries/:queryId', {
|
||||
templateUrl: '/views/query.html',
|
||||
controller: 'QueryViewCtrl',
|
||||
@@ -50,11 +67,6 @@ angular.module('redash', [
|
||||
'query': ['Query', '$q', '$route', getQuery]
|
||||
}
|
||||
});
|
||||
$routeProvider.when('/queries/new', {
|
||||
templateUrl: '/views/query.html',
|
||||
controller: 'QueryEditCtrl',
|
||||
reloadOnSearch: false
|
||||
});
|
||||
$routeProvider.when('/queries/:queryId/source', {
|
||||
templateUrl: '/views/query.html',
|
||||
controller: 'QueryEditCtrl',
|
||||
|
||||
@@ -1,125 +1,106 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
function QueryEditCtrl($controller, $scope, $window, $route, $http, $location, growl, notifications, Query, Visualization) {
|
||||
var pristineHash = "";
|
||||
var leavingPageText = "You will lose your changes if you leave";
|
||||
function QueryEditCtrl($controller, $scope, $window, $route, $location, growl, Query, Visualization) {
|
||||
var pristineHash = "";
|
||||
var leavingPageText = "You will lose your changes if you leave";
|
||||
var isNewQuery = !$route.current.locals.query.id;
|
||||
|
||||
// controller inheritance
|
||||
$controller('QueryViewCtrl', {$scope: $scope});
|
||||
// controller inheritance
|
||||
$controller('QueryViewCtrl', {$scope: $scope});
|
||||
|
||||
$scope.sourceMode = true;
|
||||
$scope.sourceMode = true;
|
||||
$scope.isDirty = undefined;
|
||||
|
||||
$scope.dirty = undefined;
|
||||
$scope.isNewQuery = false;
|
||||
$scope.canEdit = currentUser.canEdit($scope.query);
|
||||
|
||||
$scope.canEdit = currentUser.canEdit($scope.query);
|
||||
$scope.newVisualization = undefined;
|
||||
|
||||
$scope.newVisualization = undefined;
|
||||
$window.onbeforeunload = function() {
|
||||
if ($scope.canEdit && $scope.isDirty) {
|
||||
return leavingPageText;
|
||||
}
|
||||
}
|
||||
|
||||
$window.onbeforeunload = function () {
|
||||
if ($scope.canEdit && $scope.dirty) {
|
||||
return leavingPageText;
|
||||
}
|
||||
$scope.$on('$locationChangeStart', function(event, next, current) {
|
||||
if (next.split("#")[0] == current.split("#")[0]) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$scope.canEdit) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($scope.isDirty && !confirm(leavingPageText + "\n\nAre you sure you want to leave this page?")) {
|
||||
event.preventDefault();
|
||||
} else {
|
||||
Mousetrap.unbind("meta+s");
|
||||
}
|
||||
});
|
||||
|
||||
$scope.saveQuery = function(duplicate, oldId) {
|
||||
if (!oldId) {
|
||||
oldId = $scope.query.id;
|
||||
}
|
||||
|
||||
delete $scope.query.latest_query_data;
|
||||
$scope.query.$save(function(q) {
|
||||
pristineHash = q.getHash();
|
||||
$scope.isDirty = false;
|
||||
|
||||
if (duplicate) {
|
||||
growl.addSuccessMessage("Query forked");
|
||||
} else {
|
||||
growl.addSuccessMessage("Query saved");
|
||||
}
|
||||
|
||||
function getQuerySourceUrl(queryId) {
|
||||
return '/queries/' + queryId + '/source#' + $location.hash();
|
||||
};
|
||||
|
||||
Mousetrap.bindGlobal("meta+s", function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
if ($scope.canEdit) {
|
||||
$scope.saveQuery();
|
||||
}
|
||||
});
|
||||
|
||||
$scope.$on('$locationChangeStart', function (event, next, current) {
|
||||
if (next.split("#")[0] == current.split("#")[0]) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$scope.canEdit) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($scope.dirty && !confirm(leavingPageText + "\n\nAre you sure you want to leave this page?")) {
|
||||
event.preventDefault();
|
||||
} else {
|
||||
Mousetrap.unbind("meta+s");
|
||||
}
|
||||
});
|
||||
|
||||
$scope.saveQuery = function (duplicate, oldId) {
|
||||
if (!oldId) {
|
||||
oldId = $scope.query.id;
|
||||
}
|
||||
|
||||
delete $scope.query.latest_query_data;
|
||||
$scope.query.$save(function (q) {
|
||||
pristineHash = q.getHash();
|
||||
$scope.dirty = false;
|
||||
|
||||
if (duplicate) {
|
||||
growl.addSuccessMessage("Query forked");
|
||||
} else {
|
||||
growl.addSuccessMessage("Query saved");
|
||||
}
|
||||
|
||||
if (oldId != q.id) {
|
||||
$location.url(getQuerySourceUrl(q.id)).replace();
|
||||
}
|
||||
}, function (httpResponse) {
|
||||
growl.addErrorMessage("Query could not be saved");
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// new query
|
||||
if (!$route.current.locals.query) {
|
||||
$scope.query = new Query({
|
||||
query: "",
|
||||
name: "New Query",
|
||||
ttl: -1,
|
||||
user: currentUser
|
||||
});
|
||||
$scope.lockButton(false);
|
||||
$scope.isOwner = $scope.canEdit = true;
|
||||
$scope.isNewQuery = true;
|
||||
|
||||
var unbind = $scope.$watch('selectedTab == "add"', function (newPanel) {
|
||||
if (newPanel && route.params.queryId == undefined) {
|
||||
unbind();
|
||||
$scope.saveQuery();
|
||||
}
|
||||
});
|
||||
if (oldId != q.id) {
|
||||
$location.url($location.url().replace(oldId, q.id)).replace();
|
||||
}
|
||||
|
||||
$scope.$watch(function () {
|
||||
return $scope.query.getHash();
|
||||
}, function (newHash) {
|
||||
$scope.dirty = (newHash !== pristineHash);
|
||||
});
|
||||
|
||||
|
||||
$scope.deleteVisualization = function ($e, vis) {
|
||||
$e.preventDefault();
|
||||
if (confirm('Are you sure you want to delete ' + vis.name + ' ?')) {
|
||||
Visualization.delete(vis);
|
||||
if ($scope.selectedTab == vis.id) {
|
||||
$scope.selectedTab = DEFAULT_TAB;
|
||||
$location.hash($scope.selectedTab);
|
||||
}
|
||||
$scope.query.visualizations =
|
||||
$scope.query.visualizations.filter(function (v) {
|
||||
return vis.id !== v.id;
|
||||
});
|
||||
}
|
||||
};
|
||||
}, function(httpResponse) {
|
||||
growl.addErrorMessage("Query could not be saved");
|
||||
});
|
||||
};
|
||||
|
||||
angular.module('redash.controllers')
|
||||
.controller('QueryEditCtrl', ['$controller', '$scope', '$window', '$route', '$http', '$location', 'growl', 'notifications', 'Query', 'Visualization', QueryEditCtrl]);
|
||||
|
||||
$scope.deleteVisualization = function($e, vis) {
|
||||
$e.preventDefault();
|
||||
if (confirm('Are you sure you want to delete ' + vis.name + ' ?')) {
|
||||
Visualization.delete(vis);
|
||||
if ($scope.selectedTab == vis.id) {
|
||||
$scope.selectedTab = DEFAULT_TAB;
|
||||
$location.hash($scope.selectedTab);
|
||||
}
|
||||
$scope.query.visualizations =
|
||||
$scope.query.visualizations.filter(function(v) {
|
||||
return vis.id !== v.id;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$scope.$watch(function() {
|
||||
return $scope.query.getHash();
|
||||
}, function(newHash) {
|
||||
$scope.isDirty = (newHash !== pristineHash);
|
||||
});
|
||||
|
||||
if (isNewQuery) {
|
||||
// $scope.lockButton(false);
|
||||
|
||||
// save new query when creating a visualization
|
||||
var unbind = $scope.$watch('selectedTab == "add"', function(newPanel) {
|
||||
if (newPanel && $route.current.params.queryId == undefined) {
|
||||
unbind();
|
||||
$scope.saveQuery();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
angular.module('redash.controllers').controller('QueryEditCtrl', [
|
||||
'$controller', '$scope', '$window', '$route', '$location', 'growl', 'Query',
|
||||
'Visualization', QueryEditCtrl
|
||||
]);
|
||||
})();
|
||||
@@ -9,6 +9,7 @@
|
||||
$scope.queryExecuting = false;
|
||||
|
||||
$scope.isQueryOwner = currentUser.id === $scope.query.user.id;
|
||||
$scope.canViewSource = currentUser.hasPermission('view_source');
|
||||
|
||||
$scope.lockButton = function(lock) {
|
||||
$scope.queryExecuting = lock;
|
||||
|
||||
@@ -3,6 +3,24 @@
|
||||
|
||||
var directives = angular.module('redash.directives', []);
|
||||
|
||||
directives.directive('keyboardShortcut', function() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
template: '<span>foo</span>',
|
||||
scope: {
|
||||
key: '@',
|
||||
action: '='
|
||||
},
|
||||
link: function($scope) {
|
||||
Mousetrap.bindGlobal($scope.key, function(e) {
|
||||
e.preventDefault();
|
||||
$scope.action();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
directives.directive('rdTab', function() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
(function() {
|
||||
'use strict'
|
||||
|
||||
function querySourceLink() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
template: '<span ng-show="query.id && canViewSource">\
|
||||
<a ng-show="!sourceMode"\
|
||||
ng-href="{{query.id}}/source#{{selectedTab}}">Show Source\
|
||||
</a>\
|
||||
<a ng-show="sourceMode"\
|
||||
ng-href="/queries/{{query.id}}#{{selectedTab}}">Hide Source\
|
||||
</a>\
|
||||
</span>'
|
||||
}
|
||||
}
|
||||
|
||||
function queryEditor() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
@@ -58,7 +73,7 @@
|
||||
return {
|
||||
restrict: 'E',
|
||||
template: '<select\
|
||||
ng-disabled="!isOwner"\
|
||||
ng-disabled="!isQueryOwner"\
|
||||
ng-model="query.ttl"\
|
||||
ng-change="saveQuery()"\
|
||||
ng-options="c.value as c.name for c in refreshOptions">\
|
||||
@@ -96,7 +111,8 @@
|
||||
}
|
||||
|
||||
angular.module('redash.directives')
|
||||
.directive('queryRefreshSelect', queryRefreshSelect)
|
||||
.directive('querySourceLink', querySourceLink)
|
||||
.directive('queryEditor', queryEditor)
|
||||
.directive('queryRefreshSelect', queryRefreshSelect)
|
||||
.directive('queryFormatter', ['$http', queryFormatter]);
|
||||
})();
|
||||
@@ -1,5 +1,7 @@
|
||||
|
||||
<div class="container">
|
||||
<keyboard-shortcut ng-if="canEdit" key="meta+s" action="saveQuery"></keyboard-shortcut>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div class="row">
|
||||
@@ -14,9 +16,10 @@
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-2" ng-hide="isNewQuery || !currentUser.hasPermission('view_source')">
|
||||
<a ng-show="!sourceMode" ng-href="{{query.id}}/source#{{selectedTab}}" class="rd-hidden-xs pull-right">Show Source</a>
|
||||
<a ng-show="sourceMode" ng-href="/queries/{{query.id}}#{{selectedTab}}" class="rd-hidden-xs pull-right">Hide Source</a>
|
||||
<div class="col-lg-2">
|
||||
<div class="rd-hidden-xs pull-right">
|
||||
<query-source-link></query-source-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -39,10 +42,7 @@
|
||||
<strong>{{queryResult.getData().length}}</strong>
|
||||
</p>
|
||||
<p>
|
||||
<a ng-href="{{sourceHref}}" ng-click="toggleSource()">
|
||||
<span ng-show="sourceMode">Hide Source</span>
|
||||
<span ng-show="!sourceMode">View Source</span>
|
||||
</a>
|
||||
<query-source-link></query-source-link>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -64,17 +64,19 @@
|
||||
</button>
|
||||
|
||||
<button class="btn btn-success btn-xs" ng-show="canEdit" ng-click="saveQuery()">
|
||||
<span class="glyphicon glyphicon-floppy-disk"> </span> Save<span ng-show="dirty">*</span>
|
||||
<span class="glyphicon glyphicon-floppy-disk"> </span> Save<span ng-show="isDirty">*</span>
|
||||
</button>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- code editor -->
|
||||
<p ng-show="sourceMode">
|
||||
<query-editor query="query" lock="queryExecuting"></query-editor>
|
||||
</p>
|
||||
<hr ng-show="sourceMode">
|
||||
<div ng-show="sourceMode">
|
||||
<p>
|
||||
<query-editor query="query" lock="queryExecuting"></query-editor>
|
||||
</p>
|
||||
<hr>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user