Commit 29258b2c authored by Leigh B Stoller's avatar Leigh B Stoller

Various tweaks to reservation UI:

* Allow start to be optional; means "now".

* When selecting the current day, disable hours in the past.

* Catch a few more form errors.

* When editing, the start time might be in the past. Do not consider
  that an error, just pass it through since the backend is okay with
  it.
parent 7c554b32
...@@ -198,8 +198,7 @@ sub DoReserve() ...@@ -198,8 +198,7 @@ sub DoReserve()
} }
else { else {
usage() usage()
if (! (defined($count) && defined($type) && if (! (defined($count) && defined($type) && defined($end)));
defined($start) && defined($end)));
if ($type !~ /^[-\w]+$/) { if ($type !~ /^[-\w]+$/) {
fatal("Type is not a string"); fatal("Type is not a string");
......
#!/usr/bin/perl -wT #!/usr/bin/perl -wT
# #
# Copyright (c) 2008-2016 University of Utah and the Flux Group. # Copyright (c) 2008-2017 University of Utah and the Flux Group.
# #
# {{{GENIPUBLIC-LICENSE # {{{GENIPUBLIC-LICENSE
# #
...@@ -647,12 +647,12 @@ sub Reserve($) ...@@ -647,12 +647,12 @@ sub Reserve($)
my ($count,$start,$end,$type); my ($count,$start,$end,$type);
if (!$update) { if (!$update) {
foreach my $field ("count", "start", "end", "type") { foreach my $field ("count", "end", "type") {
return GeniResponse->MalformedArgsResponse("Missing $field") return GeniResponse->MalformedArgsResponse("Missing $field")
if (! (exists($argref->{$field}) && $argref->{$field} ne "")); if (! (exists($argref->{$field}) && $argref->{$field} ne ""));
} }
$count = $argref->{"count"}; $count = $argref->{"count"};
$start = $argref->{"start"}; $start = $argref->{"start"} if (exists($argref->{"start"}));
$end = $argref->{"end"}; $end = $argref->{"end"};
$type = $argref->{"type"}; $type = $argref->{"type"};
......
<?php <?php
# #
# Copyright (c) 2006-2016 University of Utah and the Flux Group. # Copyright (c) 2006-2017 University of Utah and the Flux Group.
# #
# {{{EMULAB-LICENSE # {{{EMULAB-LICENSE
# #
...@@ -217,6 +217,17 @@ class Aggregate ...@@ -217,6 +217,17 @@ class Aggregate
} }
return $am_array; return $am_array;
} }
function ThisAggregate()
{
global $DEFAULT_AGGREGATE_URN;
if (! ($aggregate = Aggregate::Lookup($DEFAULT_AGGREGATE_URN))) {
TBERROR("Aggregate::SupportsReservations: ".
"Could not load aggregate $urn!", 1);
}
return $aggregate;
}
} }
# #
......
...@@ -91,10 +91,20 @@ $(function () ...@@ -91,10 +91,20 @@ $(function ()
// Insert datepickers after html inserted. // Insert datepickers after html inserted.
$("#reserve-request-form #start_day").datepicker({ $("#reserve-request-form #start_day").datepicker({
minDate: 0, /* earliest date is today */
showButtonPanel: true, showButtonPanel: true,
onSelect: function (dateString, dateobject) {
DateChange("#start_day");
modified_callback();
}
}); });
$("#reserve-request-form #end_day").datepicker({ $("#reserve-request-form #end_day").datepicker({
minDate: 0, /* earliest date is today */
showButtonPanel: true, showButtonPanel: true,
onSelect: function (dateString, dateobject) {
DateChange("#end_day");
modified_callback();
}
}); });
/* /*
* Callback when something changes so that we can toggle the * Callback when something changes so that we can toggle the
...@@ -109,6 +119,44 @@ $(function () ...@@ -109,6 +119,44 @@ $(function ()
LoadReservations(); LoadReservations();
} }
/*
* When the date selected is today, need to disable the hours
* before the current hour.
*/
function DateChange(which)
{
var date = $("#reserve-request-form " + which).datepicker("getDate");
var now = new Date();
var selecter;
if (which == "#start_day") {
selecter = "#reserve-request-form #start_hour";
}
else {
selecter = "#reserve-request-form #end_hour";
}
if (moment(date).isSame(Date.now(), "day")) {
for (var i = 0; i <= now.getHours(); i++) {
/*
* Before we disable the option, see if it is selected.
* If so, we want make the user re-select the hour.
*/
if ($(selecter + " option:selected").val() == i) {
$(selecter).val("");
}
$(selecter + " option[value='" + i + "']")
.attr("disabled", "disabled");
}
}
else {
for (var i = 0; i <= now.getHours(); i++) {
$(selecter + " option[value='" + i + "']")
.removeAttr("disabled");
}
}
}
// //
// Check form validity. This does not check whether the reservation // Check form validity. This does not check whether the reservation
// is valid. // is valid.
...@@ -130,18 +178,36 @@ $(function () ...@@ -130,18 +178,36 @@ $(function ()
*/ */
var start_day = $('#reserve-request-form [name=start_day]').val(); var start_day = $('#reserve-request-form [name=start_day]').val();
var start_hour = $('#reserve-request-form [name=start_hour]').val(); var start_hour = $('#reserve-request-form [name=start_hour]').val();
if (start_day && start_hour) { if (start_day && !start_hour) {
aptforms.GenerateFormErrors('#reserve-request-form',
{"start" : "Missing hour"});
return;
}
else if (!start_day && start_hour) {
aptforms.GenerateFormErrors('#reserve-request-form',
{"start" : "Missing day"});
return;
}
else if (start_day && start_hour) {
var start = moment(start_day, "MM/DD/YYYY"); var start = moment(start_day, "MM/DD/YYYY");
start.hour(start_hour); start.hour(start_hour);
console.log("start", start);
$('#reserve-request-form [name=start]').val(start.format()); $('#reserve-request-form [name=start]').val(start.format());
} }
var end_day = $('#reserve-request-form [name=end_day]').val(); var end_day = $('#reserve-request-form [name=end_day]').val();
var end_hour = $('#reserve-request-form [name=end_hour]').val(); var end_hour = $('#reserve-request-form [name=end_hour]').val();
if (end_day && end_hour) { if (end_day && !end_hour) {
aptforms.GenerateFormErrors('#reserve-request-form',
{"end" : "Missing hour"});
return;
}
else if (!end_day && end_hour) {
aptforms.GenerateFormErrors('#reserve-request-form',
{"end" : "Missing day"});
return;
}
else if (end_day && end_hour) {
var end = moment(end_day, "MM/DD/YYYY"); var end = moment(end_day, "MM/DD/YYYY");
end.hour(end_hour); end.hour(end_hour);
console.log("end", end);
$('#reserve-request-form [name=end]').val(end.format()); $('#reserve-request-form [name=end]').val(end.format());
} }
aptforms.CheckForm('#reserve-request-form', "reserve", aptforms.CheckForm('#reserve-request-form', "reserve",
...@@ -284,6 +350,12 @@ $(function () ...@@ -284,6 +350,12 @@ $(function ()
$('#reserve-request-form [name=end_hour]') $('#reserve-request-form [name=end_hour]')
.val(end.format("H")); .val(end.format("H"));
console.log(start, end); console.log(start, end);
// Set the hour selectors properly in the datepicker object.
$("#reserve-request-form #start_day")
.datepicker("setDate", start.format("MM/DD/YYYY"));
$("#reserve-request-form #end_day")
.datepicker("setDate", end.format("MM/DD/YYYY"));
}; };
sup.ShowWaitWait(); sup.ShowWaitWait();
var xmlthing = sup.CallServerMethod(null, "reserve", var xmlthing = sup.CallServerMethod(null, "reserve",
......
<?php <?php
# #
# Copyright (c) 2000-2016 University of Utah and the Flux Group. # Copyright (c) 2000-2017 University of Utah and the Flux Group.
# #
# {{{EMULAB-LICENSE # {{{EMULAB-LICENSE
# #
...@@ -55,17 +55,27 @@ function Do_Reserve() ...@@ -55,17 +55,27 @@ function Do_Reserve()
$formfields = $ajax_args["formfields"]; $formfields = $ajax_args["formfields"];
$errors = array(); $errors = array();
error_log(print_r($formfields, TRUE));
# #
# All fields required, # All fields required,
# #
$required = array("pid", "count", "start", "end", $required = array("pid", "count", "end", "cluster", "type");
"cluster", "type");
foreach ($required as $field) { foreach ($required as $field) {
if (!isset($formfields[$field]) || $formfields[$field] == "") { if (!isset($formfields[$field]) || $formfields[$field] == "") {
$errors[$field] = "Missing field"; $errors[$field] = "Missing field";
} }
} }
#
# Update mode; we get the idx of the current reservation.
#
if (isset($formfields["idx"])) {
$idx = $formfields["idx"];
if (!TBvalid_integer($idx)) {
$errors["error"] = "Bad index for reservation update";
}
}
# Admins do not need a reason. # Admins do not need a reason.
if (!ISADMIN() && if (!ISADMIN() &&
(!isset($formfields["reason"]) || $formfields["reason"] == "")) { (!isset($formfields["reason"]) || $formfields["reason"] == "")) {
...@@ -82,10 +92,16 @@ function Do_Reserve() ...@@ -82,10 +92,16 @@ function Do_Reserve()
if (!TBvalid_integer($formfields["count"])) { if (!TBvalid_integer($formfields["count"])) {
$errors["count"] = TBFieldErrorString(); $errors["count"] = TBFieldErrorString();
} }
$start_ascii = $formfields["start"]; if (isset($formfields["start"]) && $formfields["start"] != "") {
$start = strtotime($formfields["start"]); $start_ascii = $formfields["start"];
if (!$start) { $start = strtotime($formfields["start"]);
$errors["start"] = "Cannot parse date"; if (!$start) {
$errors["start"] = "Cannot parse date";
}
elseif ($start < time() && !isset($idx)) {
# In update mode, just let it through.
$errors["start"] = "In the past";
}
} }
$end_ascii = $formfields["end"]; $end_ascii = $formfields["end"];
$end = strtotime($formfields["end"]); $end = strtotime($formfields["end"]);
...@@ -112,15 +128,6 @@ function Do_Reserve() ...@@ -112,15 +128,6 @@ function Do_Reserve()
!$project->AccessCheck($this_user, $TB_PROJECT_CREATEEXPT)) { !$project->AccessCheck($this_user, $TB_PROJECT_CREATEEXPT)) {
$errors["error"] = "Not enough permission in project"; $errors["error"] = "Not enough permission in project";
} }
#
# Update mode; we get the idx of the current reservation.
#
if (isset($formfields["idx"])) {
$idx = $formfields["idx"];
if (!TBvalid_integer($idx)) {
$errors["error"] = "Bad index for reservation update";
}
}
if (count($errors)) { if (count($errors)) {
SPITAJAX_ERROR(2, $errors); SPITAJAX_ERROR(2, $errors);
return; return;
...@@ -142,7 +149,8 @@ function Do_Reserve() ...@@ -142,7 +149,8 @@ function Do_Reserve()
# #
$args = "-t " . escapeshellarg($formfields["type"]) . " ". $args = "-t " . escapeshellarg($formfields["type"]) . " ".
(isset($idx) ? "-u $idx " : "") . (isset($idx) ? "-u $idx " : "") .
"-s $start -e $end $pid " . $formfields["count"]; (isset($start) ? "-s $start " : "") .
" -e $end $pid " . $formfields["count"];
# #
# Do a precheck. # Do a precheck.
......
...@@ -47,6 +47,7 @@ if (!ISADMIN()) { ...@@ -47,6 +47,7 @@ if (!ISADMIN()) {
# Verify page arguments. Cluster is a domain that we turn into a URN. # Verify page arguments. Cluster is a domain that we turn into a URN.
# #
$optargs = OptionalPageArguments("edit", PAGEARG_BOOLEAN, $optargs = OptionalPageArguments("edit", PAGEARG_BOOLEAN,
"debug", PAGEARG_BOOLEAN,
"cluster", PAGEARG_STRING, "cluster", PAGEARG_STRING,
"project", PAGEARG_PROJECT, "project", PAGEARG_PROJECT,
"idx", PAGEARG_INTEGER); "idx", PAGEARG_INTEGER);
...@@ -103,6 +104,9 @@ echo "</script>\n"; ...@@ -103,6 +104,9 @@ echo "</script>\n";
if ($edit) { if ($edit) {
$ams = array($aggregate); $ams = array($aggregate);
} }
elseif (isset($debug) && $debug) {
$ams = array(Aggregate::ThisAggregate());
}
else { else {
$ams = Aggregate::SupportsReservations(); $ams = Aggregate::SupportsReservations();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment