Commit 1de19201 authored by Leigh Stoller's avatar Leigh Stoller

Changes to the snapshot modal as discussed on 1/21/2019:

* When the profile is script based, we cannot update the profile code,
  so do not show any choices (radios), proceed as image only.

* Remove the "new profile" (3rd) option, it appears that no one at the
  meeting knew what that was about, so clearly mere users won't. Simplify!

* Rearrange the options (whole disk, account), together at the bottom.

* Swap the description and the image name inputs.

* Cleanup the help popovers and impl.
parent 7af67dbf
...@@ -2187,8 +2187,9 @@ $(function () ...@@ -2187,8 +2187,9 @@ $(function ()
* we present later depends on canclone/cansnap. But not allowed * we present later depends on canclone/cansnap. But not allowed
* to clone a repo based profile. * to clone a repo based profile.
*/ */
if (! ((window.APT_OPTIONS.canclone && !expinfo.repurl) || if (! (window.APT_OPTIONS.canclone_profile ||
window.APT_OPTIONS.cansnap)) { window.APT_OPTIONS.canupdate_profile ||
window.APT_OPTIONS.cansnapshot)) {
return; return;
} }
...@@ -2196,54 +2197,64 @@ $(function () ...@@ -2196,54 +2197,64 @@ $(function ()
$('button#snapshot_button').popover('hide'); $('button#snapshot_button').popover('hide');
DoSnapshotNode(); DoSnapshotNode();
}); });
/*
* Various help buttons for snapshot choices.
*/
var visibleHelp = null;
$('#snapshot-help-button').click(function (event) { $('.snapshot-help-button').each(function () {
event.preventDefault(); var target = $(this).find("span");
clearTimeout(snapshot_help_timer); var which = target.data("which");
$('#snapshot-help-button').popover({ var content = null;
console.info("foo", this, which, target);
switch(which) {
case 'update-profile':
content = $('#snapshot-help-div').html();
break;
case 'copy-profile':
content = $('#clone-help-div').html();
break;
case 'image-only':
content = $('#imageonly-help-div').html();
break;
}
$(target).popover({
html: true, html: true,
content: $('#snapshot-help-div').html(), content: content,
trigger: 'manual', trigger: 'manual',
placement:'auto', placement:'auto',
container:'body', container:'body',
}); });
$('#snapshot-help-button').popover('show');
$('.snapshot-popover-close').on('click', function(event) { $(this).click(function (event) {
event.preventDefault(); event.preventDefault();
$('#snapshot-help-button').popover('destroy');
if (visibleHelp) {
var tmp = visibleHelp;
visibleHelp = null;
tmp.popover('hide');
// Clicked on the same one, hide it and leave.
if (tmp.data("which") == which) {
return;
}
}
$(target).popover('show');
visibleHelp = $(target);
// Bind the close button, sleazy internal stuff.
$(target).data('bs.popover').tip()
.find(".close").click(function (event) {
$(target).popover('hide');
$(this).off("click");
visibleHelp = null;
});
}); });
}).mouseenter(function (event) {
snapshot_help_timer = setTimeout(function() {
$('#snapshot-help-button').trigger("click");
},1000)
}).mouseleave(function(){
clearTimeout(snapshot_help_timer);
}); });
$('.clone-help-button').mouseenter(function (event) {
clone_help_timer = setTimeout(function() {
$(event.target).trigger("click");
},1000)
}).mouseleave(function(){
clearTimeout(clone_help_timer);
}).click(function (event) {
event.preventDefault();
clearTimeout(clone_help_timer);
var target = $('#clone-help-popover-div');
target.popover({
html: true,
content: $('#clone-help-div').html(),
trigger: 'manual',
placement:'auto',
container:'body',
});
target.popover('show');
$('.clone-popover-close').on('click', function(event) {
event.preventDefault();
target.popover('destroy');
});
});
$('#snapshot_modal input[type=radio]').on('change', function() { $('#snapshot_modal input[type=radio]').on('change', function() {
switch($(this).val()) { switch($(this).val()) {
case 'update-profile': case 'update-profile':
...@@ -2251,16 +2262,15 @@ $(function () ...@@ -2251,16 +2262,15 @@ $(function ()
$('#snapshot-wholedisk-div').addClass("hidden"); $('#snapshot-wholedisk-div').addClass("hidden");
break; break;
case 'copy-profile': case 'copy-profile':
case 'new-profile':
$('#snapshot-name-div .new-profile').removeClass("hidden");
$('#snapshot-name-div .image-only').addClass("hidden"); $('#snapshot-name-div .image-only').addClass("hidden");
$('#snapshot-name-div .copy-profile').removeClass("hidden");
$('#snapshot-name-div').removeClass("hidden"); $('#snapshot-name-div').removeClass("hidden");
if (wholedisk) { if (wholedisk) {
$('#snapshot-wholedisk-div').removeClass("hidden"); $('#snapshot-wholedisk-div').removeClass("hidden");
} }
break; break;
case 'image-only': case 'image-only':
$('#snapshot-name-div .new-profile').addClass("hidden"); $('#snapshot-name-div .copy-profile').addClass("hidden");
$('#snapshot-name-div .image-only').removeClass("hidden"); $('#snapshot-name-div .image-only').removeClass("hidden");
$('#snapshot-name-div').removeClass("hidden"); $('#snapshot-name-div').removeClass("hidden");
if (wholedisk) { if (wholedisk) {
...@@ -2271,23 +2281,30 @@ $(function () ...@@ -2271,23 +2281,30 @@ $(function ()
}); });
/* /*
* Not allowed to clone/snap repo based profiles, which means * Hide choices in the snapshot modal per the flags.
* no choice at all, so hide everything except what name to
* use for the image.
*/ */
if (expinfo.repourl) { if (isscript ||
$('#update-profile').closest(".radio").addClass("hidden"); (!window.APT_OPTIONS.canclone_profile &&
$('#copy-profile').closest(".radio").addClass("hidden"); !window.APT_OPTIONS.canupdate_profile)) {
$('#new-profile').closest(".radio").addClass("hidden"); $('#snapshot-name-div .image-only').removeClass("hidden");
$('#image-only').prop("checked", true); $('#snapshot-name-div').removeClass("hidden");
$('#image-only').trigger("change"); if (wholedisk) {
$('#image-only').closest(".radio").addClass("hidden"); $('#snapshot-wholedisk-div').removeClass("hidden");
$('#snapshot-radio-title').addClass("hidden"); }
} }
else if (!window.APT_OPTIONS.cansnap) { else {
$('#update-profile').closest(".radio").remove(); if (!window.APT_OPTIONS.canclone_profile) {
$('#copy-profile').prop("checked", true); $('#copy-profile-radio').remove();
$('#copy-profile').trigger("change"); }
else if (!window.APT_OPTIONS.canupdate_profile) {
$('#update-profile-radio').remove();
}
// As per the 'isscript' test above, one of these must be
// available, so make the other the default.
if (!window.APT_OPTIONS.canupdate_profile) {
$('#copy-profile').prop("checked", true);
$('#copy-profile').trigger("change");
}
} }
} }
...@@ -2300,8 +2317,9 @@ $(function () ...@@ -2300,8 +2317,9 @@ $(function ()
* we present later depends on canclone/cansnap. But not allowed * we present later depends on canclone/cansnap. But not allowed
* to clone a repo based profile. * to clone a repo based profile.
*/ */
if (! ((window.APT_OPTIONS.canclone && !expinfo.repourl) || if (! (window.APT_OPTIONS.canclone_profile ||
window.APT_OPTIONS.cansnap)) { window.APT_OPTIONS.canupdate_profile ||
window.APT_OPTIONS.cansnapshot)) {
return; return;
} }
$("#snapshot_button").removeClass("hidden"); $("#snapshot_button").removeClass("hidden");
...@@ -2341,11 +2359,11 @@ $(function () ...@@ -2341,11 +2359,11 @@ $(function ()
*/ */
if (Object.keys(imageablenodes).length == 1) { if (Object.keys(imageablenodes).length == 1) {
/* /*
* If allowed to snapshot, then use the current profile name. * If allowed to update image, then use the current profile name.
* Otherwise might as well let them choose the name. * Otherwise might as well let them choose the name.
*/ */
if (window.APT_OPTIONS.cansnap) { if (window.APT_OPTIONS.cansnapshot) {
$('#snapshot-name-div .image-only input') $('#snapshot-name-div input')
.val(expinfo.profile_name); .val(expinfo.profile_name);
$('#snapshot-name-div .snapshot-name-warning') $('#snapshot-name-div .snapshot-name-warning')
.removeClass("hidden"); .removeClass("hidden");
...@@ -2361,7 +2379,7 @@ $(function () ...@@ -2361,7 +2379,7 @@ $(function ()
.on("change", function (event) { .on("change", function (event) {
var node = $(this).val(); var node = $(this).val();
var name = expinfo.profile_name + "." + node; var name = expinfo.profile_name + "." + node;
$('#snapshot-name-div .image-only input').val(name); $('#snapshot-name-div input').val(name);
$('#snapshot-name-div .snapshot-name-warning') $('#snapshot-name-div .snapshot-name-warning')
.removeClass("hidden"); .removeClass("hidden");
}); });
...@@ -2395,7 +2413,7 @@ $(function () ...@@ -2395,7 +2413,7 @@ $(function ()
}); });
$('#confirm-update-systemimage').click(function() { $('#confirm-update-systemimage').click(function() {
sup.HideModal('#confirm-update-systemimage-modal'); sup.HideModal('#confirm-update-systemimage-modal');
$('#snapshot_update_prepare_div').addClass("hidden"); $('#snapshot_update_prepare_option').addClass("hidden");
DoSnapshotNodeAux(); DoSnapshotNodeAux();
}); });
sup.ShowModal('#confirm-update-systemimage-modal', sup.ShowModal('#confirm-update-systemimage-modal',
...@@ -2432,14 +2450,17 @@ $(function () ...@@ -2432,14 +2450,17 @@ $(function ()
$('#snapshot_modal .choose-node-error').addClass("hidden"); $('#snapshot_modal .choose-node-error').addClass("hidden");
// What does the user want to do? // What does the user want to do?
var operation = $('#snapshot_modal input[type=radio]:checked').val(); var operation =
(isscript ? "image-only" :
$('#snapshot_modal input[type=radio]:checked').val());
var args = {"uuid" : uuid, var args = {"uuid" : uuid,
"node_id" : node_id, "node_id" : node_id,
"operation" : operation, "operation" : operation,
"update_prepare" : 0}; "update_prepare" : 0};
// Make sure we got an image/profile name. // Make sure we got an image/profile name.
if (operation == 'image-only') { if (operation == 'image-only') {
var name = $('#snapshot-name-div .image-only input').val(); var name = $('#snapshot-name-div input').val();
if (name == "") { if (name == "") {
$('#snapshot-name-div .name-error') $('#snapshot-name-div .name-error')
.text("Please provide an image name"); .text("Please provide an image name");
...@@ -2450,7 +2471,7 @@ $(function () ...@@ -2450,7 +2471,7 @@ $(function ()
} }
else if (operation == "copy-profile" || else if (operation == "copy-profile" ||
operation == "new-profile") { operation == "new-profile") {
var name = $('#snapshot-name-div .new-profile input').val(); var name = $('#snapshot-name-div input').val();
if (name == "") { if (name == "") {
$('#snapshot-name-div .name-error') $('#snapshot-name-div .name-error')
.text("Please provide a profile name"); .text("Please provide a profile name");
...@@ -2483,9 +2504,11 @@ $(function () ...@@ -2483,9 +2504,11 @@ $(function ()
$('#snapshot_modal').on('hidden.bs.modal', function (event) { $('#snapshot_modal').on('hidden.bs.modal', function (event) {
$(this).unbind(event); $(this).unbind(event);
$('button#snapshot_confirm').unbind("click.snapshot"); $('button#snapshot_confirm').unbind("click.snapshot");
// Kill any popovers still showing. // Hide any popovers still showing.
$('#snapshot-help-button').popover('destroy'); $('.snapshot-help-button').each(function () {
$('#clone-help-popover-div').popover('destroy'); var target = $(this).find("span");
target.popover('hide');
});
}); });
sup.ShowModal('#snapshot_modal'); sup.ShowModal('#snapshot_modal');
......
<?php <?php
# #
# Copyright (c) 2000-2018 University of Utah and the Flux Group. # Copyright (c) 2000-2019 University of Utah and the Flux Group.
# #
# {{{EMULAB-LICENSE # {{{EMULAB-LICENSE
# #
...@@ -160,28 +160,34 @@ $slice = GeniSlice::Lookup("sa", $instance->slice_uuid()); ...@@ -160,28 +160,34 @@ $slice = GeniSlice::Lookup("sa", $instance->slice_uuid());
$instance_status = $instance->status(); $instance_status = $instance->status();
$creator_uid = $creator->uid(); $creator_uid = $creator->uid();
$cansnapshot = ((isset($this_user) &&
$this_user->idx() == $creator->idx()) ||
ISADMIN() ? 1 : 0);
$canterminate = ((isset($this_user) &&
$instance->CanTerminate($this_user)) ||
ISADMIN() ? 1 : 0);
$cancopy_profile = 0;
$canclone_profile = 0;
$canupdate_profile = 0;
$isscript = 0;
if ($profile = Profile::Lookup($instance->profile_id(), if ($profile = Profile::Lookup($instance->profile_id(),
$instance->profile_version())) { $instance->profile_version())) {
$cansnap = ((isset($this_user) && #
$this_user->idx() == $creator->idx() && # Not allowed to copy/clone/update a repo based profile.
$this_user->idx() == $profile->creator_idx()) || #
ISADMIN() ? 1 : 0); if (!$profile->repourl()) {
$canclone = ((isset($this_user) && $cancopy_profile = ((isset($this_user) &&
$profile->CanClone($this_user)) || $profile->CanInstantiate($this_user)) ||
ISADMIN() ? 1 : 0); ISADMIN() ? 1 : 0);
$canterminate = ((isset($this_user) && $canclone_profile = ((isset($this_user) &&
$instance->CanTerminate($this_user)) || $profile->CanClone($this_user)) ||
ISADMIN() ? 1 : 0); ISADMIN() ? 1 : 0);
$isscript = ($profile->script() && $profile->script() != "" ? 1 : 0); $canupdate_profile = ((isset($this_user) &&
} $this_user->idx() == $profile->creator_idx()) ||
else { ISADMIN() ? 1 : 0);
$cansnap = 0; $isscript = ($profile->script() && $profile->script() != "" ? 1 : 0);
$canclone = 0; }
$canterminate = ((isset($this_user) &&
$instance->CanTerminate($this_user)) ||
ISADMIN() ? 1 : 0);
$isscript = 0;
} }
$registered = (isset($this_user) ? "true" : "false"); $registered = (isset($this_user) ? "true" : "false");
$snapping = 0; $snapping = 0;
...@@ -245,8 +251,10 @@ echo " window.APT_OPTIONS.registered = $registered;\n"; ...@@ -245,8 +251,10 @@ echo " window.APT_OPTIONS.registered = $registered;\n";
echo " window.APT_OPTIONS.isadmin = $isadmin;\n"; echo " window.APT_OPTIONS.isadmin = $isadmin;\n";
echo " window.APT_OPTIONS.isfadmin = $isfadmin;\n"; echo " window.APT_OPTIONS.isfadmin = $isfadmin;\n";
echo " window.APT_OPTIONS.isstud = $isstud;\n"; echo " window.APT_OPTIONS.isstud = $isstud;\n";
echo " window.APT_OPTIONS.cansnap = $cansnap;\n"; echo " window.APT_OPTIONS.cansnapshot = $cansnapshot;\n";
echo " window.APT_OPTIONS.canclone = $canclone;\n"; echo " window.APT_OPTIONS.canclone_profile = $canclone_profile;\n";
echo " window.APT_OPTIONS.canupdate_profile = $canupdate_profile;\n";
echo " window.APT_OPTIONS.cancopy_profile = $cancopy_profile;\n";
echo " window.APT_OPTIONS.canterminate = $canterminate;\n"; echo " window.APT_OPTIONS.canterminate = $canterminate;\n";
echo " window.APT_OPTIONS.wholedisk = $wholedisk;\n"; echo " window.APT_OPTIONS.wholedisk = $wholedisk;\n";
echo " window.APT_OPTIONS.snapping = $snapping;\n"; echo " window.APT_OPTIONS.snapping = $snapping;\n";
...@@ -269,6 +277,7 @@ echo "<script src='js/lib/nv.d3.js'></script>\n"; ...@@ -269,6 +277,7 @@ echo "<script src='js/lib/nv.d3.js'></script>\n";
echo "<script src='js/lib/jquery-2.0.3.min.js'></script>\n"; echo "<script src='js/lib/jquery-2.0.3.min.js'></script>\n";
echo "<script src='js/lib/jquery-ui.js'></script>\n"; echo "<script src='js/lib/jquery-ui.js'></script>\n";
echo "<script src='js/lib/codemirror-min.js'></script>\n"; echo "<script src='js/lib/codemirror-min.js'></script>\n";
echo "<script src='js/lib/filesize.min.js'></script>\n";
REQUIRE_UNDERSCORE(); REQUIRE_UNDERSCORE();
REQUIRE_SUP(); REQUIRE_SUP();
......
This diff is collapsed.
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