cmd/syncthing: UI for version restoration (fixes #2599) (#4602)

cmd/syncthing: Add UI for version restoration (fixes #2599)
This commit is contained in:
Audrius Butkevicius
2018-01-01 14:39:23 +00:00
committed by Jakob Borg
parent c7f136c2b8
commit b0e2050cdb
33 changed files with 20045 additions and 65 deletions

View File

@@ -371,3 +371,7 @@ ul.three-columns li, ul.two-columns li {
.tab-content {
padding-top: 10px;
}
.fancytree-ext-table {
width: 100% !important;
}

View File

@@ -27,3 +27,9 @@
.panel-heading:hover, .panel-heading:focus {
text-decoration: none;
}
.fancytree-ext-filter-hide tr.fancytree-submatch span.fancytree-title,
.fancytree-ext-filter-hide span.fancytree-node.fancytree-submatch span.fancytree-title {
color: black !important;
font-weight: lighter !important;
}

View File

@@ -28,6 +28,7 @@
"Any devices configured on an introducer device will be added to this device as well.": "Any devices configured on an introducer device will be added to this device as well.",
"Are you sure you want to remove device {%name%}?": "Are you sure you want to remove device {{name}}?",
"Are you sure you want to remove folder {%label%}?": "Are you sure you want to remove folder {{label}}?",
"Are you sure you want to restore {%count%} files?": "Are you sure you want to restore {{count}} files?",
"Auto Accept": "Auto Accept",
"Automatic upgrade now offers the choice between stable releases and release candidates.": "Automatic upgrade now offers the choice between stable releases and release candidates.",
"Automatic upgrades": "Automatic upgrades",
@@ -67,6 +68,8 @@
"Discovered": "Discovered",
"Discovery": "Discovery",
"Discovery Failures": "Discovery Failures",
"Do not restore": "Do not restore",
"Do not restore all": "Do not restore all",
"Documentation": "Documentation",
"Download Rate": "Download Rate",
"Downloaded": "Downloaded",
@@ -95,6 +98,8 @@
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.",
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.",
"Filesystem Notifications": "Filesystem Notifications",
"Filter by date": "Filter by date",
"Filter by name": "Filter by name",
"Folder": "Folder",
"Folder ID": "Folder ID",
"Folder Label": "Folder Label",
@@ -141,6 +146,7 @@
"Log tailing paused. Click here to continue.": "Log tailing paused. Click here to continue.",
"Logs": "Logs",
"Major Upgrade": "Major Upgrade",
"Mass actions": "Mass actions",
"Master": "Master",
"Maximum Age": "Maximum Age",
"Metadata Only": "Metadata Only",
@@ -201,6 +207,8 @@
"Restart": "Restart",
"Restart Needed": "Restart Needed",
"Restarting": "Restarting",
"Restore": "Restore",
"Restore Versions": "Restore Versions",
"Resume": "Resume",
"Resume All": "Resume All",
"Reused": "Reused",
@@ -210,6 +218,8 @@
"See external versioner help for supported templated command line parameters.": "See external versioner help for supported templated command line parameters.",
"See external versioning help for supported templated command line parameters.": "See external versioning help for supported templated command line parameters.",
"Select a version": "Select a version",
"Select latest version": "Select latest version",
"Select oldest version": "Select oldest version",
"Select the devices to share this folder with.": "Select the devices to share this folder with.",
"Select the folders to share with this device.": "Select the folders to share with this device.",
"Send \u0026 Receive": "Send \u0026 Receive",
@@ -232,6 +242,7 @@
"Single level wildcard (matches within a directory only)": "Single level wildcard (matches within a directory only)",
"Size": "Size",
"Smallest First": "Smallest First",
"Some items could not be restored:": "Some items could not be restored:",
"Source Code": "Source Code",
"Stable releases and release candidates": "Stable releases and release candidates",
"Stable releases are delayed by about two weeks. During this time they go through testing as release candidates.": "Stable releases are delayed by about two weeks. During this time they go through testing as release candidates.",

View File

@@ -19,10 +19,12 @@
<title ng-bind="thisDeviceName() + ' | Syncthing'"></title>
<link href="vendor/bootstrap/css/bootstrap.css" rel="stylesheet"/>
<link href="vendor/bootstrap/css/daterangepicker.css" rel="stylesheet"/>
<link href="assets/font/raleway.css" rel="stylesheet"/>
<link href="vendor/font-awesome/css/font-awesome.css" rel="stylesheet"/>
<link href="assets/css/overrides.css" rel="stylesheet"/>
<link href="assets/css/theme.css" rel="stylesheet"/>
<link href="vendor/fancytree/css/ui.fancytree.css" rel="stylesheet"/>
</head>
<body>
@@ -434,6 +436,9 @@
<button ng-if="folder.paused" type="button" class="btn btn-sm btn-default" ng-click="setFolderPause(folder.id, false)">
<span class="fa fa-play"></span>&nbsp;<span translate>Resume</span>
</button>
<button type="button" class="btn btn-default btn-sm" ng-click="restoreVersions.show(folder.id)" ng-if="folder.versioning.type">
<span class="fa fa-undo"></span>&nbsp;<span translate>Versions</span>
</button>
<button type="button" class="btn btn-sm btn-default" ng-click="rescanFolder(folder.id)" ng-show="['idle', 'stopped', 'unshared'].indexOf(folderStatus(folder)) > -1">
<span class="fa fa-refresh"></span>&nbsp;<span translate>Rescan</span>
</button>
@@ -723,6 +728,8 @@
<ng-include src="'syncthing/device/globalChangesModalView.html'"></ng-include>
<ng-include src="'syncthing/folder/editFolderModalView.html'"></ng-include>
<ng-include src="'syncthing/folder/editIgnoresModalView.html'"></ng-include>
<ng-include src="'syncthing/folder/restoreVersionsModalView.html'"></ng-include>
<ng-include src="'syncthing/folder/restoreVersionsConfirmation.html'"></ng-include>
<ng-include src="'syncthing/settings/settingsModalView.html'"></ng-include>
<ng-include src="'syncthing/settings/advancedSettingsModalView.html'"></ng-include>
<ng-include src="'syncthing/usagereport/usageReportModalView.html'"></ng-include>
@@ -744,7 +751,10 @@
<script type="text/javascript" src="vendor/angular/angular-translate.js"></script>
<script type="text/javascript" src="vendor/angular/angular-translate-loader-static-files.js"></script>
<script type="text/javascript" src="vendor/angular/angular-dirPagination.js"></script>
<script type="text/javascript" src="vendor/moment/moment.js"></script>
<script type="text/javascript" src="vendor/bootstrap/js/bootstrap.js"></script>
<script type="text/javascript" src="vendor/bootstrap/js/daterangepicker.js"></script>
<script type="text/javascript" src="vendor/fancytree/jquery.fancytree-all-deps.js"></script>
<!-- / vendor scripts -->
<!-- gui application code -->

View File

@@ -134,3 +134,75 @@ function debounce(func, wait) {
return result;
};
}
function buildTree(children) {
/* Converts
*
* {
* 'foo/bar': [...],
* 'foo/baz': [...]
* }
*
* to
*
* [
* {
* title: 'foo',
* children: [
* {
* title: 'bar',
* versions: [...],
* ...
* },
* {
* title: 'baz',
* versions: [...],
* ...
* }
* ],
* }
* ]
*/
var root = {
children: []
}
$.each(children, function(path, data) {
var parts = path.split('/');
var name = parts.splice(-1)[0];
var keySoFar = [];
var parent = root;
while (parts.length > 0) {
var part = parts.shift();
keySoFar.push(part);
var found = false;
for (var i = 0; i < parent.children.length; i++) {
if (parent.children[i].title == part) {
parent = parent.children[i];
found = true;
break;
}
}
if (!found) {
var child = {
title: part,
key: keySoFar.join('/'),
folder: true,
children: []
}
parent.children.push(child);
parent = child;
}
}
parent.children.push({
title: name,
key: path,
folder: false,
versions: data,
});
});
return root.children;
}

View File

@@ -2,7 +2,7 @@ angular.module('syncthing.core')
.config(function($locationProvider) {
$locationProvider.html5Mode({enabled: true, requireBase: false}).hashPrefix('!');
})
.controller('SyncthingController', function ($scope, $http, $location, LocaleService, Events, $filter, $q, $interval) {
.controller('SyncthingController', function ($scope, $http, $location, LocaleService, Events, $filter, $q, $compile, $timeout, $rootScope) {
'use strict';
// private/helper definitions
@@ -1107,9 +1107,9 @@ angular.module('syncthing.core')
},
show: function() {
$scope.logging.refreshFacilities();
$scope.logging.timer = $interval($scope.logging.fetch, 0, 1);
$scope.logging.timer = $timeout($scope.logging.fetch);
$('#logViewer').modal().on('hidden.bs.modal', function () {
$interval.cancel($scope.logging.timer);
$timeout.cancel($scope.logging.timer);
$scope.logging.timer = null;
$scope.logging.entries = [];
});
@@ -1138,7 +1138,7 @@ angular.module('syncthing.core')
var textArea = $('#logViewerText');
if (textArea.is(":focus")) {
if (!$scope.logging.timer) return;
$scope.logging.timer = $interval($scope.logging.fetch, 500, 1);
$scope.logging.timer = $timeout($scope.logging.fetch, 500);
return;
}
@@ -1149,7 +1149,7 @@ angular.module('syncthing.core')
$http.get(urlbase + '/system/log' + (last ? '?since=' + encodeURIComponent(last) : '')).success(function (data) {
if (!$scope.logging.timer) return;
$scope.logging.timer = $interval($scope.logging.fetch, 2000, 1);
$scope.logging.timer = $timeout($scope.logging.fetch, 2000);
if (!textArea.is(":focus")) {
if (data.messages) {
$scope.logging.entries.push.apply($scope.logging.entries, data.messages);
@@ -1767,6 +1767,233 @@ angular.module('syncthing.core')
});
};
function resetRestoreVersions() {
$scope.restoreVersions = {
folder: null,
selections: {},
versions: null,
tree: null,
errors: null,
filters: {},
massAction: function (name, action) {
$.each($scope.restoreVersions.versions, function(key) {
if (key.startsWith(name + '/') && (!$scope.restoreVersions.filters.text || key.indexOf($scope.restoreVersions.filters.text) > -1)) {
if (action == 'unset') {
delete $scope.restoreVersions.selections[key];
return;
}
var availableVersions = [];
$.each($scope.restoreVersions.filterVersions($scope.restoreVersions.versions[key]), function(idx, version) {
availableVersions.push(version.versionTime);
})
if (availableVersions.length) {
availableVersions.sort(function (a, b) { return a - b; });
if (action == 'latest') {
$scope.restoreVersions.selections[key] = availableVersions.pop();
} else if (action == 'oldest') {
$scope.restoreVersions.selections[key] = availableVersions.shift();
}
}
}
});
},
filterVersions: function(versions) {
var filteredVersions = [];
$.each(versions, function (idx, version) {
if (moment(version.versionTime).isBetween($scope.restoreVersions.filters['start'], $scope.restoreVersions.filters['end'], null, '[]')) {
filteredVersions.push(version);
}
});
return filteredVersions;
},
selectionCount: function() {
var count = 0;
$.each($scope.restoreVersions.selections, function(key, value) {
if (value) {
count++;
}
});
return count;
},
restore: function() {
$scope.restoreVersions.tree.clear();
$scope.restoreVersions.tree = null;
$scope.restoreVersions.versions = null;
var selections = {};
$.each($scope.restoreVersions.selections, function(key, value) {
if (value) {
selections[key] = value;
}
});
$scope.restoreVersions.selections = {};
$http.post(urlbase + '/folder/versions?folder=' + encodeURIComponent($scope.restoreVersions.folder), selections).success(function (data) {
if (Object.keys(data).length == 0) {
$('#restoreVersions').modal('hide');
} else {
$scope.restoreVersions.errors = data;
}
});
},
show: function(folder) {
$scope.restoreVersions.folder = folder;
var closed = false;
var modalShown = $q.defer();
$('#restoreVersions').modal().on('hidden.bs.modal', function () {
closed = true;
resetRestoreVersions();
}).on('shown.bs.modal', function() {
modalShown.resolve();
});
var dataReceived = $http.get(urlbase + '/folder/versions?folder=' + encodeURIComponent($scope.restoreVersions.folder))
.success(function (data) {
$.each(data, function(key, values) {
$.each(values, function(idx, value) {
value.modTime = new Date(value.modTime);
value.versionTime = new Date(value.versionTime);
});
});
if (closed) return;
$scope.restoreVersions.versions = data;
});
$q.all([dataReceived, modalShown.promise]).then(function() {
if (closed) {
resetRestoreVersions();
return;
}
$scope.restoreVersions.tree = $("#restoreTree").fancytree({
extensions: ["table", "filter"],
quicksearch: true,
filter: {
autoApply: true,
counter: true,
hideExpandedCounter: true,
hideExpanders: true,
highlight: true,
leavesOnly: false,
nodata: true,
mode: "hide"
},
table: {
indentation: 20,
nodeColumnIdx: 0,
},
debugLevel: 2,
source: buildTree($scope.restoreVersions.versions),
renderColumns: function(event, data) {
var node = data.node,
$tdList = $(node.tr).find(">td"),
template;
if (node.folder) {
template = '<div ng-include="\'syncthing/folder/restoreVersionsMassActions.html\'" class="pull-right"/>';
} else {
template = '<div ng-include="\'syncthing/folder/restoreVersionsVersionSelector.html\'" class="pull-right"/>';
}
var scope = $rootScope.$new(true);
scope.key = node.key;
scope.restoreVersions = $scope.restoreVersions;
$tdList.eq(1).html(
$compile(template)(scope)
);
// Force angular to redraw.
$timeout(function() {
$scope.$apply();
});
}
}).fancytree("getTree");
var minDate = moment(),
maxDate = moment(0, 'X'),
date;
// Find version window.
$.each($scope.restoreVersions.versions, function(key) {
$.each($scope.restoreVersions.versions[key], function(idx, version) {
date = moment(version.versionTime);
if (date.isBefore(minDate)) {
minDate = date;
}
if (date.isAfter(maxDate)) {
maxDate = date;
}
});
});
$scope.restoreVersions.filters['start'] = minDate;
$scope.restoreVersions.filters['end'] = maxDate;
var ranges = {
'All time': [minDate, maxDate],
'Today': [moment(), moment()],
'Yesterday': [moment().subtract(1, 'days'), moment().subtract(1, 'days')],
'Last 7 Days': [moment().subtract(6, 'days'), moment()],
'Last 30 Days': [moment().subtract(29, 'days'), moment()],
'This Month': [moment().startOf('month'), moment().endOf('month')],
'Last Month': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')]
};
// Filter out invalid ranges.
$.each(ranges, function(key, range) {
if (!range[0].isBetween(minDate, maxDate, null, '[]') && !range[1].isBetween(minDate, maxDate, null, '[]')) {
delete ranges[key];
}
});
$("#restoreVersionDateRange").daterangepicker({
timePicker: true,
timePicker24Hour: true,
timePickerSeconds: true,
autoUpdateInput: true,
opens: "left",
drops: "up",
startDate: minDate,
endDate: maxDate,
minDate: minDate,
maxDate: maxDate,
ranges: ranges,
locale: {
format: 'YYYY/MM/DD HH:mm:ss',
}
}).on('apply.daterangepicker', function(ev, picker) {
$scope.restoreVersions.filters['start'] = picker.startDate;
$scope.restoreVersions.filters['end'] = picker.endDate;
// Events for this UI element are not managed by angular.
// Force angular to wake up.
$timeout(function() {
$scope.$apply();
});
});
});
}
};
}
resetRestoreVersions();
$scope.$watchCollection('restoreVersions.filters', function() {
if (!$scope.restoreVersions.tree) return;
$scope.restoreVersions.tree.filterNodes(function (node) {
if (node.folder) return false;
if ($scope.restoreVersions.filters.text && node.key.indexOf($scope.restoreVersions.filters.text) < 0) {
return false;
}
if ($scope.restoreVersions.filterVersions(node.data.versions).length == 0) {
return false;
}
return true;
});
});
$scope.editIgnoresOnAddingFolder = function () {
if ($scope.editingExisting) {
return;

View File

@@ -1,15 +1,15 @@
<modal id="remove-device-confirmation" status="warning" icon="exclamation-circle" heading="{{'Remove Device' | translate}}" large="no" closeable="yes">
<div class="modal-body">
<p ng-model="currentDevice.name" style=" overflow : hidden; text-overflow: ellipsis; white-space: nowrap;">
<span translate translate-value-name="{{currentDevice.name}}">Are you sure you want to remove device {%name%}?</span>
</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-warning pull-left btn-sm" data-dismiss="modal" ng-click="deleteDevice()">
<span class="fa fa-minus-circle"></span>&nbsp;<span translate>Yes</span>
</button>
<button type="button" class="btn btn-default btn-sm" data-dismiss="modal">
<span class="fa fa-times"></span>&nbsp;<span translate>No</span>
</button>
</div>
<div class="modal-body">
<p ng-model="currentDevice.name" style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">
<span translate translate-value-name="{{currentDevice.name}}">Are you sure you want to remove device {%name%}?</span>
</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-warning pull-left btn-sm" data-dismiss="modal" ng-click="deleteDevice()">
<span class="fa fa-minus-circle"></span>&nbsp;<span translate>Yes</span>
</button>
<button type="button" class="btn btn-default btn-sm" data-dismiss="modal">
<span class="fa fa-times"></span>&nbsp;<span translate>No</span>
</button>
</div>
</modal>

View File

@@ -1,18 +1,18 @@
<modal id="remove-folder-confirmation" status="warning" icon="exclamation-circle" heading="{{'Remove Folder' | translate}}" large="no" closeable="yes">
<div class="modal-body">
<p ng-model="currentFolder.label" style=" overflow : hidden; text-overflow: ellipsis; white-space: nowrap;">
<span translate translate-value-label="{{currentFolder.label}}">Are you sure you want to remove folder {%label%}?</span>
</p>
<p translate>
No files will be deleted as a result of this operation.
</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-warning pull-left btn-sm" data-dismiss="modal" ng-click="deleteFolder(currentFolder.id)">
<span class="fa fa-minus-circle"></span>&nbsp;<span translate>Yes</span>
</button>
<button type="button" class="btn btn-default btn-sm" data-dismiss="modal">
<span class="fa fa-times"></span>&nbsp;<span translate>No</span>
</button>
</div>
<div class="modal-body">
<p style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">
<span translate translate-value-label="{{currentFolder.label}}">Are you sure you want to remove folder {%label%}?</span>
</p>
<p translate>
No files will be deleted as a result of this operation.
</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-warning pull-left btn-sm" data-dismiss="modal" ng-click="deleteFolder(currentFolder.id)">
<span class="fa fa-minus-circle"></span>&nbsp;<span translate>Yes</span>
</button>
<button type="button" class="btn btn-default btn-sm" data-dismiss="modal">
<span class="fa fa-times"></span>&nbsp;<span translate>No</span>
</button>
</div>
</modal>

View File

@@ -0,0 +1,15 @@
<modal id="restore-versions-confirmation" status="warning" icon="exclamation-circle" heading="{{'Restore Versions' | translate}}" large="no" closeable="yes">
<div class="modal-body">
<p style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">
<span translate-value-count="{{restoreVersions.selectionCount()}}" translate>Are you sure you want to restore {%count%} files?</span>
</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-warning pull-left btn-sm" data-dismiss="modal" ng-click="restoreVersions.restore()">
<span class="fa fa-check"></span>&nbsp;<span translate>Yes</span>
</button>
<button type="button" class="btn btn-default btn-sm" data-dismiss="modal">
<span class="fa fa-times"></span>&nbsp;<span translate>No</span>
</button>
</div>
</modal>

View File

@@ -0,0 +1,11 @@
<div class="dropdown">
<button class="btn btn-default btn-xs dropdown-toggle" type="button" data-toggle="dropdown">
<span translate>Mass actions</span>
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li><a href="#" ng-click="restoreVersions.massAction(key, 'unset')" translate>Do not restore all</a></li>
<li><a href="#" ng-click="restoreVersions.massAction(key, 'latest')" translate>Select latest version</a></li>
<li><a href="#" ng-click="restoreVersions.massAction(key, 'oldest')" translate>Select oldest version</a></li>
</ul>
</div>

View File

@@ -0,0 +1,51 @@
<modal id="restoreVersions" status="default" heading="{{'Restore Versions' | translate}}" large="yes" closeable="yes">
<div class="modal-body">
<span translate ng-if="!restoreVersions.versions && !restoreVersions.errors">Loading data...</span>
<div ng-if="restoreVersions.versions">
<table id="restoreTree">
<thead>
<tr>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<hr/>
<div class="row form-inline">
<div class="col-md-6">
<div class="form-group">
<label translate for="restoreVersionSearch">Filter by name</label>:&nbsp
<input id="restoreVersionSearch" class="form-control" type="text" ng-model="restoreVersions.filters.text">
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label translate for="restoreVersionDate">Filter by date</label>:&nbsp
<input id="restoreVersionDateRange" class="form-control">
</div>
</div>
</div>
</div>
<div ng-if="restoreVersions.errors">
<label><span translate>Some items could not be restored:</span></label>
<table class="table table-condensed table-striped">
<tbody>
<tr ng-repeat="(file, error) in restoreVersions.errors">
<td>{{ file }}</td>
<td>{{ error }}</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary btn-sm" data-toggle="modal" data-target="#restore-versions-confirmation" ng-if="restoreVersions.versions" ng-disabled="restoreVersions.selectionCount() < 1">
<span class="fa fa-check"></span>&nbsp;<span translate>Restore</span>
</button>
<button type="button" class="btn btn-default btn-sm" data-dismiss="modal">
<span class="fa fa-times"></span>&nbsp;<span translate>Close</span>
</button>
</div>
</modal>

View File

@@ -0,0 +1,17 @@
<div class="dropdown">
<button class="btn btn-default btn-xs dropdown-toggle" type="button" data-toggle="dropdown">
<span ng-if="!restoreVersions.selections[key]" translate>Do not restore</span>
<span ng-if="restoreVersions.selections[key]">{{ restoreVersions.selections[key] | date:"yyyy/MM/dd HH:mm:ss" }}</span>
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li>
<a href="#" ng-click="restoreVersions.selections[key] = undefined" translate>Do not restore</a>
</li>
<li ng-repeat="version in restoreVersions.filterVersions(restoreVersions.versions[key])">
<a href="#" ng-click="restoreVersions.selections[key] = version.versionTime">
{{ version.versionTime | date:"yyyy/MM/dd HH:mm:ss" }} {{ version.size | binary }}B
</a>
</li>
</ul>
</div>

View File

@@ -0,0 +1,269 @@
.daterangepicker {
position: absolute;
color: inherit;
background-color: #fff;
border-radius: 4px;
width: 278px;
padding: 4px;
margin-top: 1px;
top: 100px;
left: 20px;
/* Calendars */ }
.daterangepicker:before, .daterangepicker:after {
position: absolute;
display: inline-block;
border-bottom-color: rgba(0, 0, 0, 0.2);
content: ''; }
.daterangepicker:before {
top: -7px;
border-right: 7px solid transparent;
border-left: 7px solid transparent;
border-bottom: 7px solid #ccc; }
.daterangepicker:after {
top: -6px;
border-right: 6px solid transparent;
border-bottom: 6px solid #fff;
border-left: 6px solid transparent; }
.daterangepicker.opensleft:before {
right: 9px; }
.daterangepicker.opensleft:after {
right: 10px; }
.daterangepicker.openscenter:before {
left: 0;
right: 0;
width: 0;
margin-left: auto;
margin-right: auto; }
.daterangepicker.openscenter:after {
left: 0;
right: 0;
width: 0;
margin-left: auto;
margin-right: auto; }
.daterangepicker.opensright:before {
left: 9px; }
.daterangepicker.opensright:after {
left: 10px; }
.daterangepicker.dropup {
margin-top: -5px; }
.daterangepicker.dropup:before {
top: initial;
bottom: -7px;
border-bottom: initial;
border-top: 7px solid #ccc; }
.daterangepicker.dropup:after {
top: initial;
bottom: -6px;
border-bottom: initial;
border-top: 6px solid #fff; }
.daterangepicker.dropdown-menu {
max-width: none;
z-index: 3001; }
.daterangepicker.single .ranges, .daterangepicker.single .calendar {
float: none; }
.daterangepicker.show-calendar .calendar {
display: block; }
.daterangepicker .calendar {
display: none;
max-width: 270px;
margin: 4px; }
.daterangepicker .calendar.single .calendar-table {
border: none; }
.daterangepicker .calendar th, .daterangepicker .calendar td {
white-space: nowrap;
text-align: center;
min-width: 32px; }
.daterangepicker .calendar-table {
border: 1px solid #fff;
padding: 4px;
border-radius: 4px;
background-color: #fff; }
.daterangepicker table {
width: 100%;
margin: 0; }
.daterangepicker td, .daterangepicker th {
text-align: center;
width: 20px;
height: 20px;
border-radius: 4px;
border: 1px solid transparent;
white-space: nowrap;
cursor: pointer; }
.daterangepicker td.available:hover, .daterangepicker th.available:hover {
background-color: #eee;
border-color: transparent;
color: inherit; }
.daterangepicker td.week, .daterangepicker th.week {
font-size: 80%;
color: #ccc; }
.daterangepicker td.off, .daterangepicker td.off.in-range, .daterangepicker td.off.start-date, .daterangepicker td.off.end-date {
background-color: #fff;
border-color: transparent;
color: #999; }
.daterangepicker td.in-range {
background-color: #ebf4f8;
border-color: transparent;
color: #000;
border-radius: 0; }
.daterangepicker td.start-date {
border-radius: 4px 0 0 4px; }
.daterangepicker td.end-date {
border-radius: 0 4px 4px 0; }
.daterangepicker td.start-date.end-date {
border-radius: 4px; }
.daterangepicker td.active, .daterangepicker td.active:hover {
background-color: #357ebd;
border-color: transparent;
color: #fff; }
.daterangepicker th.month {
width: auto; }
.daterangepicker td.disabled, .daterangepicker option.disabled {
color: #999;
cursor: not-allowed;
text-decoration: line-through; }
.daterangepicker select.monthselect, .daterangepicker select.yearselect {
font-size: 12px;
padding: 1px;
height: auto;
margin: 0;
cursor: default; }
.daterangepicker select.monthselect {
margin-right: 2%;
width: 56%; }
.daterangepicker select.yearselect {
width: 40%; }
.daterangepicker select.hourselect, .daterangepicker select.minuteselect, .daterangepicker select.secondselect, .daterangepicker select.ampmselect {
width: 50px;
margin-bottom: 0; }
.daterangepicker .input-mini {
border: 1px solid #ccc;
border-radius: 4px;
color: #555;
height: 30px;
line-height: 30px;
display: block;
vertical-align: middle;
margin: 0 0 5px 0;
padding: 0 6px 0 28px;
width: 100%; }
.daterangepicker .input-mini.active {
border: 1px solid #08c;
border-radius: 4px; }
.daterangepicker .daterangepicker_input {
position: relative; }
.daterangepicker .daterangepicker_input i {
position: absolute;
left: 8px;
top: 8px; }
.daterangepicker.rtl .input-mini {
padding-right: 28px;
padding-left: 6px; }
.daterangepicker.rtl .daterangepicker_input i {
left: auto;
right: 8px; }
.daterangepicker .calendar-time {
text-align: center;
margin: 5px auto;
line-height: 30px;
position: relative;
padding-left: 28px; }
.daterangepicker .calendar-time select.disabled {
color: #ccc;
cursor: not-allowed; }
.ranges {
font-size: 11px;
float: none;
margin: 4px;
text-align: left; }
.ranges ul {
list-style: none;
margin: 0 auto;
padding: 0;
width: 100%; }
.ranges li {
font-size: 13px;
background-color: #f5f5f5;
border: 1px solid #f5f5f5;
border-radius: 4px;
color: #08c;
padding: 3px 12px;
margin-bottom: 8px;
cursor: pointer; }
.ranges li:hover {
background-color: #08c;
border: 1px solid #08c;
color: #fff; }
.ranges li.active {
background-color: #08c;
border: 1px solid #08c;
color: #fff; }
/* Larger Screen Styling */
@media (min-width: 564px) {
.daterangepicker {
width: auto; }
.daterangepicker .ranges ul {
width: 160px; }
.daterangepicker.single .ranges ul {
width: 100%; }
.daterangepicker.single .calendar.left {
clear: none; }
.daterangepicker.single.ltr .ranges, .daterangepicker.single.ltr .calendar {
float: left; }
.daterangepicker.single.rtl .ranges, .daterangepicker.single.rtl .calendar {
float: right; }
.daterangepicker.ltr {
direction: ltr;
text-align: left; }
.daterangepicker.ltr .calendar.left {
clear: left;
margin-right: 0; }
.daterangepicker.ltr .calendar.left .calendar-table {
border-right: none;
border-top-right-radius: 0;
border-bottom-right-radius: 0; }
.daterangepicker.ltr .calendar.right {
margin-left: 0; }
.daterangepicker.ltr .calendar.right .calendar-table {
border-left: none;
border-top-left-radius: 0;
border-bottom-left-radius: 0; }
.daterangepicker.ltr .left .daterangepicker_input {
padding-right: 12px; }
.daterangepicker.ltr .calendar.left .calendar-table {
padding-right: 12px; }
.daterangepicker.ltr .ranges, .daterangepicker.ltr .calendar {
float: left; }
.daterangepicker.rtl {
direction: rtl;
text-align: right; }
.daterangepicker.rtl .calendar.left {
clear: right;
margin-left: 0; }
.daterangepicker.rtl .calendar.left .calendar-table {
border-left: none;
border-top-left-radius: 0;
border-bottom-left-radius: 0; }
.daterangepicker.rtl .calendar.right {
margin-right: 0; }
.daterangepicker.rtl .calendar.right .calendar-table {
border-right: none;
border-top-right-radius: 0;
border-bottom-right-radius: 0; }
.daterangepicker.rtl .left .daterangepicker_input {
padding-left: 12px; }
.daterangepicker.rtl .calendar.left .calendar-table {
padding-left: 12px; }
.daterangepicker.rtl .ranges, .daterangepicker.rtl .calendar {
text-align: right;
float: right; } }
@media (min-width: 730px) {
.daterangepicker .ranges {
width: auto; }
.daterangepicker.ltr .ranges {
float: left; }
.daterangepicker.rtl .ranges {
float: right; }
.daterangepicker .calendar.left {
clear: none !important; } }

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,663 @@
/*!
* Fancytree "Lion" skin.
*
* DON'T EDIT THE CSS FILE DIRECTLY, since it is automatically generated from
* the LESS templates.
*/
/*
Lion colors:
gray highlight bar: #D4D4D4
blue highlight-bar and -border #3875D7
*/
/*******************************************************************************
* Common Styles for Fancytree Skins.
*
* This section is automatically generated from the `skin-common.less` template.
******************************************************************************/
/*------------------------------------------------------------------------------
* Helpers
*----------------------------------------------------------------------------*/
.ui-helper-hidden {
display: none;
}
/*------------------------------------------------------------------------------
* Container and UL / LI
*----------------------------------------------------------------------------*/
ul.fancytree-container {
font-family: tahoma, arial, helvetica;
font-size: 10pt;
white-space: nowrap;
padding: 3px;
margin: 0;
background-color: white;
border: 1px dotted gray;
min-height: 0%;
position: relative;
}
ul.fancytree-container ul {
padding: 0 0 0 16px;
margin: 0;
}
ul.fancytree-container ul > li:before {
content: none;
}
ul.fancytree-container li {
list-style-image: none;
list-style-position: outside;
list-style-type: none;
-moz-background-clip: border;
-moz-background-inline-policy: continuous;
-moz-background-origin: padding;
background-attachment: scroll;
background-color: transparent;
background-position: 0px 0px;
background-repeat: repeat-y;
background-image: none;
margin: 0;
}
ul.fancytree-container li.fancytree-lastsib {
background-image: none;
}
.ui-fancytree-disabled ul.fancytree-container {
opacity: 0.5;
background-color: silver;
}
ul.fancytree-connectors.fancytree-container li {
background-image: url("../skin-lion/vline.gif");
background-position: 0 0;
}
ul.fancytree-container li.fancytree-lastsib,
ul.fancytree-no-connector > li {
background-image: none;
}
li.fancytree-animating {
position: relative;
}
/*------------------------------------------------------------------------------
* Common icon definitions
*----------------------------------------------------------------------------*/
span.fancytree-empty,
span.fancytree-vline,
span.fancytree-expander,
span.fancytree-icon,
span.fancytree-checkbox,
span.fancytree-drag-helper-img,
#fancytree-drop-marker {
width: 16px;
height: 16px;
display: inline-block;
vertical-align: top;
background-repeat: no-repeat;
background-position: left;
background-image: url("../skin-lion/icons.gif");
background-position: 0px 0px;
}
span.fancytree-icon,
span.fancytree-checkbox,
span.fancytree-expander,
span.fancytree-custom-icon {
margin-top: 0px;
}
/* Used by icon option: */
span.fancytree-custom-icon {
width: 16px;
height: 16px;
display: inline-block;
margin-left: 3px;
background-position: 0px 0px;
}
/* Used by 'icon' node option: */
img.fancytree-icon {
width: 16px;
height: 16px;
margin-left: 3px;
margin-top: 0px;
vertical-align: top;
border-style: none;
}
/*------------------------------------------------------------------------------
* Expander icon
*
* Note: IE6 doesn't correctly evaluate multiples class names,
* so we create combined class names that can be used in the CSS.
*
* Prefix: fancytree-exp-
* 1st character: 'e': expanded, 'c': collapsed, 'n': no children
* 2nd character (optional): 'd': lazy (Delayed)
* 3rd character (optional): 'l': Last sibling
*----------------------------------------------------------------------------*/
span.fancytree-expander {
cursor: pointer;
}
.fancytree-exp-n span.fancytree-expander,
.fancytree-exp-nl span.fancytree-expander {
background-image: none;
cursor: default;
}
.fancytree-connectors .fancytree-exp-n span.fancytree-expander,
.fancytree-connectors .fancytree-exp-nl span.fancytree-expander {
background-image: url("../skin-lion/icons.gif");
margin-top: 0;
}
.fancytree-connectors .fancytree-exp-n span.fancytree-expander,
.fancytree-connectors .fancytree-exp-n span.fancytree-expander:hover {
background-position: 0px -64px;
}
.fancytree-connectors .fancytree-exp-nl span.fancytree-expander,
.fancytree-connectors .fancytree-exp-nl span.fancytree-expander:hover {
background-position: -16px -64px;
}
.fancytree-exp-c span.fancytree-expander {
background-position: 0px -80px;
}
.fancytree-exp-c span.fancytree-expander:hover {
background-position: -16px -80px;
}
.fancytree-exp-cl span.fancytree-expander {
background-position: 0px -96px;
}
.fancytree-exp-cl span.fancytree-expander:hover {
background-position: -16px -96px;
}
.fancytree-exp-cd span.fancytree-expander {
background-position: -64px -80px;
}
.fancytree-exp-cd span.fancytree-expander:hover {
background-position: -80px -80px;
}
.fancytree-exp-cdl span.fancytree-expander {
background-position: -64px -96px;
}
.fancytree-exp-cdl span.fancytree-expander:hover {
background-position: -80px -96px;
}
.fancytree-exp-e span.fancytree-expander,
.fancytree-exp-ed span.fancytree-expander {
background-position: -32px -80px;
}
.fancytree-exp-e span.fancytree-expander:hover,
.fancytree-exp-ed span.fancytree-expander:hover {
background-position: -48px -80px;
}
.fancytree-exp-el span.fancytree-expander,
.fancytree-exp-edl span.fancytree-expander {
background-position: -32px -96px;
}
.fancytree-exp-el span.fancytree-expander:hover,
.fancytree-exp-edl span.fancytree-expander:hover {
background-position: -48px -96px;
}
/* Fade out expanders, when container is not hovered or active */
.fancytree-fade-expander span.fancytree-expander {
transition: opacity 1.5s;
opacity: 0;
}
.fancytree-fade-expander:hover span.fancytree-expander,
.fancytree-fade-expander.fancytree-treefocus span.fancytree-expander,
.fancytree-fade-expander .fancytree-treefocus span.fancytree-expander,
.fancytree-fade-expander [class*='fancytree-statusnode-'] span.fancytree-expander {
transition: opacity 0.6s;
opacity: 1;
}
/*------------------------------------------------------------------------------
* Checkbox icon
*----------------------------------------------------------------------------*/
span.fancytree-checkbox {
margin-left: 3px;
background-position: 0px -32px;
}
span.fancytree-checkbox:hover {
background-position: -16px -32px;
}
span.fancytree-checkbox.fancytree-radio {
background-position: 0px -48px;
}
span.fancytree-checkbox.fancytree-radio:hover {
background-position: -16px -48px;
}
.fancytree-partsel span.fancytree-checkbox {
background-position: -64px -32px;
}
.fancytree-partsel span.fancytree-checkbox:hover {
background-position: -80px -32px;
}
.fancytree-partsel span.fancytree-checkbox.fancytree-radio {
background-position: -64px -48px;
}
.fancytree-partsel span.fancytree-checkbox.fancytree-radio:hover {
background-position: -80px -48px;
}
.fancytree-selected span.fancytree-checkbox {
background-position: -32px -32px;
}
.fancytree-selected span.fancytree-checkbox:hover {
background-position: -48px -32px;
}
.fancytree-selected span.fancytree-checkbox.fancytree-radio {
background-position: -32px -48px;
}
.fancytree-selected span.fancytree-checkbox.fancytree-radio:hover {
background-position: -48px -48px;
}
.fancytree-unselectable span.fancytree-checkbox {
opacity: 0.4;
filter: alpha(opacity=40);
}
.fancytree-unselectable span.fancytree-checkbox:hover {
background-position: 0px -32px;
}
.fancytree-unselectable.fancytree-partsel span.fancytree-checkbox:hover {
background-position: -64px -32px;
}
.fancytree-unselectable.fancytree-selected span.fancytree-checkbox:hover {
background-position: -32px -32px;
}
/*------------------------------------------------------------------------------
* Node type icon
* Note: IE6 doesn't correctly evaluate multiples class names,
* so we create combined class names that can be used in the CSS.
*
* Prefix: fancytree-ico-
* 1st character: 'e': expanded, 'c': collapsed
* 2nd character (optional): 'f': folder
*----------------------------------------------------------------------------*/
span.fancytree-icon {
margin-left: 3px;
background-position: 0px 0px;
}
/* Documents */
.fancytree-ico-c span.fancytree-icon:hover {
background-position: -16px 0px;
}
.fancytree-has-children.fancytree-ico-c span.fancytree-icon {
background-position: -32px 0px;
}
.fancytree-has-children.fancytree-ico-c span.fancytree-icon:hover {
background-position: -48px 0px;
}
.fancytree-ico-e span.fancytree-icon {
background-position: -64px 0px;
}
.fancytree-ico-e span.fancytree-icon:hover {
background-position: -80px 0px;
}
/* Folders */
.fancytree-ico-cf span.fancytree-icon {
background-position: 0px -16px;
}
.fancytree-ico-cf span.fancytree-icon:hover {
background-position: -16px -16px;
}
.fancytree-has-children.fancytree-ico-cf span.fancytree-icon {
background-position: -32px -16px;
}
.fancytree-has-children.fancytree-ico-cf span.fancytree-icon:hover {
background-position: -48px -16px;
}
.fancytree-ico-ef span.fancytree-icon {
background-position: -64px -16px;
}
.fancytree-ico-ef span.fancytree-icon:hover {
background-position: -80px -16px;
}
.fancytree-loading span.fancytree-expander,
.fancytree-loading span.fancytree-expander:hover,
.fancytree-statusnode-loading span.fancytree-icon,
.fancytree-statusnode-loading span.fancytree-icon:hover {
background-image: url("../skin-lion/loading.gif");
background-position: 0px 0px;
}
/* Status node icons */
.fancytree-statusnode-error span.fancytree-icon,
.fancytree-statusnode-error span.fancytree-icon:hover {
background-position: 0px -112px;
}
/*------------------------------------------------------------------------------
* Node titles and highlighting
*----------------------------------------------------------------------------*/
span.fancytree-node {
/* See #117 */
display: inherit;
width: 100%;
margin-top: 1px;
min-height: 16px;
}
span.fancytree-title {
color: black;
cursor: pointer;
display: inline-block;
vertical-align: top;
min-height: 16px;
padding: 0 3px 0 3px;
margin: 0px 0 0 3px;
border: 1px solid transparent;
-webkit-border-radius: 0px;
-moz-border-radius: 0px;
-ms-border-radius: 0px;
-o-border-radius: 0px;
border-radius: 0px;
}
span.fancytree-node.fancytree-error span.fancytree-title {
color: red;
}
/*------------------------------------------------------------------------------
* Drag'n'drop support
*----------------------------------------------------------------------------*/
div.fancytree-drag-helper span.fancytree-childcounter,
div.fancytree-drag-helper span.fancytree-dnd-modifier {
display: inline-block;
color: #fff;
background: #337ab7;
border: 1px solid gray;
min-width: 10px;
height: 10px;
line-height: 1;
vertical-align: baseline;
border-radius: 10px;
padding: 2px;
text-align: center;
font-size: 9px;
}
div.fancytree-drag-helper span.fancytree-childcounter {
position: absolute;
top: -6px;
right: -6px;
}
div.fancytree-drag-helper span.fancytree-dnd-modifier {
background: #5cb85c;
border: none;
font-weight: bolder;
}
div.fancytree-drag-helper.fancytree-drop-accept span.fancytree-drag-helper-img {
background-position: -32px -112px;
}
div.fancytree-drag-helper.fancytree-drop-reject span.fancytree-drag-helper-img {
background-position: -16px -112px;
}
/*** Drop marker icon *********************************************************/
#fancytree-drop-marker {
width: 32px;
position: absolute;
background-position: 0px -128px;
margin: 0;
}
#fancytree-drop-marker.fancytree-drop-after,
#fancytree-drop-marker.fancytree-drop-before {
width: 64px;
background-position: 0px -144px;
}
#fancytree-drop-marker.fancytree-drop-copy {
background-position: -64px -128px;
}
#fancytree-drop-marker.fancytree-drop-move {
background-position: -32px -128px;
}
/*** Source node while dragging ***********************************************/
span.fancytree-drag-source.fancytree-drag-remove {
opacity: 0.15;
}
/*** Target node while dragging cursor is over it *****************************/
/*------------------------------------------------------------------------------
* 'rtl' option
*----------------------------------------------------------------------------*/
.fancytree-container.fancytree-rtl .fancytree-title {
/*unicode-bidi: bidi-override;*/
/* optional: reverse title letters */
}
.fancytree-container.fancytree-rtl span.fancytree-connector,
.fancytree-container.fancytree-rtl span.fancytree-expander,
.fancytree-container.fancytree-rtl span.fancytree-icon,
.fancytree-container.fancytree-rtl span.fancytree-drag-helper-img,
.fancytree-container.fancytree-rtl #fancytree-drop-marker {
background-image: url("../skin-lion/icons-rtl.gif");
}
.fancytree-container.fancytree-rtl .fancytree-exp-n span.fancytree-expander,
.fancytree-container.fancytree-rtl .fancytree-exp-nl span.fancytree-expander {
background-image: none;
}
.fancytree-container.fancytree-rtl.fancytree-connectors .fancytree-exp-n span.fancytree-expander,
.fancytree-container.fancytree-rtl.fancytree-connectors .fancytree-exp-nl span.fancytree-expander {
background-image: url("../skin-lion/icons-rtl.gif");
}
ul.fancytree-container.fancytree-rtl ul {
padding: 0 16px 0 0;
}
ul.fancytree-container.fancytree-rtl.fancytree-connectors li {
background-position: right 0;
background-image: url("../skin-lion/vline-rtl.gif");
}
ul.fancytree-container.fancytree-rtl li.fancytree-lastsib,
ul.fancytree-container.fancytree-rtl.fancytree-no-connector > li {
background-image: none;
}
/*------------------------------------------------------------------------------
* 'table' extension
*----------------------------------------------------------------------------*/
table.fancytree-ext-table {
border-collapse: collapse;
}
table.fancytree-ext-table span.fancytree-node {
display: inline-block;
box-sizing: border-box;
}
/*------------------------------------------------------------------------------
* 'columnview' extension
*----------------------------------------------------------------------------*/
table.fancytree-ext-columnview tbody tr td {
position: relative;
border: 1px solid gray;
vertical-align: top;
overflow: auto;
}
table.fancytree-ext-columnview tbody tr td > ul {
padding: 0;
}
table.fancytree-ext-columnview tbody tr td > ul li {
list-style-image: none;
list-style-position: outside;
list-style-type: none;
-moz-background-clip: border;
-moz-background-inline-policy: continuous;
-moz-background-origin: padding;
background-attachment: scroll;
background-color: transparent;
background-position: 0px 0px;
background-repeat: repeat-y;
background-image: none;
/* no v-lines */
margin: 0;
}
table.fancytree-ext-columnview span.fancytree-node {
position: relative;
/* allow positioning of embedded spans */
display: inline-block;
}
table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded {
background-color: #CBE8F6;
}
table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right {
position: absolute;
right: 3px;
background-position: 0px -80px;
}
table.fancytree-ext-columnview .fancytree-has-children span.fancytree-cv-right:hover {
background-position: -16px -80px;
}
/*------------------------------------------------------------------------------
* 'filter' extension
*----------------------------------------------------------------------------*/
.fancytree-ext-filter-dimm span.fancytree-node span.fancytree-title {
color: silver;
font-weight: lighter;
}
.fancytree-ext-filter-dimm tr.fancytree-submatch span.fancytree-title,
.fancytree-ext-filter-dimm span.fancytree-node.fancytree-submatch span.fancytree-title {
color: black;
font-weight: normal;
}
.fancytree-ext-filter-dimm tr.fancytree-match span.fancytree-title,
.fancytree-ext-filter-dimm span.fancytree-node.fancytree-match span.fancytree-title {
color: black;
font-weight: bold;
}
.fancytree-ext-filter-hide tr.fancytree-hide,
.fancytree-ext-filter-hide span.fancytree-node.fancytree-hide {
display: none;
}
.fancytree-ext-filter-hide tr.fancytree-submatch span.fancytree-title,
.fancytree-ext-filter-hide span.fancytree-node.fancytree-submatch span.fancytree-title {
color: silver;
font-weight: lighter;
}
.fancytree-ext-filter-hide tr.fancytree-match span.fancytree-title,
.fancytree-ext-filter-hide span.fancytree-node.fancytree-match span.fancytree-title {
color: black;
font-weight: normal;
}
/* Hide expanders if all child nodes are hidden by filter */
.fancytree-ext-filter-hide-expanders tr.fancytree-match span.fancytree-expander,
.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-match span.fancytree-expander {
visibility: hidden;
}
.fancytree-ext-filter-hide-expanders tr.fancytree-submatch span.fancytree-expander,
.fancytree-ext-filter-hide-expanders span.fancytree-node.fancytree-submatch span.fancytree-expander {
visibility: visible;
}
.fancytree-ext-childcounter span.fancytree-icon,
.fancytree-ext-filter span.fancytree-icon {
position: relative;
}
.fancytree-ext-childcounter span.fancytree-childcounter,
.fancytree-ext-filter span.fancytree-childcounter {
color: #fff;
background: #777;
border: 1px solid gray;
position: absolute;
top: -6px;
right: -6px;
min-width: 10px;
height: 10px;
line-height: 1;
vertical-align: baseline;
border-radius: 10px;
padding: 2px;
text-align: center;
font-size: 9px;
}
/*------------------------------------------------------------------------------
* 'wide' extension
*----------------------------------------------------------------------------*/
ul.fancytree-ext-wide {
position: relative;
min-width: 100%;
z-index: 2;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
ul.fancytree-ext-wide span.fancytree-node > span {
position: relative;
z-index: 2;
}
ul.fancytree-ext-wide span.fancytree-node span.fancytree-title {
position: absolute;
z-index: 1;
left: 0px;
min-width: 100%;
margin-left: 0;
margin-right: 0;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
/*------------------------------------------------------------------------------
* 'fixed' extension
*----------------------------------------------------------------------------*/
.fancytree-ext-fixed-wrapper .fancytree-ext-fixed-hidden {
display: none;
}
.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-bottom {
border-bottom: 3px solid rgba(0, 0, 0, 0.75);
}
.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-scroll-border-right {
border-right: 3px solid rgba(0, 0, 0, 0.75);
}
.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tl {
position: absolute;
overflow: hidden;
z-index: 3;
top: 0px;
left: 0px;
}
.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-tr {
position: absolute;
overflow: hidden;
z-index: 2;
top: 0px;
}
.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-bl {
position: absolute;
overflow: hidden;
z-index: 2;
left: 0px;
}
.fancytree-ext-fixed-wrapper div.fancytree-ext-fixed-wrapper-br {
position: absolute;
overflow: scroll;
z-index: 1;
}
/*******************************************************************************
* Styles specific to this skin.
*
* This section is automatically generated from the `ui-fancytree.less` template.
******************************************************************************/
/*******************************************************************************
* Node titles
*/
span.fancytree-title {
border: 1px solid transparent;
border-radius: 0;
}
span.fancytree-focused span.fancytree-title {
outline: 1px dotted black;
}
span.fancytree-selected span.fancytree-title,
span.fancytree-active span.fancytree-title {
background-color: #D4D4D4;
}
span.fancytree-selected span.fancytree-title {
font-style: italic;
}
.fancytree-treefocus span.fancytree-selected span.fancytree-title,
.fancytree-treefocus span.fancytree-active span.fancytree-title {
color: white;
background-color: #3875D7;
}
/*******************************************************************************
* 'table' extension
*/
table.fancytree-ext-table {
border-collapse: collapse;
}
table.fancytree-ext-table tbody tr.fancytree-focused {
background-color: #99DEFD;
}
table.fancytree-ext-table tbody tr.fancytree-active {
background-color: royalblue;
}
table.fancytree-ext-table tbody tr.fancytree-selected {
background-color: #99DEFD;
}
/*******************************************************************************
* 'columnview' extension
*/
table.fancytree-ext-columnview tbody tr td {
border: 1px solid gray;
}
table.fancytree-ext-columnview span.fancytree-node.fancytree-expanded {
background-color: #ccc;
}
table.fancytree-ext-columnview span.fancytree-node.fancytree-active {
background-color: royalblue;
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 852 B

4517
gui/default/vendor/moment/moment.js vendored Normal file

File diff suppressed because it is too large Load Diff