Commit cbb56d52 authored by Keith Downie's avatar Keith Downie Committed by Leigh Stoller

Added wizard files

parent 6973d80e
/*
Common
*/
.wizard,
.tabcontrol
{
display: block;
width: 100%;
overflow: hidden;
}
.wizard a,
.tabcontrol a
{
outline: 0;
}
.wizard ul,
.tabcontrol ul
{
list-style: none !important;
padding: 0;
margin: 0;
}
.wizard ul > li,
.tabcontrol ul > li
{
display: block;
padding: 0;
}
/* Accessibility */
.wizard > .steps .current-info,
.tabcontrol > .steps .current-info
{
position: absolute;
left: -999em;
}
/*
Wizard
*/
.wizard > .steps
{
position: relative;
display: block;
margin-bottom: 10px;
padding: 0 7px 0 8px;
}
.wizard.vertical > .steps
{
display: inline;
float: left;
width: 30%;
}
.wizard > .steps .number
{
font-size: 1.429em;
}
.wizard > .steps > ul > li
{
width: 33.3%;
}
.wizard > .steps > ul > li,
.wizard > .actions > ul > li
{
float: left;
}
.wizard.vertical > .steps > ul > li
{
float: none;
width: 100%;
}
.wizard > .steps a,
.wizard > .steps a:hover,
.wizard > .steps a:active
{
display: block;
width: auto;
margin: 0 0.5em 0.5em;
padding: 1em 1em;
text-decoration: none;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
}
.wizard > .steps .disabled a,
.wizard > .steps .disabled a:hover,
.wizard > .steps .disabled a:active
{
background: #eee;
color: #aaa;
cursor: default;
}
.wizard > .steps .current a,
.wizard > .steps .current a:hover,
.wizard > .steps .current a:active
{
background: #2184be;
color: #fff;
cursor: default;
}
.wizard > .steps .done a,
.wizard > .steps .done a:hover,
.wizard > .steps .done a:active
{
background: #9dc8e2;
color: #fff;
}
.wizard > .steps .error a,
.wizard > .steps .error a:hover,
.wizard > .steps .error a:active
{
background: #ff3111;
color: #fff;
}
.wizard > .actions
{
position: relative;
display: block;
text-align: right;
padding: 0 7px;
}
.wizard.vertical > .actions
{
display: inline;
float: right;
margin: 0 2.5%;
width: 95%;
}
.wizard > .actions > ul
{
display: inline-block;
text-align: right;
}
.wizard > .actions > ul > li
{
margin: 0 0.5em;
}
.wizard.vertical > .actions > ul > li
{
margin: 0 0 0 1em;
}
.wizard > .actions a,
.wizard > .actions a:hover,
.wizard > .actions a:active
{
background: #2184be;
color: #fff;
display: block;
padding: 0.5em 1em;
text-decoration: none;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
}
.wizard > .actions .disabled a,
.wizard > .actions .disabled a:hover,
.wizard > .actions .disabled a:active
{
background: #eee;
color: #aaa;
}
.wizard > .loading
{
}
.wizard > .loading .spinner
{
}
/*
Tabcontrol
*/
.tabcontrol > .steps
{
position: relative;
display: block;
width: 100%;
}
.tabcontrol > .steps > ul
{
position: relative;
margin: 6px 0 0 0;
top: 1px;
z-index: 1;
}
.tabcontrol > .steps > ul > li
{
float: left;
margin: 5px 2px 0 0;
padding: 1px;
-webkit-border-top-left-radius: 5px;
-webkit-border-top-right-radius: 5px;
-moz-border-radius-topleft: 5px;
-moz-border-radius-topright: 5px;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
}
.tabcontrol > .steps > ul > li:hover
{
background: #edecec;
border: 1px solid #bbb;
padding: 0;
}
.tabcontrol > .steps > ul > li.current
{
background: #fff;
border: 1px solid #bbb;
border-bottom: 0 none;
padding: 0 0 1px 0;
margin-top: 0;
}
.tabcontrol > .steps > ul > li > a
{
color: #5f5f5f;
display: inline-block;
border: 0 none;
margin: 0;
padding: 10px 30px;
text-decoration: none;
}
.tabcontrol > .steps > ul > li > a:hover
{
text-decoration: none;
}
.tabcontrol > .steps > ul > li.current > a
{
padding: 15px 30px 10px 30px;
}
.tabcontrol > .content
{
position: relative;
display: inline-block;
width: 100%;
height: 35em;
overflow: hidden;
border-top: 1px solid #bbb;
padding-top: 20px;
}
.wizard > .content > .title,
.tabcontrol > .content > .title
{
position: absolute;
left: -999em;
}
.wizard form {
margin: 0;
}
#inline_jacks #showtopo_dialog, #inline_jacks #edit_dialog,
#inline_large_jacks #showtopo_dialog, #inline_large_jacks #edit_dialog {
width: auto;
}
#inline_jacks .panel, #inline_jacks .panel-body {
padding: 0;
margin: 0;
}
#inline_jacks #edit_nopicker {
height: auto;
}
.wizard #finalize_container .panel {
margin: 0;
}
.wizard #finalize_container {
padding: 0;
margin-bottom: 20px;
}
.wizard #inline_container {
padding: 0;
margin-bottom: 20px;
position: relative;
}
.wizard #inline_container #inline_overlay {
position: absolute;
display: block;
top: 0;
left: 0;
height: 100%;
width: 100%;
z-index: 20;
}
#inline_large_container button.close {
padding: 1px 5px 0 0;
}
@media (min-width: 768px) {
.wizard #finalize_container.col-lg-8 {
padding-right: 5px;
}
.wizard #inline_container {
padding-left: 10px;
}
}
\ No newline at end of file
This diff is collapsed.
//
// Start a Parameterized Profile
//
define(['underscore', 'js/quickvm_sup', 'js/JacksEditor',
'js/lib/text!template/ppform-wizard.html',
'js/lib/text!template/ppform-wizard-body.html',
'js/lib/text!template/choose-am.html',
],
function(_, sup, JacksEditor, ppmodalString, ppbodyString, chooserString)
{
'use strict';
var bodyTemplate = null;
var chooseTemplate= null;
var editor = null;
var editorLarge = null;
var defaults = null;
var uuid = "";
var amlist = null;
var amdefault = null;
var registered = true;
var callback_done = null;
var button_label = "Instantiate";
var RSPEC = null;
//
// Moved into a separate function since we want to regen the form
// after each submit, which happens via ajax on this page.
//
function GenerateModalBody(formfields, errors){
// Generate the template.
var html = bodyTemplate({
formfields: formfields,
});
html = formatter(html, errors).html();
$('#ppmodal-body').html(html);
if (!registered) {
$('#pp_form :input').attr('readonly', true);
// This is the only way to disable selects
$('#pp_form :input').attr('disabled', true);
// Have to renable the buttons after disabling selects
$('#pp_form :button').attr('disabled', false);
$('#pp_form :button').attr('readonly', false);
}
//
// Handle submit button.
//
$('#modal_profile_continue_button').click(function (event) {
event.preventDefault();
HandleSubmit();
});
}
// Formatter for the form. This did not work out nicely at all!
function formatter(fieldString, errors)
{
var root = $(fieldString);
var list = root.find('.format-me');
list.each(function (index, item) {
if (item.dataset) {
var key = item.dataset['key'];
var margin = 15;
var colsize = 12;
var outerdiv = $("<div class='form-group' " +
" style='margin-bottom: " + margin +
"px;'></div>");
if ($(item).attr('data-label')) {
var label_text =
"<label for='" + key + "' " +
" class='col-sm-4 control-label'> " +
item.dataset['label'];
if ($(item).attr('data-help')) {
label_text = label_text +
"<a href='#' class='btn btn-xs' " +
" data-toggle='popover' " +
" data-html='true' " +
" data-delay='{\"hide\":1000}' " +
" data-content='" +
item.dataset['help'] + "'>" +
"<span class='glyphicon " +
"glyphicon-question-sign'>" +
" </span></a>";
}
label_text = label_text + "</label>";
outerdiv.append($(label_text));
colsize = 6;
}
var innerdiv = $("<div class='col-sm-" +
colsize + "'></div>");
innerdiv.html($(item).clone());
if (errors && _.has(errors, key)) {
outerdiv.addClass('has-error');
innerdiv.append('<label class="control-label" ' +
'for="inputError">' +
_.escape(errors[key]) + '</label>');
}
outerdiv.append(innerdiv);
$(item).after(outerdiv);
$(item).remove();
}
});
return root;
}
function HandleSubmit()
{
/*
* If not a registered user, then continue takes them back.
*/
if (!registered) {
sup.HideModal('#ppmodal');
if (callback_done) {
callback_done(null);
}
return;
}
// Submit with check only at first, since this will return
// very fast, so no need to throw up a waitwait.
SubmitForm(1);
}
// Instantiate the new rspec on the chosen aggregate.
function Instantiate(where)
{
if (callback_done) {
callback_done(RSPEC, where);
return;
}
var callback = function(json) {
sup.HideModal("#waitwait-modal");
if (json.code) {
sup.SpitOops("oops", json.value);
return;
}
window.location.replace(json.value);
}
sup.ShowModal("#waitwait-modal");
var xmlthing = sup.CallServerMethod(null, "instantiate",
"Instantiate",
{"rspec" : RSPEC,
"where" : where,
"uuid" : uuid});
xmlthing.done(callback);
}
//
// Editor callback, returning the new rspec.
//
function EditorDone(newRspec)
{
if (!amlist || amlist.length == 1) {
Instantiate(amdefault);
}
var html = chooseTemplate({
amlist : amlist,
amdefault : amdefault,
});
$('#instantiate_div').html(html);
// Handler for instantiate submit button, which is in
// the modal.
$('#stepsContainer .actions a[href="#finish"]').click(function (event) {
event.preventDefault();
Instantiate($('.aggregate_selector #profile_where option:selected').val());
$('#instantiate_submit').click();
});
}
//
// Editor canceled; put back the configure modal.
//
function EditorCancel()
{
sup.ShowModal('#ppmodal');
}
//
// Submit the form. If no errors, we get back the rspec. Throw that
// up in a Jack editor window.
//
function SubmitForm(checkonly)
{
// Current form contents as formfields array.
var formfields = {};
var callback = function(json) {
if (!checkonly) {
sup.HideModal("#waitwait-modal");
}
if (json.code) {
if (checkonly && json.code == 2) {
// Regenerate page with errors.
GenerateModalBody(formfields, json.value);
return;
}
sup.HideModal('#ppmodal');
$('#stepsContainer').steps('previous');
$('#stepsContainer-t-1').parent().addClass('error');
//sup.SpitOops("oops", json.value);
return;
}
if (checkonly) {
// Form checked out okay, submit again to generate rspec.
sup.HideModal('#ppmodal');
sup.ShowModal("#waitwait-modal");
SubmitForm(0);
}
else {
if (_.has(json.value, "amdefault")) {
amdefault = json.value.amdefault;
}
// Got the rspec, show the editor.
RSPEC = json.value.rspec;
editor.show(json.value.rspec,
EditorDone, EditorCancel, button_label);
EditorDone(editor.fetchXml());
}
}
// Convert form data into formfields array, like all our
// form handler pages expect.
var fields = $('#pp_form').serializeArray();
$.each(fields, function(i, field) {
formfields[field.name] = field.value;
});
// This clears any errors before new submit. Needs more thought.
GenerateModalBody(formfields, null);
var xmlthing = sup.CallServerMethod(null, "manage_profile",
"BindParameters",
{"formfields" : formfields,
"uuid" : uuid,
"checkonly" : checkonly});
xmlthing.done(callback);
}
function StartPP(args) {
uuid = args.uuid;
registered = args.registered;
amlist = args.amlist;
amdefault = args.amdefault;
if (bodyTemplate) {
GenerateModalBody(defaults, null);
//sup.ShowModal('#ppmodal');
return;
}
// Caller might already have an editor instance.
editor = new JacksEditor($('#inline_jacks'), true, true, true, true);
// Callback; instead of instantiate, send rspec to callback.
if (_.has(args, "callback")) {
callback_done = args.callback;
}
// Allow caller to change the Jacks accept button label.
if (_.has(args, "button_label")) {
button_label = args.button_label;
}
/*
* Need to ask for the profile parameter form fragment and
* the initial values.
*/
var callback = function(json) {
console.info(json);
if (json.code) {
sup.SpitOops("oops", json.value);
}
defaults = json.value.defaults;
// This is the modal.
$('#stepsContainer-p-1').html(ppmodalString);
// This is the form inside the modal
bodyTemplate = _.template(ppbodyString);
// This is the aggregate selector modal.
chooseTemplate = _.template(chooserString);
// Build a new template by inserting the form fragment, which
// itself will refer to templated variables.
var html = bodyTemplate({
registered: registered,
formfrag: _.unescape(json.value.formfrag),
});
bodyTemplate = _.template(html);
GenerateModalBody(defaults, null);
//sup.ShowModal('#ppmodal');
}
var xmlthing = sup.CallServerMethod(null, "instantiate",
"GetParameters",
{"uuid" : uuid});
xmlthing.done(callback);
}
function ChangeJacksRoot(root, selectionPane) {
editor = new JacksEditor(root, true, true, selectionPane, true);
editor.show(RSPEC,
EditorDone, EditorCancel, button_label);
}
return {
HandleSubmit: HandleSubmit,
StartPP: StartPP,
ChangeJacksRoot: ChangeJacksRoot,
};
}
);
<!-- This is the topology edit modal -->
<div id='quickvm_editmodal'>
<div id='edit_dialog'>
<div class='panel panel-default'>
<div class='panel-body'>
<!-- This topo diagram goes inside this div -->
<div id='edit_container'>
<div>
<div id='edit_nopicker' class='jacks'></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<% if (! registered) { %>
<div class='text-warning'>
Since you are a guest user, you are required to use the default values
when instantiating this profile. If you want to configure different
values, please <a href='signup.php'>register for an account.</a>
</div>
<br>
<% } %>
<form id='pp_form'
class='form-horizontal' role='form' method='post'>
<div class='row'>
<div class='col-sm-12'>
<%= formfrag %>
</div>
</div>
</form>
<div>
<div>
<div class='panel panel-default'>
<div class='panel-heading'>
This profile is parameterized; please make your selections below,
and then click to continue.
</div>
<div class='panel-body'>
<div id='ppmodal-body'></div>
</div>
</div>
</div>
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