diff --git a/src/css/main.css b/src/css/main.css index 9320a5b6..a563ae92 100644 --- a/src/css/main.css +++ b/src/css/main.css @@ -243,11 +243,15 @@ kbd { .site-nav__item a:focus, .site-nav__item--active a:focus, .site-nav__item a:hover, .site-nav__item--active a:hover { background: #2E9625; color: #F2F4F0; } + .site-nav__item a.disabled, .site-nav__item--active a.disabled { + color: #2E9625; + pointer-events: none; + cursor: default; } .site-nav__item--active a { background: #2E9625; color: #FFFFFF; } - .site-nav__item--active a:focus, .site-nav__item--active a:hover { + .site-nav__item--active a:focus, .site-nav__item--active a:hover, .site-nav__item--active a.disabled { background: #2E9625; color: #FFFFFF; } diff --git a/src/js/config/routes.js b/src/js/config/routes.js index d47d7be2..b8fc3def 100644 --- a/src/js/config/routes.js +++ b/src/js/config/routes.js @@ -16,8 +16,11 @@ define(['es-ui'], function (app) { .state('app', { url: '/', templateUrl: 'index.tpl.html', - abstract: true - //controller: ['$state'] + abstract: true, + controller: ['$scope', function($scope) { + $scope.notAdminMessage = 'You must be an admin to view this item'; + $scope.projectionsNotRunningMessage = 'Projections are not running on Event Store'; + }] }); }]); }); \ No newline at end of file diff --git a/src/js/modules/projections/controllers/ProjectionsItemDebugCtrl.js b/src/js/modules/projections/controllers/ProjectionsItemDebugCtrl.js index 67d6051a..cbe866e5 100644 --- a/src/js/modules/projections/controllers/ProjectionsItemDebugCtrl.js +++ b/src/js/modules/projections/controllers/ProjectionsItemDebugCtrl.js @@ -261,6 +261,14 @@ define(['./_module'], function (app) { msg.failure('projection could not be stopped'); }); }; + + $scope.goBack = function() { + if($stateParams.fromQueryState) { + $state.go('query', {location: $scope.location}); + } else { + $state.go('^.details'); + } + } } ]); }); diff --git a/src/js/modules/projections/controllers/QueryCtrl.js b/src/js/modules/projections/controllers/QueryCtrl.js index 0e688195..150f10a4 100644 --- a/src/js/modules/projections/controllers/QueryCtrl.js +++ b/src/js/modules/projections/controllers/QueryCtrl.js @@ -6,10 +6,16 @@ define(['./_module'], function (app) { // todo: remove State Params if we will not add query for existing queries return app.controller('QueryCtrl', [ - '$scope', '$state', '$stateParams', 'QueryService', 'ProjectionsMonitor', 'MessageService', - function ($scope, $state, $stateParams, queryService, monitor, msg) { + '$scope', '$state', '$stateParams', 'QueryService', 'ProjectionsMonitor', 'MessageService','ProjectionsService', + function ($scope, $state, $stateParams, queryService, monitor, msg, projectionsService) { var location; + if ($stateParams.location) { + location = $stateParams.location; + projectionsService.query(location).then(function (result) { + $scope.query = result.data.query + }); + } function create () { var param = { @@ -38,7 +44,7 @@ define(['./_module'], function (app) { ignoreQuery: true, ignoreResult: true }).then(null, null, function (data) { - var s, stopped; + var projection, status, stateReason, stopped; if(data.state) { $scope.state = data.state; @@ -48,10 +54,13 @@ define(['./_module'], function (app) { } if(data.statistics && data.statistics.projections.length) { - s = data.statistics.projections[0].status; - $scope.status = s; - - stopped = (!!~s.indexOf('Stopped') && !~s.indexOf('Preparing')) || !!~s.indexOf('Faulted') ||!!~s.indexOf('Completed'); + projection = data.statistics.projections[0]; + status = projection.status; + stateReason = projection.stateReason; + $scope.status = status; + var lines = stateReason.match(/[^\r\n]+/g); + $scope.stateReason = lines !== null && lines.length > 0 ? lines[0] : stateReason; + stopped = (!!~status.indexOf('Stopped') && !~status.indexOf('Preparing')) || !!~status.indexOf('Faulted') ||!!~status.indexOf('Completed'); $scope.isStopped = stopped; } }); @@ -134,7 +143,8 @@ define(['./_module'], function (app) { queryService.reset(location) .then(function onQueryReset(){ $state.go('projections.item.debug', { - location: encodeURIComponent(location) + location: encodeURIComponent(location), + fromQueryState : true }, { inherit: false }); diff --git a/src/js/modules/projections/module.js b/src/js/modules/projections/module.js index 5d60a225..5ec7432c 100644 --- a/src/js/modules/projections/module.js +++ b/src/js/modules/projections/module.js @@ -66,7 +66,7 @@ define(['./_index'], function (app) { } }) .state('projections.item.debug', { - url: '/debug', + url: '/debug?fromQueryState', templateUrl: 'projections.item.debug.tpl.html', controller: 'ProjectionsItemDebugCtrl', data: { @@ -84,7 +84,7 @@ define(['./_index'], function (app) { // ========================================QUERY============ .state('query', { - url: 'query', + url: 'query?location', parent: 'app', templateUrl: 'query.tpl.html', controller: 'QueryCtrl', diff --git a/src/js/modules/projections/templates/templates.js b/src/js/modules/projections/templates/templates.js index 9b457e29..90c93f19 100644 --- a/src/js/modules/projections/templates/templates.js +++ b/src/js/modules/projections/templates/templates.js @@ -6,7 +6,7 @@ try { } module.run(['$templateCache', function($templateCache) { $templateCache.put('projections.item.debug.tpl.html', - '

Current Status: {{statusInfo}}

Source

The query has been updated but not saved. Your changes will not take effect until you hit the "Update" button

State {{ currentPartition }}

\n' +
+    '

Current Status: {{statusInfo}}

Source

The query has been updated but not saved. Your changes will not take effect until you hit the "Update" button

State {{ currentPartition }}

\n' +
     '{{ state | json }}\n' +
     '				

Events

Instructions

  1. Make sure you use the Google Chrome browser.
  2. Open a debugger (Ctrl+Shift+J on Windows).
  3. Check the debugger console for errors (occurred while running the projection definition on while loading state and events).
  4. Click the ‘Run’ button above.
  5. Watch for errors in the debugger console
  6. Check the debugging status on XXXXXXXXX.
  7. Execution will stop on ‘debugger’ statement immediately before invoking your event handler.

Any log output and emitted events will appear in the log viewer.

Log Viewer

'); }]); @@ -126,7 +126,7 @@ try { } module.run(['$templateCache', function($templateCache) { $templateCache.put('query.tpl.html', - '

{{status}}

Source

State

\n' +
+    '

{{status}}

{{stateReason}}

Source

State

\n' +
     '{{state | json}}\n' +
     '		
'); }]); diff --git a/src/js/modules/projections/views/projections.item.debug.tpl.html b/src/js/modules/projections/views/projections.item.debug.tpl.html index ac765713..82b26229 100644 --- a/src/js/modules/projections/views/projections.item.debug.tpl.html +++ b/src/js/modules/projections/views/projections.item.debug.tpl.html @@ -14,7 +14,7 @@

Projection Debug

- + diff --git a/src/js/modules/projections/views/query.tpl.html b/src/js/modules/projections/views/query.tpl.html index 221c4ca1..86c1f9b3 100644 --- a/src/js/modules/projections/views/query.tpl.html +++ b/src/js/modules/projections/views/query.tpl.html @@ -15,8 +15,9 @@

Query

- {{status}} + {{status}}

+ {{stateReason}}
diff --git a/src/js/modules/security/controllers/SignInCtrl.js b/src/js/modules/security/controllers/SignInCtrl.js index 75b0248b..56f8c9db 100644 --- a/src/js/modules/security/controllers/SignInCtrl.js +++ b/src/js/modules/security/controllers/SignInCtrl.js @@ -29,16 +29,23 @@ define(['./_module'], function (app) { $rootScope.esVersion = $rootScope.esVersion == '0.0.0.0' ? 'development build' : $rootScope.esVersion; $rootScope.projectionsAllowed = info.projectionsMode != 'None'; $rootScope.projectionsMode = info.projectionsMode; - scavengeNotificationService.start(); - authService.setCredentials($scope.log.username, $scope.log.password, $scope.log.server); - infoService.getOptions().then(function onGetOptions(response){ - var options = response.data; - for (var index in options) { - if(options[index].name == "ClusterSize" && options[index].value > 1){ - $rootScope.singleNode = false; - } - } - redirectAfterLoggingIn(); + + authService.getUserGroups($scope.log.username).then(function(groups) { + authService.setCredentials($scope.log.username, $scope.log.password, $scope.log.server, groups); + if($rootScope.isAdmin) { + scavengeNotificationService.start(); + infoService.getOptions().then(function onGetOptions(response){ + var options = response.data; + for (var index in options) { + if(options[index].name == "ClusterSize" && options[index].value > 1){ + $rootScope.singleNode = false; + } + } + redirectAfterLoggingIn(); + }); + } else { + redirectAfterLoggingIn(); + } }); }) .error(function () { diff --git a/src/js/modules/streams/controllers/StreamsListCtrl.js b/src/js/modules/streams/controllers/StreamsListCtrl.js index 98d7d84f..ad020ee9 100644 --- a/src/js/modules/streams/controllers/StreamsListCtrl.js +++ b/src/js/modules/streams/controllers/StreamsListCtrl.js @@ -3,8 +3,8 @@ define(['./_module'], function (app) { 'use strict'; return app.controller('StreamsListCtrl', [ - '$scope', '$state', 'StreamsService', - function ($scope, $state, streamsService) { + '$rootScope', '$scope', '$state', 'StreamsService', 'MessageService', + function ($rootScope, $scope, $state, streamsService, msg) { function filter (entries) { var filtered = {}, i = 0, length = entries.length, item, result = []; @@ -23,26 +23,32 @@ define(['./_module'], function (app) { return result; } - $scope.search = '$all'; - $scope.gotoStream = function ($event) { $event.preventDefault(); $event.stopPropagation(); - // todo: do check if stream exists - - $state.go('^.item.events', { streamId: $scope.search }); + streamsService.checkStreamExists($scope.search).then(function(exists) { + if(exists) { + $state.go('^.item.events', { streamId: $scope.search }); + } else { + msg.warn('Could not open stream ' + $scope.search +'. This usually means the stream does not exist or you do not have permission to view it'); + } + }); }; - streamsService.recentlyChangedStreams() - .success(function (data) { - $scope.changedStreams = filter(data.entries); - }); - - streamsService.recentlyCreatedStreams() - .success(function (data) { - $scope.createdStreams = filter(data.entries); - }); + if($rootScope.isAdmin !== false) { + $scope.search = '$all'; + + streamsService.recentlyChangedStreams() + .success(function (data) { + $scope.changedStreams = filter(data.entries); + }); + + streamsService.recentlyCreatedStreams() + .success(function (data) { + $scope.createdStreams = filter(data.entries); + }); + } } ]); }); diff --git a/src/js/modules/streams/services/StreamsService.js b/src/js/modules/streams/services/StreamsService.js index a7623b89..af58b6e3 100644 --- a/src/js/modules/streams/services/StreamsService.js +++ b/src/js/modules/streams/services/StreamsService.js @@ -75,6 +75,16 @@ define(['./_module'], function(app) { }; return $http.get(url, header); + }, + checkStreamExists: function(streamId) { + var deferred = $q.defer(); + var url = urlBuilder.build(urls.streams.events, streamId); + $http.get(url).success(function() { + deferred.resolve(true); + }).error(function() { + deferred.resolve(false); + }); + return deferred.promise; } }; } diff --git a/src/js/modules/streams/templates/templates.js b/src/js/modules/streams/templates/templates.js index 34a0ca74..0c430990 100644 --- a/src/js/modules/streams/templates/templates.js +++ b/src/js/modules/streams/templates/templates.js @@ -54,7 +54,7 @@ try { } module.run(['$templateCache', function($templateCache) { $templateCache.put('streams.item.tpl.html', - '
'); + '
'); }]); })(); @@ -66,7 +66,7 @@ try { } module.run(['$templateCache', function($templateCache) { $templateCache.put('streams.list.tpl.html', - '
Recently Created Streams
{{ stream.streamId }}
No recently created streams
Recently Changed Streams
{{ stream.streamId }}
No recently changed streams
'); + '
Recently Created Streams
{{ stream.streamId }}
No recently created streams
Recently Changed Streams
{{ stream.streamId }}
No recently changed streams
You must be an admin to view recently created streams'); }]); })(); diff --git a/src/js/modules/streams/views/streams.item.tpl.html b/src/js/modules/streams/views/streams.item.tpl.html index f5682584..4fcec399 100644 --- a/src/js/modules/streams/views/streams.item.tpl.html +++ b/src/js/modules/streams/views/streams.item.tpl.html @@ -5,7 +5,7 @@

Event Stream '{{ streamId }}'

{{ isPolling == true ? 'Pause' : 'Resume' }}