Commit 97c402fa authored by Jonathon Duerig's avatar Jonathon Duerig

Add a new image picker dialog for when an image type is specified in genilib but not enumerated

parent e3f8408e
......@@ -136,6 +136,54 @@ function Do_Instantiate()
return;
}
function ImagesWhere($where, $dblink)
{
$result = array();
$query_result = DBQueryFatal(
"select i.urn, v.description, v.version from ".
"image_versions as v left join images as i on ".
"v.urn=i.urn ".$where,
$dblink);
while ($row = mysql_fetch_array($query_result)) {
array_push($result, array(
'urn' => $row[0],
'description' => $row[1],
'version' => $row[2]));
}
return $result;
}
function Do_GetImageList()
{
global $this_user;
global $ajax_args;
$dblink = DBConnect("ims");
$systemProject = 'emulab-ops';
$myImages = array();
$projectImages = array();
$systemImages = array();
$publicImages = array();
if ($this_user && $this_user->webonly()) {
# Only public images
$publicImages = ImagesWhere("where v.visibility='public' and i.project_urn not like '%$systemProject+authority+sa'", $dblink);
$systemImages = ImagesWhere("where i.project_urn like '%$systemProject+authority+sa'", $dblink);
} else if ($this_user) {
$user_urn = addslashes($this_user->urn());
# Public images that weren't created by the user
$publicImages = ImagesWhere("where v.visibility='public' and i.project_urn not like '%$systemProject+authority+sa' and v.creator_urn != '$user_urn'", $dblink);
# System images that weren't created by the user
$systemImages = ImagesWhere("where v.visibility='public' and i.project_urn like '%$systemProject+authority+sa' and v.creator_urn != '$user_urn'", $dblink);
# All images for user
$myImages = ImagesWhere("where v.creator_urn='$user_urn'", $dblink);
}
$result = array(array("my-images" => $myImages,
"project" => $projectImages,
"system" => $systemImages,
"public" => $publicImages));
SPITAJAX_RESPONSE($result);
}
#
# Return constraint info for a set of images.
#
......
......@@ -427,7 +427,9 @@ function SPITFORM($formfields, $newuser, $errors)
}
echo "</script>\n";
echo "<script src='js/lib/jquery-2.0.3.min.js'></script>\n";
echo "<script src='https://www.emulab.net/protogeni/jacksmod/stable/jacksmod.js'></script>";
echo "<script src='https://www.emulab.net/protogeni/jacksmod/stable/imagepicker.js'></script>";
REQUIRE_UNDERSCORE();
REQUIRE_SUP();
REQUIRE_PPWIZARDSTART();
......
......@@ -6,10 +6,11 @@ $(function () {
{
'use strict';
var templates = APT_OPTIONS.fetchTemplateList(['ppform-wizard', 'ppform-wizard-body', 'choose-am']);
var templates = APT_OPTIONS.fetchTemplateList(['ppform-wizard', 'ppform-wizard-body', 'choose-am', 'image-picker-modal']);
var ppmodalString = templates['ppform-wizard'];
var ppbodyString = templates['ppform-wizard-body'];
var chooserString = templates['choose-am'];
var imagePickerString = templates['image-picker-modal'];
var bodyTemplate = null;
var chooseTemplate= null;
var editor = null;
......@@ -21,7 +22,8 @@ $(function () {
var multisite = 0;
var RSPEC = null;
var configuredone_callback = null;
var warningsfatal = 1;
var warningsfatal = 1;
var imagePicker = null;
//
// Moved into a separate function since we want to regen the form
......@@ -32,9 +34,9 @@ $(function () {
var html = bodyTemplate({
formfields: formfields,
});
html = formatter(html, errors).html();
$('#ppmodal-body').html(html);
$('#ppmodal-body').empty();
formatter(html, errors, $('#ppmodal-body'));
if (!registered) {
$('#pp_form :input').attr('readonly', true);
// This is the only way to disable selects
......@@ -43,7 +45,10 @@ $(function () {
$('#pp_form :button').attr('disabled', false);
$('#pp_form :button').attr('readonly', false);
}
imagePicker = new jacksmod.ImagePicker();
$('#image-picker-body').html(imagePickerString);
$('#imagepicker-modal .modal-body > div').append(imagePicker.el);
//
// Handle submit button.
//
......@@ -93,9 +98,10 @@ $(function () {
}
// Formatter for the form. This did not work out nicely at all!
function formatter(fieldString, errors)
{
function formatter(fieldString, errors, parent)
{
var root = $(fieldString);
parent.append(root);
var list = root.find('.format-me');
var form = root.find('#pp_form');
var hasHelp = false;
......@@ -239,6 +245,12 @@ $(function () {
oldV = $(item).val();
$(item).attr('value',v);
}
else if (item.dataset['type'] && item.dataset['type'] == 'image')
{
oldV = $(item).find('input#image-value').val();
$(item).find('input#image-value').val(v);
$(item).find('input#image-display').val(imageDisplay(v));
}
else if ($(item).prop('tagName') == 'INPUT'
&& $(item).attr('type') == 'checkbox') {
oldV = $(item).val();
......@@ -367,7 +379,12 @@ $(function () {
}
var innerdiv = $("<div class='col-sm-" +
colsize + "'></div>");
innerdiv.html($(item).clone());
var clone = $(item).clone();
if (item.dataset['type'] && item.dataset['type'] == 'image')
{
initImagePicker(clone);
}
innerdiv.html(clone);
// Handle the easy type-checked errors from the PHP/ajax call.
if (errors && _.has(errors, key)) {
......@@ -753,6 +770,101 @@ $(function () {
}
}
var globalImages = [
{
urn: 'urn:publicid:IDN+emulab.net+image+emulab-ops//UBUNTU16-64-STD',
version: '',
description: 'Ubuntu 16.04 standard image'
},
{
urn: 'urn:publicid:IDN+emulab.net+image+emulab-ops//UBUNTU14-64-STD',
version: '',
description: 'Ubuntu 14.04 standard image'
},
{
urn: 'urn:publicid:IDN+emulab.net+image+emulab-ops//CENTOS66-64-STD',
version: '',
description: 'CentOS 6.6 standard image'
},
{
urn: 'urn:publicid:IDN+emulab.net+image+emulab-ops//CENTOS71-64-STD',
version: '',
description: 'CentOS 7.1 standard image'
},
{
urn: 'urn:publicid:IDN+emulab.net+image+emulab-ops//FBSD103-64-STD',
version: '',
description: 'FreeBSD 10.3 standard image'
},
];
var userImages = [
{
urn: 'urn:publicid:IDN+emulab.net+image+testbed//JONS_COOL_IMAGE',
version: '45ac6de',
description: 'This image is super cool because it was created in an awesome fashion. You should totally pick this image, dood.'
},
{
urn: 'urn:publicid:IDN+emulab.net+image+testbed//JONS_BAD_HAIR_DAY_IMAGE',
version: 'deadbe4f',
description: 'You don\'t want this image, man. It was created under a bad moon in the middle of a total solar eclipse and is cursed for all time.'
},
];
function initImagePicker(dom) {
dom.find('button#image-select').click(function (event) {
var callback = function(json) {
$('#waitwait-modal').modal('hide');
console.log('imagepicker', json);
if (json.code == 0) {
sup.ShowModal('#imagepicker-modal');
imagePicker.pick(dom.find('input#image-value').val(), json.value[0]);
} else {
sup.SpitOops('oops', json.value);
}
}
$('#waitwait-modal').modal('show');
var xmlthing = sup.CallServerMethod(null, "instantiate", "GetImageList");
xmlthing.done(callback);
var closeFunction = function () {
imagePicker.off('selected');
imagePicker.off('closed');
sup.HideModal('#imagepicker-modal');
};
imagePicker.on('selected', function (item) {
dom.find('input#image-value').val(item);
dom.find('input#image-display').val(imageDisplay(item));
closeFunction();
});
imagePicker.on('closed', closeFunction);
$('#imagepicker-modal .modal-header button.close').on('click', closeFunction);
event.preventDefault();
});
}
function imageDisplay(v) {
var sp = v.split('+');
var display;
if (sp.length >= 4)
{
if (sp[3].substr(0, 12) == 'emulab-ops//')
{
display = sp[3].substr(12);
}
else
{
display = sp[3];
}
}
else
{
display = v;
}
return display;
}
return {
HandleSubmit: HandleSubmit,
StartPP: StartPP,
......
......@@ -744,6 +744,36 @@ class Profile
}
$form .= "</select>";
}
elseif ($type == "image") {
$form .=
"<div class='format-me' ".
"data-key='$name' ".
"data-label='$prompt' ".
"data-type='$type' ".
"$data_help_string $advanced_attr >".
"<div class='input-group'>".
"<input id='image-display' ".
"type='text' readonly ".
"class='form-control' ".
"value='<% var label = formfields.${name}; var sp = label.split('+'); var image_display; if (sp.length >= 4){ if (sp[3].substr(0, 12) == 'emulab-ops//') { image_display = sp[3].substr(12) } else { image_display = sp[3] } } else { image_display = formfields.${name} } %><%- image_display %>' >".
"<span class='input-group-btn'><button class='btn btn-success' id='image-select' ".
"style='height: 34px' ".
"type='button' ".
"$data_help_string $advanced_attr ".
"><span class='glyphicon glyphicon-pencil'></span></button></span> ".
"</div>".
"<input id='image-value' ".
"name='$name' type='hidden' ".
"value='<%- formfields.${name} %>' >".
"</div>";
}
else {
$form .=
"<input name='$name' ".
......
......@@ -208,6 +208,7 @@ function REQUIRE_PPWIZARDSTART()
AddTemplate("ppform-wizard");
AddTemplate("ppform-wizard-body");
AddTemplate("choose-am");
AddTemplate("image-picker-modal");
AddLibrary("js/ppwizardstart.js");
}
......
......@@ -97,6 +97,8 @@ $routing = array("myprofiles" =>
"Do_Instantiate",
"GetParameters" =>
"Do_GetParameters",
"GetImageList" =>
"Do_GetImageList",
"GetImageInfo" =>
"Do_GetImageInfo",
"MarkFavorite" =>
......
<!-- This is the topology view modal -->
<div id='imagepicker-modal' class='modal fade'>
<div class='modal-dialog'>
<div class='modal-content'>
<div class='modal-header'>
<button type='button' class='close'
aria-hidden='true'>
&times;</button>
<h3>Select Image...</h3>
</div>
<div class='modal-body'>
<div></div>
<br><br>
</div>
</div>
</div>
</div>
......@@ -15,4 +15,5 @@
</div>
</div>
</form>
<div id="image-picker-body"></div>
<div>
......@@ -359,6 +359,16 @@ class User
# Not via the Portal interface.
function isClassic() { return ($this->portal() ? 0 : 1); }
function urn() {
global $OURDOMAIN;
if ($this->IsNonLocal()) {
return $this->nonlocal_id();
} else {
return 'urn:publicid:IDN+' .
$OURDOMAIN . '+user+' . $this->uid();
}
}
function IsNonLocal() {
return ($this->field("nonlocal_id") ? 1 : 0);
}
......
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