mirror of
https://github.com/stylersnico/librenms.git
synced 2026-07-28 00:24:21 +02:00
Merge pull request #835 from laf/issue-711
Web UI for scheduling maintenance windows
This commit is contained in:
@@ -31,9 +31,9 @@ if (isset($_REQUEST['search']))
|
||||
|
||||
if( $_REQUEST['type'] == 'group' ) {
|
||||
include_once('../includes/device-groups.inc.php');
|
||||
foreach( dbFetchRows("SELECT name FROM device_groups WHERE name LIKE '%".$search."%'") as $group ) {
|
||||
foreach( dbFetchRows("SELECT id,name FROM device_groups WHERE name LIKE '%".$search."%'") as $group ) {
|
||||
if( $_REQUEST['map'] ) {
|
||||
$results[] = array('name'=>'g:'.$group['name']);
|
||||
$results[] = array('name'=>'g:'.$group['name'],'group_id'=>$group['id']);
|
||||
} else {
|
||||
$results[] = array('name'=>$group['name']);
|
||||
}
|
||||
@@ -74,6 +74,7 @@ if (isset($_REQUEST['search']))
|
||||
}
|
||||
$num_ports = dbFetchCell("SELECT COUNT(*) FROM `ports` WHERE device_id = ?", array($result['device_id']));
|
||||
$device[]=array('name'=>$name,
|
||||
'device_id'=>$result['device_id'],
|
||||
'url'=> generate_device_url($result),
|
||||
'colours'=>$highlight_colour,
|
||||
'device_ports'=>$num_ports,
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* LibreNMS
|
||||
*
|
||||
* Copyright (c) 2014 Neil Lathwood <https://github.com/laf/ http://www.lathwood.co.uk/fa>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version. Please see LICENSE.txt at the top level of
|
||||
* the source code distribution for details.
|
||||
*/
|
||||
|
||||
if(is_admin() === false) {
|
||||
die('ERROR: You need to be admin');
|
||||
}
|
||||
|
||||
$sub_type = $_POST['sub_type'];
|
||||
|
||||
if ($sub_type == 'new-maintenance') {
|
||||
|
||||
// Defaults
|
||||
$status = 'error';
|
||||
$update = 0;
|
||||
|
||||
$schedule_id = mres($_POST['schedule_id']);
|
||||
if ($schedule_id > 0) {
|
||||
$update = 1;
|
||||
}
|
||||
$title = mres($_POST['title']);
|
||||
$notes = mres($_POST['notes']);
|
||||
$start = mres($_POST['start']);
|
||||
$end = mres($_POST['end']);
|
||||
$maps = mres($_POST['maps']);
|
||||
|
||||
if (empty($title)) {
|
||||
$message = "Missing title<br />";
|
||||
}
|
||||
if (empty($start)) {
|
||||
$message .= "Missing start date<br />";
|
||||
}
|
||||
if (empty($end)) {
|
||||
$message .= "Missing end date<br />";
|
||||
}
|
||||
if( !is_array($_POST['maps']) ) {
|
||||
$message .= "Not mapped to any groups or devices<br />";
|
||||
}
|
||||
|
||||
if (empty($message)) {
|
||||
if (empty($schedule_id)) {
|
||||
$schedule_id = dbInsert(array('start'=>$start,'end'=>$end,'title'=>$title,'notes'=>$notes),'alert_schedule');
|
||||
} else {
|
||||
dbUpdate(array('start'=>$start,'end'=>$end,'title'=>$title,'notes'=>$notes),'alert_schedule','`schedule_id`=?',array($schedule_id));
|
||||
}
|
||||
if ($schedule_id > 0) {
|
||||
$items = array();
|
||||
$fail = 0;
|
||||
|
||||
if ($update == 1) {
|
||||
dbDelete('alert_schedule_items', '`schedule_id`=?', array($schedule_id));
|
||||
}
|
||||
|
||||
foreach( $_POST['maps'] as $target ) {
|
||||
$target = target_to_id($target);
|
||||
$item = dbInsert(array('schedule_id'=>$schedule_id,'target'=>$target),'alert_schedule_items');
|
||||
if ($item > 0) {
|
||||
array_push($items,$item);
|
||||
} else {
|
||||
$fail = 1;
|
||||
}
|
||||
}
|
||||
if ($fail == 1 && $update == 0) {
|
||||
foreach ($items as $item) {
|
||||
dbDelete('alert_schedule_items', '`item_id`=?', array($item));
|
||||
}
|
||||
dbDelete('alert_schedule', '`schedule_id`=?', array($schedule_id));
|
||||
$message = 'Issue scheduling maintenance';
|
||||
} else {
|
||||
$status = 'ok';
|
||||
$message = 'Scheduling maintenance ok';
|
||||
}
|
||||
} else {
|
||||
$message = "Issue scheduling maintenance";
|
||||
}
|
||||
}
|
||||
|
||||
$response = array('status'=>$status,'message'=>$message);
|
||||
|
||||
} elseif ($sub_type == 'parse-maintenance') {
|
||||
|
||||
$schedule_id = mres($_POST['schedule_id']);
|
||||
$schedule = dbFetchRow("SELECT * FROM `alert_schedule` WHERE `schedule_id`=?",array($schedule_id));
|
||||
$items = array();
|
||||
foreach (dbFetchRows("SELECT `target` FROM `alert_schedule_items` WHERE `schedule_id`=?",array($schedule_id)) as $targets) {
|
||||
$targets = id_to_target($targets['target']);
|
||||
array_push($items,$targets);
|
||||
}
|
||||
$response = array('start'=>$schedule['start'],'end'=>$schedule['end'],'title'=>$schedule['title'],'notes'=>$schedule['notes'],'targets'=>$items);
|
||||
} elseif ($sub_type == 'del-maintenance') {
|
||||
$schedule_id = mres($_POST['del_schedule_id']);
|
||||
dbDelete('alert_schedule_items','`schedule_id`=?',array($schedule_id));
|
||||
dbDelete('alert_schedule','`schedule_id`=?', array($schedule_id));
|
||||
$status = 'ok';
|
||||
$message = 'Maintenance schedule has been removed';
|
||||
$response = array('status'=>$status,'message'=>$message);
|
||||
}
|
||||
|
||||
echo _json_encode($response);
|
||||
@@ -0,0 +1,187 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* LibreNMS
|
||||
*
|
||||
* Copyright (c) 2014 Neil Lathwood <https://github.com/laf/ http://www.lathwood.co.uk/fa>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version. Please see LICENSE.txt at the top level of
|
||||
* the source code distribution for details.
|
||||
*/
|
||||
|
||||
if(is_admin() !== false) {
|
||||
|
||||
?>
|
||||
|
||||
<div class="modal fade bs-example-modal-sm" id="schedule-maintenance" tabindex="-1" role="dialog" aria-labelledby="Create" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h5 class="modal-title" id="Create">Create maintenance</h5>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form method="post" role="form" id="sched-form" class="form-horizontal schedule-maintenance-form">
|
||||
<input type="hidden" name="schedule_id" id="schedule_id">
|
||||
<input type="hidden" name="type" id="type" value="schedule-maintenance">
|
||||
<input type="hidden" name="sub_type" id="sub_type" value="new-maintenance">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<span id="response"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="title" class="col-sm-4 control-label">Title: </label>
|
||||
<div class="col-sm-8">
|
||||
<input type="text" class="form-control" id="title" name="title" placeholder="Maintenance title">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="notes" class="col-sm-4 control-label">Notes: </label>
|
||||
<div class="col-sm-8">
|
||||
<textarea class="form-control" id="notes" name="notes" placeholder="Maintenance notes"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="start" class="col-sm-4 control-label">Start: </label>
|
||||
<div class="col-sm-8">
|
||||
<input type="text" class="form-control date" id="start" name="start" value="<?php echo date('Y-m-d H:i'); ?>" data-date-format="YYYY-MM-DD HH:mm">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="end" class="col-sm-4 control-label">End: </label>
|
||||
<div class="col-sm-8">
|
||||
<input type="text" class="form-control date" id="end" name="end" value="<?php echo date('Y-m-d H:i',strtotime('+1 hour')); ?>" data-date-format="YYYY-MM-DD HH:mm">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for='map-stub' class='col-sm-4 control-label'>Map To: </label>
|
||||
<div class="col-sm-5">
|
||||
<input type='text' id='map-stub' name='map-stub' class='form-control'/>
|
||||
</div>
|
||||
<div class="col-sm-3">
|
||||
<button class="btn btn-primary btn-sm" type="button" name="add-map" id="add-map" value="Add">Add</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-md-12">
|
||||
<span id="map-tags"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-3 col-sm-3">
|
||||
<button class="btn btn-success" type="submit" name="sched-submit" id="sched-submit" value="save">Schedule maintenance</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$('#schedule-maintenance').on('hide.bs.modal', function (event) {
|
||||
$('#map-tags').data('tagmanager').empty();
|
||||
$('#schedule_id').val('');
|
||||
$('#title').val('');
|
||||
$('#notes').val('');
|
||||
$('#start').val('');
|
||||
$('#end').val('');
|
||||
});
|
||||
|
||||
$('#schedule-maintenance').on('show.bs.modal', function (event) {
|
||||
$('#tagmanager').tagmanager();
|
||||
var schedule_id = $('#schedule_id').val();
|
||||
$('#map-tags').tagmanager({
|
||||
strategy: 'array',
|
||||
tagFieldName: 'maps[]',
|
||||
initialCap: false
|
||||
});
|
||||
if (schedule_id > 0) {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/ajax_form.php",
|
||||
data: { type: "schedule-maintenance", sub_type: "parse-maintenance", schedule_id: schedule_id },
|
||||
dataType: "json",
|
||||
success: function(output) {
|
||||
var arr = [];
|
||||
$.each ( output['targets'], function( key, value ) {
|
||||
arr.push(value);
|
||||
});
|
||||
$('#map-tags').data('tagmanager').populate(arr);
|
||||
$('#title').val(output['title']);
|
||||
$('#notes').val(output['notes']);
|
||||
$('#start').val(output['start']);
|
||||
$('#end').val(output['end']);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$('#sched-submit').click('', function(e) {
|
||||
e.preventDefault();
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/ajax_form.php",
|
||||
data: $('form.schedule-maintenance-form').serialize(),
|
||||
dataType: "json",
|
||||
success: function(data){
|
||||
if(data.status == 'ok') {
|
||||
$("#message").html('<div class="alert alert-info">'+data.message+'</div>');
|
||||
$("#schedule-maintenance").modal('hide');
|
||||
$("#alert-schedule").bootgrid('reload');
|
||||
} else {
|
||||
$("#response").html('<div class="alert alert-info">'+data.message+'</div>');
|
||||
}
|
||||
},
|
||||
error: function(){
|
||||
$("#response").html('<div class="alert alert-info">An error occurred.</div>');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#add-map').click('',function (event) {
|
||||
$('#map-tags').data('tagmanager').populate([ $('#map-stub').val() ]);
|
||||
$('#map-stub').val('');
|
||||
});
|
||||
|
||||
$('#map-stub').typeahead([
|
||||
{
|
||||
name: 'map_devices',
|
||||
remote : '/ajax_search.php?search=%QUERY&type=device&map=1',
|
||||
header : '<h5><strong> Devices</strong></h5>',
|
||||
template: '{{name}}',
|
||||
valueKey:"name",
|
||||
engine: Hogan
|
||||
},
|
||||
{
|
||||
name: 'map_groups',
|
||||
remote : '/ajax_search.php?search=%QUERY&type=group&map=1',
|
||||
header : '<h5><strong> Groups</strong></h5>',
|
||||
template: '{{name}}',
|
||||
valueKey:"name",
|
||||
engine: Hogan
|
||||
}
|
||||
]);
|
||||
|
||||
$(function () {
|
||||
$("#start").datetimepicker({
|
||||
minDate: '<?php echo date('Y-m-d H:i'); ?>'
|
||||
});
|
||||
$("#end").datetimepicker();
|
||||
$("#start").on("dp.change", function (e) {
|
||||
$("#end").data("DateTimePicker").minDate(e.date);
|
||||
});
|
||||
$("#end").on("dp.change", function (e) {
|
||||
$("#start").data("DateTimePicker").maxDate(e.date);
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
<?php
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* LibreNMS
|
||||
*
|
||||
* Copyright (c) 2014 Neil Lathwood <https://github.com/laf/ http://www.lathwood.co.uk/fa>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version. Please see LICENSE.txt at the top level of
|
||||
* the source code distribution for details.
|
||||
*/
|
||||
|
||||
if(is_admin() !== false) {
|
||||
|
||||
?>
|
||||
|
||||
<div class="modal fade bs-example-modal-sm" id="delete-maintenance" tabindex="-1" role="dialog" aria-labelledby="delete" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h5 class="modal-title" id="Create">Delete maintenance</h5>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>If you would like to remove this maintenance then please click Delete.</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<form method="post" role="form" id="sched-del" class="form-horizontal schedule-maintenance-del">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
||||
<button type="submit" class="btn btn-danger danger" id="sched-maintenance-removal" data-target="sched-maintenance-removal">Delete</button>
|
||||
<input type="hidden" name="del_schedule_id" id="del_schedule_id">
|
||||
<input type="hidden" name="type" id="type" value="schedule-maintenance">
|
||||
<input type="hidden" name="sub_type" id="sub_type" value="del-maintenance">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$('#schedule-maintenance').on('hide.bs.modal', function (event) {
|
||||
$('#map-tags').data('tagmanager').empty();
|
||||
$('#schedule_id').val('');
|
||||
$('#title').val('');
|
||||
$('#notes').val('');
|
||||
$('#start').val('');
|
||||
$('#end').val('');
|
||||
});
|
||||
|
||||
$('#sched-maintenance-removal').click('', function(e) {
|
||||
e.preventDefault();
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/ajax_form.php",
|
||||
data: $('form.schedule-maintenance-del').serialize(),
|
||||
dataType: "json",
|
||||
success: function(data){
|
||||
if(data.status == 'ok') {
|
||||
$("#message").html('<div class="alert alert-info">'+data.message+'</div>');
|
||||
$("#delete-maintenance").modal('hide');
|
||||
$("#alert-schedule").bootgrid('reload');
|
||||
} else {
|
||||
$("#response").html('<div class="alert alert-info">'+data.message+'</div>');
|
||||
}
|
||||
},
|
||||
error: function(){
|
||||
$("#response").html('<div class="alert alert-info">An error occurred.</div>');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
<?php
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -62,6 +62,7 @@ if (isset($config['site_style']) && ($config['site_style'] == 'dark' || $config[
|
||||
if ($_SESSION['userlevel'] >= '10') {
|
||||
?>
|
||||
<li><a href="<?php echo(generate_url(array('page'=>'alert-rules'))); ?>"><i class="fa fa-tasks fa-fw fa-lg"></i> Alert Rules</a></li>
|
||||
<li><a href="<?php echo(generate_url(array('page'=>'alert-schedule'))); ?>"><i class="fa fa-calendar fa-fw fa-lg"></i> Maintenance Windows</a></li>
|
||||
<li><a href="<?php echo(generate_url(array('page'=>'alert-map'))); ?>"><i class="fa fa-link fa-fw fa-lg"></i> Alert Map</a></li>
|
||||
<li><a href="<?php echo(generate_url(array('page'=>'templates'))); ?>"><i class="fa fa-sitemap fa-fw fa-lg"></i> Alert Templates</a></li>
|
||||
<?php
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* LibreNMS
|
||||
*
|
||||
* Copyright (c) 2014 Neil Lathwood <https://github.com/laf/ http://www.lathwood.co.uk/fa>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version. Please see LICENSE.txt at the top level of
|
||||
* the source code distribution for details.
|
||||
*/
|
||||
|
||||
$where = 1;
|
||||
|
||||
if ($_SESSION['userlevel'] >= '5') {
|
||||
$sql = " FROM `alert_schedule` AS S WHERE $where";
|
||||
} else {
|
||||
$sql = " FROM `alert_schedule` AS S WHERE $where";
|
||||
$param[] = $_SESSION['user_id'];
|
||||
}
|
||||
|
||||
if (isset($searchPhrase) && !empty($searchPhrase)) {
|
||||
$sql .= " AND (`S`.`title` LIKE '%$searchPhrase%' OR `S`.`start` LIKE '%$searchPhrase%' OR `S`.`end` LIKE '%$searchPhrase%')";
|
||||
}
|
||||
|
||||
$count_sql = "SELECT COUNT(`id`) $sql";
|
||||
$total = dbFetchCell($count_sql,$param);
|
||||
if (empty($total)) {
|
||||
$total = 0;
|
||||
}
|
||||
|
||||
if (!isset($sort) || empty($sort)) {
|
||||
$sort = '`S`.`start` DESC ';
|
||||
}
|
||||
|
||||
$sql .= " ORDER BY $sort";
|
||||
|
||||
if (isset($current)) {
|
||||
$limit_low = ($current * $rowCount) - ($rowCount);
|
||||
$limit_high = $rowCount;
|
||||
}
|
||||
|
||||
if ($rowCount != -1) {
|
||||
$sql .= " LIMIT $limit_low,$limit_high";
|
||||
}
|
||||
|
||||
$sql = "SELECT `S`.`schedule_id`, DATE_FORMAT(`S`.`start`, '%D %b %Y %T') AS `start`, DATE_FORMAT(`S`.`end`, '%D %b %Y %T') AS `end`, `S`.`title` $sql";
|
||||
|
||||
foreach (dbFetchRows($sql,$param) as $schedule) {
|
||||
$status = 0;
|
||||
if ($schedule['end'] < date('dS M Y H:i::s')) {
|
||||
$status = 1;
|
||||
}
|
||||
if (date('dS M Y H:i::s') >= $schedule['start'] && date('dS M Y H:i::s') < $schedule['end']) {
|
||||
$status = 2;
|
||||
}
|
||||
$response[] = array('title'=>$schedule['title'],
|
||||
'start'=>$schedule['start'],
|
||||
'end'=>$schedule['end'],
|
||||
'id'=>$schedule['schedule_id'],
|
||||
'status'=>$status);
|
||||
}
|
||||
|
||||
$output = array('current'=>$current,'rowCount'=>$rowCount,'rows'=>$response,'total'=>$total);
|
||||
echo _json_encode($output);
|
||||
@@ -54,7 +54,6 @@
|
||||
"requireCamelCaseOrUpperCaseIdentifiers": "ignoreProperties",
|
||||
"disallowKeywords": ["with"],
|
||||
"disallowMultipleLineStrings": true,
|
||||
"validateLineBreaks": "LF",
|
||||
"validateIndentation": 4,
|
||||
"disallowTrailingWhitespace": true,
|
||||
"disallowTrailingComma": true,
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
Submitting Issues
|
||||
=================
|
||||
|
||||
If you are submitting a bug, please test and/or fork [this jsfiddle](http://jsfiddle.net/kmbo576p/) demonstrating the issue. Code issues and fringe case bugs that do not include a jsfiddle (or similar) will be closed.
|
||||
If you are submitting a bug, please test and/or fork [this jsfiddle](http://jsfiddle.net/Eonasdan/0Ltv25o8/) demonstrating the issue. Code issues and fringe case bugs that do not include a jsfiddle (or similar) will be closed.
|
||||
|
||||
Issues that are submitted without a description (title only) will be closed with no further explanation.
|
||||
|
||||
Contributing code
|
||||
=================
|
||||
@@ -22,6 +24,9 @@ Very important notes
|
||||
|
||||
* **Pull requests to the `master` branch will be closed.** Please submit all pull requests to the `development` branch.
|
||||
* **Do not include the minified files in your pull request.** Don't worry, we'll build them when we cut a release.
|
||||
* Pull requests that do not include a description (title only) and the following will be closed:
|
||||
* What the change does
|
||||
* A use case (for new features or enhancements)
|
||||
|
||||
Grunt tasks
|
||||
===========
|
||||
@@ -30,3 +35,4 @@ We use Grunt for managing the build. Here are some useful Grunt tasks:
|
||||
|
||||
* `grunt` The default task lints the code and runs the tests. You should make sure you do this before submitting a PR.
|
||||
* `grunt build` Compiles the less stylesheet and minifies the javascript source in build directory.
|
||||
* `grunt build:travis` Compliles and runs the jasmine/travis tests. **All PR's MUST pass tests in place**
|
||||
|
||||
@@ -24,11 +24,12 @@ module.exports = function (grunt) {
|
||||
|
||||
jshint: {
|
||||
all: [
|
||||
'Gruntfile.js', 'src/js/*.js'
|
||||
'Gruntfile.js', 'src/js/*.js', 'test/*.js'
|
||||
],
|
||||
options: {
|
||||
'browser' : true,
|
||||
'node' : true,
|
||||
'jquery' : true,
|
||||
'boss' : false,
|
||||
'curly' : true,
|
||||
'debug' : false,
|
||||
@@ -57,15 +58,24 @@ module.exports = function (grunt) {
|
||||
'quotmark' : 'single',
|
||||
'globals': {
|
||||
'define': false,
|
||||
'jQuery': false,
|
||||
'moment': false
|
||||
'moment': false,
|
||||
// Jasmine
|
||||
'jasmine': false,
|
||||
'describe': false,
|
||||
'xdescribe': false,
|
||||
'expect': false,
|
||||
'it': false,
|
||||
'xit': false,
|
||||
'spyOn': false,
|
||||
'beforeEach': false,
|
||||
'afterEach': false
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
jscs: {
|
||||
all: [
|
||||
'Gruntfile.js', 'src/js/*.js'
|
||||
'Gruntfile.js', 'src/js/*.js', 'test/*.js'
|
||||
],
|
||||
options: {
|
||||
config: '.jscs.json'
|
||||
@@ -86,22 +96,49 @@ module.exports = function (grunt) {
|
||||
'build/css/bootstrap-datetimepicker.css': 'src/less/bootstrap-datetimepicker-build.less'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
jasmine: {
|
||||
customTemplate: {
|
||||
src: 'src/js/*.js',
|
||||
options: {
|
||||
specs: 'test/*Spec.js',
|
||||
helpers: 'test/*Helper.js',
|
||||
styles: [
|
||||
'node_modules/bootstrap/dist/css/bootstrap.min.css',
|
||||
'build/css/bootstrap-datetimepicker.min.css'
|
||||
],
|
||||
vendor: [
|
||||
'node_modules/jquery/dist/jquery.min.js',
|
||||
'node_modules/moment/min/moment-with-locales.min.js',
|
||||
'node_modules/bootstrap/dist/js/bootstrap.min.js'
|
||||
],
|
||||
display: 'none',
|
||||
summary: 'true'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
grunt.loadTasks('tasks');
|
||||
|
||||
grunt.loadNpmTasks('grunt-contrib-jasmine');
|
||||
|
||||
// These plugins provide necessary tasks.
|
||||
require('load-grunt-tasks')(grunt);
|
||||
|
||||
// Default task.
|
||||
grunt.registerTask('default', ['jshint', 'jscs']);
|
||||
grunt.registerTask('default', ['jshint', 'jscs', 'less', 'jasmine']);
|
||||
|
||||
// travis build task
|
||||
grunt.registerTask('build:travis', [
|
||||
// code style
|
||||
'jshint', 'jscs'
|
||||
'jshint', 'jscs',
|
||||
// build
|
||||
'uglify', 'less',
|
||||
// tests
|
||||
'jasmine'
|
||||
]);
|
||||
|
||||
// Task to be run when building
|
||||
@@ -131,7 +168,7 @@ module.exports = function (grunt) {
|
||||
done();
|
||||
});
|
||||
}
|
||||
else {
|
||||
else { //--target=css
|
||||
grunt.util.spawn({
|
||||
cmd: 'src/nuget/nuget.exe',
|
||||
args: [
|
||||
@@ -152,4 +189,6 @@ module.exports = function (grunt) {
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
grunt.registerTask('test', ['jshint', 'jscs', 'uglify', 'less', 'jasmine']);
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Eonasdan, nikoskalogridis
|
||||
Copyright (c) 2015 Jonathan Peterson (@Eonasdan)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -1,17 +1,25 @@
|
||||
# Bootstrap v3 datetimepicker widget  
|
||||
# Bootstrap 3 Date/Time Picker
|
||||
 
|
||||
|
||||

|
||||
|
||||
## [View the manual and demos](http://eonasdan.github.io/bootstrap-datetimepicker/)
|
||||
|
||||
#v4
|
||||
v4 is out now! For v4 related bugs and issues see: /Eonasdan/bootstrap-datetimepicker/labels/v4.
|
||||
|
||||
v3 is going into an archive state. Please be sure to check the documents. v4 has breaking changes and is a major rewrite.
|
||||
|
||||
## Submitting Issues
|
||||
Please test and/or fork [this jsfiddle](http://jsfiddle.net/kmbo576p/) with an example of your issue before you post an issue here.
|
||||
If you have issues, please check the following first:
|
||||
* Have you read the docs?
|
||||
* Do you have the latest version of momentjs?
|
||||
* Do you have the latest version of jQuery?
|
||||
* Please test and/or fork [this jsfiddle](http://jsfiddle.net/Eonasdan/0Ltv25o8/) with an example of your issue before you post an issue here.
|
||||
|
||||
## Where do you use this?
|
||||
I'd love to know if your public site is using this plugin and list your logo on the documentation site. Please email me `eonasdan at outlook dot com`. Do not submit issue/feature request to this email, they will be ignored.
|
||||
I'd love to know if your public site is using this plugin and list your logo on the documentation site. Please email me `eonasdan at outlook dot com`. Do not submit issue/feature request to this email, they will be **ignored**.
|
||||
|
||||
## [Installation instructions](https://github.com/Eonasdan/bootstrap-datetimepicker/wiki/Installation)
|
||||
Installation instructions has been moved to the wiki
|
||||
## [Installation instructions](http://eonasdan.github.io/bootstrap-datetimepicker/Installing/)
|
||||
|
||||
## [Change Log](https://github.com/Eonasdan/bootstrap-datetimepicker/wiki/Change-Log)
|
||||
The change log has moved to the wiki
|
||||
## [Change Log](http://eonasdan.github.io/bootstrap-datetimepicker/Version%204%20Changelog/)
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
{
|
||||
"name": "eonasdan-bootstrap-datetimepicker",
|
||||
"version": "3.1.3",
|
||||
"version": "4.7.14",
|
||||
"main": [
|
||||
"build/css/bootstrap-datetimepicker.min.css",
|
||||
"build/js/bootstrap-datetimepicker.min.js"
|
||||
"build/js/bootstrap-datetimepicker.min.js",
|
||||
"src/less/_bootstrap-datetimepicker.less",
|
||||
"src/less/bootstrap-datetimepicker-build.less",
|
||||
"src/js/bootstrap-datetimepicker.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"jquery": ">=1.8.3",
|
||||
"bootstrap": ">= 3.0",
|
||||
"moment": ">=2.8.0"
|
||||
},
|
||||
"homepage": "https://github.com/Eonasdan/bootstrap-datetimepicker",
|
||||
|
||||
+245
-117
@@ -1,75 +1,76 @@
|
||||
/*!
|
||||
* Datetimepicker for Bootstrap v3
|
||||
//! version : 3.1.3
|
||||
* Datetimepicker for Bootstrap 3
|
||||
* ! version : 4.7.14
|
||||
* https://github.com/Eonasdan/bootstrap-datetimepicker/
|
||||
*/
|
||||
.bootstrap-datetimepicker-widget {
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 250px;
|
||||
list-style: none;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget.dropdown-menu {
|
||||
margin: 2px 0;
|
||||
padding: 4px;
|
||||
margin-top: 1px;
|
||||
z-index: 99999 !important;
|
||||
border-radius: 4px;
|
||||
width: 19em;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget.timepicker-sbs {
|
||||
width: 600px;
|
||||
@media (min-width: 768px) {
|
||||
.bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs {
|
||||
width: 38em;
|
||||
}
|
||||
}
|
||||
.bootstrap-datetimepicker-widget.bottom:before {
|
||||
@media (min-width: 992px) {
|
||||
.bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs {
|
||||
width: 38em;
|
||||
}
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
.bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs {
|
||||
width: 38em;
|
||||
}
|
||||
}
|
||||
.bootstrap-datetimepicker-widget.dropdown-menu:before,
|
||||
.bootstrap-datetimepicker-widget.dropdown-menu:after {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget.dropdown-menu.bottom:before {
|
||||
border-left: 7px solid transparent;
|
||||
border-right: 7px solid transparent;
|
||||
border-bottom: 7px solid #ccc;
|
||||
border-bottom: 7px solid #cccccc;
|
||||
border-bottom-color: rgba(0, 0, 0, 0.2);
|
||||
position: absolute;
|
||||
top: -7px;
|
||||
left: 7px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget.bottom:after {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
.bootstrap-datetimepicker-widget.dropdown-menu.bottom:after {
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-bottom: 6px solid white;
|
||||
position: absolute;
|
||||
top: -6px;
|
||||
left: 8px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget.top:before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
.bootstrap-datetimepicker-widget.dropdown-menu.top:before {
|
||||
border-left: 7px solid transparent;
|
||||
border-right: 7px solid transparent;
|
||||
border-top: 7px solid #ccc;
|
||||
border-top: 7px solid #cccccc;
|
||||
border-top-color: rgba(0, 0, 0, 0.2);
|
||||
position: absolute;
|
||||
bottom: -7px;
|
||||
left: 6px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget.top:after {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
.bootstrap-datetimepicker-widget.dropdown-menu.top:after {
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-top: 6px solid white;
|
||||
position: absolute;
|
||||
bottom: -6px;
|
||||
left: 7px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .dow {
|
||||
width: 14.2857%;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget.pull-right:before {
|
||||
.bootstrap-datetimepicker-widget.dropdown-menu.pull-right:before {
|
||||
left: auto;
|
||||
right: 6px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget.pull-right:after {
|
||||
.bootstrap-datetimepicker-widget.dropdown-menu.pull-right:after {
|
||||
left: auto;
|
||||
right: 7px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget > ul {
|
||||
list-style-type: none;
|
||||
.bootstrap-datetimepicker-widget .list-unstyled {
|
||||
margin: 0;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget a[data-action] {
|
||||
@@ -89,82 +90,238 @@
|
||||
.bootstrap-datetimepicker-widget button[data-action] {
|
||||
padding: 6px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table[data-hour-format="12"] .separator {
|
||||
width: 4px;
|
||||
.bootstrap-datetimepicker-widget .btn[data-action="incrementHours"]::after {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
content: "Increment Hours";
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .datepicker > div {
|
||||
display: none;
|
||||
.bootstrap-datetimepicker-widget .btn[data-action="incrementMinutes"]::after {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
content: "Increment Minutes";
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .btn[data-action="decrementHours"]::after {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
content: "Decrement Hours";
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .btn[data-action="decrementMinutes"]::after {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
content: "Decrement Minutes";
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .btn[data-action="showHours"]::after {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
content: "Show Hours";
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .btn[data-action="showMinutes"]::after {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
content: "Show Minutes";
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .btn[data-action="togglePeriod"]::after {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
content: "Toggle AM/PM";
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .btn[data-action="clear"]::after {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
content: "Clear the picker";
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .btn[data-action="today"]::after {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
content: "Set the date to today";
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .picker-switch {
|
||||
text-align: center;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .picker-switch::after {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
content: "Toggle Date and Time Screens";
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .picker-switch td {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
height: auto;
|
||||
width: auto;
|
||||
line-height: inherit;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .picker-switch td span {
|
||||
line-height: 2.5;
|
||||
height: 2.5em;
|
||||
width: 100%;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget td,
|
||||
.bootstrap-datetimepicker-widget th {
|
||||
.bootstrap-datetimepicker-widget table td,
|
||||
.bootstrap-datetimepicker-widget table th {
|
||||
text-align: center;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget td {
|
||||
height: 54px;
|
||||
line-height: 54px;
|
||||
width: 54px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget td.cw {
|
||||
font-size: 10px;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
color: #777777;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget td.day {
|
||||
.bootstrap-datetimepicker-widget table th {
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget td.day:hover,
|
||||
.bootstrap-datetimepicker-widget td.hour:hover,
|
||||
.bootstrap-datetimepicker-widget td.minute:hover,
|
||||
.bootstrap-datetimepicker-widget td.second:hover {
|
||||
.bootstrap-datetimepicker-widget table th.picker-switch {
|
||||
width: 145px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table th.disabled,
|
||||
.bootstrap-datetimepicker-widget table th.disabled:hover {
|
||||
background: none;
|
||||
color: #777777;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table th.prev::after {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
content: "Previous Month";
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table th.next::after {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
content: "Next Month";
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table thead tr:first-child th {
|
||||
cursor: pointer;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table thead tr:first-child th:hover {
|
||||
background: #eeeeee;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table td {
|
||||
height: 54px;
|
||||
line-height: 54px;
|
||||
width: 54px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table td.cw {
|
||||
font-size: .8em;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
color: #777777;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table td.day {
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table td.day:hover,
|
||||
.bootstrap-datetimepicker-widget table td.hour:hover,
|
||||
.bootstrap-datetimepicker-widget table td.minute:hover,
|
||||
.bootstrap-datetimepicker-widget table td.second:hover {
|
||||
background: #eeeeee;
|
||||
cursor: pointer;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget td.old,
|
||||
.bootstrap-datetimepicker-widget td.new {
|
||||
.bootstrap-datetimepicker-widget table td.old,
|
||||
.bootstrap-datetimepicker-widget table td.new {
|
||||
color: #777777;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget td.today {
|
||||
.bootstrap-datetimepicker-widget table td.today {
|
||||
position: relative;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget td.today:before {
|
||||
.bootstrap-datetimepicker-widget table td.today:before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
border-left: 7px solid transparent;
|
||||
border-bottom: 7px solid #428bca;
|
||||
border: 0 0 7px 7px solid transparent;
|
||||
border-bottom-color: #337ab7;
|
||||
border-top-color: rgba(0, 0, 0, 0.2);
|
||||
position: absolute;
|
||||
bottom: 4px;
|
||||
right: 4px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget td.active,
|
||||
.bootstrap-datetimepicker-widget td.active:hover {
|
||||
background-color: #428bca;
|
||||
.bootstrap-datetimepicker-widget table td.active,
|
||||
.bootstrap-datetimepicker-widget table td.active:hover {
|
||||
background-color: #337ab7;
|
||||
color: #ffffff;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
.bootstrap-datetimepicker-widget td.active.today:before {
|
||||
.bootstrap-datetimepicker-widget table td.active.today:before {
|
||||
border-bottom-color: #fff;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget td.disabled,
|
||||
.bootstrap-datetimepicker-widget td.disabled:hover {
|
||||
.bootstrap-datetimepicker-widget table td.disabled,
|
||||
.bootstrap-datetimepicker-widget table td.disabled:hover {
|
||||
background: none;
|
||||
color: #777777;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget td span {
|
||||
.bootstrap-datetimepicker-widget table td span {
|
||||
display: inline-block;
|
||||
width: 54px;
|
||||
height: 54px;
|
||||
@@ -173,66 +330,37 @@
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget td span:hover {
|
||||
.bootstrap-datetimepicker-widget table td span:hover {
|
||||
background: #eeeeee;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget td span.active {
|
||||
background-color: #428bca;
|
||||
.bootstrap-datetimepicker-widget table td span.active {
|
||||
background-color: #337ab7;
|
||||
color: #ffffff;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
.bootstrap-datetimepicker-widget td span.old {
|
||||
.bootstrap-datetimepicker-widget table td span.old {
|
||||
color: #777777;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget td span.disabled,
|
||||
.bootstrap-datetimepicker-widget td span.disabled:hover {
|
||||
.bootstrap-datetimepicker-widget table td span.disabled,
|
||||
.bootstrap-datetimepicker-widget table td span.disabled:hover {
|
||||
background: none;
|
||||
color: #777777;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget th {
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
width: 20px;
|
||||
.bootstrap-datetimepicker-widget.usetwentyfour td.hour {
|
||||
height: 27px;
|
||||
line-height: 27px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget th.picker-switch {
|
||||
width: 145px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget th.next,
|
||||
.bootstrap-datetimepicker-widget th.prev {
|
||||
font-size: 21px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget th.disabled,
|
||||
.bootstrap-datetimepicker-widget th.disabled:hover {
|
||||
background: none;
|
||||
color: #777777;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget thead tr:first-child th {
|
||||
.input-group.date .input-group-addon {
|
||||
cursor: pointer;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget thead tr:first-child th:hover {
|
||||
background: #eeeeee;
|
||||
}
|
||||
.input-group.date .input-group-addon span {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget.left-oriented:before {
|
||||
left: auto;
|
||||
right: 6px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget.left-oriented:after {
|
||||
left: auto;
|
||||
right: 7px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget ul.list-unstyled li div.timepicker div.timepicker-picker table.table-condensed tbody > tr > td {
|
||||
padding: 0px !important;
|
||||
}
|
||||
@media screen and (max-width: 767px) {
|
||||
.bootstrap-datetimepicker-widget.timepicker-sbs {
|
||||
width: 283px;
|
||||
}
|
||||
.sr-only {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
}
|
||||
|
||||
+364
-3
@@ -1,5 +1,366 @@
|
||||
/*!
|
||||
* Datetimepicker for Bootstrap v3
|
||||
//! version : 3.1.3
|
||||
* Datetimepicker for Bootstrap 3
|
||||
* ! version : 4.7.14
|
||||
* https://github.com/Eonasdan/bootstrap-datetimepicker/
|
||||
*/.bootstrap-datetimepicker-widget{top:0;left:0;width:250px;padding:4px;margin-top:1px;z-index:99999!important;border-radius:4px}.bootstrap-datetimepicker-widget.timepicker-sbs{width:600px}.bootstrap-datetimepicker-widget.bottom:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-bottom-color:rgba(0,0,0,.2);position:absolute;top:-7px;left:7px}.bootstrap-datetimepicker-widget.bottom:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #fff;position:absolute;top:-6px;left:8px}.bootstrap-datetimepicker-widget.top:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-top:7px solid #ccc;border-top-color:rgba(0,0,0,.2);position:absolute;bottom:-7px;left:6px}.bootstrap-datetimepicker-widget.top:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-top:6px solid #fff;position:absolute;bottom:-6px;left:7px}.bootstrap-datetimepicker-widget .dow{width:14.2857%}.bootstrap-datetimepicker-widget.pull-right:before{left:auto;right:6px}.bootstrap-datetimepicker-widget.pull-right:after{left:auto;right:7px}.bootstrap-datetimepicker-widget>ul{list-style-type:none;margin:0}.bootstrap-datetimepicker-widget a[data-action]{padding:6px 0}.bootstrap-datetimepicker-widget a[data-action]:active{box-shadow:none}.bootstrap-datetimepicker-widget .timepicker-hour,.bootstrap-datetimepicker-widget .timepicker-minute,.bootstrap-datetimepicker-widget .timepicker-second{width:54px;font-weight:700;font-size:1.2em;margin:0}.bootstrap-datetimepicker-widget button[data-action]{padding:6px}.bootstrap-datetimepicker-widget table[data-hour-format="12"] .separator{width:4px;padding:0;margin:0}.bootstrap-datetimepicker-widget .datepicker>div{display:none}.bootstrap-datetimepicker-widget .picker-switch{text-align:center}.bootstrap-datetimepicker-widget table{width:100%;margin:0}.bootstrap-datetimepicker-widget td,.bootstrap-datetimepicker-widget th{text-align:center;border-radius:4px}.bootstrap-datetimepicker-widget td{height:54px;line-height:54px;width:54px}.bootstrap-datetimepicker-widget td.cw{font-size:10px;height:20px;line-height:20px;color:#777}.bootstrap-datetimepicker-widget td.day{height:20px;line-height:20px;width:20px}.bootstrap-datetimepicker-widget td.day:hover,.bootstrap-datetimepicker-widget td.hour:hover,.bootstrap-datetimepicker-widget td.minute:hover,.bootstrap-datetimepicker-widget td.second:hover{background:#eee;cursor:pointer}.bootstrap-datetimepicker-widget td.old,.bootstrap-datetimepicker-widget td.new{color:#777}.bootstrap-datetimepicker-widget td.today{position:relative}.bootstrap-datetimepicker-widget td.today:before{content:'';display:inline-block;border-left:7px solid transparent;border-bottom:7px solid #428bca;border-top-color:rgba(0,0,0,.2);position:absolute;bottom:4px;right:4px}.bootstrap-datetimepicker-widget td.active,.bootstrap-datetimepicker-widget td.active:hover{background-color:#428bca;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,.25)}.bootstrap-datetimepicker-widget td.active.today:before{border-bottom-color:#fff}.bootstrap-datetimepicker-widget td.disabled,.bootstrap-datetimepicker-widget td.disabled:hover{background:0 0;color:#777;cursor:not-allowed}.bootstrap-datetimepicker-widget td span{display:inline-block;width:54px;height:54px;line-height:54px;margin:2px 1.5px;cursor:pointer;border-radius:4px}.bootstrap-datetimepicker-widget td span:hover{background:#eee}.bootstrap-datetimepicker-widget td span.active{background-color:#428bca;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,.25)}.bootstrap-datetimepicker-widget td span.old{color:#777}.bootstrap-datetimepicker-widget td span.disabled,.bootstrap-datetimepicker-widget td span.disabled:hover{background:0 0;color:#777;cursor:not-allowed}.bootstrap-datetimepicker-widget th{height:20px;line-height:20px;width:20px}.bootstrap-datetimepicker-widget th.picker-switch{width:145px}.bootstrap-datetimepicker-widget th.next,.bootstrap-datetimepicker-widget th.prev{font-size:21px}.bootstrap-datetimepicker-widget th.disabled,.bootstrap-datetimepicker-widget th.disabled:hover{background:0 0;color:#777;cursor:not-allowed}.bootstrap-datetimepicker-widget thead tr:first-child th{cursor:pointer}.bootstrap-datetimepicker-widget thead tr:first-child th:hover{background:#eee}.input-group.date .input-group-addon span{display:block;cursor:pointer;width:16px;height:16px}.bootstrap-datetimepicker-widget.left-oriented:before{left:auto;right:6px}.bootstrap-datetimepicker-widget.left-oriented:after{left:auto;right:7px}.bootstrap-datetimepicker-widget ul.list-unstyled li div.timepicker div.timepicker-picker table.table-condensed tbody>tr>td{padding:0!important}@media screen and (max-width:767px){.bootstrap-datetimepicker-widget.timepicker-sbs{width:283px}}
|
||||
*/
|
||||
.bootstrap-datetimepicker-widget {
|
||||
list-style: none;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget.dropdown-menu {
|
||||
margin: 2px 0;
|
||||
padding: 4px;
|
||||
width: 19em;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
.bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs {
|
||||
width: 38em;
|
||||
}
|
||||
}
|
||||
@media (min-width: 992px) {
|
||||
.bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs {
|
||||
width: 38em;
|
||||
}
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
.bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs {
|
||||
width: 38em;
|
||||
}
|
||||
}
|
||||
.bootstrap-datetimepicker-widget.dropdown-menu:before,
|
||||
.bootstrap-datetimepicker-widget.dropdown-menu:after {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget.dropdown-menu.bottom:before {
|
||||
border-left: 7px solid transparent;
|
||||
border-right: 7px solid transparent;
|
||||
border-bottom: 7px solid #cccccc;
|
||||
border-bottom-color: rgba(0, 0, 0, 0.2);
|
||||
top: -7px;
|
||||
left: 7px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget.dropdown-menu.bottom:after {
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-bottom: 6px solid white;
|
||||
top: -6px;
|
||||
left: 8px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget.dropdown-menu.top:before {
|
||||
border-left: 7px solid transparent;
|
||||
border-right: 7px solid transparent;
|
||||
border-top: 7px solid #cccccc;
|
||||
border-top-color: rgba(0, 0, 0, 0.2);
|
||||
bottom: -7px;
|
||||
left: 6px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget.dropdown-menu.top:after {
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-top: 6px solid white;
|
||||
bottom: -6px;
|
||||
left: 7px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget.dropdown-menu.pull-right:before {
|
||||
left: auto;
|
||||
right: 6px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget.dropdown-menu.pull-right:after {
|
||||
left: auto;
|
||||
right: 7px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .list-unstyled {
|
||||
margin: 0;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget a[data-action] {
|
||||
padding: 6px 0;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget a[data-action]:active {
|
||||
box-shadow: none;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .timepicker-hour,
|
||||
.bootstrap-datetimepicker-widget .timepicker-minute,
|
||||
.bootstrap-datetimepicker-widget .timepicker-second {
|
||||
width: 54px;
|
||||
font-weight: bold;
|
||||
font-size: 1.2em;
|
||||
margin: 0;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget button[data-action] {
|
||||
padding: 6px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .btn[data-action="incrementHours"]::after {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
content: "Increment Hours";
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .btn[data-action="incrementMinutes"]::after {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
content: "Increment Minutes";
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .btn[data-action="decrementHours"]::after {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
content: "Decrement Hours";
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .btn[data-action="decrementMinutes"]::after {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
content: "Decrement Minutes";
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .btn[data-action="showHours"]::after {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
content: "Show Hours";
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .btn[data-action="showMinutes"]::after {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
content: "Show Minutes";
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .btn[data-action="togglePeriod"]::after {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
content: "Toggle AM/PM";
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .btn[data-action="clear"]::after {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
content: "Clear the picker";
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .btn[data-action="today"]::after {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
content: "Set the date to today";
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .picker-switch {
|
||||
text-align: center;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .picker-switch::after {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
content: "Toggle Date and Time Screens";
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .picker-switch td {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
height: auto;
|
||||
width: auto;
|
||||
line-height: inherit;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget .picker-switch td span {
|
||||
line-height: 2.5;
|
||||
height: 2.5em;
|
||||
width: 100%;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table td,
|
||||
.bootstrap-datetimepicker-widget table th {
|
||||
text-align: center;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table th {
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table th.picker-switch {
|
||||
width: 145px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table th.disabled,
|
||||
.bootstrap-datetimepicker-widget table th.disabled:hover {
|
||||
background: none;
|
||||
color: #777777;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table th.prev::after {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
content: "Previous Month";
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table th.next::after {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
content: "Next Month";
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table thead tr:first-child th {
|
||||
cursor: pointer;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table thead tr:first-child th:hover {
|
||||
background: #eeeeee;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table td {
|
||||
height: 54px;
|
||||
line-height: 54px;
|
||||
width: 54px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table td.cw {
|
||||
font-size: .8em;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
color: #777777;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table td.day {
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table td.day:hover,
|
||||
.bootstrap-datetimepicker-widget table td.hour:hover,
|
||||
.bootstrap-datetimepicker-widget table td.minute:hover,
|
||||
.bootstrap-datetimepicker-widget table td.second:hover {
|
||||
background: #eeeeee;
|
||||
cursor: pointer;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table td.old,
|
||||
.bootstrap-datetimepicker-widget table td.new {
|
||||
color: #777777;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table td.today {
|
||||
position: relative;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table td.today:before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
border: 0 0 7px 7px solid transparent;
|
||||
border-bottom-color: #337ab7;
|
||||
border-top-color: rgba(0, 0, 0, 0.2);
|
||||
position: absolute;
|
||||
bottom: 4px;
|
||||
right: 4px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table td.active,
|
||||
.bootstrap-datetimepicker-widget table td.active:hover {
|
||||
background-color: #337ab7;
|
||||
color: #ffffff;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table td.active.today:before {
|
||||
border-bottom-color: #fff;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table td.disabled,
|
||||
.bootstrap-datetimepicker-widget table td.disabled:hover {
|
||||
background: none;
|
||||
color: #777777;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table td span {
|
||||
display: inline-block;
|
||||
width: 54px;
|
||||
height: 54px;
|
||||
line-height: 54px;
|
||||
margin: 2px 1.5px;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table td span:hover {
|
||||
background: #eeeeee;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table td span.active {
|
||||
background-color: #337ab7;
|
||||
color: #ffffff;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table td span.old {
|
||||
color: #777777;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget table td span.disabled,
|
||||
.bootstrap-datetimepicker-widget table td span.disabled:hover {
|
||||
background: none;
|
||||
color: #777777;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.bootstrap-datetimepicker-widget.usetwentyfour td.hour {
|
||||
height: 27px;
|
||||
line-height: 27px;
|
||||
}
|
||||
.input-group.date .input-group-addon {
|
||||
cursor: pointer;
|
||||
}
|
||||
.sr-only {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
@@ -1,10 +1,9 @@
|
||||
{
|
||||
"name": "bootstrap-datetimepicker",
|
||||
"version": "3.1.3",
|
||||
"main": ["build/css/bootstrap-datetimepicker.min.css","build/js/bootstrap-datetimepicker.min.js"],
|
||||
"version": "4.7.14",
|
||||
"main": ["build/css/bootstrap-datetimepicker.min.css","build/js/bootstrap-datetimepicker.min.js","src/less/_bootstrap-datetimepicker.less","src/less/bootstrap-datetimepicker-build.less","src/js/bootstrap-datetimepicker.js"],
|
||||
"dependencies": {
|
||||
"jquery" : ">=1.8.3",
|
||||
"bootstrap" : ">=3.0",
|
||||
"moment": ">=2.8.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "eonasdan/bootstrap-datetimepicker",
|
||||
"type": "component",
|
||||
"version": "3.1.3",
|
||||
"version": "4.7.14",
|
||||
"description": "Date/time picker widget based on twitter bootstrap",
|
||||
"keywords": [
|
||||
"bootstrap",
|
||||
@@ -12,7 +12,6 @@
|
||||
"require": {
|
||||
"robloach/component-installer": "*",
|
||||
"components/jquery": ">=1.9.1",
|
||||
"components/bootstrap": "3.*",
|
||||
"moment/moment": ">=2.8"
|
||||
},
|
||||
"extra": {
|
||||
@@ -23,7 +22,9 @@
|
||||
"files": [
|
||||
"build/js/bootstrap-datetimepicker.min.js",
|
||||
"build/css/bootstrap-datetimepicker.css",
|
||||
"build/css/bootstrap-datetimepicker.min.css"
|
||||
"build/css/bootstrap-datetimepicker.min.css",
|
||||
"src/less/_bootstrap-datetimepicker.less",
|
||||
"src/less/bootstrap-datetimepicker-build.less"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "bootstrap-datetimepicker",
|
||||
"main": "src/js/bootstrap-datetimepicker.js",
|
||||
"version": "3.1.3",
|
||||
"version": "4.7.14",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/eonasdan/bootstrap-datetimepicker.git"
|
||||
@@ -15,21 +15,21 @@
|
||||
"datepicker",
|
||||
"datetimepicker",
|
||||
"timepicker",
|
||||
"moment"
|
||||
"moment"
|
||||
],
|
||||
"dependencies": {
|
||||
"moment": "~2.8.1",
|
||||
"bootstrap": "^3.0",
|
||||
"jquery": "^1.8.3"
|
||||
"moment": "~2.8.2",
|
||||
"bootstrap": "^3.0",
|
||||
"jquery": "latest"
|
||||
},
|
||||
"devDependencies": {
|
||||
"grunt": "latest",
|
||||
"grunt-contrib-jasmine": "^0.7.0",
|
||||
"grunt-contrib-jshint": "latest",
|
||||
"grunt-contrib-less": "latest",
|
||||
"grunt-contrib-uglify": "latest",
|
||||
"grunt-jscs": "latest",
|
||||
"load-grunt-tasks": "latest",
|
||||
"grunt-string-replace": "latest",
|
||||
"grunt-contrib-less": "latest",
|
||||
"bootstrap": "latest"
|
||||
"load-grunt-tasks": "latest"
|
||||
}
|
||||
}
|
||||
|
||||
+1874
-1207
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,343 @@
|
||||
/*!
|
||||
* Datetimepicker for Bootstrap 3
|
||||
* ! version : 4.7.14
|
||||
* https://github.com/Eonasdan/bootstrap-datetimepicker/
|
||||
*/
|
||||
@bs-datetimepicker-timepicker-font-size: 1.2em;
|
||||
@bs-datetimepicker-active-bg: @btn-primary-bg;
|
||||
@bs-datetimepicker-active-color: @btn-primary-color;
|
||||
@bs-datetimepicker-border-radius: @border-radius-base;
|
||||
@bs-datetimepicker-btn-hover-bg: @gray-lighter;
|
||||
@bs-datetimepicker-disabled-color: @gray-light;
|
||||
@bs-datetimepicker-alternate-color: @gray-light;
|
||||
@bs-datetimepicker-secondary-border-color: #ccc;
|
||||
@bs-datetimepicker-secondary-border-color-rgba: rgba(0, 0, 0, 0.2);
|
||||
@bs-datetimepicker-primary-border-color: white;
|
||||
@bs-datetimepicker-text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||
|
||||
.bootstrap-datetimepicker-widget {
|
||||
list-style: none;
|
||||
|
||||
&.dropdown-menu {
|
||||
margin: 2px 0;
|
||||
padding: 4px;
|
||||
width: 19em;
|
||||
|
||||
&.timepicker-sbs {
|
||||
@media (min-width: @screen-sm-min) {
|
||||
width: 38em;
|
||||
}
|
||||
|
||||
@media (min-width: @screen-md-min) {
|
||||
width: 38em;
|
||||
}
|
||||
|
||||
@media (min-width: @screen-lg-min) {
|
||||
width: 38em;
|
||||
}
|
||||
}
|
||||
|
||||
&:before, &:after {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
&.bottom {
|
||||
&:before {
|
||||
border-left: 7px solid transparent;
|
||||
border-right: 7px solid transparent;
|
||||
border-bottom: 7px solid @bs-datetimepicker-secondary-border-color;
|
||||
border-bottom-color: @bs-datetimepicker-secondary-border-color-rgba;
|
||||
top: -7px;
|
||||
left: 7px;
|
||||
}
|
||||
|
||||
&:after {
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-bottom: 6px solid @bs-datetimepicker-primary-border-color;
|
||||
top: -6px;
|
||||
left: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
&.top {
|
||||
&:before {
|
||||
border-left: 7px solid transparent;
|
||||
border-right: 7px solid transparent;
|
||||
border-top: 7px solid @bs-datetimepicker-secondary-border-color;
|
||||
border-top-color: @bs-datetimepicker-secondary-border-color-rgba;
|
||||
bottom: -7px;
|
||||
left: 6px;
|
||||
}
|
||||
|
||||
&:after {
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-top: 6px solid @bs-datetimepicker-primary-border-color;
|
||||
bottom: -6px;
|
||||
left: 7px;
|
||||
}
|
||||
}
|
||||
|
||||
&.pull-right {
|
||||
&:before {
|
||||
left: auto;
|
||||
right: 6px;
|
||||
}
|
||||
|
||||
&:after {
|
||||
left: auto;
|
||||
right: 7px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.list-unstyled {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
a[data-action] {
|
||||
padding: 6px 0;
|
||||
}
|
||||
|
||||
a[data-action]:active {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.timepicker-hour, .timepicker-minute, .timepicker-second {
|
||||
width: 54px;
|
||||
font-weight: bold;
|
||||
font-size: @bs-datetimepicker-timepicker-font-size;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
button[data-action] {
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
.btn[data-action="incrementHours"]::after {
|
||||
.sr-only();
|
||||
content: "Increment Hours";
|
||||
}
|
||||
|
||||
.btn[data-action="incrementMinutes"]::after {
|
||||
.sr-only();
|
||||
content: "Increment Minutes";
|
||||
}
|
||||
|
||||
.btn[data-action="decrementHours"]::after {
|
||||
.sr-only();
|
||||
content: "Decrement Hours";
|
||||
}
|
||||
|
||||
.btn[data-action="decrementMinutes"]::after {
|
||||
.sr-only();
|
||||
content: "Decrement Minutes";
|
||||
}
|
||||
|
||||
.btn[data-action="showHours"]::after {
|
||||
.sr-only();
|
||||
content: "Show Hours";
|
||||
}
|
||||
|
||||
.btn[data-action="showMinutes"]::after {
|
||||
.sr-only();
|
||||
content: "Show Minutes";
|
||||
}
|
||||
|
||||
.btn[data-action="togglePeriod"]::after {
|
||||
.sr-only();
|
||||
content: "Toggle AM/PM";
|
||||
}
|
||||
|
||||
.btn[data-action="clear"]::after {
|
||||
.sr-only();
|
||||
content: "Clear the picker";
|
||||
}
|
||||
|
||||
.btn[data-action="today"]::after {
|
||||
.sr-only();
|
||||
content: "Set the date to today";
|
||||
}
|
||||
|
||||
.picker-switch {
|
||||
text-align: center;
|
||||
|
||||
&::after {
|
||||
.sr-only();
|
||||
content: "Toggle Date and Time Screens";
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
height: auto;
|
||||
width: auto;
|
||||
line-height: inherit;
|
||||
|
||||
span {
|
||||
line-height: 2.5;
|
||||
height: 2.5em;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
|
||||
|
||||
& td,
|
||||
& th {
|
||||
text-align: center;
|
||||
border-radius: @bs-datetimepicker-border-radius;
|
||||
}
|
||||
|
||||
& th {
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
width: 20px;
|
||||
|
||||
&.picker-switch {
|
||||
width: 145px;
|
||||
}
|
||||
|
||||
&.disabled,
|
||||
&.disabled:hover {
|
||||
background: none;
|
||||
color: @bs-datetimepicker-disabled-color;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
&.prev::after {
|
||||
.sr-only();
|
||||
content: "Previous Month";
|
||||
}
|
||||
|
||||
&.next::after {
|
||||
.sr-only();
|
||||
content: "Next Month";
|
||||
}
|
||||
}
|
||||
|
||||
& thead tr:first-child th {
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background: @bs-datetimepicker-btn-hover-bg;
|
||||
}
|
||||
}
|
||||
|
||||
& td {
|
||||
height: 54px;
|
||||
line-height: 54px;
|
||||
width: 54px;
|
||||
|
||||
&.cw {
|
||||
font-size: .8em;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
color: @bs-datetimepicker-alternate-color;
|
||||
}
|
||||
|
||||
&.day {
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
&.day:hover,
|
||||
&.hour:hover,
|
||||
&.minute:hover,
|
||||
&.second:hover {
|
||||
background: @bs-datetimepicker-btn-hover-bg;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&.old,
|
||||
&.new {
|
||||
color: @bs-datetimepicker-alternate-color;
|
||||
}
|
||||
|
||||
&.today {
|
||||
position: relative;
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
border: 0 0 7px 7px solid transparent;
|
||||
border-bottom-color: @bs-datetimepicker-active-bg;
|
||||
border-top-color: @bs-datetimepicker-secondary-border-color-rgba;
|
||||
position: absolute;
|
||||
bottom: 4px;
|
||||
right: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
&.active,
|
||||
&.active:hover {
|
||||
background-color: @bs-datetimepicker-active-bg;
|
||||
color: @bs-datetimepicker-active-color;
|
||||
text-shadow: @bs-datetimepicker-text-shadow;
|
||||
}
|
||||
|
||||
&.active.today:before {
|
||||
border-bottom-color: #fff;
|
||||
}
|
||||
|
||||
&.disabled,
|
||||
&.disabled:hover {
|
||||
background: none;
|
||||
color: @bs-datetimepicker-disabled-color;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
span {
|
||||
display: inline-block;
|
||||
width: 54px;
|
||||
height: 54px;
|
||||
line-height: 54px;
|
||||
margin: 2px 1.5px;
|
||||
cursor: pointer;
|
||||
border-radius: @bs-datetimepicker-border-radius;
|
||||
|
||||
&:hover {
|
||||
background: @bs-datetimepicker-btn-hover-bg;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: @bs-datetimepicker-active-bg;
|
||||
color: @bs-datetimepicker-active-color;
|
||||
text-shadow: @bs-datetimepicker-text-shadow;
|
||||
}
|
||||
|
||||
&.old {
|
||||
color: @bs-datetimepicker-alternate-color;
|
||||
}
|
||||
|
||||
&.disabled,
|
||||
&.disabled:hover {
|
||||
background: none;
|
||||
color: @bs-datetimepicker-disabled-color;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.usetwentyfour {
|
||||
td.hour {
|
||||
height: 27px;
|
||||
line-height: 27px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.input-group.date {
|
||||
& .input-group-addon {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,17 @@
|
||||
// Import boostrap variables including default color palette and fonts
|
||||
// Import bootstrap variables including default color palette and fonts
|
||||
@import "../../node_modules/bootstrap/less/variables.less";
|
||||
|
||||
// Import datepicker component
|
||||
@import "bootstrap-datetimepicker.less";
|
||||
@import "_bootstrap-datetimepicker.less";
|
||||
|
||||
|
||||
.sr-only {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0,0,0,0);
|
||||
border: 0;
|
||||
}
|
||||
|
||||
@@ -1,294 +0,0 @@
|
||||
/*!
|
||||
* Datetimepicker for Bootstrap v3
|
||||
//! version : 3.1.3
|
||||
* https://github.com/Eonasdan/bootstrap-datetimepicker/
|
||||
*/
|
||||
.bootstrap-datetimepicker-widget {
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 250px;
|
||||
padding: 4px;
|
||||
margin-top: 1px;
|
||||
z-index: 99999 !important;
|
||||
border-radius: @border-radius-base;
|
||||
|
||||
&.timepicker-sbs {
|
||||
width: 600px;
|
||||
}
|
||||
|
||||
&.bottom {
|
||||
&:before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
border-left: 7px solid transparent;
|
||||
border-right: 7px solid transparent;
|
||||
border-bottom: 7px solid #ccc;
|
||||
border-bottom-color: rgba(0,0,0,.2);
|
||||
position: absolute;
|
||||
top: -7px;
|
||||
left: 7px;
|
||||
}
|
||||
|
||||
&:after {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-bottom: 6px solid white;
|
||||
position: absolute;
|
||||
top: -6px;
|
||||
left: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
&.top {
|
||||
&:before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
border-left: 7px solid transparent;
|
||||
border-right: 7px solid transparent;
|
||||
border-top: 7px solid #ccc;
|
||||
border-top-color: rgba(0,0,0,.2);
|
||||
position: absolute;
|
||||
bottom: -7px;
|
||||
left: 6px;
|
||||
}
|
||||
|
||||
&:after {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-top: 6px solid white;
|
||||
position: absolute;
|
||||
bottom: -6px;
|
||||
left: 7px;
|
||||
}
|
||||
}
|
||||
|
||||
& .dow {
|
||||
width: 14.2857%;
|
||||
}
|
||||
|
||||
&.pull-right {
|
||||
&:before {
|
||||
left: auto;
|
||||
right: 6px;
|
||||
}
|
||||
|
||||
&:after {
|
||||
left: auto;
|
||||
right: 7px;
|
||||
}
|
||||
}
|
||||
|
||||
>ul {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
a[data-action] {
|
||||
padding: 6px 0;
|
||||
}
|
||||
|
||||
a[data-action]:active {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.timepicker-hour, .timepicker-minute, .timepicker-second {
|
||||
width: 54px;
|
||||
font-weight: bold;
|
||||
font-size: 1.2em;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
button[data-action] {
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
table[data-hour-format="12"] .separator {
|
||||
width: 4px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.datepicker > div {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.picker-switch {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
td,
|
||||
th {
|
||||
text-align: center;
|
||||
border-radius: @border-radius-base;
|
||||
}
|
||||
|
||||
td {
|
||||
height: 54px;
|
||||
line-height: 54px;
|
||||
width: 54px;
|
||||
|
||||
&.cw
|
||||
{
|
||||
font-size: 10px;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
color: @gray-light;
|
||||
}
|
||||
|
||||
&.day
|
||||
{
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
&.day:hover,
|
||||
&.hour:hover,
|
||||
&.minute:hover,
|
||||
&.second:hover {
|
||||
background: @gray-lighter;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&.old,
|
||||
&.new {
|
||||
color: @gray-light;
|
||||
}
|
||||
|
||||
&.today {
|
||||
position: relative;
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
border-left: 7px solid transparent;
|
||||
border-bottom: 7px solid @btn-primary-bg;
|
||||
border-top-color: rgba(0, 0, 0, 0.2);
|
||||
position: absolute;
|
||||
bottom: 4px;
|
||||
right: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
&.active,
|
||||
&.active:hover {
|
||||
background-color: @btn-primary-bg;
|
||||
color: @btn-primary-color;
|
||||
text-shadow: 0 -1px 0 rgba(0,0,0,.25);
|
||||
}
|
||||
|
||||
&.active.today:before {
|
||||
border-bottom-color: #fff;
|
||||
}
|
||||
|
||||
&.disabled,
|
||||
&.disabled:hover {
|
||||
background: none;
|
||||
color: @gray-light;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
span {
|
||||
display: inline-block;
|
||||
width: 54px;
|
||||
height: 54px;
|
||||
line-height: 54px;
|
||||
margin: 2px 1.5px;
|
||||
cursor: pointer;
|
||||
border-radius: @border-radius-base;
|
||||
|
||||
&:hover {
|
||||
background: @gray-lighter;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: @btn-primary-bg;
|
||||
color: @btn-primary-color;
|
||||
text-shadow: 0 -1px 0 rgba(0,0,0,.25);
|
||||
}
|
||||
|
||||
&.old {
|
||||
color: @gray-light;
|
||||
}
|
||||
|
||||
&.disabled,
|
||||
&.disabled:hover {
|
||||
background: none;
|
||||
color: @gray-light;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
th {
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
width: 20px;
|
||||
|
||||
&.picker-switch {
|
||||
width: 145px;
|
||||
}
|
||||
|
||||
&.next,
|
||||
&.prev {
|
||||
font-size: @font-size-base * 1.5;
|
||||
}
|
||||
|
||||
&.disabled,
|
||||
&.disabled:hover {
|
||||
background: none;
|
||||
color: @gray-light;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
thead tr:first-child th {
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background: @gray-lighter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.input-group {
|
||||
&.date {
|
||||
.input-group-addon span {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bootstrap-datetimepicker-widget.left-oriented {
|
||||
&:before {
|
||||
left: auto;
|
||||
right: 6px;
|
||||
}
|
||||
|
||||
&:after {
|
||||
left: auto;
|
||||
right: 7px;
|
||||
}
|
||||
}
|
||||
|
||||
.bootstrap-datetimepicker-widget ul.list-unstyled li div.timepicker div.timepicker-picker table.table-condensed tbody > tr > td {
|
||||
padding: 0px !important;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 767px) {
|
||||
.bootstrap-datetimepicker-widget.timepicker-sbs {
|
||||
width: 283px;
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Bootstrap.v3.Datetimepicker.CSS</id>
|
||||
<version>3.1.2</version>
|
||||
<version>4.0.0</version>
|
||||
<title>Bootstrap 3 Datetimepicker CSS</title>
|
||||
<authors>Eonasdan</authors>
|
||||
<owners>Eonasdan</owners>
|
||||
@@ -12,12 +12,12 @@
|
||||
|
||||
For usage, installation and demos see Project Site on GitHub
|
||||
|
||||
For CSS version install Bootstrap.v3.Datetimepicker.CSS</description>
|
||||
For LESS version install Bootstrap.v3.Datetimepicker</description>
|
||||
<releaseNotes>Check the change log on Github at https://github.com/Eonasdan/bootstrap-datetimepicker/wiki/Change-Log</releaseNotes>
|
||||
<tags>bootstrap date time picker datetimepicker datepicker jquery</tags>
|
||||
<dependencies>
|
||||
<dependency id="Twitter.Bootstrap.Less" version="3.0.0" />
|
||||
<dependency id="Moment.js" version="2.8.1" />
|
||||
<dependency id="Moment.js" version="2.8.4" />
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<files>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Bootstrap.v3.Datetimepicker</id>
|
||||
<version>3.1.2</version>
|
||||
<version>4.0.0</version>
|
||||
<title>Bootstrap 3 Datetimepicker</title>
|
||||
<authors>Eonasdan</authors>
|
||||
<owners>Eonasdan</owners>
|
||||
@@ -17,13 +17,13 @@ For CSS version install Bootstrap.v3.Datetimepicker.CSS</description>
|
||||
<tags>bootstrap date time picker datetimepicker datepicker jquery</tags>
|
||||
<dependencies>
|
||||
<dependency id="Twitter.Bootstrap.Less" version="3.0.0" />
|
||||
<dependency id="Moment.js" version="2.8.1" />
|
||||
<dependency id="Moment.js" version="2.8.4" />
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="..\..\src\js\bootstrap-datetimepicker.js" target="content\Scripts" />
|
||||
<file src="..\..\build\js\bootstrap-datetimepicker.min.js" target="content\Scripts" />
|
||||
<file src="..\..\src\less\bootstrap-datetimepicker.less" target="content\Content\less" />
|
||||
<file src="..\..\src\less\_bootstrap-datetimepicker.less" target="content\Content\less" />
|
||||
<file src="..\..\src\less\bootstrap-datetimepicker-build.less" target="content\Content\less" />
|
||||
<file src="install.ps1" target="tools\" />
|
||||
</files>
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
# install.ps1
|
||||
$DTE.ItemOperations.Navigate("https://github.com/Eonasdan/bootstrap-datetimepicker#change-log", $DTE.vsNavigateOptions.vsNavigateOptionsNewWindow)
|
||||
$DTE.ItemOperations.Navigate("http://eonasdan.github.io/bootstrap-datetimepicker/", $DTE.vsNavigateOptions.vsNavigateOptionsNewWindow)
|
||||
|
||||
@@ -0,0 +1,700 @@
|
||||
describe('Plugin initialization and component basic construction', function () {
|
||||
'use strict';
|
||||
|
||||
it('loads jquery plugin properly', function () {
|
||||
expect($('<div>').datetimepicker).toBeDefined();
|
||||
expect(typeof $('<div>').datetimepicker).toEqual('function');
|
||||
expect($('<div>').datetimepicker.defaults).toBeDefined();
|
||||
});
|
||||
|
||||
it('creates the component with default options on an input element', function () {
|
||||
var dtp = $('<input>');
|
||||
$(document).find('body').append(dtp);
|
||||
|
||||
expect(function () {
|
||||
dtp = dtp.datetimepicker();
|
||||
}).not.toThrow();
|
||||
|
||||
expect(dtp).not.toBe(null);
|
||||
});
|
||||
|
||||
xit('calls destroy when Element that the component is attached is removed', function () {
|
||||
var dtpElement = $('<div>').attr('class', 'row').append($('<div>').attr('class', 'col-md-12').append($('<input>'))),
|
||||
dtp;
|
||||
$(document).find('body').append(dtpElement);
|
||||
dtpElement.datetimepicker();
|
||||
dtp = dtpElement.data('DateTimePicker');
|
||||
spyOn(dtp, 'destroy').and.callThrough();
|
||||
dtpElement.remove();
|
||||
expect(dtp.destroy).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Public API method tests', function () {
|
||||
'use strict';
|
||||
var dtp,
|
||||
dtpElement,
|
||||
dpChangeSpy,
|
||||
dpShowSpy,
|
||||
dpHideSpy,
|
||||
dpErrorSpy;
|
||||
|
||||
beforeEach(function () {
|
||||
dpChangeSpy = jasmine.createSpy('dp.change event Spy');
|
||||
dpShowSpy = jasmine.createSpy('dp.show event Spy');
|
||||
dpHideSpy = jasmine.createSpy('dp.hide event Spy');
|
||||
dpErrorSpy = jasmine.createSpy('dp.error event Spy');
|
||||
dtpElement = $('<input>').attr('id', 'dtp');
|
||||
|
||||
$(document).find('body').append($('<div>').attr('class', 'row').append($('<div>').attr('class', 'col-md-12').append(dtpElement)));
|
||||
$(document).find('body').on('dp.change', dpChangeSpy);
|
||||
$(document).find('body').on('dp.show', dpShowSpy);
|
||||
$(document).find('body').on('dp.hide', dpHideSpy);
|
||||
$(document).find('body').on('dp.error', dpErrorSpy);
|
||||
|
||||
dtpElement.datetimepicker();
|
||||
dtp = dtpElement.data('DateTimePicker');
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
dtp.destroy();
|
||||
dtpElement.remove();
|
||||
});
|
||||
|
||||
describe('configuration option name match to public api function', function () {
|
||||
Object.getOwnPropertyNames($.fn.datetimepicker.defaults).forEach(function (key) {
|
||||
it('has function ' + key + '()', function () {
|
||||
expect(dtp[key]).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('date() function', function () {
|
||||
describe('typechecking', function () {
|
||||
it('accepts a null', function () {
|
||||
expect(function () {
|
||||
dtp.date(null);
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('accepts a string', function () {
|
||||
expect(function () {
|
||||
dtp.date('2013/05/24');
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('accepts a Date object', function () {
|
||||
expect(function () {
|
||||
dtp.date(new Date());
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('accepts a Moment object', function () {
|
||||
expect(function () {
|
||||
dtp.date(moment());
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('does not accept undefined', function () {
|
||||
expect(function () {
|
||||
dtp.date(undefined);
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it('does not accept a number', function () {
|
||||
expect(function () {
|
||||
dtp.date(0);
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it('does not accept a generic Object', function () {
|
||||
expect(function () {
|
||||
dtp.date({});
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it('does not accept a boolean', function () {
|
||||
expect(function () {
|
||||
dtp.date(false);
|
||||
}).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('functionality', function () {
|
||||
it('has no date set upon construction', function () {
|
||||
expect(dtp.date()).toBe(null);
|
||||
});
|
||||
|
||||
it('sets the date correctly', function () {
|
||||
var timestamp = moment();
|
||||
dtp.date(timestamp);
|
||||
expect(dtp.date().isSame(timestamp)).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('format() function', function () {
|
||||
describe('typechecking', function () {
|
||||
it('accepts a false value', function () {
|
||||
expect(function () {
|
||||
dtp.format(false);
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('accepts a string', function () {
|
||||
expect(function () {
|
||||
dtp.format('YYYY-MM-DD');
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('does not accept undefined', function () {
|
||||
expect(function () {
|
||||
dtp.format(undefined);
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it('does not accept true', function () {
|
||||
expect(function () {
|
||||
dtp.format(true);
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it('does not accept a generic Object', function () {
|
||||
expect(function () {
|
||||
dtp.format({});
|
||||
}).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('functionality', function () {
|
||||
it('returns no format before format is set', function () {
|
||||
expect(dtp.format()).toBe(false);
|
||||
});
|
||||
|
||||
it('sets the format correctly', function () {
|
||||
dtp.format('YYYY-MM-DD');
|
||||
expect(dtp.format()).toBe('YYYY-MM-DD');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('destroy() function', function () {
|
||||
describe('existence', function () {
|
||||
it('is defined', function () {
|
||||
expect(dtp.destroy).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('toggle() function', function () {
|
||||
describe('existence', function () {
|
||||
it('is defined', function () {
|
||||
expect(dtp.toggle).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
// describe('functionality', function () {
|
||||
// it('')
|
||||
// });
|
||||
});
|
||||
|
||||
describe('show() function', function () {
|
||||
describe('existence', function () {
|
||||
it('is defined', function () {
|
||||
expect(dtp.show).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('functionality', function () {
|
||||
it('emits a show event when called while widget is hidden', function () {
|
||||
dtp.show();
|
||||
expect(dpShowSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('does not emit a show event when called and widget is already showing', function () {
|
||||
dtp.hide();
|
||||
dtp.show();
|
||||
dpShowSpy.calls.reset();
|
||||
dtp.show();
|
||||
expect(dpShowSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('actually shows the widget', function () {
|
||||
dtp.show();
|
||||
expect($(document).find('body').find('.bootstrap-datetimepicker-widget').length).toEqual(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('hide() function', function () {
|
||||
describe('existence', function () {
|
||||
it('is defined', function () {
|
||||
expect(dtp.hide).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('functionality', function () {
|
||||
it('emits a hide event when called while widget is shown', function () {
|
||||
dtp.show();
|
||||
dtp.hide();
|
||||
expect(dpHideSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('does not emit a hide event when called while widget is hidden', function () {
|
||||
dtp.hide();
|
||||
expect(dpHideSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('actually hides the widget', function () {
|
||||
dtp.show();
|
||||
dtp.hide();
|
||||
expect($(document).find('body').find('.bootstrap-datetimepicker-widget').length).toEqual(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('disable() function', function () {
|
||||
describe('existence', function () {
|
||||
it('is defined', function () {
|
||||
expect(dtp.disable).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('enable() function', function () {
|
||||
describe('existence', function () {
|
||||
it('is defined', function () {
|
||||
expect(dtp.enable).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('options() function', function () {
|
||||
describe('existence', function () {
|
||||
it('is defined', function () {
|
||||
expect(dtp.options).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('disabledDates() function', function () {
|
||||
describe('existence', function () {
|
||||
it('is defined', function () {
|
||||
expect(dtp.disabledDates).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('enabledDates() function', function () {
|
||||
describe('existence', function () {
|
||||
it('is defined', function () {
|
||||
expect(dtp.enabledDates).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('daysOfWeekDisabled() function', function () {
|
||||
describe('existence', function () {
|
||||
it('is defined', function () {
|
||||
expect(dtp.daysOfWeekDisabled).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('maxDate() function', function () {
|
||||
describe('existence', function () {
|
||||
it('is defined', function () {
|
||||
expect(dtp.maxDate).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('minDate() function', function () {
|
||||
describe('existence', function () {
|
||||
it('is defined', function () {
|
||||
expect(dtp.minDate).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('defaultDate() function', function () {
|
||||
describe('existence', function () {
|
||||
it('is defined', function () {
|
||||
expect(dtp.defaultDate).toBeDefined();
|
||||
});
|
||||
});
|
||||
describe('functionality', function () {
|
||||
it('returns no defaultDate before defaultDate is set', function () {
|
||||
expect(dtp.defaultDate()).toBe(false);
|
||||
});
|
||||
|
||||
it('sets the defaultDate correctly', function () {
|
||||
var timestamp = moment();
|
||||
dtp.defaultDate(timestamp);
|
||||
expect(dtp.defaultDate().isSame(timestamp)).toBe(true);
|
||||
expect(dtp.date().isSame(timestamp)).toBe(true);
|
||||
});
|
||||
|
||||
it('triggers a change event upon setting a default date and input field is empty', function () {
|
||||
dtp.date(null);
|
||||
dtp.defaultDate(moment());
|
||||
expect(dpChangeSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('does not override input value if it already has one', function () {
|
||||
var timestamp = moment();
|
||||
dtp.date(timestamp);
|
||||
dtp.defaultDate(moment().year(2000));
|
||||
expect(dtp.date().isSame(timestamp)).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('locale() function', function () {
|
||||
describe('functionality', function () {
|
||||
it('it has the same locale as the global moment locale with default options', function () {
|
||||
expect(dtp.locale()).toBe(moment.locale());
|
||||
});
|
||||
|
||||
it('it switches to a selected locale without affecting global moment locale', function () {
|
||||
dtp.locale('el');
|
||||
dtp.date(moment());
|
||||
expect(dtp.locale()).toBe('el');
|
||||
expect(dtp.date().locale()).toBe('el');
|
||||
expect(moment.locale()).toBe('en');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('useCurrent() function', function () {
|
||||
describe('existence', function () {
|
||||
it('is defined', function () {
|
||||
expect(dtp.useCurrent).toBeDefined();
|
||||
});
|
||||
});
|
||||
describe('check type and parameter validity', function () {
|
||||
it('accepts either a boolean value or string', function () {
|
||||
var useCurrentOptions = ['year', 'month', 'day', 'hour', 'minute'];
|
||||
|
||||
expect(function () {
|
||||
dtp.useCurrent(false);
|
||||
}).not.toThrow();
|
||||
expect(function () {
|
||||
dtp.useCurrent(true);
|
||||
}).not.toThrow();
|
||||
|
||||
useCurrentOptions.forEach(function (value) {
|
||||
expect(function () {
|
||||
dtp.useCurrent(value);
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
expect(function () {
|
||||
dtp.useCurrent('test');
|
||||
}).toThrow();
|
||||
expect(function () {
|
||||
dtp.useCurrent({});
|
||||
}).toThrow();
|
||||
});
|
||||
});
|
||||
describe('functionality', function () {
|
||||
it('triggers a change event upon show() and input field is empty', function () {
|
||||
dtp.useCurrent(true);
|
||||
dtp.show();
|
||||
expect(dpChangeSpy).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('ignoreReadonly() function', function () {
|
||||
describe('existence', function () {
|
||||
it('is defined', function () {
|
||||
expect(dtp.ignoreReadonly).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('stepping() function', function () {
|
||||
describe('existence', function () {
|
||||
it('is defined', function () {
|
||||
expect(dtp.stepping).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('collapse() function', function () {
|
||||
describe('existence', function () {
|
||||
it('is defined', function () {
|
||||
expect(dtp.collapse).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('icons() function', function () {
|
||||
describe('existence', function () {
|
||||
it('is defined', function () {
|
||||
expect(dtp.icons).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('useStrict() function', function () {
|
||||
describe('existence', function () {
|
||||
it('is defined', function () {
|
||||
expect(dtp.useStrict).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('sideBySide() function', function () {
|
||||
describe('existence', function () {
|
||||
it('is defined', function () {
|
||||
expect(dtp.sideBySide).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('viewMode() function', function () {
|
||||
describe('existence', function () {
|
||||
it('is defined', function () {
|
||||
expect(dtp.viewMode).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('widgetPositioning() function', function () {
|
||||
describe('existence', function () {
|
||||
it('is defined', function () {
|
||||
expect(dtp.widgetPositioning).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('calendarWeeks() function', function () {
|
||||
describe('existence', function () {
|
||||
it('is defined', function () {
|
||||
expect(dtp.calendarWeeks).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('showTodayButton() function', function () {
|
||||
describe('existence', function () {
|
||||
it('is defined', function () {
|
||||
expect(dtp.showTodayButton).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('showClear() function', function () {
|
||||
describe('existence', function () {
|
||||
it('is defined', function () {
|
||||
expect(dtp.showClear).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('dayViewHeaderFormat() function', function () {
|
||||
describe('typechecking', function () {
|
||||
it('does not accept a false value', function () {
|
||||
expect(function () {
|
||||
dtp.dayViewHeaderFormat(false);
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it('accepts a string', function () {
|
||||
expect(function () {
|
||||
dtp.dayViewHeaderFormat('YYYY-MM-DD');
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('does not accept undefined', function () {
|
||||
expect(function () {
|
||||
dtp.dayViewHeaderFormat(undefined);
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it('does not accept true', function () {
|
||||
expect(function () {
|
||||
dtp.dayViewHeaderFormat(true);
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it('does not accept a generic Object', function () {
|
||||
expect(function () {
|
||||
dtp.dayViewHeaderFormat({});
|
||||
}).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('functionality', function () {
|
||||
it('expects dayViewHeaderFormat to be default of MMMM YYYY', function () {
|
||||
expect(dtp.dayViewHeaderFormat()).toBe('MMMM YYYY');
|
||||
});
|
||||
|
||||
it('sets the dayViewHeaderFormat correctly', function () {
|
||||
dtp.dayViewHeaderFormat('MM YY');
|
||||
expect(dtp.dayViewHeaderFormat()).toBe('MM YY');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('extraFormats() function', function () {
|
||||
describe('typechecking', function () {
|
||||
it('accepts a false value', function () {
|
||||
expect(function () {
|
||||
dtp.extraFormats(false);
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('does not accept a string', function () {
|
||||
expect(function () {
|
||||
dtp.extraFormats('YYYY-MM-DD');
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it('does not accept undefined', function () {
|
||||
expect(function () {
|
||||
dtp.extraFormats(undefined);
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it('does not accept true', function () {
|
||||
expect(function () {
|
||||
dtp.extraFormats(true);
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it('accepts an Array', function () {
|
||||
expect(function () {
|
||||
dtp.extraFormats(['YYYY-MM-DD']);
|
||||
}).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('functionality', function () {
|
||||
it('returns no extraFormats before extraFormats is set', function () {
|
||||
expect(dtp.extraFormats()).toBe(false);
|
||||
});
|
||||
|
||||
it('sets the extraFormats correctly', function () {
|
||||
dtp.extraFormats(['YYYY-MM-DD']);
|
||||
expect(dtp.extraFormats()[0]).toBe('YYYY-MM-DD');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('toolbarPlacement() function', function () {
|
||||
describe('existence', function () {
|
||||
it('is defined', function () {
|
||||
expect(dtp.toolbarPlacement).toBeDefined();
|
||||
});
|
||||
});
|
||||
describe('check type and parameter validity', function () {
|
||||
it('does not accept a false value', function () {
|
||||
expect(function () {
|
||||
dtp.dayViewHeaderFormat(false);
|
||||
}).toThrow();
|
||||
});
|
||||
it('does not accept a false value', function () {
|
||||
expect(function () {
|
||||
dtp.dayViewHeaderFormat(false);
|
||||
}).toThrow();
|
||||
});
|
||||
it('accepts a string', function () {
|
||||
var toolbarPlacementOptions = ['default', 'top', 'bottom'];
|
||||
|
||||
toolbarPlacementOptions.forEach(function (value) {
|
||||
expect(function () {
|
||||
dtp.toolbarPlacement(value);
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
expect(function () {
|
||||
dtp.toolbarPlacement('test');
|
||||
}).toThrow();
|
||||
expect(function () {
|
||||
dtp.toolbarPlacement({});
|
||||
}).toThrow();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('widgetParent() function', function () {
|
||||
describe('typechecking', function () {
|
||||
it('accepts a null', function () {
|
||||
expect(function () {
|
||||
dtp.widgetParent(null);
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('accepts a string', function () {
|
||||
expect(function () {
|
||||
dtp.widgetParent('testDiv');
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('accepts a jquery object', function () {
|
||||
expect(function () {
|
||||
dtp.widgetParent($('#testDiv'));
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('does not accept undefined', function () {
|
||||
expect(function () {
|
||||
dtp.widgetParent(undefined);
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it('does not accept a number', function () {
|
||||
expect(function () {
|
||||
dtp.widgetParent(0);
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it('does not accept a generic Object', function () {
|
||||
expect(function () {
|
||||
dtp.widgetParent({});
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it('does not accept a boolean', function () {
|
||||
expect(function () {
|
||||
dtp.widgetParent(false);
|
||||
}).toThrow();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('keepOpen() function', function () {
|
||||
describe('existence', function () {
|
||||
it('is defined', function () {
|
||||
expect(dtp.keepOpen).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('inline() function', function () {
|
||||
describe('existence', function () {
|
||||
it('is defined', function () {
|
||||
expect(dtp.inline).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('clear() function', function () {
|
||||
describe('existence', function () {
|
||||
it('is defined', function () {
|
||||
expect(dtp.clear).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('keyBinds() function', function () {
|
||||
describe('existence', function () {
|
||||
it('is defined', function () {
|
||||
expect(dtp.keyBinds).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* LibreNMS
|
||||
*
|
||||
* Copyright (c) 2014 Neil Lathwood <https://github.com/laf/ http://www.lathwood.co.uk/fa>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version. Please see LICENSE.txt at the top level of
|
||||
* the source code distribution for details.
|
||||
*/
|
||||
|
||||
$pagetitle[] = "Alert Schedule";
|
||||
$no_refresh = TRUE;
|
||||
if(is_admin() !== false) {
|
||||
|
||||
require_once("includes/modal/alert_schedule.inc.php");
|
||||
require_once("includes/modal/remove_alert_schedule.inc.php");
|
||||
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<span id="message"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel panel-default panel-condensed">
|
||||
<div class="table-responsive">
|
||||
<table id="alert-schedule" class="table table-condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-column-id="title">Title</th>
|
||||
<th data-column-id="start" data-order="desc">Start</th>
|
||||
<th data-column-id="end">End</th>
|
||||
<th data-column-id="actions" data-sortable="false" data-searchable="false" data-formatter="commands">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
|
||||
var grid = $("#alert-schedule").bootgrid({
|
||||
ajax: true,
|
||||
formatters: {
|
||||
"commands": function(column, row)
|
||||
{
|
||||
if (row.status == 1) {
|
||||
return '<button type="button" class="btn btn-xs btn-danger" disabled>Lapsed</button>';
|
||||
} else {
|
||||
var response = "<button type=\"button\" class=\"btn btn-xs btn-primary command-edit\" data-toggle='modal' data-target='#schedule-maintenance' data-schedule_id=\"" + row.id + "\"><span class=\"fa fa-pencil\"></span></button> " +
|
||||
"<button type=\"button\" class=\"btn btn-xs btn-danger command-delete\" data-schedule_id=\"" + row.id + "\"><span class=\"fa fa-trash-o\"></span></button>";
|
||||
if (row.status == 2) {
|
||||
response = response + ' <button type="button" class="btn btn-xs btn-success" disabled>Current</button>';
|
||||
}
|
||||
return response;
|
||||
}
|
||||
}
|
||||
},
|
||||
templates: {
|
||||
header: "<div id=\"{{ctx.id}}\" class=\"{{css.header}}\"><div class=\"row\">"+
|
||||
"<div class=\"col-sm-8 actionBar\"><span class=\"pull-left\">"+
|
||||
"<button type=\"button\" class=\"btn btn-primary btn-sm\" data-toggle=\"modal\" data-target=\"#schedule-maintenance\">Schedule maintenance</button>"+
|
||||
"</span></div>"+
|
||||
"<div class=\"col-sm-4 actionBar\"><p class=\"{{css.search}}\"></p><p class=\"{{css.actions}}\"></p></div></div></div>"
|
||||
},
|
||||
rowCount: [50,100,250,-1],
|
||||
post: function ()
|
||||
{
|
||||
return {
|
||||
id: "alert-schedule",
|
||||
};
|
||||
},
|
||||
url: "/ajax_table.php"
|
||||
}).on("loaded.rs.jquery.bootgrid", function()
|
||||
{
|
||||
/* Executes after data is loaded and rendered */
|
||||
grid.find(".command-edit").on("click", function(e)
|
||||
{
|
||||
$('#schedule_id').val($(this).data("schedule_id"));
|
||||
$("#schedule-maintenance").modal('show');
|
||||
}).end().find(".command-delete").on("click", function(e)
|
||||
{
|
||||
$('#del_schedule_id').val($(this).data("schedule_id"));
|
||||
$('#delete-maintenance').modal('show');
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<?php
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -156,8 +156,8 @@ if (!$auth)
|
||||
</form>
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
$("#dtpickerfrom").datetimepicker({useSeconds: false, useCurrent: true, sideBySide: true, useStrict: false, showToday: true});
|
||||
$("#dtpickerto").datetimepicker({useSeconds: false, useCurrent: true, sideBySide: true, useStrict: false, showToday: true});
|
||||
$("#dtpickerfrom").datetimepicker({useCurrent: true, sideBySide: true, useStrict: false});
|
||||
$("#dtpickerto").datetimepicker({useCurrent: true, sideBySide: true, useStrict: false});
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1154,3 +1154,21 @@ function set_curl_proxy($post)
|
||||
curl_setopt($post, CURLOPT_PROXY, $config['callback_proxy']);
|
||||
}
|
||||
}
|
||||
|
||||
function target_to_id($target) {
|
||||
if( $target[0].$target[1] == "g:" ) {
|
||||
$target = "g".dbFetchCell('SELECT id FROM device_groups WHERE name = ?',array(substr($target,2)));
|
||||
} else {
|
||||
$target = dbFetchCell('SELECT device_id FROM devices WHERE hostname = ?',array($target));
|
||||
}
|
||||
return $target;
|
||||
}
|
||||
|
||||
function id_to_target($id) {
|
||||
if( $id[0] == "g" ) {
|
||||
$id = 'g:'.dbFetchCell("SELECT name FROM device_groups WHERE id = ?",array(substr($id,1)));
|
||||
} else {
|
||||
$id = dbFetchCell("SELECT hostname FROM devices WHERE device_id = ?",array($id));
|
||||
}
|
||||
return $id;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
ALTER TABLE `alert_schedule` DROP `device_id`;
|
||||
ALTER TABLE `alert_schedule` CHANGE `id` `schedule_id` INT( 11 ) NOT NULL AUTO_INCREMENT;
|
||||
ALTER TABLE `alert_schedule` ADD `title` VARCHAR( 255 ) NOT NULL ,ADD `notes` TEXT NOT NULL ;
|
||||
CREATE TABLE `librenms`.`alert_schedule_items` (`item_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,`schedule_id` INT NOT NULL ,`target` VARCHAR( 255 ) NOT NULL ,INDEX ( `schedule_id` )) ENGINE = INNODB;
|
||||
Reference in New Issue
Block a user