mirror of
https://github.com/valitydev/redash.git
synced 2024-11-07 09:28:51 +00:00
[#138] editCtrl inheriting viewCtrl
This commit is contained in:
parent
2ba4bcd98e
commit
af9318fbd1
@ -121,6 +121,7 @@
|
|||||||
<script src="/scripts/controllers/controllers.js"></script>
|
<script src="/scripts/controllers/controllers.js"></script>
|
||||||
<script src="/scripts/controllers/admin_controllers.js"></script>
|
<script src="/scripts/controllers/admin_controllers.js"></script>
|
||||||
<script src="/scripts/controllers/query_view.js"></script>
|
<script src="/scripts/controllers/query_view.js"></script>
|
||||||
|
<script src="/scripts/controllers/query_edit.js"></script>
|
||||||
<script src="/scripts/visualizations/base.js"></script>
|
<script src="/scripts/visualizations/base.js"></script>
|
||||||
<script src="/scripts/visualizations/chart.js"></script>
|
<script src="/scripts/visualizations/chart.js"></script>
|
||||||
<script src="/scripts/visualizations/cohort.js"></script>
|
<script src="/scripts/visualizations/cohort.js"></script>
|
||||||
|
@ -42,35 +42,25 @@ angular.module('redash', [
|
|||||||
controller: 'QueriesCtrl',
|
controller: 'QueriesCtrl',
|
||||||
reloadOnSearch: false
|
reloadOnSearch: false
|
||||||
});
|
});
|
||||||
$routeProvider.when('/queries/new', {
|
|
||||||
templateUrl: '/views/queryview.html',
|
|
||||||
controller: 'QueryViewCtrl',
|
|
||||||
reloadOnSearch: false,
|
|
||||||
resolve: {
|
|
||||||
'viewSource': function isViewSource() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// TODO
|
|
||||||
// we should have 2 controllers: queryViewCtrl and queryEditCtrl
|
|
||||||
$routeProvider.when('/queries/:queryId', {
|
$routeProvider.when('/queries/:queryId', {
|
||||||
templateUrl: '/views/queryview.html',
|
templateUrl: '/views/query.html',
|
||||||
controller: 'QueryViewCtrl',
|
controller: 'QueryViewCtrl',
|
||||||
reloadOnSearch: false,
|
reloadOnSearch: false,
|
||||||
resolve: {
|
resolve: {
|
||||||
'query': ['Query', '$q', '$route', getQuery]
|
'query': ['Query', '$q', '$route', getQuery]
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
$routeProvider.when('/queries/new', {
|
||||||
|
templateUrl: '/views/query.html',
|
||||||
|
controller: 'QueryEditCtrl',
|
||||||
|
reloadOnSearch: false
|
||||||
|
});
|
||||||
$routeProvider.when('/queries/:queryId/source', {
|
$routeProvider.when('/queries/:queryId/source', {
|
||||||
templateUrl: '/views/queryview.html',
|
templateUrl: '/views/query.html',
|
||||||
controller: 'QueryViewCtrl',
|
controller: 'QueryEditCtrl',
|
||||||
reloadOnSearch: false,
|
reloadOnSearch: false,
|
||||||
resolve: {
|
resolve: {
|
||||||
'query': ['Query', '$q', '$route', getQuery],
|
'query': ['Query', '$q', '$route', getQuery]
|
||||||
'viewSource': function isViewSource() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$routeProvider.when('/admin/status', {
|
$routeProvider.when('/admin/status', {
|
||||||
|
122
rd_ui/app/scripts/controllers/query_edit.js
Normal file
122
rd_ui/app/scripts/controllers/query_edit.js
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
(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";
|
||||||
|
|
||||||
|
$controller('QueryViewCtrl', {$scope: $scope});
|
||||||
|
|
||||||
|
$scope.dirty = undefined;
|
||||||
|
$scope.isNewQuery = false;
|
||||||
|
|
||||||
|
$scope.isSourceVisible = true;
|
||||||
|
|
||||||
|
$scope.newVisualization = undefined;
|
||||||
|
|
||||||
|
$window.onbeforeunload = function () {
|
||||||
|
if ($scope.canEdit && $scope.dirty) {
|
||||||
|
return leavingPageText;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$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;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
angular.module('redash.controllers')
|
||||||
|
.controller('QueryEditCtrl', ['$controller', '$scope', '$window', '$route', '$http', '$location', 'growl', 'notifications', 'Query', 'Visualization', QueryEditCtrl]);
|
||||||
|
|
||||||
|
})();
|
@ -1,78 +1,24 @@
|
|||||||
(function () {
|
(function () {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var QueryViewCtrl = function ($scope, $window, $route, $http, $location, growl, notifications, Query, Visualization, DataSource) {
|
function QueryViewCtrl($scope, $window, $route, $http, $location, growl, notifications, Query, Visualization) {
|
||||||
var DEFAULT_TAB = 'table';
|
var DEFAULT_TAB = 'table';
|
||||||
var pristineHash = "";
|
|
||||||
var leavingPageText = "You will lose your changes if you leave";
|
|
||||||
var route = $route.current;
|
var route = $route.current;
|
||||||
|
|
||||||
$scope.dataSources = DataSource.get(function(dataSources) {
|
$scope.query = route.locals.query;
|
||||||
$scope.query.data_source_id = $scope.query.data_source_id || dataSources[0].id;
|
$scope.queryResult = $scope.query.getQueryResult();
|
||||||
});
|
|
||||||
|
|
||||||
$scope.dirty = undefined;
|
|
||||||
$scope.isNewQuery = false;
|
|
||||||
$scope.isOwner = false;
|
|
||||||
$scope.canEdit = false;
|
|
||||||
$scope.canFork = false;
|
|
||||||
|
|
||||||
$scope.isSourceVisible = route.locals.viewSource;
|
|
||||||
|
|
||||||
$scope.queryExecuting = false;
|
$scope.queryExecuting = false;
|
||||||
|
|
||||||
$scope.newVisualization = undefined;
|
$scope.isOwner = currentUser.canEdit($scope.query);
|
||||||
|
$scope.canEdit = $scope.isSourceVisible && $scope.isOwner;
|
||||||
|
$scope.canFork = true;
|
||||||
|
|
||||||
updateSourceHref();
|
$scope.sourceHref = getQuerySourceUrl();
|
||||||
|
|
||||||
$window.onbeforeunload = function () {
|
|
||||||
if ($scope.canEdit && $scope.dirty) {
|
|
||||||
return leavingPageText;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateSourceHref() {
|
|
||||||
if ($scope.query && $scope.query.id) {
|
|
||||||
$scope.sourceHref = $scope.isSourceVisible ?
|
|
||||||
$location.url().replace('source', '') : getQuerySourceUrl($scope.query.id);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function getQuerySourceUrl(queryId) {
|
function getQuerySourceUrl(queryId) {
|
||||||
return '/queries/' + queryId + '/source#' + $location.hash();
|
return '/queries/' + $scope.query.id + '/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.$watch(function () {
|
|
||||||
return $location.hash()
|
|
||||||
}, function (hash) {
|
|
||||||
$scope.selectedTab = hash || DEFAULT_TAB;
|
|
||||||
updateSourceHref();
|
|
||||||
});
|
|
||||||
|
|
||||||
$scope.lockButton = function (lock) {
|
$scope.lockButton = function (lock) {
|
||||||
$scope.queryExecuting = lock;
|
$scope.queryExecuting = lock;
|
||||||
};
|
};
|
||||||
@ -88,31 +34,6 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
$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");
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.duplicateQuery = function () {
|
$scope.duplicateQuery = function () {
|
||||||
var oldId = $scope.query.id;
|
var oldId = $scope.query.id;
|
||||||
$scope.query.id = null;
|
$scope.query.id = null;
|
||||||
@ -121,7 +42,17 @@
|
|||||||
$scope.saveQuery(true, oldId);
|
$scope.saveQuery(true, oldId);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Query Editor:
|
$scope.executeQuery = function () {
|
||||||
|
$scope.queryResult = $scope.query.getQueryResult(0);
|
||||||
|
$scope.lockButton(true);
|
||||||
|
$scope.cancelling = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.cancelExecution = function () {
|
||||||
|
$scope.cancelling = true;
|
||||||
|
$scope.queryResult.cancelExecution();
|
||||||
|
};
|
||||||
|
|
||||||
$scope.editorOptions = {
|
$scope.editorOptions = {
|
||||||
mode: 'text/x-sql',
|
mode: 'text/x-sql',
|
||||||
lineWrapping: true,
|
lineWrapping: true,
|
||||||
@ -204,100 +135,17 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// view or source pages: controller is instantiated with a query
|
|
||||||
if (route.locals.query) {
|
|
||||||
$scope.query = route.locals.query;
|
|
||||||
pristineHash = $scope.query.getHash();
|
|
||||||
$scope.dirty = false;
|
|
||||||
$scope.queryResult = $scope.query.getQueryResult();
|
|
||||||
|
|
||||||
$scope.isOwner = currentUser.canEdit($scope.query);
|
|
||||||
$scope.canEdit = $scope.isSourceVisible && $scope.isOwner;
|
|
||||||
$scope.canFork = true;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// new query
|
|
||||||
$scope.query = new Query({
|
|
||||||
query: "",
|
|
||||||
name: "New Query",
|
|
||||||
ttl: -1,
|
|
||||||
user: currentUser
|
|
||||||
});
|
|
||||||
$scope.lockButton(false);
|
|
||||||
$scope.isOwner = $scope.canEdit = true;
|
|
||||||
$scope.isNewQuery = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
$scope.$watch('query.name', function () {
|
$scope.$watch('query.name', function () {
|
||||||
$scope.$parent.pageTitle = $scope.query.name;
|
$scope.$parent.pageTitle = $scope.query.name;
|
||||||
});
|
});
|
||||||
|
|
||||||
$scope.$watch(function () {
|
$scope.$watch(function () {
|
||||||
return $scope.query.getHash();
|
return $location.hash()
|
||||||
}, function (newHash) {
|
}, function (hash) {
|
||||||
$scope.dirty = (newHash !== pristineHash);
|
$scope.selectedTab = hash || DEFAULT_TAB;
|
||||||
});
|
$scope.sourceHref = getQuerySourceUrl();
|
||||||
|
|
||||||
$scope.updateDataSource = function() {
|
|
||||||
$scope.query.latest_query_data = null;
|
|
||||||
$scope.query.latest_query_data_id = null;
|
|
||||||
Query.save({
|
|
||||||
'id': $scope.query.id,
|
|
||||||
'data_source_id': $scope.query.data_source_id,
|
|
||||||
'latest_query_data_id': null
|
|
||||||
});
|
|
||||||
|
|
||||||
$scope.executeQuery();
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.executeQuery = function () {
|
|
||||||
$scope.queryResult = $scope.query.getQueryResult(0);
|
|
||||||
$scope.lockButton(true);
|
|
||||||
$scope.cancelling = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.cancelExecution = function () {
|
|
||||||
$scope.cancelling = true;
|
|
||||||
$scope.queryResult.cancelExecution();
|
|
||||||
};
|
|
||||||
|
|
||||||
$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;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var unbind = $scope.$watch('selectedTab == "add"', function (newPanel) {
|
|
||||||
if (newPanel && route.params.queryId == undefined) {
|
|
||||||
unbind();
|
|
||||||
$scope.saveQuery();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
angular.module('redash.controllers').controller('QueryViewCtrl',
|
angular.module('redash.controllers')
|
||||||
[
|
.controller('QueryViewCtrl', ['$scope', '$window', '$route', '$http', '$location', 'growl', 'notifications', 'Query', 'Visualization', QueryViewCtrl]);
|
||||||
'$scope',
|
|
||||||
'$window',
|
|
||||||
'$route',
|
|
||||||
'$http',
|
|
||||||
'$location',
|
|
||||||
'growl',
|
|
||||||
'notifications',
|
|
||||||
'Query',
|
|
||||||
'Visualization',
|
|
||||||
'DataSource',
|
|
||||||
QueryViewCtrl
|
|
||||||
]);
|
|
||||||
|
|
||||||
})();
|
})();
|
171
rd_ui/app/views/query.html
Normal file
171
rd_ui/app/views/query.html
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-10">
|
||||||
|
<h2>
|
||||||
|
<edit-in-place editable="isOwner" done="saveQuery" ignore-blanks='true' value="query.name"></edit-in-place>
|
||||||
|
</h2>
|
||||||
|
<p>
|
||||||
|
<em>
|
||||||
|
<edit-in-place editable="isOwner" done="saveQuery" editor="textarea" placeholder="No description" ignore-blanks='false' value="query.description"></edit-in-place>
|
||||||
|
</em>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-2" ng-hide="isNewQuery || !currentUser.hasPermission('view_source')">
|
||||||
|
<a ng-href="{{sourceHref}}" ng-click="toggleSource()" class="hidden-xs pull-right">
|
||||||
|
<span ng-show="isSourceVisible">Hide Source</span>
|
||||||
|
<span ng-show="!isSourceVisible">View Source</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="visible-xs">
|
||||||
|
<p>
|
||||||
|
<span class="text-muted">Last update </span>
|
||||||
|
<strong>
|
||||||
|
<rd-time-ago value="queryResult.query_result.retrieved_at"></rd-time-ago>
|
||||||
|
</strong>
|
||||||
|
|
||||||
|
<span class="text-muted">Created By </span>
|
||||||
|
<strong ng-hide="isOwner">{{query.user.name}}</strong>
|
||||||
|
<strong ng-show="isOwner">You</strong>
|
||||||
|
|
||||||
|
<span class="text-muted">Runtime </span>
|
||||||
|
<strong ng-show="!queryExecuting">{{queryResult.getRuntime() | durationHumanize}}</strong>
|
||||||
|
<span ng-show="queryExecuting">Running…</span>
|
||||||
|
|
||||||
|
<span class="text-muted">Rows </span>
|
||||||
|
<strong>{{queryResult.getData().length}}</strong>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<a ng-href="{{sourceHref}}" ng-click="toggleSource()">
|
||||||
|
<span ng-show="isSourceVisible">Hide Source</span>
|
||||||
|
<span ng-show="!isSourceVisible">View Source</span>
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<div ng-show="isSourceVisible">
|
||||||
|
<p>
|
||||||
|
<button type="button" class="btn btn-primary btn-xs" ng-disabled="queryExecuting" ng-click="executeQuery()">
|
||||||
|
<span class="glyphicon glyphicon-play"></span> Execute
|
||||||
|
</button>
|
||||||
|
<query-formatter query="query" lock="queryExecuting" editor-options="editorOptions"></query-formatter>
|
||||||
|
<span class="pull-right">
|
||||||
|
<button class="btn btn-xs btn-default rd-hidden-xs" ng-show="canFork" ng-click="duplicateQuery()">
|
||||||
|
<span class="glyphicon glyphicon-share-alt"></span> Fork
|
||||||
|
</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>
|
||||||
|
</button>
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- code editor -->
|
||||||
|
<p ng-show="isSourceVisible">
|
||||||
|
<query-editor query="query"></query-editor>
|
||||||
|
</p>
|
||||||
|
<hr ng-show="isSourceVisible">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-3 rd-hidden-xs">
|
||||||
|
<p>
|
||||||
|
<span class="glyphicon glyphicon-time"></span>
|
||||||
|
<span class="text-muted">Last update </span>
|
||||||
|
<strong>
|
||||||
|
<rd-time-ago value="queryResult.query_result.retrieved_at"></rd-time-ago>
|
||||||
|
</strong>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<span class="glyphicon glyphicon-user"></span>
|
||||||
|
<span class="text-muted">Created By </span>
|
||||||
|
<strong ng-hide="isOwner">{{query.user.name}}</strong>
|
||||||
|
<strong ng-show="isOwner">You</strong>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<span class="glyphicon glyphicon-play"></span>
|
||||||
|
<span class="text-muted">Runtime </span>
|
||||||
|
<strong ng-show="!queryExecuting">{{queryResult.getRuntime() | durationHumanize}}</strong>
|
||||||
|
<span ng-show="queryExecuting">Running…</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<span class="glyphicon glyphicon-align-justify"></span>
|
||||||
|
<span class="text-muted">Rows </span><strong>{{queryResult.getData().length}}</strong>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<span class="glyphicon glyphicon-refresh"></span>
|
||||||
|
<span class="text-muted">Refresh Interval</span>
|
||||||
|
<query-refresh-select></query-refresh-select>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<a class="btn btn-primary btn-sm" ng-disabled="queryExecuting || !queryResult.getData()" ng-href="{{dataUri}}" download="{{dataFilename}}" target="_self">
|
||||||
|
<span class="glyphicon glyphicon-cloud-download"></span>
|
||||||
|
<span class="rd-hidden-xs">Download Dataset</span>
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-lg-9">
|
||||||
|
<!-- alerts -->
|
||||||
|
<div class="alert alert-info" ng-show="queryResult.getStatus() == 'processing'">
|
||||||
|
Executing query… <rd-timer timestamp="queryResult.getUpdatedAt()"></rd-timer>
|
||||||
|
<button type="button" class="btn btn-warning btn-xs pull-right" ng-disabled="cancelling" ng-click="cancelExecution()">Cancel</button>
|
||||||
|
</div>
|
||||||
|
<div class="alert alert-info" ng-show="queryResult.getStatus() == 'waiting'">
|
||||||
|
Query in queue… <rd-timer timestamp="queryResult.getUpdatedAt()"></rd-timer>
|
||||||
|
<button type="button" class="btn btn-warning btn-xs pull-right" ng-disabled="cancelling" ng-click="cancelExecution()">Cancel</button>
|
||||||
|
</div>
|
||||||
|
<div class="alert alert-danger" ng-show="queryResult.getError()">Error running query: <strong>{{queryResult.getError()}}</strong></div>
|
||||||
|
|
||||||
|
<!-- tabs and data -->
|
||||||
|
<div ng-show="queryResult.getStatus() == 'done'">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<ul class="nav nav-tabs">
|
||||||
|
<rd-tab tab-id="table" name="Table"></rd-tab>
|
||||||
|
<rd-tab tab-id="pivot" name="Pivot Table"></rd-tab>
|
||||||
|
<rd-tab tab-id="{{vis.id}}" name="{{vis.name}}" ng-hide="vis.type=='TABLE'" ng-repeat="vis in query.visualizations">
|
||||||
|
<span class="remove" ng-click="deleteVisualization($event, vis)" ng-show="canEdit"> ×</span>
|
||||||
|
</rd-tab>
|
||||||
|
<rd-tab tab-id="add" name="+ New" removeable="true" ng-show="canEdit"></rd-tab>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<grid-renderer ng-show="selectedTab == 'table'" query-result="queryResult" items-per-page="50"></grid-renderer>
|
||||||
|
<pivot-table-renderer ng-show="selectedTab == 'pivot'" query-result="queryResult"></pivot-table-renderer>
|
||||||
|
|
||||||
|
<div ng-show="selectedTab == vis.id" ng-repeat="vis in query.visualizations">
|
||||||
|
<visualization-renderer visualization="vis" query-result="queryResult"></visualization-renderer>
|
||||||
|
<edit-visulatization-form visualization="vis" query="query" query-result="queryResult" ng-show="canEdit"></edit-visulatization-form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div ng-show="selectedTab == 'add'">
|
||||||
|
<visualization-renderer visualization="newVisualization" query-result="queryResult"></visualization-renderer>
|
||||||
|
<edit-visulatization-form visualization="newVisualization" query="query" ng-show="canEdit"></edit-visulatization-form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -31,7 +31,8 @@
|
|||||||
</strong>
|
</strong>
|
||||||
|
|
||||||
<span class="text-muted">Created By </span>
|
<span class="text-muted">Created By </span>
|
||||||
<strong>{{query.user.name}}</strong>
|
<strong ng-hide="isOwner">{{query.user.name}}</strong>
|
||||||
|
<strong ng-show="isOwner">You</strong>
|
||||||
|
|
||||||
<span class="text-muted">Runtime </span>
|
<span class="text-muted">Runtime </span>
|
||||||
<strong ng-show="!queryExecuting">{{queryResult.getRuntime() | durationHumanize}}</strong>
|
<strong ng-show="!queryExecuting">{{queryResult.getRuntime() | durationHumanize}}</strong>
|
||||||
@ -94,7 +95,9 @@
|
|||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<span class="glyphicon glyphicon-user"></span>
|
<span class="glyphicon glyphicon-user"></span>
|
||||||
<span class="text-muted">Created By </span><strong>{{query.user.name}}</strong>
|
<span class="text-muted">Created By </span>
|
||||||
|
<strong ng-hide="isOwner">{{query.user.name}}</strong>
|
||||||
|
<strong ng-show="isOwner">You</strong>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<span class="glyphicon glyphicon-play"></span>
|
<span class="glyphicon glyphicon-play"></span>
|
||||||
|
Loading…
Reference in New Issue
Block a user