Commit 3d9dba6d by Őry Máté Committed by cloud

dashboard: add simple template based vm list view

closes #107
parent 33415e82
{% extends "dashboard/base.html" %} {% extends "dashboard/base.html" %}
{% load i18n %} {% load i18n %}
{% load render_table from django_tables2 %}
{% block content %} {% block content %}
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading"> <div class="panel-heading">
<h3 class="no-margin"><i class="icon-desktop"></i> Your virtual machines</h3> <h3 class="no-margin"><i class="icon-desktop"></i>{% trans "Virtual machines" %}</h3>
</div> </div>
<div class="pull-right" style="max-width: 250px; margin-top: 15px; margin-right: 15px;"> <div class="pull-right" style="max-width: 250px; margin-top: 15px; margin-right: 15px;">
<form action="" method="GET" class="input-group"> <form action="" method="GET" class="input-group">
<input type="text" name="s"{% if request.GET.s %} value="{{ request.GET.s }}"{% endif %} class="form-control input-tags" placeholder="Search..." /> <input type="text" name="s"{% if request.GET.s %} value="{{ request.GET.s }}"{% endif %} class="form-control input-tags" placeholder="{% trans "Search..."%}" />
<div class="input-group-btn"> <div class="input-group-btn">
<button type="submit" class="form-control btn btn-primary input-tags" title="search"><i class="icon-search"></i></button> <button type="submit" class="form-control btn btn-primary input-tags" title="search"><i class="icon-search"></i></button>
</div> </div>
...@@ -19,31 +18,47 @@ ...@@ -19,31 +18,47 @@
</div> </div>
<div class="panel-body vm-list-group-control"> <div class="panel-body vm-list-group-control">
<p> <p>
<strong>Group actions</strong> <strong>{% trans "Group actions" %}</strong>
<button id="vm-list-group-select-all" class="btn btn-info btn-xs">Select all</button> <button id="vm-list-group-select-all" class="btn btn-info btn-xs">{% trans "Select all" %}</button>
<a class="btn btn-default btn-xs" id="vm-list-group-migrate" disabled><i class="icon-truck"></i> Migrate</a> <a class="btn btn-default btn-xs" id="vm-list-group-migrate" disabled><i class="icon-truck"></i> {% trans "Migrate" %}</a>
<a disabled href="#" class="btn btn-default btn-xs"><i class="icon-refresh"></i> Reboot</a> <a disabled href="#" class="btn btn-default btn-xs"><i class="icon-refresh"></i> {% trans "Reboot" %}</a>
<a disabled href="#" class="btn btn-default btn-xs"><i class="icon-off"></i> Shutdown</a> <a disabled href="#" class="btn btn-default btn-xs"><i class="icon-off"></i> {% trans "Shutdown" %}</a>
<a id="vm-list-group-delete" disabled href="#" class="btn btn-danger btn-xs"><i class="icon-remove"></i> Discard</a> <a id="vm-list-group-delete" disabled href="#" class="btn btn-danger btn-xs"><i class="icon-remove"></i> {% trans "Destroy" %}</a>
</p> </p>
</div> </div>
<div class="panel-body"> <div class="panel-body">
{% render_table table %} <table class="table table-bordered table-striped table-hover vm-list-table">
</div> <thead><tr>
<th class="orderable pk sortable vm-list-table-thin"><a href="?sort=pk">{% trans "ID" %}</a></th>
<th class="name orderable sortable"><a href="?sort=name">{% trans "Name" %}</a></th>
<th>{% trans "State" %}</th>
<th class="orderable sortable"><a href="?sort=owner">{% trans "Owner" %}</a></th>
{% if user.is_superuser %}<th class="orderable sortable"><a href="?sort=node">{% trans "Node" %}</a></th>{% endif %}
</tr></thead><tbody>
{% for i in object_list %}
<tr class="{% cycle 'odd' 'even' %}">
<td class="pk"><div id="vm-{{i.pk}}">{{i.pk}}</div> </td>
<td class="name"><a class="real-link" href="{% url "dashboard.views.detail" i.pk %}">{{ i.name }}</a> </td>
<td class="state">{{ i.cached_state }}</td>
<td>{{ i.owner }}</td>
{% if user.is_superuser %}<td>{{ i.node.name|default:"-" }}</td>{% endif %}
</tr>
{% empty %}
<tr><td colspan="4">{% trans "You have no virtual machines." %}</td></tr>
{% endfor %}
</tbody>
</table>
</div> </div>
</div> </div>
</div> </div>
<div class="alert alert-info">
Tip #1: you can select multiple vm instances while holding down the <strong>CTRL</strong> key!
</div> </div>
<div class="alert alert-info"> <div class="alert alert-info">
Tip #2: if you want to select multiple instances by one click select an instance then hold down <strong>SHIFT</strong> key and select another one! {% trans "You can select multiple vm instances while holding down the <strong>CTRL</strong> key." %}
{% trans "If you want to select multiple instances by one click select an instance then hold down <strong>SHIFT</strong> key and select another one!" %}
</div> </div>
<style> <style>
.popover { .popover {
max-width: 600px; max-width: 600px;
......
...@@ -19,7 +19,7 @@ from django.shortcuts import redirect, render, get_object_or_404 ...@@ -19,7 +19,7 @@ from django.shortcuts import redirect, render, get_object_or_404
from django.views.decorators.http import require_GET from django.views.decorators.http import require_GET
from django.views.generic.detail import SingleObjectMixin from django.views.generic.detail import SingleObjectMixin
from django.views.generic import (TemplateView, DetailView, View, DeleteView, from django.views.generic import (TemplateView, DetailView, View, DeleteView,
UpdateView, CreateView) UpdateView, CreateView, ListView)
from django.contrib import messages from django.contrib import messages
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.template.defaultfilters import title as title_filter from django.template.defaultfilters import title as title_filter
...@@ -36,7 +36,7 @@ from .forms import ( ...@@ -36,7 +36,7 @@ from .forms import (
CircleAuthenticationForm, DiskAddForm, HostForm, LeaseForm, NodeForm, CircleAuthenticationForm, DiskAddForm, HostForm, LeaseForm, NodeForm,
TemplateForm, TraitForm, VmCustomizeForm, TemplateForm, TraitForm, VmCustomizeForm,
) )
from .tables import (VmListTable, NodeListTable, NodeVmListTable, from .tables import (NodeListTable, NodeVmListTable,
TemplateListTable, LeaseListTable, GroupListTable,) TemplateListTable, LeaseListTable, GroupListTable,)
from vm.models import ( from vm.models import (
Instance, instance_activity, InstanceActivity, InstanceTemplate, Interface, Instance, instance_activity, InstanceActivity, InstanceTemplate, Interface,
...@@ -117,9 +117,10 @@ class IndexView(LoginRequiredMixin, TemplateView): ...@@ -117,9 +117,10 @@ class IndexView(LoginRequiredMixin, TemplateView):
} }
}) })
running = [i for i in instances if i.state == 'RUNNING'] running = [i for i in instances if i.cached_state == 'RUNNING']
stopped = [i for i in instances if i.state not in ['RUNNING', stopped = [i for i in instances if i.cached_state not in ['RUNNING',
'NOSTATE']] 'NOSTATE']]
context.update({ context.update({
'running_vms': running, 'running_vms': running,
'running_vm_num': len(running), 'running_vm_num': len(running),
...@@ -872,11 +873,8 @@ class TemplateDelete(LoginRequiredMixin, DeleteView): ...@@ -872,11 +873,8 @@ class TemplateDelete(LoginRequiredMixin, DeleteView):
return HttpResponseRedirect(success_url) return HttpResponseRedirect(success_url)
class VmList(LoginRequiredMixin, SingleTableView): class VmList(LoginRequiredMixin, ListView):
template_name = "dashboard/vm-list.html" template_name = "dashboard/vm-list.html"
table_class = VmListTable
table_pagination = False
model = Instance
def get(self, *args, **kwargs): def get(self, *args, **kwargs):
if self.request.is_ajax(): if self.request.is_ajax():
...@@ -905,7 +903,7 @@ class VmList(LoginRequiredMixin, SingleTableView): ...@@ -905,7 +903,7 @@ class VmList(LoginRequiredMixin, SingleTableView):
s = self.request.GET.get("s") s = self.request.GET.get("s")
if s: if s:
queryset = queryset.filter(name__icontains=s) queryset = queryset.filter(name__icontains=s)
return queryset return queryset.select_related('owner', 'node')
class NodeList(LoginRequiredMixin, SuperuserRequiredMixin, SingleTableView): class NodeList(LoginRequiredMixin, SuperuserRequiredMixin, SingleTableView):
......
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