Allows row status to be determined as the aggregate of multiple columns.
Instances table handles both status columns correctly now. Fixes bug 948419. Syspanel instances table no longer has "launch instance" action. Fixes bug 952609. Allows ajax-updating for volumes table. Fixes bug 948396. Change-Id: I8657c79d0ab7ec5972cc7c4886d7f009a1710876
This commit is contained in:
parent
24f6bc59b2
commit
44f670e104
@ -201,13 +201,20 @@ class InstancesTable(tables.DataTable):
|
||||
(None, True),
|
||||
("none", True)
|
||||
)
|
||||
STATUS_CHOICES = (
|
||||
("active", True),
|
||||
("error", False),
|
||||
)
|
||||
name = tables.Column("name", link="horizon:nova:instances_and_volumes:" \
|
||||
"instances:detail",
|
||||
verbose_name=_("Instance Name"))
|
||||
ip = tables.Column(get_ips, verbose_name=_("IP Address"))
|
||||
size = tables.Column(get_size, verbose_name=_("Size"))
|
||||
status = tables.Column("status", filters=(title,),
|
||||
verbose_name=_("Status"))
|
||||
status = tables.Column("status",
|
||||
filters=(title,),
|
||||
verbose_name=_("Status"),
|
||||
status=True,
|
||||
status_choices=STATUS_CHOICES)
|
||||
task = tables.Column("OS-EXT-STS:task_state",
|
||||
verbose_name=_("Task"),
|
||||
filters=(title,),
|
||||
@ -220,7 +227,7 @@ class InstancesTable(tables.DataTable):
|
||||
class Meta:
|
||||
name = "instances"
|
||||
verbose_name = _("Instances")
|
||||
status_column = "task"
|
||||
status_columns = ["status", "task"]
|
||||
table_actions = (LaunchLink, TerminateInstance)
|
||||
row_actions = (EditInstance, ConsoleLink, LogLink, SnapshotLink,
|
||||
TogglePause, ToggleSuspend, RebootInstance,
|
||||
|
@ -74,6 +74,12 @@ class CreateSnapshot(tables.LinkAction):
|
||||
return volume.status == "available"
|
||||
|
||||
|
||||
class UpdateRow(tables.UpdateAction):
|
||||
def get_data(self, request, volume_id):
|
||||
volume = api.volume_get(request, volume_id)
|
||||
return volume
|
||||
|
||||
|
||||
def get_size(volume):
|
||||
return _("%s GB") % volume.size
|
||||
|
||||
@ -95,12 +101,21 @@ def get_attachment(volume):
|
||||
|
||||
|
||||
class VolumesTableBase(tables.DataTable):
|
||||
STATUS_CHOICES = (
|
||||
("in-use", True),
|
||||
("available", True),
|
||||
("creating", None),
|
||||
("error", False),
|
||||
)
|
||||
name = tables.Column("displayName", verbose_name=_("Name"))
|
||||
description = tables.Column("displayDescription",
|
||||
verbose_name=_("Description"))
|
||||
size = tables.Column(get_size, verbose_name=_("Size"))
|
||||
status = tables.Column("status", filters=(title,),
|
||||
verbose_name=_("Status"))
|
||||
status = tables.Column("status",
|
||||
filters=(title,),
|
||||
verbose_name=_("Status"),
|
||||
status=True,
|
||||
status_choices=STATUS_CHOICES)
|
||||
|
||||
def get_object_display(self, obj):
|
||||
return obj.displayName
|
||||
@ -113,8 +128,10 @@ class VolumesTable(VolumesTableBase):
|
||||
class Meta:
|
||||
name = "volumes"
|
||||
verbose_name = _("Volumes")
|
||||
status_columns = ["status"]
|
||||
table_actions = (CreateVolume, DeleteVolume,)
|
||||
row_actions = (EditAttachments, CreateSnapshot, DeleteVolume)
|
||||
row_actions = (EditAttachments, CreateSnapshot,
|
||||
DeleteVolume, UpdateRow)
|
||||
|
||||
|
||||
class DetachVolume(tables.BatchAction):
|
||||
|
@ -38,6 +38,10 @@ class SyspanelInstancesTable(tables.DataTable):
|
||||
(None, True),
|
||||
("none", True)
|
||||
)
|
||||
STATUS_CHOICES = (
|
||||
("active", True),
|
||||
("error", False),
|
||||
)
|
||||
tenant = tables.Column("tenant_name", verbose_name=_("Tenant"))
|
||||
user = tables.Column("user_id", verbose_name=_("User"))
|
||||
internal_id = tables.Column("internal_identifier",
|
||||
@ -48,8 +52,11 @@ class SyspanelInstancesTable(tables.DataTable):
|
||||
verbose_name=_("Instance Name"))
|
||||
ip = tables.Column(get_ips, verbose_name=_("IP Address"))
|
||||
size = tables.Column(get_size, verbose_name=_("Size"))
|
||||
status = tables.Column("status", filters=(title,),
|
||||
verbose_name=_("Status"))
|
||||
status = tables.Column("status",
|
||||
filters=(title,),
|
||||
verbose_name=_("Status"),
|
||||
status=True,
|
||||
status_choices=STATUS_CHOICES)
|
||||
task = tables.Column("OS-EXT-STS:task_state",
|
||||
verbose_name=_("Task"),
|
||||
filters=(title,),
|
||||
@ -62,8 +69,8 @@ class SyspanelInstancesTable(tables.DataTable):
|
||||
class Meta:
|
||||
name = "instances"
|
||||
verbose_name = _("Instances")
|
||||
status_column = "task"
|
||||
table_actions = (LaunchLink, TerminateInstance)
|
||||
status_columns = ["status", "task"]
|
||||
table_actions = (TerminateInstance,)
|
||||
row_actions = (EditInstance, ConsoleLink, LogLink, SnapshotLink,
|
||||
TogglePause, ToggleSuspend, RebootInstance,
|
||||
TerminateInstance, UpdateRow)
|
||||
|
@ -55,4 +55,4 @@ class ServicesTable(tables.DataTable):
|
||||
verbose_name = _("Services")
|
||||
table_actions = (ServiceFilterAction,)
|
||||
multi_select = False
|
||||
status_column = "enabled"
|
||||
status_columns = ["enabled"]
|
||||
|
@ -264,8 +264,8 @@ class Row(object):
|
||||
|
||||
.. attribute:: status
|
||||
|
||||
Boolean value representing the status of this row according
|
||||
to the value of the table's ``status_column`` value if it is set.
|
||||
Boolean value representing the status of this row calculated from
|
||||
the values of the table's ``status_columns`` if they are set.
|
||||
|
||||
.. attribute:: status_class
|
||||
|
||||
@ -299,15 +299,17 @@ class Row(object):
|
||||
|
||||
@property
|
||||
def status(self):
|
||||
column_name = self.table._meta.status_column
|
||||
if column_name:
|
||||
return self.cells[column_name].status
|
||||
column_names = self.table._meta.status_columns
|
||||
if column_names:
|
||||
statuses = dict([(column_name, self.cells[column_name].status) for
|
||||
column_name in column_names])
|
||||
return self.table.calculate_row_status(statuses)
|
||||
|
||||
@property
|
||||
def status_class(self):
|
||||
column_name = self.table._meta.status_column
|
||||
if column_name:
|
||||
return self.cells[column_name].get_status_class(self.status)
|
||||
column_names = self.table._meta.status_columns
|
||||
if column_names:
|
||||
return self.table.get_row_status_class(self.status)
|
||||
else:
|
||||
return ''
|
||||
|
||||
@ -371,7 +373,7 @@ class Cell(object):
|
||||
return self._status
|
||||
|
||||
if self.column.status or \
|
||||
self.column.table._meta.status_column == self.column.name:
|
||||
self.column.name in self.column.table._meta.status_columns:
|
||||
#returns the first matching status found
|
||||
data_value_lower = unicode(self.data).lower()
|
||||
for status_name, status_value in self.column.status_choices:
|
||||
@ -453,20 +455,18 @@ class DataTableOptions(object):
|
||||
The name of the context variable which will contain the table when
|
||||
it is rendered. Defaults to ``"table"``.
|
||||
|
||||
.. attribute:: status_column
|
||||
.. attribute:: status_columns
|
||||
|
||||
The name of a column on this table which represents the "state"
|
||||
of the data object being represented. The collumn must already be
|
||||
designated as a status column by passing the ``status=True``
|
||||
parameter to the column.
|
||||
A list or tuple of column names which represents the "state"
|
||||
of the data object being represented.
|
||||
|
||||
If ``status_column`` is set, when the rows are rendered the value
|
||||
If ``status_columns`` is set, when the rows are rendered the value
|
||||
of this column will be used to add an extra class to the row in
|
||||
the form of ``"status_up"`` or ``"status_down"`` for that row's
|
||||
data.
|
||||
|
||||
This is useful for displaying the enabled/disabled status of a
|
||||
service, for example.
|
||||
The row status is used by other Horizon components to trigger tasks
|
||||
such as dynamic AJAX updating.
|
||||
|
||||
.. attribute:: row_class
|
||||
|
||||
@ -484,7 +484,7 @@ class DataTableOptions(object):
|
||||
or self.name.title()
|
||||
self.verbose_name = unicode(verbose_name)
|
||||
self.columns = getattr(options, 'columns', None)
|
||||
self.status_column = getattr(options, 'status_column', None)
|
||||
self.status_columns = getattr(options, 'status_columns', [])
|
||||
self.table_actions = getattr(options, 'table_actions', [])
|
||||
self.row_actions = getattr(options, 'row_actions', [])
|
||||
self.row_class = getattr(options, 'row_class', Row)
|
||||
@ -893,6 +893,46 @@ class DataTable(object):
|
||||
"""
|
||||
return http.urlquote_plus(self.get_object_id(self.data[-1]))
|
||||
|
||||
def calculate_row_status(self, statuses):
|
||||
"""
|
||||
Returns a boolean value determining the overall row status
|
||||
based on the dictionary of column name to status mappings passed in.
|
||||
|
||||
By default, it uses the following logic:
|
||||
|
||||
#. If any statuses are ``False``, return ``False``.
|
||||
#. If no statuses are ``False`` but any or ``None``, return ``None``.
|
||||
#. If all statuses are ``True``, return ``True``.
|
||||
|
||||
This provides the greatest protection against false positives without
|
||||
weighting any particular columns.
|
||||
|
||||
The ``statuses`` parameter is passed in as a dictionary mapping
|
||||
column names to their statuses in order to allow this function to
|
||||
be overridden in such a way as to weight one column's status over
|
||||
another should that behavior be desired.
|
||||
"""
|
||||
values = statuses.values()
|
||||
if any([status is False for status in values]):
|
||||
return False
|
||||
elif any([status is None for status in values]):
|
||||
return None
|
||||
else:
|
||||
return True
|
||||
|
||||
def get_row_status_class(self, status):
|
||||
"""
|
||||
Returns a css class name determined by the status value. This class
|
||||
name is used to indicate the status of the rows in the table if
|
||||
any ``status_columns`` have been specified.
|
||||
"""
|
||||
if status is True:
|
||||
return "status_up"
|
||||
elif status is False:
|
||||
return "status_down"
|
||||
else:
|
||||
return "status_unknown"
|
||||
|
||||
def get_columns(self):
|
||||
""" Returns this table's columns including auto-generated ones."""
|
||||
return self.columns.values()
|
||||
|
@ -147,7 +147,7 @@ class MyTable(tables.DataTable):
|
||||
class Meta:
|
||||
name = "my_table"
|
||||
verbose_name = "My Table"
|
||||
status_column = "status"
|
||||
status_columns = ["status"]
|
||||
columns = ('id', 'name', 'value', 'optional', 'status')
|
||||
table_actions = (MyFilterAction, MyAction, MyBatchAction)
|
||||
row_actions = (MyAction, MyLinkAction, MyUpdateAction,
|
||||
|
Loading…
Reference in New Issue
Block a user