Setup page to display fake data

This commit is contained in:
Joe Fiorini 2015-05-05 14:50:52 -04:00
parent 455b599ecb
commit 8acc73c833
23 changed files with 3967 additions and 9 deletions

View File

@ -32,6 +32,7 @@ import {PortalController} from 'tower/controllers/Portal';
import dataServices from 'tower/services/_data-services';
import dashboardGraphs from 'tower/directives/_dashboard-graphs';
import systemTracking from 'tower/system-tracking/main';
import routeExtensions from 'tower/shared/route-extensions/main';
import breadcrumbs from 'tower/shared/breadcrumbs/main';
@ -80,6 +81,7 @@ var tower = angular.module('Tower', [
routeExtensions.name,
browserData.name,
breadcrumbs.name,
systemTracking.name,
'AuthService',
'Utilities',
'LicenseHelper',

View File

@ -846,18 +846,29 @@ export function InventoriesManage ($log, $scope, $rootScope, $location,
// you need this so that the event doesn't bubble to the watcher above
// for the host list
e.stopPropagation();
if (selection.length > 0) {
$scope.hostsSelected = true;
// $scope.adhocButtonTipContents = "Launch adhoc command for the "
// + "selected groups and hosts.";
} else {
if (selection.length === 0) {
$scope.hostsSelected = false;
// $scope.adhocButtonTipContents = "Launch adhoc command for the "
// + "inventory.";
} else if (selection.length === 1) {
$scope.systemTrackingTooltip = "Compare host over time";
$scope.hostsSelected = true;
$scope.systemTrackingDisabled = false;
} else if (selection.length === 2) {
$scope.systemTrackingTooltip = "Compare hosts against each other";
$scope.hostsSelected = true;
$scope.systemTrackingDisabled = false;
} else {
$scope.hostsSelected = true;
$scope.systemTrackingDisabled = true;
}
$scope.hostsSelectedItems = selection.selectedItems;
});
$scope.systemTracking = function() {
$location.path('/inventories/' + $scope.inventory.id +
'/system-tracking/' +
_.pluck($scope.hostsSelectedItems, "id").join(","));
};
// populates host patterns based on selected hosts/groups
$scope.populateAdhocForm = function() {
var host_patterns = "all";

View File

@ -87,6 +87,16 @@ export default
},
actions: {
system_tracking: {
label: 'System Tracking',
ngClick: 'systemTracking()', //'editInventoryProperties(inventory.id)',
awToolTip: "{{ systemTrackingTooltip }}",
dataTipWatch: "systemTrackingTooltip",
dataPlacement: 'top',
awFeature: 'system_tracking',
ngDisabled: 'systemTrackingDisabled',
ngShow: 'hostsSelected'
},
create: {
mode: 'all',
ngClick: "createHost()",
@ -103,7 +113,7 @@ export default
awToolTip: "View Activity Stream",
mode: 'all',
awFeature: 'activity_streams'
}
},
}
});

View File

