Query snippets pages

This commit is contained in:
Arik Fraimovich 2016-11-07 18:09:11 +02:00
parent 0e5325ef1c
commit d49e5f9d57
14 changed files with 279 additions and 1 deletions

View File

@ -8,3 +8,5 @@ export { default as queryLink } from './query-link';
export { default as parameters } from './parameters';
export { default as permissionsEditor } from './permissions-editor';
export { default as dynamicTable } from './dynamic-table';
export { default as paginator } from './paginator';
export { default as settingsScreen } from './settings-screen';

View File

@ -0,0 +1,31 @@
class PaginatorCtrl {
constructor() {
this.page = this.paginator.page;
}
pageChanged() {
this.paginator.setPage(this.page);
}
}
export default function (ngModule) {
ngModule.component('paginator', {
template: `
<div class="text-center">
<ul uib-pagination total-items="$ctrl.paginator.totalCount"
items-per-page="$ctrl.paginator.itemsPerPage"
ng-model="$ctrl.page"
max-size="6"
class="pagination"
boundary-link-numbers="true"
rotate="false"
next-text='>'
previous-text='<'
ng-change="$ctrl.pageChanged()"></ul>
</div>
`,
bindings: {
paginator: '<',
},
controller: PaginatorCtrl,
});
}

View File

@ -0,0 +1,18 @@
<page-header title="Settings">
</page-header>
<div class="container">
<div class="container bg-white p-5">
<ul class="tab-nav">
<li ng-class="{'active': dsPage }" ng-if="showDsLink"><a href="data_sources">Data Sources</a></li>
<li ng-class="{'active': usersPage }" ng-if="showUsersLink"><a href="users">Users</a></li>
<li ng-class="{'active': groupsPage }" ng-if="showGroupsLink"><a href="groups">Groups</a></li>
<li ng-class="{'active': destinationsPage }" ng-if="showDestinationsLink"><a href="destinations">Alert Destinations</a></li>
<li ng-class="{'active': snippetsPage }"><a href="query_snippets">Query Snippets</a></li>
</ul>
<div ng-transclude>
</div>
</div>
</div>

View File

@ -0,0 +1,24 @@
import startsWith from 'underscore.string/startsWith';
import template from './settings-screen.html';
export default function (ngModule) {
ngModule.directive('settingsScreen', $location =>
({
restrict: 'E',
transclude: true,
template,
controller($scope, currentUser) {
$scope.usersPage = startsWith($location.path(), '/users');
$scope.groupsPage = startsWith($location.path(), '/groups');
$scope.dsPage = startsWith($location.path(), '/data_sources');
$scope.destinationsPage = startsWith($location.path(), '/destinations');
$scope.snippetsPage = startsWith($location.path(), '/query_snippets');
$scope.showGroupsLink = currentUser.hasPermission('list_users');
$scope.showUsersLink = currentUser.hasPermission('list_users');
$scope.showDsLink = currentUser.hasPermission('admin');
$scope.showDestinationsLink = currentUser.hasPermission('admin');
},
})
);
}

View File

