Commit a304c0e4 by Kálmán Viktor

dashboard: reworked template list

parent aea321fc
......@@ -1184,3 +1184,22 @@ class VmListSearchForm(forms.Form):
data = self.data.copy()
data['stype'] = "all"
self.data = data
class TemplateListSearchForm(forms.Form):
s = forms.CharField(widget=forms.TextInput(attrs={
'class': "form-control input-tags",
'placeholder': _("Search...")
}))
stype = forms.ChoiceField(vm_search_choices, widget=forms.Select(attrs={
'class': "btn btn-default input-tags",
}))
def __init__(self, *args, **kwargs):
super(TemplateListSearchForm, self).__init__(*args, **kwargs)
# set initial value, otherwise it would be overwritten by request.GET
if not self.data.get("stype"):
data = self.data.copy()
data['stype'] = "all"
self.data = data
......@@ -39,6 +39,7 @@ $(function() {
$(".template-list-table thead th").css("cursor", "pointer");
$(".template-list-table th a").on("click", function(event) {
if(!$(this).closest("th").data("sort")) return true;
event.preventDefault();
});
});
......
......@@ -146,13 +146,10 @@ class TemplateListTable(Table):
template_name="dashboard/template-list/column-template-name.html",
attrs={'th': {'data-sort': "string"}}
)
num_cores = Column(
verbose_name=_("Cores"),
attrs={'th': {'data-sort': "int"}}
)
ram_size = TemplateColumn(
"{{ record.ram_size }} MiB",
resources = TemplateColumn(
template_name="dashboard/template-list/column-template-resources.html",
attrs={'th': {'data-sort': "int"}},
order_by=("ram_size"),
)
lease = TemplateColumn(
"{{ record.lease.name }}",
......@@ -170,11 +167,14 @@ class TemplateListTable(Table):
verbose_name=_("Owner"),
attrs={'th': {'data-sort': "string"}}
)
created = TemplateColumn(
template_name="dashboard/template-list/column-template-created.html",
verbose_name=_("Created at"),
)
running = TemplateColumn(
template_name="dashboard/template-list/column-template-running.html",
verbose_name=_("Running"),
attrs={'th': {'data-sort': "int"}},
orderable=False,
)
actions = TemplateColumn(
verbose_name=_("Actions"),
......@@ -187,8 +187,8 @@ class TemplateListTable(Table):
model = InstanceTemplate
attrs = {'class': ('table table-bordered table-striped table-hover'
' template-list-table')}
fields = ('name', 'num_cores', 'ram_size', 'system',
'access_method', 'lease', 'owner', 'running', 'actions', )
fields = ('name', 'resources', 'system', 'access_method', 'lease',
'owner', 'created', 'running', 'actions', )
prefix = "template-"
......
{% load i18n %}
{% if user and user.pk %}
{% if user.get_full_name %}
{{ user.get_full_name }}
{% else %}
{{ user.username }}
{% endif %}
{% if user.get_full_name %}{{ user.get_full_name }}{% else %}{{ user.username }}{% endif %}{% if new_line %}<br />{% endif %}
{% if show_org %}
{% if user.profile and user.profile.org_id %}
......
{{ record.created|date }}
<br />
{{ record.created|time }}
{% include "dashboard/_display-name.html" with user=record.owner show_org=True %}
{% include "dashboard/_display-name.html" with user=record.owner show_org=True new_line=True %}
{% load i18n %}
{{ record.ram_size }}MiB RAM
<br />
{% blocktrans with num_cores=record.num_cores count count=record.num_cores %}
{{ num_cores }} CPU core
{% plural %}
{{ num_cores }} CPU cores
{% endblocktrans %}
......@@ -70,7 +70,8 @@ from .forms import (
VmSaveForm, UserKeyForm, VmRenewForm, VmStateChangeForm,
CirclePasswordChangeForm, VmCreateDiskForm, VmDownloadDiskForm,
TraitsForm, RawDataForm, GroupPermissionForm, AclUserAddForm,
VmResourcesForm, VmAddInterfaceForm, VmListSearchForm
VmResourcesForm, VmAddInterfaceForm, VmListSearchForm,
TemplateListSearchForm,
)
from .tables import (
......@@ -169,6 +170,52 @@ class FilterMixin(object):
return super(FilterMixin,
self).get_queryset().filter(**self.get_queryset_filters())
def create_fake_get(self):
"""
Updates the request's GET dict to filter the vm list
For example: "name:xy node:1" updates the GET dict
to resemble this URL ?name=xy&node=1
"name:xy node:1".split(":") becomes ["name", "xy node", "1"]
we pop the the first element and use it as the first dict key
then we iterate over the rest of the list and split by the last
whitespace, the first part of this list will be the previous key's
value, then last part of the list will be the next key.
The final dict looks like this: {'name': xy, 'node':1}
"""
s = self.request.GET.get("s")
if s:
s = s.split(":")
if len(s) < 2: # if there is no ':' in the string, filter by name
got = {'name': s[0]}
else:
latest = s.pop(0)
got = {'%s' % latest: None}
for i in s[:-1]:
new = i.rsplit(" ", 1)
got[latest] = new[0]
latest = new[1] if len(new) > 1 else None
got[latest] = s[-1]
# generate a new GET request, that is kinda fake
fake = self.request.GET.copy()
for k, v in got.iteritems():
fake[k] = v
self.request.GET = fake
def create_acl_queryset(self, model):
cleaned_data = self.search_form.cleaned_data
stype = cleaned_data.get('stype', "all")
superuser = stype == "all"
shared = stype == "shared"
level = "owner" if stype == "owned" else "user"
queryset = model.get_objects_with_level(
level, self.request.user,
group_also=shared, disregard_superuser=not superuser,
)
return queryset
class IndexView(LoginRequiredMixin, TemplateView):
template_name = "dashboard/index.html"
......@@ -1517,7 +1564,7 @@ class TemplateDetail(LoginRequiredMixin, SuccessMessageMixin, UpdateView):
return kwargs
class TemplateList(LoginRequiredMixin, SingleTableView):
class TemplateList(LoginRequiredMixin, FilterMixin, SingleTableView):
template_name = "dashboard/template-list.html"
model = InstanceTemplate
table_class = TemplateListTable
......@@ -1525,15 +1572,24 @@ class TemplateList(LoginRequiredMixin, SingleTableView):
def get_context_data(self, *args, **kwargs):
context = super(TemplateList, self).get_context_data(*args, **kwargs)
context['lease_table'] = LeaseListTable(Lease.objects.all(),
request=self.request)
context['lease_table'] = LeaseListTable(
Lease.get_objects_with_level("user", self.request.user),
request=self.request)
context['search_form'] = self.search_form
return context
def get(self, *args, **kwargs):
self.search_form = TemplateListSearchForm(self.request.GET)
self.search_form.full_clean()
return super(TemplateList, self).get(*args, **kwargs)
def get_queryset(self):
logger.debug('TemplateList.get_queryset() called. User: %s',
unicode(self.request.user))
return InstanceTemplate.get_objects_with_level(
'user', self.request.user).all()
queryset = self.create_acl_queryset(InstanceTemplate)
return queryset.annotate(running=Count('instance_set'))
class TemplateDelete(LoginRequiredMixin, DeleteView):
......@@ -1611,7 +1667,7 @@ class VmList(LoginRequiredMixin, FilterMixin, ListView):
def get_queryset(self):
logger.debug('VmList.get_queryset() called. User: %s',
unicode(self.request.user))
queryset = self.create_default_queryset()
queryset = self.create_acl_queryset(Instance).filter(destroyed_at=None)
self.create_fake_get()
sort = self.request.GET.get("sort")
......@@ -1626,52 +1682,6 @@ class VmList(LoginRequiredMixin, FilterMixin, ListView):
**self.get_queryset_filters()).select_related('owner', 'node'
).distinct()
def create_default_queryset(self):
cleaned_data = self.search_form.cleaned_data
stype = cleaned_data.get('stype', "all")
superuser = stype == "all"
shared = stype == "shared"
level = "owner" if stype == "owned" else "user"
queryset = Instance.get_objects_with_level(
level, self.request.user,
group_also=shared, disregard_superuser=not superuser,
).filter(destroyed_at=None)
return queryset
def create_fake_get(self):
"""
Updates the request's GET dict to filter the vm list
For example: "name:xy node:1" updates the GET dict
to resemble this URL ?name=xy&node=1
"name:xy node:1".split(":") becomes ["name", "xy node", "1"]
we pop the the first element and use it as the first dict key
then we iterate over the rest of the list and split by the last
whitespace, the first part of this list will be the previous key's
value, then last part of the list will be the next key.
The final dict looks like this: {'name': xy, 'node':1}
"""
s = self.request.GET.get("s")
if s:
s = s.split(":")
if len(s) < 2: # if there is no ':' in the string, filter by name
got = {'name': s[0]}
else:
latest = s.pop(0)
got = {'%s' % latest: None}
for i in s[:-1]:
new = i.rsplit(" ", 1)
got[latest] = new[0]
latest = new[1] if len(new) > 1 else None
got[latest] = s[-1]
# generate a new GET request, that is kinda fake
fake = self.request.GET.copy()
for k, v in got.iteritems():
fake[k] = v
self.request.GET = fake
class NodeList(LoginRequiredMixin, SuperuserRequiredMixin, SingleTableView):
template_name = "dashboard/node-list.html"
......
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