mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-17 04:58:16 -06:00
10587 pagination
This commit is contained in:
parent
bbdf5c76cb
commit
7d44da0a2a
@ -5,7 +5,7 @@ from django.conf import settings
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from extras.models import *
|
||||
from netbox.tables import NetBoxTable, columns
|
||||
from netbox.tables import BaseTable, NetBoxTable, columns
|
||||
from .template_code import *
|
||||
|
||||
__all__ = (
|
||||
@ -21,6 +21,8 @@ __all__ = (
|
||||
'JournalEntryTable',
|
||||
'ObjectChangeTable',
|
||||
'SavedFilterTable',
|
||||
'ReportResultsTable',
|
||||
'ScriptResultsTable',
|
||||
'TaggedItemTable',
|
||||
'TagTable',
|
||||
'WebhookTable',
|
||||
@ -507,3 +509,67 @@ class JournalEntryTable(NetBoxTable):
|
||||
default_columns = (
|
||||
'pk', 'created', 'created_by', 'assigned_object_type', 'assigned_object', 'kind', 'comments'
|
||||
)
|
||||
|
||||
|
||||
class ScriptResultsTable(BaseTable):
|
||||
index = tables.Column(
|
||||
verbose_name=_('Line')
|
||||
)
|
||||
time = tables.Column(
|
||||
verbose_name=_('Time')
|
||||
)
|
||||
status = tables.TemplateColumn(
|
||||
template_code="""{% load log_levels %}{% log_level record.status %}""",
|
||||
verbose_name=_('Level')
|
||||
)
|
||||
message = tables.Column(
|
||||
verbose_name=_('Message')
|
||||
)
|
||||
|
||||
class Meta(BaseTable.Meta):
|
||||
empty_text = _('No results found')
|
||||
fields = (
|
||||
'index', 'time', 'status', 'message',
|
||||
)
|
||||
default_columns = (
|
||||
'index', 'time', 'status', 'message',
|
||||
)
|
||||
|
||||
|
||||
class ReportResultsTable(BaseTable):
|
||||
index = tables.Column(
|
||||
verbose_name=_('Line')
|
||||
)
|
||||
method = tables.Column(
|
||||
verbose_name=_('Method')
|
||||
)
|
||||
time = tables.Column(
|
||||
verbose_name=_('Time')
|
||||
)
|
||||
status = tables.Column(
|
||||
empty_values=(),
|
||||
verbose_name=_('Level')
|
||||
)
|
||||
status = tables.TemplateColumn(
|
||||
template_code="""{% load log_levels %}{% log_level record.status %}""",
|
||||
verbose_name=_('Level')
|
||||
)
|
||||
|
||||
object = tables.Column(
|
||||
verbose_name=_('Object')
|
||||
)
|
||||
url = tables.Column(
|
||||
verbose_name=_('Url')
|
||||
)
|
||||
message = tables.Column(
|
||||
verbose_name=_('Message')
|
||||
)
|
||||
|
||||
class Meta(BaseTable.Meta):
|
||||
empty_text = _('No results found')
|
||||
fields = (
|
||||
'index', 'method', 'time', 'status', 'object', 'url', 'message',
|
||||
)
|
||||
default_columns = (
|
||||
'index', 'method', 'time', 'status', 'object', 'url', 'message',
|
||||
)
|
||||
|
@ -17,6 +17,7 @@ from extras.dashboard.forms import DashboardWidgetAddForm, DashboardWidgetForm
|
||||
from extras.dashboard.utils import get_widget_class
|
||||
from netbox.constants import DEFAULT_ACTION_PERMISSIONS
|
||||
from netbox.views import generic
|
||||
from netbox.views.generic.mixins import TableMixin
|
||||
from utilities.forms import ConfirmationForm, get_field_value
|
||||
from utilities.paginator import EnhancedPaginator, get_paginate_count
|
||||
from utilities.rqworker import get_workers_for_queue
|
||||
@ -26,6 +27,7 @@ from utilities.views import ContentTypePermissionRequiredMixin, register_model_v
|
||||
from . import filtersets, forms, tables
|
||||
from .models import *
|
||||
from .scripts import run_script
|
||||
from .tables import ReportResultsTable, ScriptResultsTable
|
||||
|
||||
|
||||
#
|
||||
@ -1143,47 +1145,72 @@ class LegacyScriptRedirectView(ContentTypePermissionRequiredMixin, View):
|
||||
return redirect(f'{url}{path}')
|
||||
|
||||
|
||||
class ScriptResultView(generic.ObjectView):
|
||||
class ScriptResultView(TableMixin, generic.ObjectView):
|
||||
queryset = Job.objects.all()
|
||||
|
||||
def get_required_permission(self):
|
||||
return 'extras.view_script'
|
||||
|
||||
def job_to_result_array(self, job):
|
||||
results = []
|
||||
def get_table(self, job, request, bulk_actions=True):
|
||||
data = []
|
||||
tests = None
|
||||
table_logs = table_tests = None
|
||||
index = 0
|
||||
if job.data:
|
||||
if 'log' in job.data:
|
||||
if 'tests' in job.data:
|
||||
tests = job.data['tests']
|
||||
|
||||
for log in job.data['log']:
|
||||
index += 1
|
||||
result = {
|
||||
'method': None,
|
||||
'index': index,
|
||||
'time': log.get('time', None),
|
||||
'level': log.get('level', None),
|
||||
'object': log.get('object', None),
|
||||
'status': log.get('status', None),
|
||||
'message': log.get('message', None),
|
||||
}
|
||||
results.append(result)
|
||||
data.append(result)
|
||||
|
||||
table_logs = ScriptResultsTable(data, user=request.user)
|
||||
table_logs.configure(request)
|
||||
else:
|
||||
for test in job.data:
|
||||
if 'log' in test:
|
||||
for time, level, obj, url, message in test['log']:
|
||||
tests = job.data
|
||||
|
||||
if tests:
|
||||
for method, test_data in tests.items():
|
||||
if 'log' in test_data:
|
||||
for time, status, obj, url, message in test_data['log']:
|
||||
index += 1
|
||||
result = {
|
||||
'method': test,
|
||||
'index': index,
|
||||
'method': method,
|
||||
'time': time,
|
||||
'level': level,
|
||||
'status': status,
|
||||
'object': obj,
|
||||
'url': url,
|
||||
'message': message,
|
||||
}
|
||||
data.append(result)
|
||||
|
||||
return data
|
||||
table_tests = ReportResultsTable(data, user=request.user)
|
||||
table_tests.configure(request)
|
||||
|
||||
return table_logs, table_tests
|
||||
|
||||
def get(self, request, **kwargs):
|
||||
job = get_object_or_404(Job.objects.all(), pk=kwargs.get('job_pk'))
|
||||
table_logs = table_tests = None
|
||||
|
||||
if job.completed:
|
||||
table_logs, table_tests = self.get_table(job, request, bulk_actions=False)
|
||||
|
||||
context = {
|
||||
'script': job.object,
|
||||
'job': job,
|
||||
'table_logs': table_logs,
|
||||
'table_tests': table_tests,
|
||||
}
|
||||
|
||||
if job.data and 'log' in job.data:
|
||||
# Script
|
||||
context['tests'] = job.data.get('tests', {})
|
||||
|
@ -3,6 +3,7 @@
|
||||
{% load log_levels %}
|
||||
{% load i18n %}
|
||||
|
||||
<div class="htmx-container">
|
||||
<p>
|
||||
{% if job.started %}
|
||||
{% trans "Started" %}: <strong>{{ job.started|annotated_date }}</strong>
|
||||
@ -18,32 +19,12 @@
|
||||
</p>
|
||||
{% if job.completed %}
|
||||
|
||||
{# Script log. Legacy reports will not have this. #}
|
||||
{% if 'log' in job.data %}
|
||||
<div class="card mb-3">
|
||||
<div class="card">
|
||||
<div class="table-responsive" id="object_list">
|
||||
<h5 class="card-header">{% trans "Log" %}</h5>
|
||||
{% if job.data.log %}
|
||||
<table class="table table-hover panel-body">
|
||||
<tr>
|
||||
<th>{% trans "Line" %}</th>
|
||||
<th>{% trans "Time" %}</th>
|
||||
<th>{% trans "Level" %}</th>
|
||||
<th>{% trans "Message" %}</th>
|
||||
</tr>
|
||||
{% for log in job.data.log %}
|
||||
<tr>
|
||||
<td>{{ forloop.counter }}</td>
|
||||
<td>{{ log.time|placeholder }}</td>
|
||||
<td>{% log_level log.status %}</td>
|
||||
<td>{{ log.message|markdown }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% else %}
|
||||
<div class="card-body text-muted">{% trans "None" %}</div>
|
||||
{% endif %}
|
||||
{% include 'htmx/table.html' with table=table_logs %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# Script output. Legacy reports will not have this. #}
|
||||
{% if 'output' in job.data %}
|
||||
@ -57,9 +38,7 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# Test method logs (for legacy Reports) #}
|
||||
{% if tests %}
|
||||
|
||||
{% if table_tests %}
|
||||
{# Summary of test methods #}
|
||||
<div class="card">
|
||||
<h5 class="card-header">{% trans "Test Summary" %}</h5>
|
||||
@ -80,47 +59,13 @@
|
||||
|
||||
{# Detailed results for individual tests #}
|
||||
<div class="card">
|
||||
<div class="table-responsive" id="object_list">
|
||||
<h5 class="card-header">{% trans "Test Details" %}</h5>
|
||||
<table class="table table-hover report">
|
||||
<thead>
|
||||
<tr class="table-headings">
|
||||
<th>{% trans "Time" %}</th>
|
||||
<th>{% trans "Level" %}</th>
|
||||
<th>{% trans "Object" %}</th>
|
||||
<th>{% trans "Message" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for test, data in tests.items %}
|
||||
<tr>
|
||||
<th colspan="4" style="font-family: monospace">
|
||||
<a name="{{ test }}"></a>{{ test }}
|
||||
</th>
|
||||
</tr>
|
||||
{% for time, level, obj, url, message in data.log %}
|
||||
<tr class="{% if level == 'failure' %}danger{% elif level %}{{ level }}{% endif %}">
|
||||
<td>{{ time }}</td>
|
||||
<td>
|
||||
<label class="badge text-bg-{% if level == 'failure' %}danger{% else %}{{ level }}{% endif %}">{{ level|title }}</label>
|
||||
</td>
|
||||
<td>
|
||||
{% if obj and url %}
|
||||
<a href="{{ url }}">{{ obj }}</a>
|
||||
{% elif obj %}
|
||||
{{ obj }}
|
||||
{% else %}
|
||||
{{ ''|placeholder }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="rendered-markdown">{{ message|markdown }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% include 'htmx/table.html' with table=table_tests %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
{% elif job.started %}
|
||||
{% include 'extras/inc/result_pending.html' %}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user