@ -11,6 +11,10 @@ import uiBootstrap from 'angular-ui-bootstrap';
import uiSelect from 'ui-select';
import toastr from 'angular-toastr';
import 'angular-moment';
import 'brace';
import 'angular-ui-ace';
import { ngTable } from 'ng-table';
import { each } from 'underscore';
@ -25,7 +29,7 @@ import registerVisualizations from './visualizations';
import markdownFilter from './filters/markdown';
const requirements = [
ngRoute, ngResource, ngSanitize, uiBootstrap, uiSelect, ngTable.name, 'angularMoment', toastr,
ngRoute, ngResource, ngSanitize, uiBootstrap, uiSelect, ngTable.name, 'angularMoment', toastr, 'ui.ace',
];
const ngModule = angular.module('app', requirements);
@ -88,6 +92,7 @@ function registerPages() {
ngModule.config(($routeProvider) => {
each(routes, (route, path) => {
console.log('Route: ', path);
$routeProvider.when(path, route);
});
});

View File

@ -4,3 +4,4 @@ export { default as alertsList } from './alerts-list';
export { default as alert } from './alert';
export { default as admin } from './admin';
export { default as dashboards } from './dashboards';
export { default as querySnippets } from './query-snippets';

View File

@ -0,0 +1,29 @@
<settings-screen>
<div class="">
<form name="snippetForm" class="form">
<div class="form-group">
<label>Trigger</label>
<input type="string" class="form-control" ng-model="$ctrl.snippet.trigger" ng-disabled="!$ctrl.canEdit" required>
</div>
<div class="form-group">
<label>Description</label>
<input type="string" class="form-control" ng-model="$ctrl.snippet.description" ng-disabled="!$ctrl.canEdit">
</div>
<div class="form-group">
<label>Snippet</label>
<pre ng-if="!$ctrl.canEdit">{{$ctrl.snippet.snippet}}</pre>
<div ui-ace="$ctrl.editorOptions" ng-model="$ctrl.snippet.snippet" style="height:300px" ng-if="$ctrl.canEdit"></div>
</div>
<div class="form-group" ng-if="$ctrl.canEdit">
<button class="btn btn-primary" ng-disabled="!snippetForm.$valid" ng-click="$ctrl.saveChanges()">Save</button>
<button class="btn btn-danger" ng-if="$ctrl.snippet.id" ng-click="$ctrl.delete()">Delete</button>
</div>
<small ng-if="$ctrl.snippet.user">
Created by: {{$ctrl.snippet.user.name}}
</small>
</form>
</div>
</settings-screen>

View File

@ -0,0 +1,64 @@
import 'brace/mode/snippets';
import template from './edit.html';
function SnippetCtrl($routeParams, $http, $location, toastr, currentUser, Events, QuerySnippet) {
// $scope.$parent.pageTitle = 'Query Snippets';
this.snippetId = $routeParams.snippetId;
Events.record(currentUser, 'view', 'query_snippet', this.snippetId);
this.editorOptions = {
mode: 'snippets',
advanced: {
behavioursEnabled: true,
enableSnippets: false,
autoScrollEditorIntoView: true,
},
onLoad(editor) {
editor.$blockScrolling = Infinity;
editor.getSession().setUseWrapMode(true);
editor.setShowPrintMargin(false);
},
};
this.saveChanges = () => {
this.snippet.$save((snippet) => {
toastr.success('Saved.');
if (this.snippetId === 'new') {
$location.path(`/query_snippets/${snippet.id}`).replace();
}
}, () => {
toastr.error('Failed saving snippet.');
});
};
this.delete = () => {
this.snippet.$delete(() => {
$location.path('/query_snippets');
toastr.sucess('Query snippet deleted.');
}, () => {
toastr.error('Failed deleting query snippet.');
});
};
if (this.snippetId === 'new') {
this.snippet = new QuerySnippet({ description: '' });
this.canEdit = true;
} else {
this.snippet = QuerySnippet.get({ id: this.snippetId }, (snippet) => {
this.canEdit = currentUser.canEdit(snippet);
});
}
}
export default function (ngModule) {
ngModule.component('snippetPage', {
template,
controller: SnippetCtrl,
});
return {
'/query_snippets/:snippetId': {
template: '<snippet-page></snippet-page>',
},
};
}

View File

@ -0,0 +1,8 @@
import registerList from './list';
import registerEdit from './edit';
export default function (ngModule) {
const routes = Object.assign({}, registerList(ngModule),
registerEdit(ngModule));
return routes;
}

View File

@ -0,0 +1,41 @@
<settings-screen>
<div class="row voffset1">
<div class="col-md-12">
<p>
<a href="query_snippets/new" class="btn btn-default"><i class="fa fa-plus"></i> New Snippet</a>
</p>
<table class="table table-condensed table-hover">
<thead>
<tr>
<th>Trigger</th>
<th>Description</th>
<th>Snippet</th>
<th>Created By</th>
<th>Updated At</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in $ctrl.snippets.getPageRows()">
<td>
<a href="query_snippets/{{row.id}}">{{row.trigger}}</a>
</td>
<td>
{{row.description}}
</td>
<td>
{{row.snippet}}
</td>
<td>
{{row.user.name}}
</td>
<td>
<span am-time-ago="row.created_at"></span>
</td>
</tr>
</tbody>
</table>
<paginator paginator="$ctrl.snippets"></paginator>
</div>
</div>
</settings-screen>

View File

@ -0,0 +1,25 @@
import { Paginator } from '../../utils';
import template from './list.html';
function SnippetsCtrl($location, currentUser, Events, QuerySnippet) {
Events.record(currentUser, 'view', 'page', 'query_snippets');
// $scope.$parent.pageTitle = 'Query Snippets';
this.snippets = new Paginator([], { itemsPerPage: 20 });
QuerySnippet.query((snippets) => {
this.snippets.updateRows(snippets);
});
}
export default function (ngModule) {
ngModule.component('snippetsListPage', {
template,
controller: SnippetsCtrl,
});
return {
'/query_snippets': {
template: '<snippets-list-page></snippets-list-page>',
},
};
}

View File

@ -0,0 +1 @@
export { default as Paginator } from './paginator';

View File

@ -0,0 +1,27 @@
export default class Paginator {
constructor(rows, { page = 1, itemsPerPage = 20, totalCount = undefined } = {}) {
this.page = page;
this.itemsPerPage = itemsPerPage;
this.updateRows(rows, totalCount);
}
setPage(page) {
this.page = page;
}
getPageRows() {
const first = this.itemsPerPage * (this.page - 1);
const last = this.itemsPerPage * (this.page);
return this.rows.slice(first, last);
}
updateRows(rows, totalCount = undefined) {
this.rows = rows;
if (this.rows) {
this.totalCount = totalCount || rows.length;
} else {
this.totalCount = 0;
}
}
}

View File

@ -25,11 +25,13 @@
"angular-route": "^1.5.8",
"angular-sanitize": "^1.5.8",
"angular-toastr": "^2.1.1",
"angular-ui-ace": "^0.2.3",
"angular-ui-bootstrap": "^2.2.0",
"babel-core": "^6.18.0",
"babel-loader": "^6.2.7",
"babel-preset-es2015": "^6.18.0",
"babel-preset-stage-2": "^6.18.0",
"brace": "^0.9.0",
"css-loader": "^0.25.0",
"d3": "^3.5.17",
"debug": "^2.2.0",