Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/ServicePulse.Host/ServicePulse.Host.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
<ItemGroup>
<Content Include="app\css\animate-css\animate.css" />
<Content Include="app\css\animate-css\animate.min.css" />
<Content Include="app\js\configuration\configuration.service.js" />
<Content Include="app\lib\angular\ui-bootstrap-tpls-0.14.3.min.js" />
<Content Include="app\css\font-awesome\css\font-awesome.css" />
<Content Include="app\css\font-awesome\css\font-awesome.min.css" />
Expand Down
2 changes: 1 addition & 1 deletion src/ServicePulse.Host/app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,6 @@ <h4>Warning!</h4>
<script src="js/configuration/configuration.module.js"></script>
<script src="js/configuration/configuration.route.js"></script>
<script src="js/configuration/configuration.controller.js"></script>

<script src="js/configuration/configuration.service.js"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -1,26 +1,71 @@
; (function (window, angular, undefined) {
; (function (window, angular, $, undefined) {
'use strict';

function controller($scope, serviceControlService) {
function createWorkflowState(optionalStatus, optionalMessage) {
return {
status: optionalStatus || 'working',
message: optionalMessage || 'working'
};
}

function controller(
$scope,
$window,
$timeout,
configurationService) {

$scope.model = { endpoints: [] };


function autoGetEndPoints() {
configurationService.getData()
.then(function (response) {
if (response.data.length > 0) {
// need a map in some ui state for controlling animations
var endPoints = response.data.map(function (obj) {
var nObj = obj;
nObj.workflow_state = createWorkflowState('ready', '');
return nObj;
});

$scope.model = { endpoints: [], changes: {} };
$scope.model.endpoints = endPoints;
}

$scope.update = function (id) {
var newState = $scope.model.changes[id];

});
};

$scope.update = function (id, monitor) {

var result = $.grep($scope.model.endpoints, function (e) { return e.id === id; })[0];
result.workflow_state = createWorkflowState('working', 'Updating');

serviceControlService.updateEndpoint(id, { "monitor_heartbeat": newState });

configurationService.update(id, monitor, 'Updating', 'Update Failed')
.then(function (message) {
result.workflow_state = createWorkflowState('ready', message);
result.monitor_heartbeat = monitor;
}, function (message) {
result.workflow_state = createWorkflowState('error', message);
})
.finally(function () {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

empty?


});
};

serviceControlService.getEndpoints()
.then(function (response) {
$scope.model.endpoints = response;
});

autoGetEndPoints();

};

controller.$inject = ['$scope', 'serviceControlService'];
controller.$inject = [
'$scope',
'$window',
'$interval',
'configurationService'];

angular.module('configuration')
.controller('ConfigurationCtrl', controller);

} (window, window.angular));
} (window, window.angular, window.jQuery));

15 changes: 13 additions & 2 deletions src/ServicePulse.Host/app/js/configuration/configuration.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,25 @@ <h2><i class="fa fa-cog"></i><span class="break"></span>Endpoints Configuration<
<th>Name</th>
<th>Host</th>
<th>Latest Heartbeat</th>
<th>Enabled</th>
<th><span tooltip="Monitor the endpoint, and send alert if heartbeats are not received.">Monitor</span></th>
</tr>
<tr class="interactiveList" ng-repeat="e in model.endpoints | orderBy:'name'">
<tr ng-repeat="e in model.endpoints | orderBy:'name'">
<td>{{e.name}}</td>
<td>{{e.host_display_name}}</td>
<td ng-show="e.heartbeat_information"><sp-moment date="{{e.heartbeat_information.last_report_at}}" /></td>
<td ng-show="!e.heartbeat_information">N/A</td>
<td><input type="checkbox" ng-checked="e.monitor_heartbeat" ng-model="model.changes[e.id]" ng-change="update('{{e.id}}')"></td>
<td><span ng-show="e.monitor_heartbeat"><i class="fa fa-check"></i></span><span ng-show="!e.monitor_heartbeat"><i class="fa fa-times"></i></span></td>
<td>
<div ng-show="e.workflow_state.status !== 'ready'" class="animate-box">
{{e.workflow_state.message}}
</div>

<div ng-show="e.workflow_state.status === 'ready'" class="switch">
<button class="btn " ng-class="{'btn-warning' : e.monitor_heartbeat, 'btn-default': !e.monitor_heartbeat}" ng-click="update(e.id, !e.monitor_heartbeat)">{{e.monitor_heartbeat ? "Disable" : "Enable"}}</button>
</div>

</td>
</tr>
</table>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
; (function (window, angular, undefined) {
'use strict';

angular.module('configuration', []);
angular.module('configuration', ['ui.bootstrap']);

} (window, window.angular));

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
;
(function (window, angular, undefined) {
'use strict';

function Service($http, $q, scConfig, uri) {

function patchPromise(url, data, success, error) {

var defer = $q.defer();

success = success || 'success';
error = error || 'error';

$http({
url: url,
data: data,
method: 'PATCH'
})
.success(function (response) {
defer.resolve(success + ':' + response);
})
.error(function (response, status, headers, config) {
if (status === '304') {
defer.resolve(success + ':' + response);
} else {
defer.reject(error + ':' + response);
}
});

return defer.promise;
}

function getData() {
var url = uri.join(scConfig.service_control_url, 'endpoints');
return $http.get(url).then(function (response) {
return {
data: response.data
};
});
}

var service = {
getData: getData,
update: function (id, newState, success, error) {
var url = uri.join(scConfig.service_control_url, 'endpoints', id);
return patchPromise(url, { "monitor_heartbeat": newState }, success, error);
}
};

return service;

}

Service.$inject = ['$http', '$q', 'scConfig', 'uri'];

angular.module('configuration')
.factory('configurationService', Service);


}(window, window.angular));
89 changes: 46 additions & 43 deletions src/ServicePulse.Host/app/js/failed_messages/failedMessages.html
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ <h2>Loading...</h2> We are still grouping your failed messages, it shouldn't be
</sp-moment>
</div>
<div class="col-sm-3 col-md-3">

<button type="button" class="btn btn-default btn-sm" tooltip="Archive Group" ng-click="archiveExceptionGroup(excGroup)" ng-disabled="excGroup.count == 0"><i class="fa fa-archive"></i></button>
<button type="button" class="btn btn-default btn-sm" tooltip="Retry Group" ng-click="retryExceptionGroup(excGroup)" ng-disabled="excGroup.count == 0"><i class="fa fa-refresh"></i></button>
</div>
Expand Down Expand Up @@ -144,50 +144,53 @@ <h2 class="failedMessages-header">
<div infinite-scroll="loadMoreResults(selectedExceptionGroup)" infinite-scroll-distance="0" infinite-scroll-disabled="disableLoadingData">
<div class="scRow interactiveList" ng-repeat="row in model.failedMessages">
<div class="row scSelectableRow" ng-class="{rowSelected: row.selected == true}" ng-click="toggleRowSelect(row)" style="cursor: pointer;">
<div class="check col-sm-1 col-md-1">
<div class="check col-md-1">
<input type="checkbox" ng-disabled="row.retried || row.archived" ng-checked="row.selected">
</div>
</div>
<div class="col-sm-11 col-md-11" ng-init="row.panel = 0">
<a eat-click="" ng-show="row.panel === 1" class="btn btn-link btn-default btn-sm" ng-click="togglePanel(row, 0)"><i class="fa fa-minus-square action_icon"></i> Hide stacktrace</a>
<a eat-click="" ng-hide="row.panel === 1" class="btn btn-link btn-default btn-sm" ng-click="togglePanel(row, 1)"><i class="fa fa-plus-square action_icon"></i> Show stacktrace</a>
<a eat-click="" ng-show="row.panel === 2" class="btn btn-link btn-default btn-sm" ng-click="togglePanel(row, 0)"><i class="fa fa-minus-square action_icon"></i> Hide headers</a>
<a eat-click="" ng-hide="row.panel === 2" class="btn btn-link btn-default btn-sm" ng-click="togglePanel(row, 2)"><i class="fa fa-plus-square action_icon"></i> Show headers</a>
<a eat-click="" ng-show="row.panel === 3" class="btn btn-link btn-default btn-sm" ng-click="togglePanel(row, 0)"><i class="fa fa-minus-square action_icon"></i> Hide message body</a>
<a eat-click="" ng-hide="row.panel === 3" class="btn btn-link btn-default btn-sm" ng-click="togglePanel(row, 3)"><i class="fa fa-plus-square action_icon"></i> Show message body</a>
<a eat-click="" clip-copy="" data-clipboard-text="{{row.message_id}}" class="btn btn-link btn-default btn-sm"><span><i class="fa fa-clipboard action_icon"></i> Copy Id to clipboard</span></a>
<a eat-click="" tooltip="This only works if ServiceInsight is installed." class="btn btn-link btn-default btn-sm" ng-click="debugInServiceInsight($index)"><i class="icon-service-insight"></i> Open in ServiceInsight</a>
</div>
<div class=" row">
<div class="rowText hard-wrap col-sm-10 col-md-10">{{row.message_type || 'Message Type Unknown - missing metadata EnclosedMessageTypes'}}</div>
<div class="text-right col-sm-2 col-md-2">
<sp-moment date="{{row.time_sent}}">
</sp-moment>
</div>
</div>
<div class="row">
<div class="col-sm-8 col-md-8">
<pre ng-show="row.panel === 0">{{ row.exception.message }}</pre>
<pre ng-show="row.panel === 1">{{ row.exception.stack_trace }}</pre>
<table class="table" ng-show="row.panel === 2 && row.messageHeaders">
<tbody>
<tr class="interactiveList" ng-repeat="header in row.messageHeaders">
<td nowrap="nowrap">{{header.key}}</td>
<td><pre>{{header.value}}</pre></td>
</tr>
</tbody>
</table>
<div class="alert alert-info" ng-show="row.panel === 2 && row.headersUnavailable">{{row.headersUnavailable}}</div>
<pre ng-show="row.panel === 3 && row.messageBody">{{row.messageBody}}</pre>
<div class="alert alert-info" ng-show="row.panel === 3 && row.bodyUnavailable">{{row.bodyUnavailable}}</div>
</div>
<div class="text-right hard-wrap col-sm-4 col-md-4" title="In: {{row.receiving_endpoint.name}} on {{row.receiving_endpoint.host}}">in {{row.receiving_endpoint.name}} on {{row.receiving_endpoint.host}}</div>
</div>
<div class="row">
<div class="text-left col-sm-6 col-md-6">
<span ng-if="row.retried" tooltip="Message is being retried" class="label label-info">Retried</span>
<span ng-if="row.archived" tooltip="Message is being archived" class="label label-info">Archived</span>
<span ng-if="row.number_of_processing_attempts > 1" tooltip="This message has already failed {{row.number_of_processing_attempts}} times" class="label label-important">Repeated Failure</span>
<div class="col-md-11">
<div ng-init="row.panel = 0">
<a eat-click="" ng-show="row.panel === 1" class="btn btn-link btn-default btn-sm" ng-click="togglePanel(row, 0)"><i class="fa fa-minus-square action_icon"></i> Hide stacktrace</a>
<a eat-click="" ng-hide="row.panel === 1" class="btn btn-link btn-default btn-sm" ng-click="togglePanel(row, 1)"><i class="fa fa-plus-square action_icon"></i> Show stacktrace</a>
<a eat-click="" ng-show="row.panel === 2" class="btn btn-link btn-default btn-sm" ng-click="togglePanel(row, 0)"><i class="fa fa-minus-square action_icon"></i> Hide headers</a>
<a eat-click="" ng-hide="row.panel === 2" class="btn btn-link btn-default btn-sm" ng-click="togglePanel(row, 2)"><i class="fa fa-plus-square action_icon"></i> Show headers</a>
<a eat-click="" ng-show="row.panel === 3" class="btn btn-link btn-default btn-sm" ng-click="togglePanel(row, 0)"><i class="fa fa-minus-square action_icon"></i> Hide message body</a>
<a eat-click="" ng-hide="row.panel === 3" class="btn btn-link btn-default btn-sm" ng-click="togglePanel(row, 3)"><i class="fa fa-plus-square action_icon"></i> Show message body</a>
<a eat-click="" clip-copy="" data-clipboard-text="{{row.message_id}}" class="btn btn-link btn-default btn-sm"><span><i class="fa fa-clipboard action_icon"></i> Copy Id to clipboard</span></a>
<a eat-click="" tooltip="This only works if ServiceInsight is installed." class="btn btn-link btn-default btn-sm" ng-click="debugInServiceInsight($index)"><i class="icon-service-insight"></i> Open in ServiceInsight</a>
</div>

<div class=" row">
<div class="rowText hard-wrap col-md-10">{{row.message_type || 'Message Type Unknown - missing metadata EnclosedMessageTypes'}}</div>
<div class="text-right col-md-2">
<sp-moment date="{{row.time_sent}}">
</sp-moment>
</div>
</div>
<div class="row">
<div class="col-md-8">
<pre ng-show="row.panel === 0">{{ row.exception.message }}</pre>
<pre ng-show="row.panel === 1">{{ row.exception.stack_trace }}</pre>
<table class="table" ng-show="row.panel === 2 && row.messageHeaders">
<tbody>
<tr class="interactiveList" ng-repeat="header in row.messageHeaders">
<td nowrap="nowrap">{{header.key}}</td>
<td><pre>{{header.value}}</pre></td>
</tr>
</tbody>
</table>
<div class="alert alert-info" ng-show="row.panel === 2 && row.headersUnavailable">{{row.headersUnavailable}}</div>
<pre ng-show="row.panel === 3 && row.messageBody">{{row.messageBody}}</pre>
<div class="alert alert-info" ng-show="row.panel === 3 && row.bodyUnavailable">{{row.bodyUnavailable}}</div>
</div>
<div class="text-right hard-wrap col-sm-4 col-md-4" title="In: {{row.receiving_endpoint.name}} on {{row.receiving_endpoint.host}}">in {{row.receiving_endpoint.name}} on {{row.receiving_endpoint.host}}</div>
</div>
<div class="row">
<div class="text-left col-md-6">
<span ng-if="row.retried" tooltip="Message is being retried" class="label label-info">Retried</span>
<span ng-if="row.archived" tooltip="Message is being archived" class="label label-info">Archived</span>
<span ng-if="row.number_of_processing_attempts > 1" tooltip="This message has already failed {{row.number_of_processing_attempts}} times" class="label label-important">Repeated Failure</span>
</div>
</div>
</div>
</div>
</div>
Expand Down
Loading