Cleaning up gui plugin
- fixing bug url - removing limit action and custom alarm query code - simplifying logger setup in settings - removing unused rickshaw enhancements - deleting deprecated styling overrides from theme Change-Id: I26de161295e37235419054aa350ffd868dd9586d Signed-off-by: Tyler Smith <tyler.smith@windriver.com>
This commit is contained in:
parent
161e69480f
commit
5627f93254
@ -15,4 +15,4 @@ Pull requests submitted through GitHub will be ignored.
|
||||
|
||||
Bugs should be filed on Launchpad, not GitHub:
|
||||
|
||||
https://bugs.launchpad.net/horizon
|
||||
https://bugs.launchpad.net/starlingx
|
||||
|
@ -8,61 +8,18 @@
|
||||
#
|
||||
# PBR should always appear first
|
||||
pbr>=1.6 # Apache-2.0
|
||||
# Horizon Core Requirements
|
||||
Babel>=2.3.4 # BSD
|
||||
Django<1.9,>=1.8 # BSD
|
||||
Pint>=0.5 # BSD
|
||||
django-babel>=0.5.1 # BSD
|
||||
django-compressor>=2.0 # MIT
|
||||
django-openstack-auth>=2.4.0 # Apache-2.0
|
||||
django-pyscss>=2.0.2 # BSD License (2 clause)
|
||||
httplib2>=0.7.5 # MIT
|
||||
iso8601>=0.1.11 # MIT
|
||||
netaddr!=0.7.16,>=0.7.13 # BSD
|
||||
oslo.concurrency>=3.8.0 # Apache-2.0
|
||||
oslo.config>=3.14.0 # Apache-2.0
|
||||
oslo.i18n>=2.1.0 # Apache-2.0
|
||||
oslo.policy>=1.9.0 # Apache-2.0
|
||||
oslo.serialization>=1.10.0 # Apache-2.0
|
||||
oslo.utils>=3.16.0 # Apache-2.0
|
||||
pyScss!=1.3.5,>=1.3.4 # MIT License
|
||||
python-ceilometerclient>=2.5.0 # Apache-2.0
|
||||
python-cinderclient!=1.7.0,!=1.7.1,>=1.6.0 # Apache-2.0
|
||||
python-glanceclient!=2.4.0,>=2.3.0 # Apache-2.0
|
||||
python-heatclient>=1.4.0 # Apache-2.0
|
||||
python-keystoneclient!=2.1.0,>=2.0.0 # Apache-2.0
|
||||
python-neutronclient>=5.1.0 # Apache-2.0
|
||||
python-novaclient!=2.33.0,>=2.29.0 # Apache-2.0
|
||||
python-swiftclient>=2.2.0 # Apache-2.0
|
||||
fmclient>=1.0
|
||||
cgcs-patch>=1.0
|
||||
distributedcloud-client>=1.0.0
|
||||
cgtsclient1.0
|
||||
sysinv>=1.0
|
||||
nfv-client>=1.0.0
|
||||
sm-client>=1.0.0
|
||||
python-cephclient>=13.2.2.0
|
||||
pytz>=2013.6 # MIT
|
||||
PyYAML>=3.1.0 # MIT
|
||||
requests-toolbelt>=0.5
|
||||
six>=1.9.0 # MIT
|
||||
XStatic>=1.0.0 # MIT License
|
||||
XStatic-Angular>=1.3.7 # MIT License
|
||||
XStatic-Angular-Bootstrap>=0.11.0.2 # MIT License
|
||||
XStatic-Angular-FileUpload>=12.0.4.0 # MIT License
|
||||
XStatic-Angular-Gettext>=2.1.0.2 # MIT License
|
||||
XStatic-Angular-lrdragndrop>=1.0.2.2 # MIT License
|
||||
XStatic-Angular-Schema-Form>=0.8.13.0 # MIT
|
||||
XStatic-Bootstrap-Datepicker>=1.3.1.0 # Apache 2.0 License
|
||||
XStatic-Bootstrap-SCSS>=3 # Apache 2.0 License
|
||||
XStatic-bootswatch>=3.3.5.3 # MIT License
|
||||
XStatic-D3>=3.1.6.2 # BSD License (3 clause)
|
||||
XStatic-Hogan>=2.0.0.2 # Apache 2.0 License
|
||||
XStatic-Font-Awesome>=4.3.0 # SIL OFL 1.1 License, MIT License
|
||||
XStatic-Jasmine>=2.1.2.0 # MIT License
|
||||
XStatic-jQuery>=1.7.2 # MIT License
|
||||
XStatic-JQuery-Migrate>=1.2.1.1 # MIT License
|
||||
XStatic-JQuery.quicksearch>=2.0.3.1 # MIT License
|
||||
XStatic-JQuery.TableSorter>=2.14.5.1 # MIT License
|
||||
XStatic-jquery-ui>=1.10.1 # MIT License
|
||||
XStatic-JSEncrypt>=2.0.0.2 # MIT License
|
||||
XStatic-mdi>=1.4.57.0 # SIL OPEN FONT LICENSE Version 1.1
|
||||
XStatic-objectpath>=1.2.1.0 # MIT
|
||||
XStatic-Rickshaw>=1.5.0 # BSD License (prior)
|
||||
XStatic-roboto-fontface>=0.4.3.2 # Apache 2.0 License
|
||||
XStatic-smart-table!=1.4.13.0,>=1.4.5.3 # MIT License
|
||||
XStatic-Spin>=1.2.5.2 # MIT License
|
||||
XStatic-term.js>=0.0.4 # MIT License
|
||||
XStatic-tv4>=1.2.7.0 # MIT
|
||||
|
@ -1,2 +0,0 @@
|
||||
from starlingx_dashboard.horizon.tables.actions import FixedWithQueryFilter # noqa
|
||||
from starlingx_dashboard.horizon.tables.actions import LimitAction # noqa
|
@ -1,201 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2018 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
from collections import OrderedDict
|
||||
|
||||
from django.conf import settings
|
||||
from django.utils.translation import ugettext_lazy as _ # noqa
|
||||
|
||||
from horizon.tables.actions import BaseAction
|
||||
from horizon.tables import FilterAction
|
||||
|
||||
DEFAULT_TABLE_LIMITS = [10, 20, 50, 100, 500, 1000]
|
||||
|
||||
|
||||
class FixedWithQueryFilter(FilterAction):
|
||||
"""FilterAction
|
||||
|
||||
A FilterAction that visually renders like a combination
|
||||
FixedFilterAction and a FilterAction of type query.
|
||||
|
||||
Before extracting data from the filter, always ensure to first call
|
||||
the method updateFromRequestDataToSession(..) which will copy current
|
||||
request data to the session
|
||||
|
||||
Use get_filter_string(self, request) method to extract the current
|
||||
filter string
|
||||
|
||||
Use get_filter_field(self,request) method to extract the current
|
||||
"choice" value
|
||||
"""
|
||||
def __init__(self, **kwargs):
|
||||
super(FixedWithQueryFilter, self).__init__(**kwargs)
|
||||
self.filter_type = "fixedwithquery"
|
||||
self.filter_choices = []
|
||||
self.default_value = ''
|
||||
self.grouped_choices = []
|
||||
self.disabled_choices = []
|
||||
|
||||
def _get_fieldFromGETorPOSTorSESSION(self, request, param_name):
|
||||
"""Utility method
|
||||
|
||||
Utility method for getting 'named" data (param_name) from either
|
||||
GET/POST or Session .
|
||||
IMPORTANT NOTE: Has the side-effect of storing the data into
|
||||
the session
|
||||
TODO: In the future, this method should really live in some
|
||||
utility module.
|
||||
|
||||
:param request:
|
||||
:param param_name:
|
||||
:return: value of data referenced by param_name
|
||||
"""
|
||||
the_field = None
|
||||
|
||||
if param_name in request.GET:
|
||||
the_field = request.GET.get(param_name, '')
|
||||
|
||||
if the_field is None and param_name in request.POST:
|
||||
the_field = request.POST.get(param_name, '')
|
||||
|
||||
if the_field is None and param_name in request.session:
|
||||
the_field = request.session.get(param_name, '')
|
||||
|
||||
if the_field is not None:
|
||||
request.session[param_name] = the_field
|
||||
|
||||
return the_field
|
||||
|
||||
def get_filter_field(self, request):
|
||||
param_name = '%s_field' % self.get_param_name()
|
||||
filter_field = self._get_fieldFromGETorPOSTorSESSION(request,
|
||||
param_name)
|
||||
self.filter_field = filter_field \
|
||||
if filter_field \
|
||||
else self.default_value
|
||||
return filter_field
|
||||
|
||||
def get_filter_string(self, request):
|
||||
param_name = self.get_param_name()
|
||||
filter_string = self._get_fieldFromGETorPOSTorSESSION(request,
|
||||
param_name)
|
||||
self.filter_string = filter_string if filter_string else ''
|
||||
self.build_grouped_choices()
|
||||
|
||||
return filter_string
|
||||
|
||||
def updateFromRequestDataToSession(self, request):
|
||||
# The desired side-effect of calling the following 2 functions
|
||||
# will update the filter field and filter string into
|
||||
# the session so that they are 'remembered' across requests
|
||||
self.get_filter_field(request)
|
||||
self.get_filter_string(request)
|
||||
|
||||
def set_disabled_filter_field_for_group(self, grpNo, disabled_status):
|
||||
self.disabled_choices[grpNo] = disabled_status
|
||||
|
||||
def get_filter_field_for_group(self, grpNo):
|
||||
splitted = self.filter_field.split("|")
|
||||
if len(splitted) <= grpNo:
|
||||
raise Exception("get_filter_field_for_group: grpNo out of \
|
||||
range! grpNo={}".format(grpNo))
|
||||
value = splitted[grpNo]
|
||||
if not value:
|
||||
value = self.default_value.split("|")[grpNo]
|
||||
return value
|
||||
|
||||
def build_grouped_choices(self):
|
||||
grps = []
|
||||
grpNo = 0
|
||||
|
||||
for choices_in_group in self.filter_choices:
|
||||
currentGrpValue = self.get_filter_field_for_group(grpNo)
|
||||
disable_status = self.disabled_choices[grpNo]
|
||||
|
||||
grps.append(
|
||||
{
|
||||
"grpNo": grpNo,
|
||||
"filter_choices": choices_in_group,
|
||||
"value": currentGrpValue,
|
||||
"disabled": disable_status
|
||||
}
|
||||
)
|
||||
grpNo = grpNo + 1
|
||||
|
||||
self.grouped_choices = grps
|
||||
|
||||
return grps
|
||||
|
||||
|
||||
class LimitAction(BaseAction):
|
||||
"""A base class representing a count limit action for a table.
|
||||
|
||||
.. attribute:: name
|
||||
|
||||
The short name or "slug" representing this action. Defaults to
|
||||
``"limit"``.
|
||||
|
||||
.. attribute:: limits
|
||||
|
||||
A set of table entry limits. Default: ``"settings.TABLE_LIMITS"``.
|
||||
|
||||
.. attribute:: limit_format
|
||||
|
||||
A default format sting used do format the verbose
|
||||
name of each limit count.
|
||||
Default: ``"%(count)s %(name)s"``.
|
||||
|
||||
.. attribute:: verbose_name
|
||||
|
||||
A descriptive entity name to be used . Default: ``"Entries"``.
|
||||
"""
|
||||
|
||||
# class attribute name is used for ordering of Actions in table
|
||||
name = "limit"
|
||||
verbose_name = _("Entries")
|
||||
limit_format = _("%(count)s %(name)s")
|
||||
limits = set(getattr(settings, 'TABLE_LIMITS', DEFAULT_TABLE_LIMITS))
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(LimitAction, self).__init__(**kwargs)
|
||||
self.name = kwargs.get('name', self.name)
|
||||
self.limits = kwargs.get('limits', self.limits)
|
||||
self.limit_format = kwargs.get('limit_format', self.limit_format)
|
||||
self.verbose_name = kwargs.get('verbose_name', self.verbose_name)
|
||||
|
||||
def get_param_name(self):
|
||||
"""Returns the limit parameter name for this table action."""
|
||||
return self.table._meta.limit_param
|
||||
|
||||
def get_default_classes(self):
|
||||
classes = super(LimitAction, self).get_default_classes()
|
||||
classes += ("btn", "btn-default", "btn-sm",
|
||||
"btn-limit", "dropdown-toggle")
|
||||
return classes
|
||||
|
||||
def get_limit_display(self):
|
||||
"""Default formatter for each limit entry."""
|
||||
count = self.table.get_limit_count()
|
||||
return self.get_limit_name(count)
|
||||
|
||||
def get_limit_name(self, count):
|
||||
"""Default formatter for each limit entry."""
|
||||
if count is None:
|
||||
return "Default Limit"
|
||||
return str(self.limit_format % {'count': count,
|
||||
'name': self.verbose_name})
|
||||
|
||||
def get_limit_count(self):
|
||||
"""Return the current table limit for tables that support paging."""
|
||||
count = self.table.get_limit_count()
|
||||
return count
|
||||
|
||||
def get_limits(self):
|
||||
""""Return the set of limits supported by the action."""
|
||||
limits = {}
|
||||
for count in self.limits:
|
||||
limits[count] = self.get_limit_name(count)
|
||||
return OrderedDict(sorted(limits.items(), key=lambda limit: limit[0]))
|
@ -142,149 +142,45 @@ except Exception:
|
||||
pass
|
||||
|
||||
|
||||
LOGGING = {
|
||||
'version': 1,
|
||||
# When set to True this will disable all logging except
|
||||
# for loggers specified in this configuration dictionary. Note that
|
||||
# if nothing is specified here and disable_existing_loggers is True,
|
||||
# django.db.backends will still log unless it is disabled explicitly.
|
||||
'disable_existing_loggers': False,
|
||||
'formatters': {
|
||||
'simple': {
|
||||
'format': '%(levelno)s %(levelname)s %(message)s',
|
||||
},
|
||||
'standard': {
|
||||
'format': '%(levelno)s %(asctime)s [%(levelname)s] '
|
||||
'%(name)s: %(message)s',
|
||||
},
|
||||
'verbose': {
|
||||
'format': '%(levelno)s %(levelname)s %(asctime)s %(module)s '
|
||||
'%(process)d %(thread)d %(message)s',
|
||||
},
|
||||
'operation': {
|
||||
# The format of "%(message)s" is defined by
|
||||
# OPERATION_LOG_OPTIONS['format']
|
||||
'format': '%(asctime)s %(message)s',
|
||||
},
|
||||
},
|
||||
'handlers': {
|
||||
'null': {
|
||||
'level': 'DEBUG',
|
||||
'class': 'logging.NullHandler',
|
||||
},
|
||||
'console': {
|
||||
# Set the level to "DEBUG" for verbose output logging.
|
||||
'level': 'INFO',
|
||||
'class': 'logging.StreamHandler',
|
||||
},
|
||||
'syslog': {
|
||||
# Set the level to "DEBUG" for verbose output logging.
|
||||
'level': 'INFO',
|
||||
'formatter': 'standard',
|
||||
'class': 'logging.handlers.SysLogHandler',
|
||||
'facility': 'local7',
|
||||
'address': '/dev/log',
|
||||
},
|
||||
'operation': {
|
||||
'level': 'INFO',
|
||||
'formatter': 'operation',
|
||||
'class': 'logging.handlers.SysLogHandler',
|
||||
'facility': 'local7',
|
||||
'address': '/dev/log',
|
||||
},
|
||||
},
|
||||
'loggers': {
|
||||
# Logging from django.db.backends is VERY verbose, send to null
|
||||
# by default.
|
||||
'django.db.backends': {
|
||||
'handlers': ['null'],
|
||||
'propagate': False,
|
||||
},
|
||||
'requests': {
|
||||
'handlers': ['null'],
|
||||
'propagate': False,
|
||||
},
|
||||
'horizon': {
|
||||
'handlers': ['syslog'],
|
||||
'level': 'DEBUG',
|
||||
'propagate': False,
|
||||
},
|
||||
'horizon.operation_log': {
|
||||
'handlers': ['syslog'],
|
||||
'level': 'INFO',
|
||||
'propagate': False,
|
||||
},
|
||||
'openstack_dashboard': {
|
||||
'handlers': ['syslog'],
|
||||
'level': 'DEBUG',
|
||||
'propagate': False,
|
||||
},
|
||||
'starlingx_dashboard': {
|
||||
'handlers': ['syslog'],
|
||||
'level': 'DEBUG',
|
||||
'propagate': False,
|
||||
},
|
||||
'novaclient': {
|
||||
'handlers': ['syslog'],
|
||||
'level': 'DEBUG',
|
||||
'propagate': False,
|
||||
},
|
||||
'cinderclient': {
|
||||
'handlers': ['syslog'],
|
||||
'level': 'DEBUG',
|
||||
'propagate': False,
|
||||
},
|
||||
'keystoneclient': {
|
||||
'handlers': ['syslog'],
|
||||
'level': 'DEBUG',
|
||||
'propagate': False,
|
||||
},
|
||||
'glanceclient': {
|
||||
'handlers': ['syslog'],
|
||||
'level': 'DEBUG',
|
||||
'propagate': False,
|
||||
},
|
||||
'neutronclient': {
|
||||
'handlers': ['syslog'],
|
||||
'level': 'DEBUG',
|
||||
'propagate': False,
|
||||
},
|
||||
'heatclient': {
|
||||
'handlers': ['syslog'],
|
||||
'level': 'DEBUG',
|
||||
'propagate': False,
|
||||
},
|
||||
'swiftclient': {
|
||||
'handlers': ['null'],
|
||||
'level': 'DEBUG',
|
||||
'propagate': False,
|
||||
},
|
||||
'openstack_auth': {
|
||||
'handlers': ['syslog'],
|
||||
'level': 'DEBUG',
|
||||
'propagate': False,
|
||||
},
|
||||
'nose.plugins.manager': {
|
||||
'handlers': ['syslog'],
|
||||
'level': 'DEBUG',
|
||||
'propagate': False,
|
||||
},
|
||||
'django': {
|
||||
'handlers': ['syslog'],
|
||||
'level': 'DEBUG',
|
||||
'propagate': False,
|
||||
},
|
||||
'iso8601': {
|
||||
'handlers': ['null'],
|
||||
'propagate': False,
|
||||
},
|
||||
'scss': {
|
||||
'handlers': ['null'],
|
||||
'propagate': False,
|
||||
},
|
||||
},
|
||||
# Override LOGGING settings
|
||||
LOGGING['formatters']['standard'] = { # noqa
|
||||
'format':
|
||||
'%(levelno)s %(asctime)s [%(levelname)s] %(name)s: %(message)s'
|
||||
}
|
||||
|
||||
LOGGING['formatters']['operation'] = { # noqa
|
||||
# The format of "%(message)s" is defined by
|
||||
# OPERATION_LOG_OPTIONS['format']
|
||||
'format': '%(asctime)s %(message)s',
|
||||
}
|
||||
|
||||
# Overwrite the console handler to send to syslog
|
||||
LOGGING['handlers']['console'] = { # noqa
|
||||
'level': 'DEBUG' if DEBUG else 'INFO', # noqa
|
||||
'formatter': 'standard',
|
||||
'class': 'logging.handlers.SysLogHandler',
|
||||
'facility': 'local7',
|
||||
'address': '/dev/log',
|
||||
}
|
||||
|
||||
# Overwrite the operation handler to send to syslog
|
||||
LOGGING['handlers']['operation'] = { # noqa
|
||||
'level': 'INFO',
|
||||
'formatter': 'operation',
|
||||
'class': 'logging.handlers.SysLogHandler',
|
||||
'facility': 'local7',
|
||||
'address': '/dev/log',
|
||||
}
|
||||
|
||||
LOGGING['loggers'].update({ # noqa
|
||||
'starlingx_dashboard': {
|
||||
'handlers': ['console'],
|
||||
'level': 'DEBUG',
|
||||
'propagate': False,
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
# Session overrides
|
||||
SESSION_ENGINE = 'django.contrib.sessions.backends.file'
|
||||
SESSION_FILE_PATH = '/var/tmp'
|
||||
|
@ -1 +0,0 @@
|
||||
TABLE_LIMITS = 100
|
@ -1,513 +0,0 @@
|
||||
Rickshaw.namespace('Rickshaw.Series.FixedDuration.ExtendedData');
|
||||
|
||||
Rickshaw.Series.FixedDuration.ExtendedData = Rickshaw.Class.create(Rickshaw.Series.FixedDuration, {
|
||||
|
||||
initialize: function ($super, data, palette, options) {
|
||||
$super(data, palette, options);
|
||||
|
||||
this.lastTimestamp = 0;
|
||||
},
|
||||
|
||||
addData: function($super, data, x) {
|
||||
|
||||
var index = this.getIndex();
|
||||
|
||||
Rickshaw.keys(data).forEach(function(name) {
|
||||
if (!this.itemByName(name)) {
|
||||
this.addItem({name: name});
|
||||
}
|
||||
}, this);
|
||||
|
||||
var count = 0;
|
||||
this.forEach(function(item) {
|
||||
count = 0;
|
||||
var points = (Array.isArray(data[item.name])) ? data[item.name] : [data[item.name]];
|
||||
points.forEach(function(point) {
|
||||
var datum = Object.create(point);
|
||||
datum.x = x || this.getTimestamp(datum.x) || ((index * this.timeInterval || 1) + this.timeBase);
|
||||
datum.y = (datum.y || 0);
|
||||
item.data.push(datum);
|
||||
count++;
|
||||
if (datum.x > this.lastTimestamp) {
|
||||
this.lastTimestamp = datum.x;
|
||||
}
|
||||
}, this);
|
||||
}, this);
|
||||
|
||||
this.currentSize += count;
|
||||
this.currentIndex += count;
|
||||
|
||||
if (this.maxDataPoints !== undefined) {
|
||||
while (this.currentSize > this.maxDataPoints) {
|
||||
this.dropData();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
zeroData: function() {
|
||||
this.forEach(function(item) {
|
||||
item.data.forEach(function(datum) {
|
||||
datum.y = 0;
|
||||
});
|
||||
}, this);
|
||||
},
|
||||
|
||||
/* timestamp rounded down to the nearest interval time */
|
||||
getTimestamp: function(timestamp) {
|
||||
return Math.floor(timestamp / this.timeInterval) * this.timeInterval;
|
||||
},
|
||||
|
||||
getLastTimestamp: function() {
|
||||
return this.lastTimestamp;
|
||||
}
|
||||
});
|
||||
|
||||
Rickshaw.namespace('Rickshaw.Fixtures.Number');
|
||||
|
||||
Rickshaw.Fixtures.Number.formatBinaryBytes = function(y) {
|
||||
//CGCS addition
|
||||
var abs_y = Math.abs(y);
|
||||
if (abs_y >= 1125899906842624) { return (y / 1125899906842624).toFixed(0) + "P"; }
|
||||
else if (abs_y >= 1099511627776){ return (y / 1099511627776).toFixed(0) + "T"; }
|
||||
else if (abs_y >= 1073741824) { return (y / 1073741824).toFixed(0) + "G"; }
|
||||
else if (abs_y >= 1048576) { return (y / 1048576).toFixed(0) + "M"; }
|
||||
else if (abs_y >= 1024) { return (y / 1024).toFixed(0) + "K"; }
|
||||
else if (abs_y < 1 && y > 0) { return y.toFixed(0); }
|
||||
else if (abs_y === 0) { return '0'; }
|
||||
else { return y.toFixed(0); }
|
||||
};
|
||||
|
||||
|
||||
Rickshaw.namespace('Rickshaw.Graph.Behavior.Series.Toggle');
|
||||
|
||||
Rickshaw.Graph.Behavior.Series.Toggle = function(args) {
|
||||
|
||||
this.graph = args.graph;
|
||||
this.legend = args.legend;
|
||||
|
||||
var self = this;
|
||||
|
||||
this.addAnchor = function(line) {
|
||||
|
||||
var anchor = document.createElement('a');
|
||||
anchor.innerHTML = '✔';
|
||||
anchor.classList.add('action');
|
||||
line.element.insertBefore(anchor, line.element.firstChild);
|
||||
|
||||
anchor.onclick = function(e) {
|
||||
if (line.series.disabled) {
|
||||
line.series.enable();
|
||||
line.element.classList.remove('disabled');
|
||||
} else {
|
||||
if (this.graph.series.filter(function(s) { return !s.disabled }).length <= 1) return;
|
||||
line.series.disable();
|
||||
line.element.classList.add('disabled');
|
||||
}
|
||||
|
||||
}.bind(this);
|
||||
|
||||
var label = line.element.getElementsByTagName('span')[0];
|
||||
label.onclick = function(e){
|
||||
|
||||
var disableAllOtherLines = line.series.disabled;
|
||||
if ( ! disableAllOtherLines ) {
|
||||
for ( var i = 0; i < self.legend.lines.length; i++ ) {
|
||||
var l = self.legend.lines[i];
|
||||
if ( line.series === l.series ) {
|
||||
// noop
|
||||
} else if ( l.series.disabled ) {
|
||||
// noop
|
||||
} else {
|
||||
disableAllOtherLines = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// show all or none
|
||||
if ( disableAllOtherLines ) {
|
||||
|
||||
// these must happen first or else we try ( and probably fail ) to make a no line graph
|
||||
line.series.enable(false);
|
||||
line.element.classList.remove('disabled');
|
||||
|
||||
self.legend.lines.forEach(function(l){
|
||||
if ( line.series === l.series ) {
|
||||
// noop
|
||||
} else {
|
||||
l.series.disable(false);
|
||||
l.element.classList.add('disabled');
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
|
||||
self.legend.lines.forEach(function(l){
|
||||
l.series.enable(false);
|
||||
l.element.classList.remove('disabled');
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
self.graph.update();
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
if (this.legend) {
|
||||
|
||||
var $ = jQuery;
|
||||
if (typeof $ != 'undefined' && $(this.legend.list).sortable) {
|
||||
|
||||
$(this.legend.list).sortable( {
|
||||
start: function(event, ui) {
|
||||
ui.item.bind('no.onclick',
|
||||
function(event) {
|
||||
event.preventDefault();
|
||||
}
|
||||
);
|
||||
},
|
||||
stop: function(event, ui) {
|
||||
setTimeout(function(){
|
||||
ui.item.unbind('no.onclick');
|
||||
}, 250);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.legend.lines.forEach( function(l) {
|
||||
self.addAnchor(l);
|
||||
} );
|
||||
}
|
||||
|
||||
this._addBehavior = function() {
|
||||
|
||||
this.graph.series.forEach( function(s) {
|
||||
// Update parameter is CGCS addition
|
||||
s.disable = function(update) {
|
||||
|
||||
if (self.graph.series.length <= 1) {
|
||||
throw('only one series left');
|
||||
}
|
||||
|
||||
s.disabled = true;
|
||||
if (update !== false) {
|
||||
self.graph.update();
|
||||
}
|
||||
};
|
||||
|
||||
s.enable = function(update) {
|
||||
s.disabled = false;
|
||||
if (update !== false) {
|
||||
self.graph.update();
|
||||
}
|
||||
};
|
||||
} );
|
||||
};
|
||||
this._addBehavior();
|
||||
|
||||
this.updateBehaviour = function () { this._addBehavior() };
|
||||
|
||||
};
|
||||
|
||||
|
||||
Rickshaw.namespace('Rickshaw.Graph.HoverDetail');
|
||||
|
||||
Rickshaw.Graph.HoverDetail = Rickshaw.Class.create({
|
||||
|
||||
initialize: function(args) {
|
||||
|
||||
var graph = this.graph = args.graph;
|
||||
|
||||
this.xFormatter = args.xFormatter || function(x) {
|
||||
return new Date( x * 1000 ).toUTCString();
|
||||
};
|
||||
|
||||
this.yFormatter = args.yFormatter || function(y) {
|
||||
return y === null ? y : y.toFixed(2);
|
||||
};
|
||||
|
||||
var element = this.element = document.createElement('div');
|
||||
element.className = 'detail';
|
||||
|
||||
this.visible = true;
|
||||
graph.element.appendChild(element);
|
||||
|
||||
this.lastEvent = null;
|
||||
this._addListeners();
|
||||
|
||||
this.onShow = args.onShow;
|
||||
this.onHide = args.onHide;
|
||||
this.onRender = args.onRender;
|
||||
|
||||
this.formatter = args.formatter || this.formatter;
|
||||
|
||||
},
|
||||
|
||||
formatter: function(series, x, y, formattedX, formattedY, d) {
|
||||
return series.name + ': ' + formattedY;
|
||||
},
|
||||
|
||||
update: function(e) {
|
||||
|
||||
e = e || this.lastEvent;
|
||||
if (!e) return;
|
||||
this.lastEvent = e;
|
||||
|
||||
if (!e.target.nodeName.match(/^(path|svg|rect|circle)$/)) return;
|
||||
|
||||
var graph = this.graph;
|
||||
|
||||
var eventX = e.offsetX || e.layerX;
|
||||
var eventY = e.offsetY || e.layerY;
|
||||
|
||||
var j = 0;
|
||||
var points = [];
|
||||
var nearestPoint;
|
||||
|
||||
this.graph.series.active().forEach( function(series) {
|
||||
|
||||
var data = this.graph.stackedData[j++];
|
||||
|
||||
if (!data.length)
|
||||
return;
|
||||
|
||||
var domainX = graph.x.invert(eventX);
|
||||
|
||||
var domainIndexScale = d3.scale.linear()
|
||||
.domain([data[0].x, data.slice(-1)[0].x])
|
||||
.range([0, data.length - 1]);
|
||||
|
||||
var approximateIndex = Math.round(domainIndexScale(domainX));
|
||||
if (approximateIndex == data.length - 1) approximateIndex--;
|
||||
|
||||
var dataIndex = Math.min(approximateIndex || 0, data.length - 1);
|
||||
|
||||
for (var i = approximateIndex; i < data.length - 1;) {
|
||||
|
||||
if (!data[i] || !data[i + 1]) break;
|
||||
|
||||
if (data[i].x <= domainX && data[i + 1].x > domainX) {
|
||||
dataIndex = Math.abs(domainX - data[i].x) < Math.abs(domainX - data[i + 1].x) ? i : i + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (data[i + 1].x <= domainX) { i++ } else { i-- }
|
||||
}
|
||||
|
||||
if (dataIndex < 0) dataIndex = 0;
|
||||
var value = data[dataIndex];
|
||||
|
||||
var distance = Math.sqrt(
|
||||
Math.pow(Math.abs(graph.x(value.x) - eventX), 2) +
|
||||
Math.pow(Math.abs(graph.y(value.y + value.y0) - eventY), 2)
|
||||
);
|
||||
|
||||
var xFormatter = series.xFormatter || this.xFormatter;
|
||||
var yFormatter = series.yFormatter || this.yFormatter;
|
||||
|
||||
var point = {
|
||||
formattedXValue: xFormatter(value.x),
|
||||
formattedYValue: yFormatter(series.scale ? series.scale.invert(value.y) : value.y),
|
||||
series: series,
|
||||
value: value,
|
||||
distance: distance,
|
||||
order: j,
|
||||
name: series.name
|
||||
};
|
||||
|
||||
if (!nearestPoint || distance < nearestPoint.distance) {
|
||||
nearestPoint = point;
|
||||
}
|
||||
|
||||
points.push(point);
|
||||
|
||||
}, this );
|
||||
|
||||
if (!nearestPoint)
|
||||
return;
|
||||
|
||||
nearestPoint.active = true;
|
||||
|
||||
var domainX = nearestPoint.value.x;
|
||||
var formattedXValue = nearestPoint.formattedXValue;
|
||||
|
||||
this.element.innerHTML = '';
|
||||
this.element.style.left = graph.x(domainX) + 'px';
|
||||
|
||||
this.visible && this.render( {
|
||||
points: points,
|
||||
detail: points, // for backwards compatibility
|
||||
mouseX: eventX,
|
||||
mouseY: eventY,
|
||||
formattedXValue: formattedXValue,
|
||||
domainX: domainX
|
||||
} );
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
this.visible = false;
|
||||
this.element.classList.add('inactive');
|
||||
|
||||
if (typeof this.onHide == 'function') {
|
||||
this.onHide();
|
||||
}
|
||||
},
|
||||
|
||||
show: function() {
|
||||
this.visible = true;
|
||||
this.element.classList.remove('inactive');
|
||||
|
||||
if (typeof this.onShow == 'function') {
|
||||
this.onShow();
|
||||
}
|
||||
},
|
||||
|
||||
render: function(args) {
|
||||
|
||||
var graph = this.graph;
|
||||
var points = args.points;
|
||||
var point = points.filter( function(p) { return p.active } ).shift();
|
||||
|
||||
if (point.value.y === null) return;
|
||||
|
||||
var formattedXValue = point.formattedXValue;
|
||||
var formattedYValue = point.formattedYValue;
|
||||
|
||||
this.element.innerHTML = '';
|
||||
this.element.style.left = graph.x(point.value.x) + 'px';
|
||||
|
||||
var xLabel = document.createElement('div');
|
||||
|
||||
xLabel.className = 'x_label';
|
||||
xLabel.innerHTML = formattedXValue;
|
||||
this.element.appendChild(xLabel);
|
||||
|
||||
var item = document.createElement('div');
|
||||
|
||||
item.className = 'item';
|
||||
|
||||
// invert the scale if this series displays using a scale
|
||||
var series = point.series;
|
||||
var actualY = series.scale ? series.scale.invert(point.value.y) : point.value.y;
|
||||
|
||||
item.innerHTML = this.formatter(series, point.value.x, actualY, formattedXValue, formattedYValue, point);
|
||||
item.style.top = this.graph.y(point.value.y0 + point.value.y) + 'px';
|
||||
|
||||
this.element.appendChild(item);
|
||||
|
||||
var dot = document.createElement('div');
|
||||
|
||||
dot.className = 'dot';
|
||||
dot.style.top = item.style.top;
|
||||
dot.style.borderColor = series.color;
|
||||
|
||||
this.element.appendChild(dot);
|
||||
|
||||
if (point.active) {
|
||||
item.classList.add('active');
|
||||
dot.classList.add('active');
|
||||
}
|
||||
|
||||
// Assume left alignment until the element has been displayed and
|
||||
// bounding box calculations are possible.
|
||||
var alignables = [xLabel, item];
|
||||
alignables.forEach(function(el) {
|
||||
el.classList.add('left');
|
||||
});
|
||||
|
||||
this.show();
|
||||
|
||||
// If left-alignment results in any error, try right-alignment.
|
||||
var leftAlignError = this._calcLayoutError(alignables);
|
||||
if (leftAlignError > 0) {
|
||||
alignables.forEach(function(el) {
|
||||
el.classList.remove('left');
|
||||
el.classList.add('right');
|
||||
});
|
||||
|
||||
// If right-alignment is worse than left alignment, switch back.
|
||||
var rightAlignError = this._calcLayoutError(alignables);
|
||||
if (rightAlignError > leftAlignError) {
|
||||
alignables.forEach(function(el) {
|
||||
el.classList.remove('right');
|
||||
el.classList.add('left');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof this.onRender == 'function') {
|
||||
this.onRender(args);
|
||||
}
|
||||
},
|
||||
|
||||
_calcLayoutError: function(alignables) {
|
||||
// Layout error is calculated as the number of linear pixels by which
|
||||
// an alignable extends past the left or right edge of the parent.
|
||||
// CGCS addition
|
||||
try {
|
||||
var parentRect = this.element.parentNode.getBoundingClientRect();
|
||||
} catch(e) {
|
||||
var parentRect = this.element.getBoundingClientRect();
|
||||
}
|
||||
// CGCS addition
|
||||
try { parent.subclasses.push(klass) } catch(e) {}
|
||||
var error = 0;
|
||||
var alignRight = alignables.forEach(function(el) {
|
||||
var rect = el.getBoundingClientRect();
|
||||
if (!rect.width) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (rect.right > parentRect.right) {
|
||||
error += rect.right - parentRect.right;
|
||||
}
|
||||
|
||||
if (rect.left < parentRect.left) {
|
||||
error += parentRect.left - rect.left;
|
||||
}
|
||||
});
|
||||
return error;
|
||||
},
|
||||
|
||||
_addListeners: function() {
|
||||
|
||||
this.graph.element.addEventListener(
|
||||
'mousemove',
|
||||
function(e) {
|
||||
this.visible = true;
|
||||
this.update(e);
|
||||
}.bind(this),
|
||||
false
|
||||
);
|
||||
|
||||
this.graph.onUpdate( function() { this.update() }.bind(this) );
|
||||
|
||||
this.graph.element.addEventListener(
|
||||
'mouseout',
|
||||
function(e) {
|
||||
if (e.relatedTarget && !(e.relatedTarget.compareDocumentPosition(this.graph.element) & Node.DOCUMENT_POSITION_CONTAINS)) {
|
||||
this.hide();
|
||||
}
|
||||
}.bind(this),
|
||||
false
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Rickshaw.namespace('Rickshaw.Series.HoverDetail.Panel');
|
||||
|
||||
Rickshaw.Graph.HoverDetail.Panel = Rickshaw.Class.create(Rickshaw.Graph.HoverDetail, {
|
||||
// CGCS addition
|
||||
formatter: function(series, x, y, formattedX, formattedY, d) {
|
||||
if (d.value.formattedY !== undefined) {
|
||||
formattedY = d.value.formattedY;
|
||||
}
|
||||
var date = '<span class="date">' + new Date(x * 1000).toLocaleString() + '</span>';
|
||||
var swatch = '<span class="swatch" style="background-color: ' + series.color + '"></span>';
|
||||
var value = '<span class="value">' + series.label + ': ' + formattedY + '</span><br>' + date;
|
||||
var content = swatch + value;
|
||||
return content;
|
||||
}
|
||||
});
|
@ -4,10 +4,6 @@
|
||||
|
||||
// WRS components
|
||||
@import "components/badges";
|
||||
// (Eddie Ramirez): To be deprecated
|
||||
// @import "components/sidebar";
|
||||
// @import "components/topbar";
|
||||
// @import "components/splash";
|
||||
@import "components/charts";
|
||||
@import "components/tables";
|
||||
|
||||
|
@ -1,134 +0,0 @@
|
||||
|
||||
// Indent selected menu items
|
||||
#sidebar .openstack-panel.active {
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
// Squish accordian pills
|
||||
#sidebar-accordion {
|
||||
a {
|
||||
background-color: $main-nav-bg-color;
|
||||
color: $main-nav-bg-color;
|
||||
padding: .4em 1.2em;
|
||||
background: transparent;
|
||||
}
|
||||
.panel > a{
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
// Coloring of sidebar
|
||||
#sidebar {
|
||||
|
||||
// Header highlight color
|
||||
//.openstack-dashboard > a:hover,
|
||||
.openstack-dashboard > a:focus,
|
||||
li {
|
||||
background-color: $sidebar-background-color;
|
||||
}
|
||||
|
||||
.nav-pills.nav-stacked {
|
||||
& > li {
|
||||
& > a {
|
||||
color: $windriver-white;
|
||||
background: $main-nav-bg-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dashboard headers
|
||||
#sidebar-accordion > li.panel > a{
|
||||
//font-size: 15px;
|
||||
border-radius: 9px;
|
||||
background-color: $windriver-lighter-gray;
|
||||
}
|
||||
|
||||
// Panel group headers
|
||||
#sidebar-accordion li.openstack-panel-group > a {
|
||||
//font-size: 15px;
|
||||
color: $windriver-white;
|
||||
text-align: left;
|
||||
|
||||
&:hover {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
// All links
|
||||
li.openstack-dashboard a.openstack-panel {
|
||||
color: $windriver-white;
|
||||
// Link on hover
|
||||
&:hover {
|
||||
color: $windriver-lighter-red;
|
||||
background-color: $sidebar-background-color;
|
||||
}
|
||||
}
|
||||
|
||||
// Selected panel
|
||||
li.openstack-dashboard a.openstack-panel.active {
|
||||
color: $sidebar-active-color;
|
||||
background: $windriver-white;
|
||||
border-left: 2px;
|
||||
border-left-style: solid;
|
||||
border-left-color: $sidebar-active-color;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#sidebar {
|
||||
float: none;
|
||||
display: table-cell;
|
||||
|
||||
height: 100%;
|
||||
background-color: $sidebar-background-color;
|
||||
|
||||
.branding {
|
||||
padding-bottom: 0px;
|
||||
padding-top: 0px;
|
||||
padding-left: 0px;
|
||||
text-align: center;
|
||||
|
||||
/* vertical gradient (excluding IE9 and below - which clips the nav-tabs) */
|
||||
background-color: mix($brand-bg-color, $brand-bg-highlight, 60%); // Old Browswers
|
||||
background-image: -moz-linear-gradient(top, $brand-bg-color, $brand-bg-highlight); // FF 3.6+
|
||||
background-image: -ms-linear-gradient(top, $brand-bg-color, $brand-bg-highlight); // IE10
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from($brand-bg-color), to($brand-bg-highlight)); // Safari 4+, Chrome 2+
|
||||
background-image: -webkit-linear-gradient(top, $brand-bg-color, $brand-bg-highlight); // Safari 5.1+, Chrome 10+
|
||||
background-image: -o-linear-gradient(top, $brand-bg-color, $brand-bg-highlight); // Opera 11.10
|
||||
background-image: linear-gradient(top, $brand-bg-color, $brand-bg-highlight); // The standard
|
||||
background-repeat: repeat-x;
|
||||
|
||||
.brand {
|
||||
background: none;
|
||||
padding-bottom: 0px;
|
||||
margin-top: 0px;
|
||||
|
||||
a {
|
||||
float: none;
|
||||
color: $brand-text-color;
|
||||
text-indent: inherit;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
text-shadow: 2px 1px 15px #000;
|
||||
font-size: 20px;
|
||||
line-height: 20px;
|
||||
margin: 20px 0px 0px 0px;
|
||||
padding-top: 0px;
|
||||
padding-bottom: 0px;
|
||||
height: $brand-height;
|
||||
width: $brand-width;
|
||||
}
|
||||
}
|
||||
|
||||
.system {
|
||||
width: $sidebar-width;
|
||||
overflow-wrap: break-word;
|
||||
text-align: center;
|
||||
color: $brand-text-color;
|
||||
padding-top: 0px;
|
||||
padding-bottom: 0px;
|
||||
margin-bottom: 10px;
|
||||
font-size: 15px;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
|
||||
#splash {
|
||||
background: $splash-bg-color;
|
||||
color: $splash-text-color;
|
||||
|
||||
.panel , .panel-heading, .panel-footer{
|
||||
background: $splash-login-bg-color;
|
||||
border-color: $splash-border-color;
|
||||
}
|
||||
|
||||
.panel-body {
|
||||
// Unstretch text fields
|
||||
margin-right: 40px;
|
||||
margin-left: 40px;
|
||||
}
|
||||
|
||||
.panel-heading{
|
||||
// White line
|
||||
border-bottom-color: $splash-label-color;
|
||||
|
||||
/* vertical gradient (excluding IE9 and below - which clips the nav-tabs) */
|
||||
background-color: mix($brand-bg-color, $splash-login-bg-color, 60%); // Old Browswers
|
||||
background-image: -moz-linear-gradient(top, $brand-bg-color, $splash-login-bg-color); // FF 3.6+
|
||||
background-image: -ms-linear-gradient(top, $brand-bg-color, $splash-login-bg-color); // IE10
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from($brand-bg-color), to($splash-login-bg-color)); // Safari 4+, Chrome 2+
|
||||
background-image: -webkit-linear-gradient(top, $brand-bg-color, $splash-login-bg-color); // Safari 5.1+, Chrome 10+
|
||||
background-image: -o-linear-gradient(top, $brand-bg-color, $splash-login-bg-color); // Opera 11.10
|
||||
background-image: linear-gradient(top, $brand-bg-color, $splash-login-bg-color); // The standard
|
||||
background-repeat: repeat-x;
|
||||
|
||||
}
|
||||
|
||||
.panel-footer {
|
||||
// Hide lower line
|
||||
border-top: none;
|
||||
|
||||
// Move over button
|
||||
button {
|
||||
margin-right: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.red-line {
|
||||
height: 53px;
|
||||
width: 43%;
|
||||
border-bottom: 2px solid $windriver-red;
|
||||
margin-bottom: -18px;
|
||||
margin-left: -16px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
display: block;
|
||||
color: $splash-text-color;
|
||||
text-align: center;
|
||||
margin-bottom: 30px;
|
||||
font-size: 32px;
|
||||
line-height: 39px;
|
||||
text-shadow: 2px 2px 4px #000000;
|
||||
}
|
||||
form label {
|
||||
color: $splash-label-color;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
|
||||
.navbar-fixed-top, .topbar {
|
||||
padding: 0px 0px;
|
||||
background-color: $topbar-background-color;
|
||||
|
||||
a.navbar-brand {
|
||||
padding-left: 0px;
|
||||
}
|
||||
|
||||
h1.brand a {
|
||||
background: none;
|
||||
}
|
||||
|
||||
.navbar-default .navbar-nav {
|
||||
.dropdown-menu {
|
||||
background-color: white;
|
||||
}
|
||||
& > li > a{
|
||||
color: $topbar-text-color;
|
||||
}
|
||||
}
|
||||
|
||||
.context_selection{
|
||||
float: left;
|
||||
}
|
||||
|
||||
.user_settings {
|
||||
float: right;
|
||||
}
|
||||
|
||||
// Styling for time & alarms
|
||||
.navbar-center {
|
||||
color: $topbar-text-color;
|
||||
padding-top: 0.8em;
|
||||
|
||||
display: table;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
float: none;
|
||||
|
||||
.datetime {
|
||||
padding-right: 13px;
|
||||
}
|
||||
}
|
||||
}
|
4
tox.ini
4
tox.ini
@ -16,7 +16,7 @@ setenv = VIRTUAL_ENV={envdir}
|
||||
OS_STDOUT_CAPTURE=1
|
||||
OS_STDERR_CAPTURE=1
|
||||
OS_TEST_TIMEOUT=60
|
||||
STX_DC_CLIENT = {env:STX_DC_CLIENT:git/distributedcloud-client}
|
||||
STX_DC_CLIENT = {env:STX_DC_CLIENT:distributedcloud-client}
|
||||
deps = -r{toxinidir}/test-requirements.txt
|
||||
|
||||
[testenv:linters]
|
||||
@ -57,7 +57,7 @@ usedevelop = False
|
||||
skip_install = True
|
||||
deps = {[testenv]deps}
|
||||
git+git://github.com/starlingx-staging/stx-horizon.git
|
||||
-e{[tox]stxdir}/{env:STX_DC_CLIENT}
|
||||
-e{[tox]stxdir}/{env:STX_DC_CLIENT}/distributedcloud-client
|
||||
-e{[tox]stxdir}/config/sysinv/cgts-client/cgts-client
|
||||
-e{[tox]stxdir}/config/sysinv/sysinv/sysinv
|
||||
-e{[tox]stxdir}/fault/python-fmclient/fmclient
|
||||
|
Loading…
x
Reference in New Issue
Block a user