Cleaned up jobs list display

This commit is contained in:
jeremystretch 2022-12-08 15:42:43 -05:00
parent f4842ad8db
commit 23bd7ce9a7
8 changed files with 47 additions and 14 deletions

View File

@ -99,9 +99,9 @@ class SiteTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = Site model = Site
fields = ( fields = (
'pk', 'id', 'name', 'slug', 'status', 'facility', 'region', 'group', 'tenant', 'tenant_group', 'asns', 'asn_count', 'pk', 'id', 'name', 'slug', 'status', 'facility', 'region', 'group', 'tenant', 'tenant_group', 'asns',
'time_zone', 'description', 'physical_address', 'shipping_address', 'latitude', 'longitude', 'comments', 'asn_count', 'time_zone', 'description', 'physical_address', 'shipping_address', 'latitude', 'longitude',
'contacts', 'tags', 'created', 'last_updated', 'actions', 'comments', 'contacts', 'tags', 'created', 'last_updated', 'actions',
) )
default_columns = ('pk', 'name', 'status', 'facility', 'region', 'group', 'tenant', 'description') default_columns = ('pk', 'name', 'status', 'facility', 'region', 'group', 'tenant', 'description')

View File

@ -148,12 +148,12 @@ class JobResultStatusChoices(ChoiceSet):
STATUS_FAILED = 'failed' STATUS_FAILED = 'failed'
CHOICES = ( CHOICES = (
(STATUS_PENDING, 'Pending'), (STATUS_PENDING, 'Pending', 'cyan'),
(STATUS_SCHEDULED, 'Scheduled'), (STATUS_SCHEDULED, 'Scheduled', 'gray'),
(STATUS_RUNNING, 'Running'), (STATUS_RUNNING, 'Running', 'blue'),
(STATUS_COMPLETED, 'Completed'), (STATUS_COMPLETED, 'Completed', 'green'),
(STATUS_ERRORED, 'Errored'), (STATUS_ERRORED, 'Errored', 'red'),
(STATUS_FAILED, 'Failed'), (STATUS_FAILED, 'Failed', 'red'),
) )
TERMINAL_STATE_CHOICES = ( TERMINAL_STATE_CHOICES = (

View File

@ -640,6 +640,9 @@ class JobResult(models.Model):
def get_absolute_url(self): def get_absolute_url(self):
return reverse(f'extras:{self.obj_type.name}_result', args=[self.pk]) return reverse(f'extras:{self.obj_type.name}_result', args=[self.pk])
def get_status_color(self):
return JobResultStatusChoices.colors.get(self.status)
@property @property
def duration(self): def duration(self):
if not self.completed: if not self.completed:

View File

@ -1,5 +1,6 @@
import django_tables2 as tables import django_tables2 as tables
from django.conf import settings from django.conf import settings
from django.utils.translation import gettext as _
from extras.models import * from extras.models import *
from netbox.tables import NetBoxTable, columns from netbox.tables import NetBoxTable, columns
@ -41,6 +42,15 @@ class JobResultTable(NetBoxTable):
name = tables.Column( name = tables.Column(
linkify=True linkify=True
) )
obj_type = columns.ContentTypeColumn(
verbose_name=_('Type')
)
status = columns.ChoiceFieldColumn()
created = columns.DateTimeColumn()
scheduled = columns.DateTimeColumn()
interval = columns.DurationColumn()
started = columns.DateTimeColumn()
completed = columns.DateTimeColumn()
actions = columns.ActionsColumn( actions = columns.ActionsColumn(
actions=('delete',) actions=('delete',)
) )
@ -48,11 +58,11 @@ class JobResultTable(NetBoxTable):
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = JobResult model = JobResult
fields = ( fields = (
'pk', 'id', 'name', 'obj_type', 'status', 'created', 'scheduled', 'interval', 'started', 'completed', 'pk', 'id', 'obj_type', 'name', 'status', 'created', 'scheduled', 'interval', 'started', 'completed',
'user', 'job_id', 'user', 'job_id',
) )
default_columns = ( default_columns = (
'pk', 'id', 'name', 'obj_type', 'status', 'created', 'scheduled', 'interval', 'started', 'completed', 'pk', 'id', 'obj_type', 'name', 'status', 'created', 'scheduled', 'interval', 'started', 'completed',
'user', 'user',
) )

View File

@ -299,7 +299,7 @@ OTHER_MENU = Menu(
), ),
MenuItem( MenuItem(
link='extras:jobresult_list', link='extras:jobresult_list',
link_text=_('Job Results'), link_text=_('Jobs'),
permissions=['extras.view_jobresult'], permissions=['extras.view_jobresult'],
), ),
), ),

View File

@ -28,6 +28,7 @@ __all__ = (
'ContentTypesColumn', 'ContentTypesColumn',
'CustomFieldColumn', 'CustomFieldColumn',
'CustomLinkColumn', 'CustomLinkColumn',
'DurationColumn',
'LinkedCountColumn', 'LinkedCountColumn',
'MarkdownColumn', 'MarkdownColumn',
'ManyToManyColumn', 'ManyToManyColumn',
@ -77,6 +78,24 @@ class DateTimeColumn(tables.DateTimeColumn):
return cls(**kwargs) return cls(**kwargs)
class DurationColumn(tables.Column):
"""
Express a duration of time (in minutes) in a human-friendly format. Example: 437 minutes becomes "7h 17m"
"""
def render(self, value):
ret = ''
if days := value // 1440:
ret += f'{days}d '
if hours := value % 1440 // 60:
ret += f'{hours}h '
if minutes := value % 60:
ret += f'{minutes}m'
return ret.strip()
def value(self, value):
return value
class ManyToManyColumn(tables.ManyToManyColumn): class ManyToManyColumn(tables.ManyToManyColumn):
""" """
Overrides django-tables2's stock ManyToManyColumn to ensure that value() returns only plaintext data. Overrides django-tables2's stock ManyToManyColumn to ensure that value() returns only plaintext data.

View File

@ -1,10 +1,11 @@
{% load humanize %}
{% load helpers %} {% load helpers %}
<p> <p>
{% if result.started %} {% if result.started %}
Started: <strong>{{ result.started|annotated_date }}</strong> Started: <strong>{{ result.started|annotated_date }}</strong>
{% elif result.scheduled %} {% elif result.scheduled %}
Scheduled for: <strong>{{ result.scheduled|annotated_date }}</strong> Scheduled for: <strong>{{ result.scheduled|annotated_date }}</strong> ({{ result.scheduled|naturaltime }})
{% else %} {% else %}
Created: <strong>{{ result.created|annotated_date }}</strong> Created: <strong>{{ result.created|annotated_date }}</strong>
{% endif %} {% endif %}

View File

@ -5,7 +5,7 @@
{% if result.started %} {% if result.started %}
Started: <strong>{{ result.started|annotated_date }}</strong> Started: <strong>{{ result.started|annotated_date }}</strong>
{% elif result.scheduled %} {% elif result.scheduled %}
Scheduled for: <strong>{{ result.scheduled|annotated_date }}</strong> Scheduled for: <strong>{{ result.scheduled|annotated_date }}</strong> ({{ result.scheduled|naturaltime }})
{% else %} {% else %}
Created: <strong>{{ result.created|annotated_date }}</strong> Created: <strong>{{ result.created|annotated_date }}</strong>
{% endif %} {% endif %}