@ -103,6 +103,9 @@ angular.module('GeneratorHelpers', [systemStatus.name])
action = params.action,
size = params.size;
switch (action) {
case 'system_tracking':
icon = "fa-crosshairs";
break;
case 'help':
icon = "fa-question-circle";
break;

View File

@ -12,6 +12,7 @@
class="options.class"
data-title="{{options.dataTitle}}"
icon-size="{{options.iconSize}}"
ng-disabled="{{options.ngDisabled}}"
ng-click="$eval(options.ngClick)"
ng-hide="isHiddenByOptions(options) ||
hiddenOnCurrentPage(options.basePaths) ||

View File

@ -0,0 +1,7 @@
export default
['xorObjects', 'formatResults', function(xorObjects, formatResults) {
return function compareHosts(module, factData1, factData2) {
var diffed = xorObjects('name', factData1, factData2);
return formatResults('name', 'version', diffed);
};
}];

View File

@ -0,0 +1,63 @@
import fakeData from './fake-data';
function getComparisonData(module) {
var valueName, leftValue, rightValue;
switch(module) {
case 'packages':
valueName = 'bash';
leftValue = '5.2.3';
rightValue = '5.2.4';
break;
case 'services':
valueName = 'httpd';
leftValue = 'started';
rightValue = 'absent';
break;
case 'files':
valueName = '/etc/sudoers';
leftValue = 'some string';
rightValue = 'some other string';
break;
case 'ansible':
valueName = 'ansible_ipv4_address';
leftValue = '192.168.0.1';
rightValue = '192.168.0.2';
break;
}
return [{ module: module,
valueName: valueName,
leftValue: leftValue,
rightValue: rightValue
}];
}
export default
['$q', 'compareHosts', function factDataServiceFactory($q, compareHosts) {
return function(type) {
if (type === 'multiHost') {
return { get: function(inventoryId, module, host1, host2) {
var result = {};
result.leftFilterValue = host1;
result.rightFilterValue = host2;
result.factComparisonData = compareHosts(module, fakeData.host1, fakeData.host2);
return result;
}
};
} else if (type === 'singleHost') {
return { get: function(inventoryId, module, startDate, endDate) {
var result = {};
result.leftFilterValue = startDate;
result.rightFilterValue = endDate;
result.factComparisonData = getComparisonData(module);
return result;
}
};
}
};
}]

View File

@ -0,0 +1,16 @@
/** @define FactModuleFilter */
.FactModuleFilter {
width: 100%;
display: flex;
margin-bottom: 2.8rem;
&-module {
flex: 1;
&--isActive {
// copied from bootstrap's .btn:focus
background-color: #ebebeb;
border-color: #adadad;
z-index: 2;
}
}
}

View File

@ -0,0 +1,69 @@
/** @define FactModulePickers */
.FactModulePickers {
width: 100%;
display: flex;
margin-bottom: 15px;
&-dateSpacer {
flex: initial;
width: 0px;
}
&-dateContainer {
flex: 1;
display: flex;
flex-wrap: wrap;
}
&-date {
flex: 1;
// flex-wrap: wrap;
display: flex;
}
&-date--right,
&-label--right {
margin-left: 7px;
}
&-date--left {
margin-right: 7px;
}
&-label {
flex: initial;
width: 100%;
font-weight: 700;
padding-bottom: 5px;
}
&-dateIcon {
flex: initial;
padding: 6px 12px;
font-size: 14px;
border-radius: 4px 0 0 4px;
border: 1px solid #ccc;
border-right: 0;
background-color: #fff;
}
&-dateIcon:hover,
&-dateIcon:focus,
&-dateIcon:active {
background-color: #ccc;
}
&-dateInput {
flex: 1;
border-radius: 0 4px 4px 0;
border: 1px solid #ccc;
padding: 6px 12px;
}
&-dateInput:focus,
&-dateInput:active {
outline-offset: 0;
outline: 0;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,13 @@
export default
function() {
return function formatResults(compareKey, displayKey, results) {
return results.reduce(function(arr, value) {
var obj =
{ keyName: value[compareKey],
value1: value.position === 0 ? value[displayKey] : 'absent',
value2: value.position === 1 ? value[displayKey] : 'absent'
};
return arr.concat(obj);
}, []);
};
}

View File

@ -0,0 +1,28 @@
import route from './system-tracking.route';
import singleHostDataService from './single-host-data.service';
import factDataServiceFactory from './fact-data-service.factory';
import controller from './system-tracking.controller';
import stringOrDateFilter from './string-or-date.filter';
import xorObjects from './xor-objects.factory';
import formatResults from './format-results.factory';
import compareHosts from './compare-hosts.factory';
export default
angular.module('systemTracking',
[ 'angularMoment'
])
.factory('factDataServiceFactory', factDataServiceFactory)
.service('singleHostDataService', singleHostDataService)
.factory('xorObjects', xorObjects)
.factory('formatResults', formatResults)
.factory('compareHosts', compareHosts)
.filter('stringOrDate', stringOrDateFilter)
.controller('systemTracking', controller)
.config(['$routeProvider', function($routeProvider) {
var url = route.route;
delete route.route;
$routeProvider.when(url, route);
}]);

View File

@ -0,0 +1,168 @@
## How I will do it
1. Find all facts from results
2. Filter out all "same facts"
3. Transform for display
### Finding facts from results
Iterate over fact collection. Check if a thing is a fact or not (it is a fact when all of its key's values are comparable (not an object or array). If it's a fact, then transform it to an object that contains the nested key and value from each candidate. If it's not a fact, then recurse passing in the parent keys & value until we find a fact.
To accomplish this we'll reduce over the values in the fact collection to create a new array. For each key, we'll check the type of its value. If it's an object or an array, we'll append the key to an array of parent keys and pass that and the value into a recursive call. If it's not an object or array, we'll record the parent key path as an array & both left & right values. We'll return the accumulator array with that object concatenated to it.
End result example (FactComparison):
[{ keyPath: ['sda', 'partitions', 'sda1'],
key: 'sectors',
leftValue: '39843840',
rightValue: '13254121'
},
{ keyPath: ['sda', partitions', 'sda1'],
key: 'model',
leftValue: 'VMware Virtual S",
rightValue: ''
}];
### Filtering out "same" facts
This needs to look at all of the facts by parent key and remove any of those that have one or more differences. This will leave plenty of context for the user to determine exactly what is different here. For example, given the facts:
#### Left Host
```json
{ "ansible_mounts":
[{
"device": "/dev/sda1",
"fstype": "ext4",
"mount": "/",
"options": "rw,errors=remount-ro",
"size_available": 15032406016,
"size_total": 20079898624
}]
}
```
#### Right Host
```json
{ "ansible_mounts":
[{
"device": "/dev/sda1",
"fstype": "btrfs",
"mount": "/",
"options": "rw,errors=remount-ro",
"size_available": 153985231054,
"size_total": 53056978564321
}]
}
```
If all the user could see was that the `fstype` fields were different, this would leave them wondering "what device is that on? where did that come from?" We are solving this problem by displaying all sibling properties of a fact regardless of whether they are different when at least one of those properties contains a difference.
Therefore, to compare facts we need to first group them by their keys. Once we do that, we'll have a structure like:
```json
{ 'sda.partitions.sda1':
[{ keyPath: ['sda', 'partitions', 'sda1'],
key: 'sectors',
leftValue: '39843840',
rightValue: '13254121'
},
{ keyPath: ['sda', partitions', 'sda1'],
key: 'model',
leftValue: 'VMware Virtual S",
rightValue: ''
}]
}
```
The simplest way to handle this would be to map over each key in this grouped object and return a filtered array of only objects with differences. Then we could iterate over the resulting object and filter out any keys whose value is an empty array, leaving us with only the keys that contain at least a single difference. Finally, we iterate over the original collection keeping only those values whose `keyPath` is in the previous collection of keys and return that result.
### Transforming for display
Given fact comparisons of:
[{ keyPath: ['ansible_devices', 'sda'],
key: 'host',
leftValue: 'SCSI storage controller: LSI Logic / Symbios Logic 53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI (rev 01)',
rightValue: ''
},
{ keyPath: ['ansible_devices', 'sda'],
key: 'model',
leftValue: 'VMWare Virtual S',
rightValue: 'APPLE SSD SM256C'
},
{ keyPath: ['ansible_devices', 'sda', 'partitions', 'sda1'],
key: 'sectors',
leftValue: '39843840',
rightValue: '13254121'
},
{ keyPath: ['ansible_devices', 'sda', partitions', 'sda1'],
key: 'sectorsize',
leftValue: '512',
rightValue: '512'
},
{ keyPath: ['ansible_mounts', '0'],
key: 'device',
leftValue: '/dev/sda5',
rightValue: '/dev/sda1'
},
{ keyPath: ['ansible_mounts', '0'],
key: 'fstype',
leftValue: 'ext4',
rightValue: 'btrfs'
},
{ keyPath: ['ansible_mounts', '1'],
key: 'device',
leftValue: 'absent',
rightValue: '/dev/sda5'
}];
We need to transform that to something like:
[{ keyPath: ['ansible_devices', 'sda'],
displayKeyPath: 'ansible_devices.sda',
nestingLevel: 1,
facts:
[{ keyPath: ['ansible_devices', 'sda'],
key: 'host',
value1: 'SCSI storage controller: LSI Logic / Symbios Logic 53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI (rev 01)',
value2: ''
},
{ keyPath: ['ansible_devices', 'sda'],
keyName: 'model',
value1: 'VMWare Virtual S',
value2: 'APPLE SSD SM256C'
}],
},
{ keyPath: ['ansible_devices', 'sda', 'partitions', 'sda1'],
displayKeyPath: 'partitions.sda1',
nestingLevel: 2,
facts:
// ...
},
{ keyPath: ['ansible_mounts'],
displayKeyPath: 'ansible_mounts',
nestingLevel: 1,
isArray: true,
facts:
[ [{ keyPath: ['ansible_mounts', '0'],
key: 'device',
leftValue: '/dev/sda5',
rightValue: '/dev/sda1'
},
{ keyPath: ['ansible_mounts', '0'],
key: 'fstype',
leftValue: 'ext4',
rightValue: 'btrfs'
}],
[{ keyPath: ['ansible_mounts', '1'],
key: 'device',
leftValue: 'absent',
rightValue: '/dev/sda5'
}]
]
}]
```

View File

@ -0,0 +1,51 @@
export default ['Rest', 'GetBasePath', 'ProcessErrors',
function (Rest, GetBasePath, ProcessErrors) {
return {
getFacts: function(version){
var promise;
Rest.setUrl(version.related.fact_view);
promise = Rest.get();
return promise.then(function (data) {
return data.data.fact;
}).catch(function (response) {
ProcessErrors(null, response.data, response.status, null, {
hdr: 'Error!',
msg: 'Failed to get license info. GET returned status: ' +
response.status
});
});
},
getVersion: function(host_id, module, startDate, endDate){
//move the build url into getVersion and have the
// parameters passed into this
var promise,
url = this.buildUrl(host_id, module, startDate, endDate);
Rest.setUrl(url);
promise = Rest.get();
return promise.then(function(data) {
return data.data.results[0];
}).catch(function (response) {
ProcessErrors(null, response.data, response.status, null, {
hdr: 'Error!',
msg: 'Failed to get license info. GET returned status: ' +
response.status
});
});
},
buildUrl: function(host_id, module, startDate, endDate){
var url = GetBasePath('hosts') + host_id + '/fact_versions/',
params= [["module", module] , ['startDate', startDate.format()], ['endDate', endDate.format()]];
params = params.filter(function(p){
return !_.isEmpty(p[1]);
});
params = params.map(function(p){
return p.join("=");
}).join("&");
url = _.compact([url, params]).join("?");
return url;
}
};
}];

View File

@ -0,0 +1,12 @@
export default
[ 'amDateFormatFilter',
function(dateFormat) {
return function(string, format) {
if (moment.isMoment(string)) {
return dateFormat(string, format);
} else {
return string;
}
};
}
]

View File

@ -0,0 +1,96 @@
function controller($rootScope, $scope, $routeParams, $location, $q, factDataServiceFactory, moment) {
var service;
var inventoryId = $routeParams.id;
var hostIds = $routeParams.hosts.split(',');
var moduleParam = $location.search().module || 'packages';
var configReadyOff =
$rootScope.$on('ConfigReady', function() {
$(".date").systemTrackingDP({
autoclose: true
});
configReadyOff();
});
$scope.leftFilterValue = hostIds[0];
$scope.rightFilterValue = hostIds[1];
$scope.factModulePickersLabelLeft = "Fact collection date for host " + $scope.leftFilterValue;
$scope.factModulePickersLabelRight = "Fact collection date for host " + $scope.rightFilterValue;
$scope.modules =
[{ name: 'packages',
displayName: 'Packages',
isActive: true,
displayType: 'flat'
},
{ name: 'services',
displayName: 'Services',
isActive: false,
displayType: 'flat'
},
{ name: 'files',
displayName: 'Files',
isActive: false,
displayType: 'flat'
},
{ name: 'ansible',
displayName: 'Ansible',
isActive: false,
displayType: 'nested'
}
];
// Use this to determine how to orchestrate the services
var viewType = hostIds.length > 1 ? 'multiHost' : 'singleHost';
if (viewType === 'singleHost') {
var startDate = moment();
$scope.leftFilterValue = startDate;
$scope.rightFilterValue = startDate.clone().subtract(1, 'days');
}
service = factDataServiceFactory(viewType);
function reloadData(activeModule) {
activeModule.then(function(module) {
$scope.factData =
service.get(inventoryId,
module.name,
$scope.leftFilterValue,
$scope.rightFilterValue);
});
}
$scope.setActiveModule = function(newModuleName) {
var newModule = _.find($scope.modules, function(module) {
return module.name === newModuleName;
});
$scope.modules.forEach(function(module) {
module.isActive = false;
});
newModule.isActive = true;
$location.search('module', newModuleName);
reloadData($q.when(newModule));
};
$scope.setActiveModule(moduleParam);
}
export default
[ '$rootScope',
'$scope',
'$routeParams',
'$location',
'$q',
'factDataServiceFactory',
'moment',
controller
];

View File

@ -0,0 +1,51 @@
<div class="FactModulePickers">
<div class="FactModulePickers-dateSpacer">
</div>
<div class="FactModulePickers-dateContainer">
<span class="FactModulePickers-label">{{ factModulePickersLabelLeft }}</span>
<div class="input-prepend date FactModulePickers-date FactModulePickers-date--left">
<button class="add-on FactModulePickers-dateIcon"><i class="fa fa-calendar"></i></button>
<input class="FactModulePickers-dateInput" type="text" value="12-02-2012">
</div>
</div>
<div class="FactModulePickers-dateContainer">
<span class="FactModulePickers-label FactModulePickers-label--right">
{{ factModulePickersLabelRight }}
</span>
<div class="input-prepend date FactModulePickers-date FactModulePickers-date--right">
<button class="add-on FactModulePickers-dateIcon"><i class="fa fa-calendar"></i></button>
<input class="FactModulePickers-dateInput" type="text" value="12-02-2012">
</div>
</div>
</div>
<nav class="btn-group FactModuleFilter">
<button
ng-class="{ 'btn': true,
'btn-default': true,
'Button--pseudo': true,
'FactModuleFilter-module': true,
'FactModuleFilter-module--isActive': module.isActive,
}"
ng-click="setActiveModule(module.name)"
ng-repeat="module in modules">
{{module.displayName}}
</button>
</nav>
<table class="table table-condensed">
<thead>
<tr>
<th></th>
<th>{{factData.leftFilterValue|stringOrDate:'L'}}</th>
<th>{{factData.rightFilterValue|stringOrDate:'L'}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="fact in factData.factComparisonData">
<td>{{fact.keyName}}</td>
<td>{{fact.value1}}</td>
<td>{{fact.value2}}</td>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,5 @@
export default {
route: '/inventories/:id/system-tracking/:hosts',
controller: 'systemTracking',
templateUrl: '/static/js/system-tracking/system-tracking.partial.html'
};

View File

@ -0,0 +1,28 @@
export default
function() {
return function xorObjects(key, thing1, thing2) {
var values1 = _.pluck(thing1, key);
var values2 = _.pluck(thing2, key);
var valuesDiff = _.xor(values1, values2);
return valuesDiff.reduce(function(arr, value) {
var searcher = {};
searcher[key] = value;
var valuePosition1 = _.find(thing1, searcher);
if (valuePosition1) {
valuePosition1.position = 0;
}
var valuePosition2 = _.find(thing2, searcher);
if (valuePosition2) {
valuePosition2.position = 1;
}
return _.compact(arr.concat(valuePosition1).concat(valuePosition2));
}, []);
};
}

View File

@ -40,6 +40,7 @@
@import "survey-maker.less";
@import "portal.less";
@import "text-label.less";
@import "bootstrap-datepicker.less";
/* Bootstrap fix that's causing a right margin to appear
whenver a modal is opened */

View File

@ -0,0 +1,752 @@
/*!
* Datepicker for Bootstrap v1.4.0 (https://github.com/eternicode/bootstrap-datepicker)
*
* Copyright 2012 Stefan Petre
* Improvements by Andrew Rowls
* Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0)
*/
.datepicker {
padding: 4px;
border-radius: 4px;
direction: ltr;
}
.datepicker-inline {
width: 220px;
}
.datepicker.datepicker-rtl {
direction: rtl;
}
.datepicker.datepicker-rtl table tr td span {
float: right;
}
.datepicker-dropdown {
top: 0;
left: 0;
}
.datepicker-dropdown:before {
content: '';
display: inline-block;
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-bottom: 7px solid #ccc;
border-top: 0;
border-bottom-color: rgba(0, 0, 0, 0.2);
position: absolute;
}
.datepicker-dropdown:after {
content: '';
display: inline-block;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid #fff;
border-top: 0;
position: absolute;
}
.datepicker-dropdown.datepicker-orient-left:before {
left: 6px;
}
.datepicker-dropdown.datepicker-orient-left:after {
left: 7px;
}
.datepicker-dropdown.datepicker-orient-right:before {
right: 6px;
}
.datepicker-dropdown.datepicker-orient-right:after {
right: 7px;
}
.datepicker-dropdown.datepicker-orient-top:before {
top: -7px;
}
.datepicker-dropdown.datepicker-orient-top:after {
top: -6px;
}
.datepicker-dropdown.datepicker-orient-bottom:before {
bottom: -7px;
border-bottom: 0;
border-top: 7px solid #999;
}
.datepicker-dropdown.datepicker-orient-bottom:after {
bottom: -6px;
border-bottom: 0;
border-top: 6px solid #fff;
}
.datepicker > div {
display: none;
}
.datepicker.days .datepicker-days,
.datepicker.months .datepicker-months,
.datepicker.years .datepicker-years {
display: block;
}
.datepicker table {
margin: 0;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.datepicker table tr td,
.datepicker table tr th {
text-align: center;
width: 30px;
height: 30px;
border-radius: 4px;
border: none;
}
.table-striped .datepicker table tr td,
.table-striped .datepicker table tr th {
background-color: transparent;
}
.datepicker table tr td.day:hover,
.datepicker table tr td.day.focused {
background: #eeeeee;
cursor: pointer;
}
.datepicker table tr td.old,
.datepicker table tr td.new {
color: #999999;
}
.datepicker table tr td.disabled,
.datepicker table tr td.disabled:hover {
background: none;
color: #999999;
cursor: default;
}
.datepicker table tr td.today,
.datepicker table tr td.today:hover,
.datepicker table tr td.today.disabled,
.datepicker table tr td.today.disabled:hover {
color: #000000;
background-color: #ffdb99;
border-color: #ffb733;
}
.datepicker table tr td.today:hover,
.datepicker table tr td.today:hover:hover,
.datepicker table tr td.today.disabled:hover,
.datepicker table tr td.today.disabled:hover:hover,
.datepicker table tr td.today:focus,
.datepicker table tr td.today:hover:focus,
.datepicker table tr td.today.disabled:focus,
.datepicker table tr td.today.disabled:hover:focus,
.datepicker table tr td.today:active,
.datepicker table tr td.today:hover:active,
.datepicker table tr td.today.disabled:active,
.datepicker table tr td.today.disabled:hover:active,
.datepicker table tr td.today.active,
.datepicker table tr td.today:hover.active,
.datepicker table tr td.today.disabled.active,
.datepicker table tr td.today.disabled:hover.active,
.open .dropdown-toggle.datepicker table tr td.today,
.open .dropdown-toggle.datepicker table tr td.today:hover,
.open .dropdown-toggle.datepicker table tr td.today.disabled,
.open .dropdown-toggle.datepicker table tr td.today.disabled:hover {
color: #000000;
background-color: #ffcd70;
border-color: #f59e00;
}
.datepicker table tr td.today:active,
.datepicker table tr td.today:hover:active,
.datepicker table tr td.today.disabled:active,
.datepicker table tr td.today.disabled:hover:active,
.datepicker table tr td.today.active,
.datepicker table tr td.today:hover.active,
.datepicker table tr td.today.disabled.active,
.datepicker table tr td.today.disabled:hover.active,
.open .dropdown-toggle.datepicker table tr td.today,
.open .dropdown-toggle.datepicker table tr td.today:hover,
.open .dropdown-toggle.datepicker table tr td.today.disabled,
.open .dropdown-toggle.datepicker table tr td.today.disabled:hover {
background-image: none;
}
.datepicker table tr td.today.disabled,
.datepicker table tr td.today:hover.disabled,
.datepicker table tr td.today.disabled.disabled,
.datepicker table tr td.today.disabled:hover.disabled,
.datepicker table tr td.today[disabled],
.datepicker table tr td.today:hover[disabled],
.datepicker table tr td.today.disabled[disabled],
.datepicker table tr td.today.disabled:hover[disabled],
fieldset[disabled] .datepicker table tr td.today,
fieldset[disabled] .datepicker table tr td.today:hover,
fieldset[disabled] .datepicker table tr td.today.disabled,
fieldset[disabled] .datepicker table tr td.today.disabled:hover,
.datepicker table tr td.today.disabled:hover,
.datepicker table tr td.today:hover.disabled:hover,
.datepicker table tr td.today.disabled.disabled:hover,
.datepicker table tr td.today.disabled:hover.disabled:hover,
.datepicker table tr td.today[disabled]:hover,
.datepicker table tr td.today:hover[disabled]:hover,
.datepicker table tr td.today.disabled[disabled]:hover,
.datepicker table tr td.today.disabled:hover[disabled]:hover,
fieldset[disabled] .datepicker table tr td.today:hover,
fieldset[disabled] .datepicker table tr td.today:hover:hover,
fieldset[disabled] .datepicker table tr td.today.disabled:hover,
fieldset[disabled] .datepicker table tr td.today.disabled:hover:hover,
.datepicker table tr td.today.disabled:focus,
.datepicker table tr td.today:hover.disabled:focus,
.datepicker table tr td.today.disabled.disabled:focus,
.datepicker table tr td.today.disabled:hover.disabled:focus,
.datepicker table tr td.today[disabled]:focus,
.datepicker table tr td.today:hover[disabled]:focus,
.datepicker table tr td.today.disabled[disabled]:focus,
.datepicker table tr td.today.disabled:hover[disabled]:focus,
fieldset[disabled] .datepicker table tr td.today:focus,
fieldset[disabled] .datepicker table tr td.today:hover:focus,
fieldset[disabled] .datepicker table tr td.today.disabled:focus,
fieldset[disabled] .datepicker table tr td.today.disabled:hover:focus,
.datepicker table tr td.today.disabled:active,
.datepicker table tr td.today:hover.disabled:active,
.datepicker table tr td.today.disabled.disabled:active,
.datepicker table tr td.today.disabled:hover.disabled:active,
.datepicker table tr td.today[disabled]:active,
.datepicker table tr td.today:hover[disabled]:active,
.datepicker table tr td.today.disabled[disabled]:active,
.datepicker table tr td.today.disabled:hover[disabled]:active,
fieldset[disabled] .datepicker table tr td.today:active,
fieldset[disabled] .datepicker table tr td.today:hover:active,
fieldset[disabled] .datepicker table tr td.today.disabled:active,
fieldset[disabled] .datepicker table tr td.today.disabled:hover:active,
.datepicker table tr td.today.disabled.active,
.datepicker table tr td.today:hover.disabled.active,
.datepicker table tr td.today.disabled.disabled.active,
.datepicker table tr td.today.disabled:hover.disabled.active,
.datepicker table tr td.today[disabled].active,
.datepicker table tr td.today:hover[disabled].active,
.datepicker table tr td.today.disabled[disabled].active,
.datepicker table tr td.today.disabled:hover[disabled].active,
fieldset[disabled] .datepicker table tr td.today.active,
fieldset[disabled] .datepicker table tr td.today:hover.active,
fieldset[disabled] .datepicker table tr td.today.disabled.active,
fieldset[disabled] .datepicker table tr td.today.disabled:hover.active {
background-color: #ffdb99;
border-color: #ffb733;
}
.datepicker table tr td.today:hover:hover {
color: #000;
}
.datepicker table tr td.today.active:hover {
color: #fff;
}
.datepicker table tr td.range,
.datepicker table tr td.range:hover,
.datepicker table tr td.range.disabled,
.datepicker table tr td.range.disabled:hover {
background: #eeeeee;
border-radius: 0;
}
.datepicker table tr td.range.today,
.datepicker table tr td.range.today:hover,
.datepicker table tr td.range.today.disabled,
.datepicker table tr td.range.today.disabled:hover {
color: #000000;
background-color: #f7ca77;
border-color: #f1a417;
border-radius: 0;
}
.datepicker table tr td.range.today:hover,
.datepicker table tr td.range.today:hover:hover,
.datepicker table tr td.range.today.disabled:hover,
.datepicker table tr td.range.today.disabled:hover:hover,
.datepicker table tr td.range.today:focus,
.datepicker table tr td.range.today:hover:focus,
.datepicker table tr td.range.today.disabled:focus,
.datepicker table tr td.range.today.disabled:hover:focus,
.datepicker table tr td.range.today:active,
.datepicker table tr td.range.today:hover:active,
.datepicker table tr td.range.today.disabled:active,
.datepicker table tr td.range.today.disabled:hover:active,
.datepicker table tr td.range.today.active,
.datepicker table tr td.range.today:hover.active,
.datepicker table tr td.range.today.disabled.active,
.datepicker table tr td.range.today.disabled:hover.active,
.open .dropdown-toggle.datepicker table tr td.range.today,
.open .dropdown-toggle.datepicker table tr td.range.today:hover,
.open .dropdown-toggle.datepicker table tr td.range.today.disabled,
.open .dropdown-toggle.datepicker table tr td.range.today.disabled:hover {
color: #000000;
background-color: #f4bb51;
border-color: #bf800c;
}
.datepicker table tr td.range.today:active,
.datepicker table tr td.range.today:hover:active,
.datepicker table tr td.range.today.disabled:active,
.datepicker table tr td.range.today.disabled:hover:active,
.datepicker table tr td.range.today.active,
.datepicker table tr td.range.today:hover.active,
.datepicker table tr td.range.today.disabled.active,
.datepicker table tr td.range.today.disabled:hover.active,
.open .dropdown-toggle.datepicker table tr td.range.today,
.open .dropdown-toggle.datepicker table tr td.range.today:hover,
.open .dropdown-toggle.datepicker table tr td.range.today.disabled,
.open .dropdown-toggle.datepicker table tr td.range.today.disabled:hover {
background-image: none;
}
.datepicker table tr td.range.today.disabled,
.datepicker table tr td.range.today:hover.disabled,
.datepicker table tr td.range.today.disabled.disabled,
.datepicker table tr td.range.today.disabled:hover.disabled,
.datepicker table tr td.range.today[disabled],
.datepicker table tr td.range.today:hover[disabled],
.datepicker table tr td.range.today.disabled[disabled],
.datepicker table tr td.range.today.disabled:hover[disabled],
fieldset[disabled] .datepicker table tr td.range.today,
fieldset[disabled] .datepicker table tr td.range.today:hover,
fieldset[disabled] .datepicker table tr td.range.today.disabled,
fieldset[disabled] .datepicker table tr td.range.today.disabled:hover,
.datepicker table tr td.range.today.disabled:hover,
.datepicker table tr td.range.today:hover.disabled:hover,
.datepicker table tr td.range.today.disabled.disabled:hover,
.datepicker table tr td.range.today.disabled:hover.disabled:hover,
.datepicker table tr td.range.today[disabled]:hover,
.datepicker table tr td.range.today:hover[disabled]:hover,
.datepicker table tr td.range.today.disabled[disabled]:hover,
.datepicker table tr td.range.today.disabled:hover[disabled]:hover,
fieldset[disabled] .datepicker table tr td.range.today:hover,
fieldset[disabled] .datepicker table tr td.range.today:hover:hover,
fieldset[disabled] .datepicker table tr td.range.today.disabled:hover,
fieldset[disabled] .datepicker table tr td.range.today.disabled:hover:hover,
.datepicker table tr td.range.today.disabled:focus,
.datepicker table tr td.range.today:hover.disabled:focus,
.datepicker table tr td.range.today.disabled.disabled:focus,
.datepicker table tr td.range.today.disabled:hover.disabled:focus,
.datepicker table tr td.range.today[disabled]:focus,
.datepicker table tr td.range.today:hover[disabled]:focus,
.datepicker table tr td.range.today.disabled[disabled]:focus,
.datepicker table tr td.range.today.disabled:hover[disabled]:focus,
fieldset[disabled] .datepicker table tr td.range.today:focus,
fieldset[disabled] .datepicker table tr td.range.today:hover:focus,
fieldset[disabled] .datepicker table tr td.range.today.disabled:focus,
fieldset[disabled] .datepicker table tr td.range.today.disabled:hover:focus,
.datepicker table tr td.range.today.disabled:active,
.datepicker table tr td.range.today:hover.disabled:active,
.datepicker table tr td.range.today.disabled.disabled:active,
.datepicker table tr td.range.today.disabled:hover.disabled:active,
.datepicker table tr td.range.today[disabled]:active,
.datepicker table tr td.range.today:hover[disabled]:active,
.datepicker table tr td.range.today.disabled[disabled]:active,
.datepicker table tr td.range.today.disabled:hover[disabled]:active,
fieldset[disabled] .datepicker table tr td.range.today:active,
fieldset[disabled] .datepicker table tr td.range.today:hover:active,
fieldset[disabled] .datepicker table tr td.range.today.disabled:active,
fieldset[disabled] .datepicker table tr td.range.today.disabled:hover:active,
.datepicker table tr td.range.today.disabled.active,
.datepicker table tr td.range.today:hover.disabled.active,
.datepicker table tr td.range.today.disabled.disabled.active,
.datepicker table tr td.range.today.disabled:hover.disabled.active,
.datepicker table tr td.range.today[disabled].active,
.datepicker table tr td.range.today:hover[disabled].active,
.datepicker table tr td.range.today.disabled[disabled].active,
.datepicker table tr td.range.today.disabled:hover[disabled].active,
fieldset[disabled] .datepicker table tr td.range.today.active,
fieldset[disabled] .datepicker table tr td.range.today:hover.active,
fieldset[disabled] .datepicker table tr td.range.today.disabled.active,
fieldset[disabled] .datepicker table tr td.range.today.disabled:hover.active {
background-color: #f7ca77;
border-color: #f1a417;
}
.datepicker table tr td.selected,
.datepicker table tr td.selected:hover,
.datepicker table tr td.selected.disabled,
.datepicker table tr td.selected.disabled:hover {
color: #ffffff;
background-color: #999999;
border-color: #555555;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.datepicker table tr td.selected:hover,
.datepicker table tr td.selected:hover:hover,
.datepicker table tr td.selected.disabled:hover,
.datepicker table tr td.selected.disabled:hover:hover,
.datepicker table tr td.selected:focus,
.datepicker table tr td.selected:hover:focus,
.datepicker table tr td.selected.disabled:focus,
.datepicker table tr td.selected.disabled:hover:focus,
.datepicker table tr td.selected:active,
.datepicker table tr td.selected:hover:active,
.datepicker table tr td.selected.disabled:active,
.datepicker table tr td.selected.disabled:hover:active,
.datepicker table tr td.selected.active,
.datepicker table tr td.selected:hover.active,
.datepicker table tr td.selected.disabled.active,
.datepicker table tr td.selected.disabled:hover.active,
.open .dropdown-toggle.datepicker table tr td.selected,
.open .dropdown-toggle.datepicker table tr td.selected:hover,
.open .dropdown-toggle.datepicker table tr td.selected.disabled,
.open .dropdown-toggle.datepicker table tr td.selected.disabled:hover {
color: #ffffff;
background-color: #858585;
border-color: #373737;
}
.datepicker table tr td.selected:active,
.datepicker table tr td.selected:hover:active,
.datepicker table tr td.selected.disabled:active,
.datepicker table tr td.selected.disabled:hover:active,
.datepicker table tr td.selected.active,
.datepicker table tr td.selected:hover.active,
.datepicker table tr td.selected.disabled.active,
.datepicker table tr td.selected.disabled:hover.active,
.open .dropdown-toggle.datepicker table tr td.selected,
.open .dropdown-toggle.datepicker table tr td.selected:hover,
.open .dropdown-toggle.datepicker table tr td.selected.disabled,
.open .dropdown-toggle.datepicker table tr td.selected.disabled:hover {
background-image: none;
}
.datepicker table tr td.selected.disabled,
.datepicker table tr td.selected:hover.disabled,
.datepicker table tr td.selected.disabled.disabled,
.datepicker table tr td.selected.disabled:hover.disabled,
.datepicker table tr td.selected[disabled],
.datepicker table tr td.selected:hover[disabled],
.datepicker table tr td.selected.disabled[disabled],
.datepicker table tr td.selected.disabled:hover[disabled],
fieldset[disabled] .datepicker table tr td.selected,
fieldset[disabled] .datepicker table tr td.selected:hover,
fieldset[disabled] .datepicker table tr td.selected.disabled,
fieldset[disabled] .datepicker table tr td.selected.disabled:hover,
.datepicker table tr td.selected.disabled:hover,
.datepicker table tr td.selected:hover.disabled:hover,
.datepicker table tr td.selected.disabled.disabled:hover,
.datepicker table tr td.selected.disabled:hover.disabled:hover,
.datepicker table tr td.selected[disabled]:hover,
.datepicker table tr td.selected:hover[disabled]:hover,
.datepicker table tr td.selected.disabled[disabled]:hover,
.datepicker table tr td.selected.disabled:hover[disabled]:hover,
fieldset[disabled] .datepicker table tr td.selected:hover,
fieldset[disabled] .datepicker table tr td.selected:hover:hover,
fieldset[disabled] .datepicker table tr td.selected.disabled:hover,
fieldset[disabled] .datepicker table tr td.selected.disabled:hover:hover,
.datepicker table tr td.selected.disabled:focus,
.datepicker table tr td.selected:hover.disabled:focus,
.datepicker table tr td.selected.disabled.disabled:focus,
.datepicker table tr td.selected.disabled:hover.disabled:focus,
.datepicker table tr td.selected[disabled]:focus,
.datepicker table tr td.selected:hover[disabled]:focus,
.datepicker table tr td.selected.disabled[disabled]:focus,
.datepicker table tr td.selected.disabled:hover[disabled]:focus,
fieldset[disabled] .datepicker table tr td.selected:focus,
fieldset[disabled] .datepicker table tr td.selected:hover:focus,
fieldset[disabled] .datepicker table tr td.selected.disabled:focus,
fieldset[disabled] .datepicker table tr td.selected.disabled:hover:focus,
.datepicker table tr td.selected.disabled:active,
.datepicker table tr td.selected:hover.disabled:active,
.datepicker table tr td.selected.disabled.disabled:active,
.datepicker table tr td.selected.disabled:hover.disabled:active,
.datepicker table tr td.selected[disabled]:active,
.datepicker table tr td.selected:hover[disabled]:active,
.datepicker table tr td.selected.disabled[disabled]:active,
.datepicker table tr td.selected.disabled:hover[disabled]:active,
fieldset[disabled] .datepicker table tr td.selected:active,
fieldset[disabled] .datepicker table tr td.selected:hover:active,
fieldset[disabled] .datepicker table tr td.selected.disabled:active,
fieldset[disabled] .datepicker table tr td.selected.disabled:hover:active,
.datepicker table tr td.selected.disabled.active,
.datepicker table tr td.selected:hover.disabled.active,
.datepicker table tr td.selected.disabled.disabled.active,
.datepicker table tr td.selected.disabled:hover.disabled.active,
.datepicker table tr td.selected[disabled].active,
.datepicker table tr td.selected:hover[disabled].active,
.datepicker table tr td.selected.disabled[disabled].active,
.datepicker table tr td.selected.disabled:hover[disabled].active,
fieldset[disabled] .datepicker table tr td.selected.active,
fieldset[disabled] .datepicker table tr td.selected:hover.active,
fieldset[disabled] .datepicker table tr td.selected.disabled.active,
fieldset[disabled] .datepicker table tr td.selected.disabled:hover.active {
background-color: #999999;
border-color: #555555;
}
.datepicker table tr td.active,
.datepicker table tr td.active:hover,
.datepicker table tr td.active.disabled,
.datepicker table tr td.active.disabled:hover {
color: #ffffff;
background-color: #428bca;
border-color: #357ebd;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.datepicker table tr td.active:hover,
.datepicker table tr td.active:hover:hover,
.datepicker table tr td.active.disabled:hover,
.datepicker table tr td.active.disabled:hover:hover,
.datepicker table tr td.active:focus,
.datepicker table tr td.active:hover:focus,
.datepicker table tr td.active.disabled:focus,
.datepicker table tr td.active.disabled:hover:focus,
.datepicker table tr td.active:active,
.datepicker table tr td.active:hover:active,
.datepicker table tr td.active.disabled:active,
.datepicker table tr td.active.disabled:hover:active,
.datepicker table tr td.active.active,
.datepicker table tr td.active:hover.active,
.datepicker table tr td.active.disabled.active,
.datepicker table tr td.active.disabled:hover.active,
.open .dropdown-toggle.datepicker table tr td.active,
.open .dropdown-toggle.datepicker table tr td.active:hover,
.open .dropdown-toggle.datepicker table tr td.active.disabled,
.open .dropdown-toggle.datepicker table tr td.active.disabled:hover {
color: #ffffff;
background-color: #3276b1;
border-color: #285e8e;
}
.datepicker table tr td.active:active,
.datepicker table tr td.active:hover:active,
.datepicker table tr td.active.disabled:active,
.datepicker table tr td.active.disabled:hover:active,
.datepicker table tr td.active.active,
.datepicker table tr td.active:hover.active,
.datepicker table tr td.active.disabled.active,
.datepicker table tr td.active.disabled:hover.active,
.open .dropdown-toggle.datepicker table tr td.active,
.open .dropdown-toggle.datepicker table tr td.active:hover,
.open .dropdown-toggle.datepicker table tr td.active.disabled,
.open .dropdown-toggle.datepicker table tr td.active.disabled:hover {
background-image: none;
}
.datepicker table tr td.active.disabled,
.datepicker table tr td.active:hover.disabled,
.datepicker table tr td.active.disabled.disabled,
.datepicker table tr td.active.disabled:hover.disabled,
.datepicker table tr td.active[disabled],
.datepicker table tr td.active:hover[disabled],
.datepicker table tr td.active.disabled[disabled],
.datepicker table tr td.active.disabled:hover[disabled],
fieldset[disabled] .datepicker table tr td.active,
fieldset[disabled] .datepicker table tr td.active:hover,
fieldset[disabled] .datepicker table tr td.active.disabled,
fieldset[disabled] .datepicker table tr td.active.disabled:hover,
.datepicker table tr td.active.disabled:hover,
.datepicker table tr td.active:hover.disabled:hover,
.datepicker table tr td.active.disabled.disabled:hover,
.datepicker table tr td.active.disabled:hover.disabled:hover,
.datepicker table tr td.active[disabled]:hover,
.datepicker table tr td.active:hover[disabled]:hover,
.datepicker table tr td.active.disabled[disabled]:hover,
.datepicker table tr td.active.disabled:hover[disabled]:hover,
fieldset[disabled] .datepicker table tr td.active:hover,
fieldset[disabled] .datepicker table tr td.active:hover:hover,
fieldset[disabled] .datepicker table tr td.active.disabled:hover,
fieldset[disabled] .datepicker table tr td.active.disabled:hover:hover,
.datepicker table tr td.active.disabled:focus,
.datepicker table tr td.active:hover.disabled:focus,
.datepicker table tr td.active.disabled.disabled:focus,
.datepicker table tr td.active.disabled:hover.disabled:focus,
.datepicker table tr td.active[disabled]:focus,
.datepicker table tr td.active:hover[disabled]:focus,
.datepicker table tr td.active.disabled[disabled]:focus,
.datepicker table tr td.active.disabled:hover[disabled]:focus,
fieldset[disabled] .datepicker table tr td.active:focus,
fieldset[disabled] .datepicker table tr td.active:hover:focus,
fieldset[disabled] .datepicker table tr td.active.disabled:focus,
fieldset[disabled] .datepicker table tr td.active.disabled:hover:focus,
.datepicker table tr td.active.disabled:active,
.datepicker table tr td.active:hover.disabled:active,
.datepicker table tr td.active.disabled.disabled:active,
.datepicker table tr td.active.disabled:hover.disabled:active,
.datepicker table tr td.active[disabled]:active,
.datepicker table tr td.active:hover[disabled]:active,
.datepicker table tr td.active.disabled[disabled]:active,
.datepicker table tr td.active.disabled:hover[disabled]:active,
fieldset[disabled] .datepicker table tr td.active:active,
fieldset[disabled] .datepicker table tr td.active:hover:active,
fieldset[disabled] .datepicker table tr td.active.disabled:active,
fieldset[disabled] .datepicker table tr td.active.disabled:hover:active,
.datepicker table tr td.active.disabled.active,
.datepicker table tr td.active:hover.disabled.active,
.datepicker table tr td.active.disabled.disabled.active,
.datepicker table tr td.active.disabled:hover.disabled.active,
.datepicker table tr td.active[disabled].active,
.datepicker table tr td.active:hover[disabled].active,
.datepicker table tr td.active.disabled[disabled].active,
.datepicker table tr td.active.disabled:hover[disabled].active,
fieldset[disabled] .datepicker table tr td.active.active,
fieldset[disabled] .datepicker table tr td.active:hover.active,
fieldset[disabled] .datepicker table tr td.active.disabled.active,
fieldset[disabled] .datepicker table tr td.active.disabled:hover.active {
background-color: #428bca;
border-color: #357ebd;
}
.datepicker table tr td span {
display: block;
width: 23%;
height: 54px;
line-height: 54px;
float: left;
margin: 1%;
cursor: pointer;
border-radius: 4px;
}
.datepicker table tr td span:hover {
background: #eeeeee;
}
.datepicker table tr td span.disabled,
.datepicker table tr td span.disabled:hover {
background: none;
color: #999999;
cursor: default;
}
.datepicker table tr td span.active,
.datepicker table tr td span.active:hover,
.datepicker table tr td span.active.disabled,
.datepicker table tr td span.active.disabled:hover {
color: #ffffff;
background-color: #428bca;
border-color: #357ebd;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.datepicker table tr td span.active:hover,
.datepicker table tr td span.active:hover:hover,
.datepicker table tr td span.active.disabled:hover,
.datepicker table tr td span.active.disabled:hover:hover,
.datepicker table tr td span.active:focus,
.datepicker table tr td span.active:hover:focus,
.datepicker table tr td span.active.disabled:focus,
.datepicker table tr td span.active.disabled:hover:focus,
.datepicker table tr td span.active:active,
.datepicker table tr td span.active:hover:active,
.datepicker table tr td span.active.disabled:active,
.datepicker table tr td span.active.disabled:hover:active,
.datepicker table tr td span.active.active,
.datepicker table tr td span.active:hover.active,
.datepicker table tr td span.active.disabled.active,
.datepicker table tr td span.active.disabled:hover.active,
.open .dropdown-toggle.datepicker table tr td span.active,
.open .dropdown-toggle.datepicker table tr td span.active:hover,
.open .dropdown-toggle.datepicker table tr td span.active.disabled,
.open .dropdown-toggle.datepicker table tr td span.active.disabled:hover {
color: #ffffff;
background-color: #3276b1;
border-color: #285e8e;
}
.datepicker table tr td span.active:active,
.datepicker table tr td span.active:hover:active,
.datepicker table tr td span.active.disabled:active,
.datepicker table tr td span.active.disabled:hover:active,
.datepicker table tr td span.active.active,
.datepicker table tr td span.active:hover.active,
.datepicker table tr td span.active.disabled.active,
.datepicker table tr td span.active.disabled:hover.active,
.open .dropdown-toggle.datepicker table tr td span.active,
.open .dropdown-toggle.datepicker table tr td span.active:hover,
.open .dropdown-toggle.datepicker table tr td span.active.disabled,
.open .dropdown-toggle.datepicker table tr td span.active.disabled:hover {
background-image: none;
}
.datepicker table tr td span.active.disabled,
.datepicker table tr td span.active:hover.disabled,
.datepicker table tr td span.active.disabled.disabled,
.datepicker table tr td span.active.disabled:hover.disabled,
.datepicker table tr td span.active[disabled],
.datepicker table tr td span.active:hover[disabled],
.datepicker table tr td span.active.disabled[disabled],
.datepicker table tr td span.active.disabled:hover[disabled],
fieldset[disabled] .datepicker table tr td span.active,
fieldset[disabled] .datepicker table tr td span.active:hover,
fieldset[disabled] .datepicker table tr td span.active.disabled,
fieldset[disabled] .datepicker table tr td span.active.disabled:hover,
.datepicker table tr td span.active.disabled:hover,
.datepicker table tr td span.active:hover.disabled:hover,
.datepicker table tr td span.active.disabled.disabled:hover,
.datepicker table tr td span.active.disabled:hover.disabled:hover,
.datepicker table tr td span.active[disabled]:hover,
.datepicker table tr td span.active:hover[disabled]:hover,
.datepicker table tr td span.active.disabled[disabled]:hover,
.datepicker table tr td span.active.disabled:hover[disabled]:hover,
fieldset[disabled] .datepicker table tr td span.active:hover,
fieldset[disabled] .datepicker table tr td span.active:hover:hover,
fieldset[disabled] .datepicker table tr td span.active.disabled:hover,
fieldset[disabled] .datepicker table tr td span.active.disabled:hover:hover,
.datepicker table tr td span.active.disabled:focus,
.datepicker table tr td span.active:hover.disabled:focus,
.datepicker table tr td span.active.disabled.disabled:focus,
.datepicker table tr td span.active.disabled:hover.disabled:focus,
.datepicker table tr td span.active[disabled]:focus,
.datepicker table tr td span.active:hover[disabled]:focus,
.datepicker table tr td span.active.disabled[disabled]:focus,
.datepicker table tr td span.active.disabled:hover[disabled]:focus,
fieldset[disabled] .datepicker table tr td span.active:focus,
fieldset[disabled] .datepicker table tr td span.active:hover:focus,
fieldset[disabled] .datepicker table tr td span.active.disabled:focus,
fieldset[disabled] .datepicker table tr td span.active.disabled:hover:focus,
.datepicker table tr td span.active.disabled:active,
.datepicker table tr td span.active:hover.disabled:active,
.datepicker table tr td span.active.disabled.disabled:active,
.datepicker table tr td span.active.disabled:hover.disabled:active,
.datepicker table tr td span.active[disabled]:active,
.datepicker table tr td span.active:hover[disabled]:active,
.datepicker table tr td span.active.disabled[disabled]:active,
.datepicker table tr td span.active.disabled:hover[disabled]:active,
fieldset[disabled] .datepicker table tr td span.active:active,
fieldset[disabled] .datepicker table tr td span.active:hover:active,
fieldset[disabled] .datepicker table tr td span.active.disabled:active,
fieldset[disabled] .datepicker table tr td span.active.disabled:hover:active,
.datepicker table tr td span.active.disabled.active,
.datepicker table tr td span.active:hover.disabled.active,
.datepicker table tr td span.active.disabled.disabled.active,
.datepicker table tr td span.active.disabled:hover.disabled.active,
.datepicker table tr td span.active[disabled].active,
.datepicker table tr td span.active:hover[disabled].active,
.datepicker table tr td span.active.disabled[disabled].active,
.datepicker table tr td span.active.disabled:hover[disabled].active,
fieldset[disabled] .datepicker table tr td span.active.active,
fieldset[disabled] .datepicker table tr td span.active:hover.active,
fieldset[disabled] .datepicker table tr td span.active.disabled.active,
fieldset[disabled] .datepicker table tr td span.active.disabled:hover.active {
background-color: #428bca;
border-color: #357ebd;
}
.datepicker table tr td span.old,
.datepicker table tr td span.new {
color: #999999;
}
.datepicker .datepicker-switch {
width: 145px;
}
.datepicker thead tr:first-child th,
.datepicker tfoot tr th {
cursor: pointer;
}
.datepicker thead tr:first-child th:hover,
.datepicker tfoot tr th:hover {
background: #eeeeee;
}
.datepicker .cw {
font-size: 10px;
width: 12px;
padding: 0 2px 0 5px;
vertical-align: middle;
}
.datepicker thead tr:first-child .cw {
cursor: default;
background-color: transparent;
}
.input-group.date .input-group-addon {
cursor: pointer;
}
.input-daterange {
width: 100%;
}
.input-daterange input {
text-align: center;
}
.input-daterange input:first-child {
border-radius: 3px 0 0 3px;
}
.input-daterange input:last-child {
border-radius: 0 3px 3px 0;
}
.input-daterange .input-group-addon {
width: auto;
min-width: 16px;
padding: 4px 5px;
font-weight: normal;
line-height: 1.42857143;
text-align: center;
text-shadow: 0 1px 0 #fff;
vertical-align: middle;
background-color: #eeeeee;
border: solid #cccccc;
border-width: 1px 0;
margin-left: -5px;
margin-right: -5px;
}

View File

@ -4,7 +4,7 @@ function assertUrlDeferred(url, obj) {
angular.isUndefined(obj[url].promise.then)) {
var urls = [];
for (key in obj) {
for (var key in obj) {
if (/\//.test(key)) {
urls.push(key);
}

View File

@ -0,0 +1,57 @@
import systemTracking from 'tower/system-tracking/main';
import {describeModule} from '../describe-module';
describeModule(systemTracking.name)
.testService('singleHostDataService', function(test, restStub) {
var service;
test.withService(function(_service) {
service = _service;
});
it('returns list of versions', function() {
var version = [{}],
host_id = 1,
module = 'packages',
start = moment('2015-05-05'),
end = moment('2015-05-06'),
result = {
data: {
results: version
}
};
var actual = service.getVersion(host_id, module, start, end);
restStub.succeed(result);
restStub.flush();
return expect(actual).to.eventually.equal(version[0]);
});
it('returns list of facts', function() {
var facts = [{}],
version = {
"module" : "package",
"timestamp": '2015-05-07T14:57:37',
"related" : {
"fact_view" : "/api/v1/hosts/1/fact_view/?module=packages&datetime=2015-05-07T14%3A57%3A37Z"
}
},
result = {
data: {
fact: facts
}
};
var actual = service.getFacts(version);
restStub.succeedAt(version.related.fact_view, result);
restStub.flush();
return expect(actual).to.eventually.equal(facts);
});
});