Commit 317e11b7 by Kálmán Viktor

dashboard: template wizard draft 2

parent f1402363
/* ===========================================================
# bootstrap-tour - v0.9.1
# http://bootstraptour.com
# ==============================================================
# Copyright 2012-2013 Ulrich Sossou
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
*/
.tour-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1100;background-color:#000;opacity:.8}.tour-step-backdrop{position:relative;z-index:1101;background:inherit}.tour-step-background{position:absolute;z-index:1100;background:inherit;border-radius:6px}.popover[class*=tour-]{z-index:1100}.popover[class*=tour-] .popover-navigation{padding:9px 14px}.popover[class*=tour-] .popover-navigation [data-role=end]{float:right}.popover[class*=tour-] .popover-navigation [data-role=prev],.popover[class*=tour-] .popover-navigation [data-role=next],.popover[class*=tour-] .popover-navigation [data-role=end]{cursor:pointer}.popover[class*=tour-] .popover-navigation [data-role=prev].disabled,.popover[class*=tour-] .popover-navigation [data-role=next].disabled,.popover[class*=tour-] .popover-navigation [data-role=end].disabled{cursor:default}.popover[class*=tour-].orphan{position:fixed;margin-top:0}.popover[class*=tour-].orphan .arrow{display:none}
\ No newline at end of file
/* TODO i18n
* https://docs.djangoproject.com/en/1.5/topics/i18n/translation/#internationalization-in-javascript-code
* TODO new tour template
* http://bootstraptour.com/api/
* TODO change placeholder yos
*/
$(function() {
$(".vm-details-start-template-tour").click(function() {
ttour = createTemplateTour();
ttour.init();
ttour.start();
});
});
function createTemplateTour() {
var ttour = new Tour({
storage: false,
});
ttour.addStep({
element: ".alert-new-template",
title: "Template Tutorial Tour",
content: "Welcome to the template tutorial. In this quick tour, we gonna show you how to do the steps described above. " +
"For the next tour step press the Next button or the right arrow (or Back button/left arrow for the previous step). " +
"During the tour please don't try the functions because it may lead to graphical glitches, however " +
"you can end the tour any time you want with the End Tour button!",
placement: "bottom",
backdrop: true,
});
ttour.addStep({
backdrop: true,
element: 'a[href="#home"]',
title: "Home tab",
content: "yo",
placement: 'top',
onShow: function() {
console.log("yosag van");
$('a[href="#home"]').trigger("click");
},
});
ttour.addStep({
element: 'a[href="#resources"]',
title: "Resources tab",
backdrop: true,
placement: 'top',
content: "On the resources tab you can edit the CPU/RAM options and add/remove disks!",
onShow: function() {
$('a[href="#resources"]').trigger("click");
},
});
ttour.addStep({
element: '#vm-details-resources-form',
placement: 'left',
backdrop: true,
title: "Resources",
content: '<p><strong>CPU priority:</strong> higher (or lower?) is better</p>' +
'<p><strong>CPU count:</strong> yooo</p>' +
'<p><strong>RAM amount:</strong> yoo RAM</p>',
onShow: function() {
$('a[href="#resources"]').trigger("click");
},
});
ttour.addStep({
element: '.vm-details-resources-disk',
backdrop: true,
placement: 'left',
title: "Disks",
content: "jo a kontent, bar lehetne hosszabb is es akkor nem nez ki ilyen butan az end tour gomb!",
onShow: function() {
$('a[href="#resources"]').trigger("click");
},
});
ttour.addStep({
element: 'a[href="#network"]',
backdrop: true,
placement: 'top',
title: "Network tab",
content: 'You can add new network interfaces or remove existing ones here.',
onShow: function() {
$('a[href="#network"]').trigger("click");
},
});
ttour.addStep({
element: "#vm-details-button-deploy",
title: "Deploy",
backdrop: true,
content: "Deploy the virtual machine",
});
ttour.addStep({
element: "#vm-info-pane",
title: "Connect",
backdrop: true,
content: "Use the connection string or connect with your choice of client!",
});
ttour.addStep({
element: ".alert-new-template",
placement: "bottom",
title: "Customize the virtual machine",
content: "Do the modifications",
});
ttour.addStep({
element: ".vm-details-button-save-as",
title: "Save",
placement: "left",
backdrop: true,
content: "Press this button and wait!",
});
ttour.addStep({
element: ".alert-new-template",
title: "Fin",
backdrop: true,
placement: "bottom",
content: "Congrats you managed to sit trough this exciting tour!",
});
return ttour;
}
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
<script src="{{ STATIC_URL }}dashboard/js/jquery.knob.js"></script> <script src="{{ STATIC_URL }}dashboard/js/jquery.knob.js"></script>
<script src="{{ STATIC_URL}}dashboard/bootstrap-slider/bootstrap-slider.js"></script> <script src="{{ STATIC_URL}}dashboard/bootstrap-slider/bootstrap-slider.js"></script>
<link rel="stylesheet" href="{{ STATIC_URL }}dashboard/bootstrap-slider/slider.css"/> <link rel="stylesheet" href="{{ STATIC_URL }}dashboard/bootstrap-slider/slider.css"/>
<link href="{{ STATIC_URL }}dashboard/bootstrap-tour.min.css" rel="stylesheet">
<link href="{{ STATIC_URL }}dashboard/dashboard.css" rel="stylesheet"> <link href="{{ STATIC_URL }}dashboard/dashboard.css" rel="stylesheet">
<script src="{{ STATIC_URL }}dashboard/dashboard.js"></script> <script src="{{ STATIC_URL }}dashboard/dashboard.js"></script>
</head> </head>
......
...@@ -4,7 +4,8 @@ ...@@ -4,7 +4,8 @@
{% trans "Customize an existing template or create a brand new one from scratch!" %} {% trans "Customize an existing template or create a brand new one from scratch!" %}
</div> </div>
<form action="{% url "dashboard.views.template-create" %}"> <form action="{% url "dashboard.views.template-choose" %}" method="POST">
{% csrf_token %}
<div class="template-choose-list"> <div class="template-choose-list">
{% for t in templates %} {% for t in templates %}
<div class="panel panel-default template-choose-list-element"> <div class="panel panel-default template-choose-list-element">
......
...@@ -4,6 +4,51 @@ ...@@ -4,6 +4,51 @@
{% block title-page %}{{ instance.name }} | vm{% endblock %} {% block title-page %}{{ instance.name }} | vm{% endblock %}
{% block content %} {% block content %}
<style>
.alert-new-template {
background: #3071a9;
color: white;
font-size: 25px;
}
.alert-new-template ol {
margin-left: 25px;
}
</style>
{% if instance.is_base %}
<div class="alert alert-info alert-new-template">
<strong>{% trans "This is the master vm of your new template" %}</strong>
<a href="#" class="btn btn-default btn-lg pull-right vm-details-start-template-tour">
<i class="icon-play"></i> {% trans "Start template tutorial tour" %}
</a>
<ol>
<li>Modify the vm to suit your needs <strong>(optional)</strong>
<ul>
<li>Change the description</li>
<li>Change the resources it will need (CPU and RAM)</li>
<li>Attach or deattach disks</li>
<li>Add or remove network interfaces</li>
</ul>
</li>
<li>Deploy the vm</li>
<li>Connect to the machine</li>
<li>Do all the needed installation/customization</li>
<li>Log off</li>
<li>
Press the "Save as template" button
<form style="display: inline;" class="vm-details-button-save-as pull-right"
method="POST" action="{% url "dashboard.views.detail" pk=instance.pk %}">
{% csrf_token %}
<input type="hidden" name="save_as" />
<button class="btn btn-default btn-lg" type="submit">
<i class="icon-save"></i> {% trans "Save as template" %}
</button>
</form>
</li>
</ol>
</div>
{% endif %}
<div class="body-content"> <div class="body-content">
<div class="page-header"> <div class="page-header">
<div class="pull-right" style="padding-top: 15px;"> <div class="pull-right" style="padding-top: 15px;">
...@@ -12,7 +57,7 @@ ...@@ -12,7 +57,7 @@
<input type="hidden" name="sleep" /> <input type="hidden" name="sleep" />
<button title="{% trans "Sleep" %}" class="btn btn-default btn-xs" type="submit"><i class="icon-moon"></i></button> <button title="{% trans "Sleep" %}" class="btn btn-default btn-xs" type="submit"><i class="icon-moon"></i></button>
</form> </form>
<form style="display: inline;" method="POST" action="{% url "dashboard.views.detail" pk=instance.pk %}"> <form style="display: inline;" method="POST" action="{% url "dashboard.views.detail" pk=instance.pk %}" id="vm-details-button-deploy">
{% csrf_token %} {% csrf_token %}
<input type="hidden" name="deploy" /> <input type="hidden" name="deploy" />
<button title="{% trans "Deploy" %}" class="btn btn-default btn-xs" type="submit"><i class="icon-play"></i></button> <button title="{% trans "Deploy" %}" class="btn btn-default btn-xs" type="submit"><i class="icon-play"></i></button>
...@@ -47,7 +92,7 @@ ...@@ -47,7 +92,7 @@
<a title="Migrate" data-vm-pk="{{ instance.pk }}" href="{% url "dashboard.views.vm-migrate" pk=instance.pk %}" class="btn btn-default btn-xs vm-migrate"> <a title="Migrate" data-vm-pk="{{ instance.pk }}" href="{% url "dashboard.views.vm-migrate" pk=instance.pk %}" class="btn btn-default btn-xs vm-migrate">
<i class="icon-truck"></i> <i class="icon-truck"></i>
</a> </a>
<form style="display: inline;" method="POST" action="{% url "dashboard.views.detail" pk=instance.pk %}"> <form style="display: inline;" class="vm-details-button-save-as" method="POST" action="{% url "dashboard.views.detail" pk=instance.pk %}">
{% csrf_token %} {% csrf_token %}
<input type="hidden" name="save_as" /> <input type="hidden" name="save_as" />
<button title="{% trans "Save as template" %}" class="btn btn-default btn-xs" type="submit"><i class="icon-save"></i></button> <button title="{% trans "Save as template" %}" class="btn btn-default btn-xs" type="submit"><i class="icon-save"></i></button>
...@@ -194,8 +239,10 @@ ...@@ -194,8 +239,10 @@
{% endblock %} {% endblock %}
{% block extra_js %} {% block extra_js %}
<script src="{{ STATIC_URL }}dashboard/bootstrap-tour.min.js"></script>
<script src="{{ STATIC_URL }}dashboard/vm-details.js"></script> <script src="{{ STATIC_URL }}dashboard/vm-details.js"></script>
<script src="{{ STATIC_URL }}dashboard/vm-common.js"></script> <script src="{{ STATIC_URL }}dashboard/vm-common.js"></script>
<script src="{{ STATIC_URL }}dashboard/vm-console.js"></script> <script src="{{ STATIC_URL }}dashboard/vm-console.js"></script>
<script src="{{ STATIC_URL }}dashboard/disk-list.js"></script> <script src="{{ STATIC_URL }}dashboard/disk-list.js"></script>
<script src="{{ STATIC_URL }}dashboard/vm-tour.js"></script>
{% endblock %} {% endblock %}
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
<hr /> <hr />
<div class="row"> <div class="row vm-details-resources-disk">
<div class="col-sm-11"> <div class="col-sm-11">
<h3> <h3>
{% trans "Disks" %} {% trans "Disks" %}
......
...@@ -757,10 +757,25 @@ class TemplateChoose(TemplateView): ...@@ -757,10 +757,25 @@ class TemplateChoose(TemplateView):
'box_title': _('Choose template'), 'box_title': _('Choose template'),
'ajax_title': False, 'ajax_title': False,
'template': "dashboard/_template-create-1.html", 'template': "dashboard/_template-create-1.html",
'templates': templates.all(), 'templates': templates.all(), # TODO acl?
}) })
return context return context
def post(self, request, *args, **kwargs):
if not request.user.has_perm('vm.create_template'):
raise PermissionDenied()
template = request.POST.get("parent")
if template == "base_vm":
return redirect(reverse("dashboard.views.template-create"))
else:
template = get_object_or_404(InstanceTemplate, pk=template)
instance = Instance.create_from_template(
template=template, owner=request.user, is_base=True)
return redirect(instance.get_absolute_url())
class TemplateClone(CreateView): class TemplateClone(CreateView):
template_name = "dashboard/template-clone.html" template_name = "dashboard/template-clone.html"
......
...@@ -212,6 +212,7 @@ class Instance(AclBase, VirtualMachineDescModel, StatusModel, ...@@ -212,6 +212,7 @@ class Instance(AclBase, VirtualMachineDescModel, StatusModel,
vnc_port = IntegerField(blank=True, default=None, null=True, vnc_port = IntegerField(blank=True, default=None, null=True,
help_text=_("TCP port where VNC console listens."), help_text=_("TCP port where VNC console listens."),
unique=True, verbose_name=_('vnc_port')) unique=True, verbose_name=_('vnc_port'))
is_base = BooleanField(default=False)
owner = ForeignKey(User) owner = ForeignKey(User)
destroyed_at = DateTimeField(blank=True, null=True, destroyed_at = DateTimeField(blank=True, null=True,
help_text=_("The virtual machine's time of " help_text=_("The virtual machine's time of "
......
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 sign in to comment