Get dashboard working and upgrade bootstrap. Note: the bootstrap fixes will be coming in the followup CL
This commit is contained in:
parent
79f39697fe
commit
524705b88c
18 changed files with 429 additions and 260 deletions
|
@ -705,5 +705,11 @@
|
|||
}
|
||||
|
||||
.realtime-area-chart, .realtime-line-chart {
|
||||
display: inline-block;
|
||||
margin: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.rickshaw_graph {
|
||||
overflow: hidden;
|
||||
padding-bottom: 40px;
|
||||
}
|
|
@ -4972,3 +4972,9 @@ i.slack-icon {
|
|||
left: 16px;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.chart-col h4, .chart-col h5 {
|
||||
display: block;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<div class="config-setup-tool-element">
|
||||
<div class="quay-spinner" ng-if="!config"></div>
|
||||
<div class="cor-loader" ng-if="!config"></div>
|
||||
<div ng-show="config && config['SUPER_USERS']">
|
||||
<form id="configform" name="configform">
|
||||
|
||||
|
@ -289,7 +289,7 @@
|
|||
<div class="description">
|
||||
<p>
|
||||
Authentication for the registry can be handled by either the registry itself or LDAP.
|
||||
External authentication providers (such as Github) can be used on top of this choice.
|
||||
External authentication providers (such as GitHub) can be used on top of this choice.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
@ -339,20 +339,20 @@
|
|||
</div>
|
||||
</div> <!-- /Authentication -->
|
||||
|
||||
<!-- Github Authentication -->
|
||||
<!-- GitHub Authentication -->
|
||||
<div class="co-panel">
|
||||
<div class="co-panel-heading">
|
||||
<i class="fa fa-github"></i> Github (Enterprise) Authentication
|
||||
<i class="fa fa-github"></i> GitHub (Enterprise) Authentication
|
||||
</div>
|
||||
<div class="co-panel-body">
|
||||
<div class="description">
|
||||
<p>
|
||||
If enabled, users can use Github or Github Enterprise to authenticate to the registry.
|
||||
If enabled, users can use GitHub or GitHub Enterprise to authenticate to the registry.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Note:</strong> A registered Github (Enterprise) OAuth application is required.
|
||||
<strong>Note:</strong> A registered GitHub (Enterprise) OAuth application is required.
|
||||
View instructions on how to
|
||||
<a href="https://coreos.com/docs/enterprise-registry/github-auth/" target="_blank">
|
||||
<a href="https://coreos.com/docs/enterprise-registry/github-app/" target="_blank">
|
||||
Create an OAuth Application in GitHub
|
||||
</a>
|
||||
</p>
|
||||
|
@ -360,21 +360,21 @@
|
|||
|
||||
<div class="co-checkbox">
|
||||
<input id="ftghl" type="checkbox" ng-model="config.FEATURE_GITHUB_LOGIN">
|
||||
<label for="ftghl">Enable Github Authentication</label>
|
||||
<label for="ftghl">Enable GitHub Authentication</label>
|
||||
</div>
|
||||
|
||||
<table class="config-table" ng-if="config.FEATURE_GITHUB_LOGIN">
|
||||
<tr>
|
||||
<td>Github:</td>
|
||||
<td>GitHub:</td>
|
||||
<td>
|
||||
<select ng-model="mapped.GITHUB_LOGIN_KIND">
|
||||
<option value="hosted">Github.com</option>
|
||||
<option value="enterprise">Github Enterprise</option>
|
||||
<option value="hosted">GitHub.com</option>
|
||||
<option value="enterprise">GitHub Enterprise</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr ng-if="mapped.GITHUB_LOGIN_KIND == 'enterprise'">
|
||||
<td>Github Endpoint:</td>
|
||||
<td>GitHub Endpoint:</td>
|
||||
<td>
|
||||
<span class="config-string-field"
|
||||
binding="config.GITHUB_LOGIN_CONFIG.GITHUB_ENDPOINT"
|
||||
|
@ -382,7 +382,7 @@
|
|||
pattern="{{ GITHUB_REGEX }}">
|
||||
</span>
|
||||
<div class="help-text">
|
||||
The Github Enterprise endpoint. Must start with http:// or https://.
|
||||
The GitHub Enterprise endpoint. Must start with http:// or https://.
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -402,7 +402,7 @@
|
|||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div> <!-- /Github Authentication -->
|
||||
</div> <!-- /GitHub Authentication -->
|
||||
|
||||
<!-- Google Authentication -->
|
||||
<div class="co-panel">
|
||||
|
@ -471,20 +471,20 @@
|
|||
</div> <!-- /Build Support -->
|
||||
|
||||
|
||||
<!-- Github Trigger -->
|
||||
<!-- GitHub Trigger -->
|
||||
<div class="co-panel" ng-if="config.FEATURE_BUILD_SUPPORT" style="margin-top: 20px;">
|
||||
<div class="co-panel-heading">
|
||||
<i class="fa fa-github"></i> Github (Enterprise) Build Triggers
|
||||
<i class="fa fa-github"></i> GitHub (Enterprise) Build Triggers
|
||||
</div>
|
||||
<div class="co-panel-body">
|
||||
<div class="description">
|
||||
<p>
|
||||
If enabled, users can setup Github or Github Enterprise triggers to invoke Registry builds.
|
||||
If enabled, users can setup GitHub or GitHub Enterprise triggers to invoke Registry builds.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Note:</strong> A registered Github (Enterprise) OAuth application (<strong>separate from Github Authentication</strong>) is required.
|
||||
<strong>Note:</strong> A registered GitHub (Enterprise) OAuth application (<strong>separate from GitHub Authentication</strong>) is required.
|
||||
View instructions on how to
|
||||
<a href="https://coreos.com/docs/enterprise-registry/github-auth/" target="_blank">
|
||||
<a href="https://coreos.com/docs/enterprise-registry/github-app/" target="_blank">
|
||||
Create an OAuth Application in GitHub
|
||||
</a>
|
||||
</p>
|
||||
|
@ -492,21 +492,21 @@
|
|||
|
||||
<div class="co-checkbox">
|
||||
<input id="ftgb" type="checkbox" ng-model="config.FEATURE_GITHUB_BUILD">
|
||||
<label for="ftgb">Enable Github Triggers</label>
|
||||
<label for="ftgb">Enable GitHub Triggers</label>
|
||||
</div>
|
||||
|
||||
<table class="config-table" ng-if="config.FEATURE_GITHUB_BUILD">
|
||||
<tr>
|
||||
<td>Github:</td>
|
||||
<td>GitHub:</td>
|
||||
<td>
|
||||
<select ng-model="mapped.GITHUB_TRIGGER_KIND">
|
||||
<option value="hosted">Github.com</option>
|
||||
<option value="enterprise">Github Enterprise</option>
|
||||
<option value="hosted">GitHub.com</option>
|
||||
<option value="enterprise">GitHub Enterprise</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr ng-if="mapped.GITHUB_TRIGGER_KIND == 'enterprise'">
|
||||
<td>Github Endpoint:</td>
|
||||
<td>GitHub Endpoint:</td>
|
||||
<td>
|
||||
<span class="config-string-field"
|
||||
binding="config.GITHUB_TRIGGER_CONFIG.GITHUB_ENDPOINT"
|
||||
|
@ -514,7 +514,7 @@
|
|||
pattern="{{ GITHUB_REGEX }}">
|
||||
</span>
|
||||
<div class="help-text">
|
||||
The Github Enterprise endpoint. Must start with http:// or https://.
|
||||
The GitHub Enterprise endpoint. Must start with http:// or https://.
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -534,7 +534,7 @@
|
|||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div> <!-- /Github Trigger -->
|
||||
</div> <!-- /GitHub Trigger -->
|
||||
</form>
|
||||
|
||||
<!-- Save Bar -->
|
||||
|
|
|
@ -1,39 +1,75 @@
|
|||
<div class="ps-usage-graph-element">
|
||||
<div quay-show="Features.BUILD_SUPPORT" ng-if="data.build && data.build.job_total">
|
||||
Build Workers:
|
||||
<div class="realtime-area-chart"
|
||||
data="[data.build.job_total, data.build.running_total]"
|
||||
labels="['Queued Build Jobs', 'Running Build Jobs']"
|
||||
colors="['rgb(157, 194, 211)', 'rgb(56, 122, 163)']"
|
||||
counter="counter"></div>
|
||||
<!-- Build Charts -->
|
||||
<div quay-show="Features.BUILD_SUPPORT">
|
||||
<div class="alert alert-warning" ng-if="data.build && data.build.job_total == null">
|
||||
Cannot load build system status. Please restart your container.
|
||||
</div>
|
||||
<div ng-if="data.build && data.build.job_total >= 0">
|
||||
<div class="col-md-6 chart-col">
|
||||
<h4>Build Queue</h4>
|
||||
<h5>
|
||||
Running Jobs: {{ data.build.running_total }} | Total Jobs: {{ data.build.job_total }}
|
||||
</h5>
|
||||
<div class="realtime-area-chart"
|
||||
data="[data.build.job_total, data.build.running_total]"
|
||||
labels="['Queued Build Jobs', 'Running Build Jobs']"
|
||||
colors="['rgb(157, 194, 211)', 'rgb(56, 122, 163)']"
|
||||
counter="counter"
|
||||
minimum="-10"
|
||||
maximum="auto"></div>
|
||||
</div>
|
||||
|
||||
<div class="realtime-area-chart"
|
||||
data="[data.build.job_total, data.build.workers, data.build.running_local]"
|
||||
labels="['Queued Build Jobs', 'Build Workers (local)', 'Running Build Jobs (local)']"
|
||||
colors="['rgb(157, 194, 211)', 'rgb(161, 208, 93)', 'rgb(210, 237, 130)']"
|
||||
counter="counter"></div>
|
||||
<div class="col-md-6 chart-col">
|
||||
<h4>Local Build Workers</h4>
|
||||
<h5>
|
||||
Local Workers: {{ data.build.workers }} | Working: {{ data.build.running_local }}
|
||||
</h5>
|
||||
<div class="realtime-area-chart"
|
||||
data="[data.build.job_total, data.build.workers, data.build.running_local]"
|
||||
labels="['Queued Build Jobs', 'Build Workers (local)', 'Running Build Jobs (local)']"
|
||||
colors="['rgb(157, 194, 211)', 'rgb(161, 208, 93)', 'rgb(210, 237, 130)']"
|
||||
counter="counter"
|
||||
minimum="-10"
|
||||
maximum="auto"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
CPU:
|
||||
<div class="realtime-line-chart" data="data.count.cpu" counter="counter"
|
||||
label-template="CPU #{x} %"></div>
|
||||
<!-- CPU, Memory and Network -->
|
||||
<div class="col-md-4 chart-col">
|
||||
<h4>CPU Usage %</h4>
|
||||
<div class="realtime-line-chart" data="data.count.cpu" counter="counter"
|
||||
label-template="CPU #{x} %"
|
||||
minimum="-10" maximum="110"></div>
|
||||
</div>
|
||||
|
||||
Process Count:
|
||||
<div class="realtime-line-chart" data="data.count.processes" counter="counter"
|
||||
label-template="Process Count"></div>
|
||||
<div class="col-md-4 chart-col">
|
||||
<h4>Process Count</h4>
|
||||
<div class="realtime-line-chart" data="data.count.processes" counter="counter"
|
||||
label-template="Process Count"></div>
|
||||
</div>
|
||||
|
||||
Virtual Memory:
|
||||
<div class="realtime-line-chart" data="data.count.virtual_mem[2]" counter="counter"
|
||||
label-template="Virtual Memory %"></div>
|
||||
<div class="col-md-4 chart-col">
|
||||
<h4>Virtual Memory %</h4>
|
||||
<div class="realtime-line-chart" data="data.count.virtual_mem[2]" counter="counter"
|
||||
label-template="Virtual Memory %"
|
||||
minimum="-10" maximum="110"></div>
|
||||
</div>
|
||||
|
||||
Swap Memory:
|
||||
<div class="realtime-line-chart" data="data.count.swap_mem[3]" counter="counter"
|
||||
label-template="Swap Memory %"></div>
|
||||
<div class="col-md-4 chart-col">
|
||||
<h4>Swap Memory</h4>
|
||||
<div class="realtime-line-chart" data="data.count.swap_mem[3]" counter="counter"
|
||||
label-template="Swap Memory %"></div>
|
||||
</div>
|
||||
|
||||
Network Connections:
|
||||
<div class="realtime-line-chart" data="data.count.connections" counter="counter"
|
||||
label-template="Network Connection Count"></div>
|
||||
<div class="col-md-4 chart-col">
|
||||
<h4>Network Connections</h4>
|
||||
<div class="realtime-line-chart" data="data.count.connections" counter="counter"
|
||||
label-template="Network Connection Count"></div>
|
||||
</div>
|
||||
|
||||
Network Usage:
|
||||
<div class="realtime-line-chart" data="data.count.network" labels="['Bytes In', 'Bytes Out']" counter="counter"></div>
|
||||
<div class="col-md-4 chart-col">
|
||||
<h4>Network Usage (Bytes)</h4>
|
||||
<div class="realtime-line-chart" data="data.count.network" labels="['Bytes In', 'Bytes Out']" counter="counter"></div>
|
||||
</div>
|
||||
</div>
|
|
@ -1,3 +1,6 @@
|
|||
<div class="realtime-area-chart-element">
|
||||
<div class="chart" style="width: 450px; height: 250px;"></div>
|
||||
<div ng-show="counter >= 1">
|
||||
<div class="chart"></div>
|
||||
</div>
|
||||
<div class="cor-loader-inline" ng-if="counter < 1"></div>
|
||||
</div>
|
|
@ -1,3 +1,6 @@
|
|||
<div class="realtime-line-chart-element">
|
||||
<div class="chart" style="width: 450px; height: 250px;"></div>
|
||||
<div ng-show="counter >= 1">
|
||||
<div class="chart"></div>
|
||||
</div>
|
||||
<div class="cor-loader-inline" ng-if="counter < 1"></div>
|
||||
</div>
|
206
static/js/app.js
206
static/js/app.js
|
@ -6602,178 +6602,6 @@ quayApp.directive('locationView', function () {
|
|||
});
|
||||
|
||||
|
||||
quayApp.directive('realtimeAreaChart', function () {
|
||||
var directiveDefinitionObject = {
|
||||
priority: 0,
|
||||
templateUrl: '/static/directives/realtime-area-chart.html',
|
||||
replace: false,
|
||||
transclude: false,
|
||||
restrict: 'C',
|
||||
scope: {
|
||||
'data': '=data',
|
||||
'labels': '=labels',
|
||||
'colors': '=colors',
|
||||
'counter': '=counter'
|
||||
},
|
||||
controller: function($scope, $element) {
|
||||
var graph = null;
|
||||
var series = [];
|
||||
var palette = new Rickshaw.Color.Palette( { scheme: 'spectrum14' } );
|
||||
var colors = $scope.colors || [];
|
||||
|
||||
var setupGraph = function() {
|
||||
for (var i = 0; i < $scope.labels.length; ++i) {
|
||||
series.push({
|
||||
name: $scope.labels[i],
|
||||
color: i >= colors.length ? palette.color(): $scope.colors[i],
|
||||
stroke: 'rgba(0,0,0,0.15)',
|
||||
data: []
|
||||
});
|
||||
}
|
||||
|
||||
graph = new Rickshaw.Graph( {
|
||||
element: $element.find('.chart')[0],
|
||||
renderer: 'area',
|
||||
stroke: true,
|
||||
series: series,
|
||||
min: 0
|
||||
});
|
||||
};
|
||||
|
||||
var refresh = function(data) {
|
||||
if (!data || $scope.counter < 0) { return; }
|
||||
if (!graph) {
|
||||
setupGraph();
|
||||
}
|
||||
|
||||
for (var i = 0; i < $scope.data.length; ++i) {
|
||||
series[i].data.push(
|
||||
{'x': $scope.counter, 'y': $scope.data[i] }
|
||||
);
|
||||
}
|
||||
|
||||
hoverDetail = new Rickshaw.Graph.HoverDetail({
|
||||
graph: graph,
|
||||
xFormatter: function(x) {
|
||||
return x.toString();
|
||||
}
|
||||
});
|
||||
|
||||
graph.renderer.unstack = true;
|
||||
graph.render();
|
||||
};
|
||||
|
||||
$scope.$watch('counter', function() {
|
||||
refresh($scope.data_raw);
|
||||
});
|
||||
|
||||
$scope.$watch('data', function(data) {
|
||||
$scope.data_raw = data;
|
||||
refresh($scope.data_raw);
|
||||
});
|
||||
}
|
||||
};
|
||||
return directiveDefinitionObject;
|
||||
});
|
||||
|
||||
|
||||
quayApp.directive('realtimeLineChart', function () {
|
||||
var directiveDefinitionObject = {
|
||||
priority: 0,
|
||||
templateUrl: '/static/directives/realtime-line-chart.html',
|
||||
replace: false,
|
||||
transclude: false,
|
||||
restrict: 'C',
|
||||
scope: {
|
||||
'data': '=data',
|
||||
'labels': '=labels',
|
||||
'counter': '=counter',
|
||||
'labelTemplate': '@labelTemplate'
|
||||
},
|
||||
controller: function($scope, $element) {
|
||||
var graph = null;
|
||||
var hoverDetail = null;
|
||||
var series = [];
|
||||
var counter = 0;
|
||||
var palette = new Rickshaw.Color.Palette( { scheme: 'spectrum14' } );
|
||||
|
||||
var setupGraph = function() {
|
||||
graph = new Rickshaw.Graph({
|
||||
element: $element.find('.chart')[0],
|
||||
renderer: 'line',
|
||||
series: series,
|
||||
min: 'auto',
|
||||
padding: {
|
||||
'top': 0.1,
|
||||
'left': 0.01,
|
||||
'right': 0.01,
|
||||
'bottom': 0.1
|
||||
}
|
||||
});
|
||||
|
||||
hoverDetail = new Rickshaw.Graph.HoverDetail({
|
||||
graph: graph,
|
||||
xFormatter: function(x) {
|
||||
return x.toString();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var refresh = function(data) {
|
||||
if (!data) { return; }
|
||||
if (!graph) {
|
||||
setupGraph();
|
||||
}
|
||||
|
||||
if (typeof data == 'number') {
|
||||
data = [data];
|
||||
}
|
||||
|
||||
if ($scope.labels) {
|
||||
data = data.slice(0, $scope.labels.length);
|
||||
}
|
||||
|
||||
if (series.length == 0){
|
||||
for (var i = 0; i < data.length; ++i) {
|
||||
var title = $scope.labels ? $scope.labels[i] : $scope.labelTemplate.replace('{x}', i + 1);
|
||||
series.push({
|
||||
'color': palette.color(),
|
||||
'data': [],
|
||||
'name': title
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
counter++;
|
||||
|
||||
for (var i = 0; i < data.length; ++i) {
|
||||
var arr = series[i].data;
|
||||
arr.push({
|
||||
'x': counter,
|
||||
'y': data[i]
|
||||
})
|
||||
|
||||
if (arr.length > 10) {
|
||||
series[i].data = arr.slice(arr.length - 10, arr.length);
|
||||
}
|
||||
}
|
||||
|
||||
graph.render();
|
||||
};
|
||||
|
||||
$scope.$watch('counter', function(counter) {
|
||||
refresh($scope.data_raw);
|
||||
});
|
||||
|
||||
$scope.$watch('data', function(data) {
|
||||
$scope.data_raw = data;
|
||||
});
|
||||
}
|
||||
};
|
||||
return directiveDefinitionObject;
|
||||
});
|
||||
|
||||
|
||||
quayApp.directive('psUsageGraph', function () {
|
||||
var directiveDefinitionObject = {
|
||||
priority: 0,
|
||||
|
@ -6782,18 +6610,40 @@ quayApp.directive('psUsageGraph', function () {
|
|||
transclude: false,
|
||||
restrict: 'C',
|
||||
scope: {
|
||||
'isEnabled': '=isEnabled'
|
||||
},
|
||||
controller: function($scope, $element) {
|
||||
$scope.counter = -1;
|
||||
$scope.data = null;
|
||||
|
||||
var source = new EventSource('/realtime/ps');
|
||||
source.onmessage = function(e) {
|
||||
$scope.$apply(function() {
|
||||
$scope.counter++;
|
||||
$scope.data = JSON.parse(e.data);
|
||||
});
|
||||
var source = null;
|
||||
|
||||
var connect = function() {
|
||||
if (source) { return; }
|
||||
source = new EventSource('/realtime/ps');
|
||||
source.onmessage = function(e) {
|
||||
$scope.$apply(function() {
|
||||
$scope.counter++;
|
||||
$scope.data = JSON.parse(e.data);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
var disconnect = function() {
|
||||
if (!source) { return; }
|
||||
source.close();
|
||||
source = null;
|
||||
};
|
||||
|
||||
$scope.$watch('isEnabled', function(value) {
|
||||
if (value) {
|
||||
connect();
|
||||
} else {
|
||||
disconnect();
|
||||
}
|
||||
});
|
||||
|
||||
$scope.$on("$destroy", disconnect);
|
||||
}
|
||||
};
|
||||
return directiveDefinitionObject;
|
||||
|
|
|
@ -17,6 +17,11 @@ function SuperUserAdminCtrl($scope, $timeout, ApiService, Features, UserService,
|
|||
$scope.pollChannel = null;
|
||||
$scope.logsScrolled = false;
|
||||
$scope.csrf_token = encodeURIComponent(window.__token);
|
||||
$scope.dashboardActive = false;
|
||||
|
||||
$scope.setDashboardActive = function(active) {
|
||||
$scope.dashboardActive = active;
|
||||
};
|
||||
|
||||
$scope.configurationSaved = function() {
|
||||
$scope.requiresRestart = true;
|
||||
|
|
|
@ -307,10 +307,10 @@ angular.module("core-config-setup", ['angularFileUpload'])
|
|||
if (!value) { return; }
|
||||
|
||||
ApiService.scGetConfig().then(function(resp) {
|
||||
$scope.config = resp['config'];
|
||||
$scope.config = resp['config'] || {};
|
||||
initializeMappedLogic($scope.config);
|
||||
$scope.mapped['$hasChanges'] = false;
|
||||
});
|
||||
}, ApiService.errorDisplay('Could not load config'));
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
@ -270,9 +270,18 @@ angular.module("core-ui", [])
|
|||
'tabActive': '@tabActive',
|
||||
'tabTitle': '@tabTitle',
|
||||
'tabTarget': '@tabTarget',
|
||||
'tabInit': '&tabInit'
|
||||
'tabInit': '&tabInit',
|
||||
'tabShown': '&tabShown',
|
||||
'tabHidden': '&tabHidden'
|
||||
},
|
||||
controller: function($rootScope, $scope, $element) {
|
||||
$element.find('a[data-toggle="tab"]').on('hidden.bs.tab', function (e) {
|
||||
$scope.tabHidden({});
|
||||
});
|
||||
|
||||
$element.find('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
|
||||
$scope.tabShown({});
|
||||
});
|
||||
}
|
||||
};
|
||||
return directiveDefinitionObject;
|
||||
|
@ -297,6 +306,236 @@ angular.module("core-ui", [])
|
|||
return directiveDefinitionObject;
|
||||
})
|
||||
|
||||
.directive('realtimeAreaChart', function () {
|
||||
var directiveDefinitionObject = {
|
||||
priority: 0,
|
||||
templateUrl: '/static/directives/realtime-area-chart.html',
|
||||
replace: false,
|
||||
transclude: false,
|
||||
restrict: 'C',
|
||||
scope: {
|
||||
'data': '=data',
|
||||
'labels': '=labels',
|
||||
'colors': '=colors',
|
||||
'counter': '=counter'
|
||||
},
|
||||
controller: function($scope, $element) {
|
||||
var graph = null;
|
||||
var series = [];
|
||||
var palette = new Rickshaw.Color.Palette( { scheme: 'spectrum14' } );
|
||||
var colors = $scope.colors || [];
|
||||
|
||||
var setupGraph = function() {
|
||||
for (var i = 0; i < $scope.labels.length; ++i) {
|
||||
series.push({
|
||||
name: $scope.labels[i],
|
||||
color: i >= colors.length ? palette.color(): $scope.colors[i],
|
||||
stroke: 'rgba(0,0,0,0.15)',
|
||||
data: []
|
||||
});
|
||||
}
|
||||
|
||||
var options = {
|
||||
element: $element.find('.chart')[0],
|
||||
renderer: 'area',
|
||||
stroke: true,
|
||||
series: series,
|
||||
min: 0,
|
||||
padding: {
|
||||
'top': 0.3,
|
||||
'left': 0,
|
||||
'right': 0,
|
||||
'bottom': 0.3
|
||||
}
|
||||
};
|
||||
|
||||
if ($scope.minimum != null) {
|
||||
options['min'] = $scope.minimum == 'auto' ? 'auto' : $scope.minimum * 1;
|
||||
} else {
|
||||
options['min'] = 0;
|
||||
}
|
||||
|
||||
if ($scope.maximum != null) {
|
||||
options['max'] = $scope.maximum == 'auto' ? 'auto' : $scope.maximum * 1;
|
||||
}
|
||||
|
||||
graph = new Rickshaw.Graph(options);
|
||||
|
||||
xaxes = new Rickshaw.Graph.Axis.Time({
|
||||
graph: graph,
|
||||
timeFixture: new Rickshaw.Fixtures.Time.Local()
|
||||
});
|
||||
|
||||
yaxes = new Rickshaw.Graph.Axis.Y({
|
||||
graph: graph,
|
||||
tickFormat: Rickshaw.Fixtures.Number.formatKMBT
|
||||
});
|
||||
|
||||
hoverDetail = new Rickshaw.Graph.HoverDetail({
|
||||
graph: graph,
|
||||
xFormatter: function(x) {
|
||||
return new Date(x * 1000).toString();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var refresh = function(data) {
|
||||
if (!data || $scope.counter < 0) { return; }
|
||||
if (!graph) {
|
||||
setupGraph();
|
||||
}
|
||||
|
||||
var timecode = new Date().getTime() / 1000;
|
||||
for (var i = 0; i < $scope.data.length; ++i) {
|
||||
var arr = series[i].data;
|
||||
arr.push(
|
||||
{'x': timecode, 'y': $scope.data[i] }
|
||||
);
|
||||
|
||||
if (arr.length > 10) {
|
||||
series[i].data = arr.slice(arr.length - 10, arr.length);
|
||||
}
|
||||
}
|
||||
|
||||
graph.renderer.unstack = true;
|
||||
graph.update();
|
||||
};
|
||||
|
||||
$scope.$watch('counter', function() {
|
||||
refresh($scope.data_raw);
|
||||
});
|
||||
|
||||
$scope.$watch('data', function(data) {
|
||||
$scope.data_raw = data;
|
||||
refresh($scope.data_raw);
|
||||
});
|
||||
}
|
||||
};
|
||||
return directiveDefinitionObject;
|
||||
})
|
||||
|
||||
|
||||
.directive('realtimeLineChart', function () {
|
||||
var directiveDefinitionObject = {
|
||||
priority: 0,
|
||||
templateUrl: '/static/directives/realtime-line-chart.html',
|
||||
replace: false,
|
||||
transclude: false,
|
||||
restrict: 'C',
|
||||
scope: {
|
||||
'data': '=data',
|
||||
'labels': '=labels',
|
||||
'counter': '=counter',
|
||||
'labelTemplate': '@labelTemplate',
|
||||
'minimum': '@minimum',
|
||||
'maximum': '@maximum'
|
||||
},
|
||||
controller: function($scope, $element) {
|
||||
var graph = null;
|
||||
var xaxes = null;
|
||||
var yaxes = null;
|
||||
var hoverDetail = null;
|
||||
var series = [];
|
||||
var counter = 0;
|
||||
var palette = new Rickshaw.Color.Palette( { scheme: 'spectrum14' } );
|
||||
|
||||
var setupGraph = function() {
|
||||
var options = {
|
||||
element: $element.find('.chart')[0],
|
||||
renderer: 'line',
|
||||
series: series,
|
||||
padding: {
|
||||
'top': 0.3,
|
||||
'left': 0,
|
||||
'right': 0,
|
||||
'bottom': 0.3
|
||||
}
|
||||
};
|
||||
|
||||
if ($scope.minimum != null) {
|
||||
options['min'] = $scope.minimum == 'auto' ? 'auto' : $scope.minimum * 1;
|
||||
} else {
|
||||
options['min'] = 0;
|
||||
}
|
||||
|
||||
if ($scope.maximum != null) {
|
||||
options['max'] = $scope.maximum == 'auto' ? 'auto' : $scope.maximum * 1;
|
||||
}
|
||||
|
||||
graph = new Rickshaw.Graph(options);
|
||||
xaxes = new Rickshaw.Graph.Axis.Time({
|
||||
graph: graph,
|
||||
timeFixture: new Rickshaw.Fixtures.Time.Local()
|
||||
});
|
||||
|
||||
yaxes = new Rickshaw.Graph.Axis.Y({
|
||||
graph: graph,
|
||||
tickFormat: Rickshaw.Fixtures.Number.formatKMBT
|
||||
});
|
||||
|
||||
hoverDetail = new Rickshaw.Graph.HoverDetail({
|
||||
graph: graph,
|
||||
xFormatter: function(x) {
|
||||
return new Date(x * 1000).toString();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var refresh = function(data) {
|
||||
if (data == null) { return; }
|
||||
if (!graph) {
|
||||
setupGraph();
|
||||
}
|
||||
|
||||
if (typeof data == 'number') {
|
||||
data = [data];
|
||||
}
|
||||
|
||||
if ($scope.labels) {
|
||||
data = data.slice(0, $scope.labels.length);
|
||||
}
|
||||
|
||||
if (series.length == 0){
|
||||
for (var i = 0; i < data.length; ++i) {
|
||||
var title = $scope.labels ? $scope.labels[i] : $scope.labelTemplate.replace('{x}', i + 1);
|
||||
series.push({
|
||||
'color': palette.color(),
|
||||
'data': [],
|
||||
'name': title
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
counter++;
|
||||
var timecode = new Date().getTime() / 1000;
|
||||
|
||||
for (var i = 0; i < data.length; ++i) {
|
||||
var arr = series[i].data;
|
||||
arr.push({
|
||||
'x': timecode,
|
||||
'y': data[i]
|
||||
})
|
||||
|
||||
if (arr.length > 10) {
|
||||
series[i].data = arr.slice(arr.length - 10, arr.length);
|
||||
}
|
||||
}
|
||||
|
||||
graph.update();
|
||||
};
|
||||
|
||||
$scope.$watch('counter', function(counter) {
|
||||
refresh($scope.data_raw);
|
||||
});
|
||||
|
||||
$scope.$watch('data', function(data) {
|
||||
$scope.data_raw = data;
|
||||
});
|
||||
}
|
||||
};
|
||||
return directiveDefinitionObject;
|
||||
})
|
||||
|
||||
.directive('corStepBar', function() {
|
||||
var directiveDefinitionObject = {
|
||||
priority: 4,
|
||||
|
|
|
@ -20,7 +20,8 @@
|
|||
tab-target="#users" tab-init="loadUsers()">
|
||||
<i class="fa fa-group"></i>
|
||||
</span>
|
||||
<span class="cor-tab" tab-title="Dashboard" tab-target="#dashboard">
|
||||
<span class="cor-tab" tab-title="Dashboard" tab-target="#dashboard"
|
||||
tab-shown="setDashboardActive(true)" tab-hidden="setDashboardActive(false)">
|
||||
<i class="fa fa-tachometer"></i>
|
||||
</span>
|
||||
<span class="cor-tab" tab-title="Container Usage" tab-target="#usage-counter" tab-init="getUsage()">
|
||||
|
@ -47,7 +48,7 @@
|
|||
|
||||
<!-- Dashboard tab -->
|
||||
<div id="dashboard" class="tab-pane">
|
||||
<div class="ps-usage-graph" is-enabled="true"></div>
|
||||
<div class="ps-usage-graph" is-enabled="dashboardActive"></div>
|
||||
</div>
|
||||
|
||||
<!-- Debugging tab -->
|
||||
|
|
Reference in a new issue