- Updated various views to replace 'dashboard-card' with 'content-card' for consistency in styling. - Modified filter and table card classes across multiple pages including applications, campaigns, commands, datasets, dayparts, displays, display groups, display profiles, fonts, layouts, libraries, menu boards, modules, player software, playlists, resolutions, schedules, settings, sync groups, tags, tasks, templates, transitions, users, and user groups.
178 lines
7.2 KiB
Twig
178 lines
7.2 KiB
Twig
{#
|
|
/*
|
|
* OTS Signs Theme - Task Page
|
|
* Based on Xibo CMS task-page.twig with OTS styling
|
|
*/
|
|
#}
|
|
{% extends "authed.twig" %}
|
|
{% import "inline.twig" as inline %}
|
|
|
|
{% block title %}{{ "Tasks"|trans }} | {% endblock %}
|
|
|
|
{% block actionMenu %}{% endblock %}
|
|
|
|
{% block pageContent %}
|
|
<div class="ots-displays-page">
|
|
<div class="page-header ots-page-header">
|
|
<h1>{% trans "Tasks" %}</h1>
|
|
<p class="text-muted">{% trans "Manage scheduled system tasks." %}</p>
|
|
</div>
|
|
|
|
<div class="widget content-card ots-displays-card">
|
|
<div class="widget-body ots-displays-body">
|
|
<div class="XiboGrid" id="{{ random() }}">
|
|
<div class="XiboFilter card mb-3 bg-light content-card ots-filter-card" style="display:none;">
|
|
<div class="FilterDiv card-body" id="Filter">
|
|
<form class="form-inline">
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<div class="XiboData card pt-3 content-card ots-table-card">
|
|
<div class="ots-table-toolbar">
|
|
{% if settings.TASK_CONFIG_LOCKED_CHECKB == 0 or settings.TASK_CONFIG_LOCKED_CHECKB == "Unchecked" %}
|
|
<button class="btn btn-sm btn-success ots-toolbar-btn XiboFormButton" href="{{ url_for("task.add.form") }}"><i class="fa fa-plus-circle" aria-hidden="true"></i></button>
|
|
{% endif %}
|
|
<button class="btn btn-sm btn-primary ots-toolbar-btn" id="refreshGrid" title="{% trans "Refresh the Table" %}" href="#"><i class="fa fa-refresh" aria-hidden="true"></i></button>
|
|
</div>
|
|
<table id="tasks" class="table table-striped" data-state-preference-name="taskGrid">
|
|
<thead>
|
|
<tr>
|
|
<th>{% trans "ID" %}</th>
|
|
<th>{% trans "Name" %}</th>
|
|
<th>{% trans "Active" %}</th>
|
|
<th>{% trans "Status" %}</th>
|
|
<th>{% trans "Next Run" %}</th>
|
|
<th>{% trans "Run Now" %}</th>
|
|
<th>{% trans "Last Run" %}</th>
|
|
<th>{% trans "Last Status" %}</th>
|
|
<th>{% trans "Last Duration" %}</th>
|
|
<th class="rowMenu"></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block javaScript %}
|
|
<script type="text/javascript" nonce="{{ cspNonce }}">
|
|
var table = $("#tasks").DataTable({
|
|
"language": dataTablesLanguage,
|
|
dom: dataTablesTemplate,
|
|
serverSide: true,
|
|
stateSave: true,
|
|
responsive: true,
|
|
stateDuration: 0,
|
|
stateLoadCallback: dataTableStateLoadCallback,
|
|
stateSaveCallback: dataTableStateSaveCallback,
|
|
filter: false,
|
|
searchDelay: 3000,
|
|
"order": [[ 1, "asc"]],
|
|
ajax: {
|
|
"url": "{{ url_for("task.search") }}",
|
|
"data": function(d) {
|
|
$.extend(d, $("#tasks").closest(".XiboGrid").find(".FilterDiv form").serializeObject());
|
|
}
|
|
},
|
|
"columns": [
|
|
{ "data": "taskId" , responsivePriority: 2},
|
|
{ "data": "name" , responsivePriority: 2},
|
|
{
|
|
"data": "isActive",
|
|
responsivePriority: 2,
|
|
"render": dataTableTickCrossColumn
|
|
},
|
|
{
|
|
"data": "status",
|
|
"render": function (data, type, row) {
|
|
if (type !== "display")
|
|
return data;
|
|
|
|
var icon = "";
|
|
var title = "";
|
|
if (data === 1) {
|
|
if (moment(row.lastRunStartDt, "X").tz) {
|
|
title = "PID: " + row.pid + " (" + moment(row.lastRunStartDt, "X").tz(timezone).format(jsDateFormat) + ")";
|
|
} else {
|
|
title = "PID: " + row.pid + " (" + moment(row.lastRunStartDt, "X").format(jsDateFormat) + ")";
|
|
}
|
|
icon = "fa-cogs";
|
|
}
|
|
else if (data === 3) {
|
|
title = "Exit: " + row.lastRunExitCode;
|
|
icon = "fa-bug";
|
|
}
|
|
else if (data === 5) {
|
|
title = "Time out";
|
|
icon = "fa-hourglass-o";
|
|
}
|
|
else {
|
|
title = "";
|
|
icon = "fa-clock-o";
|
|
}
|
|
|
|
return '<span class="fa ' + icon + '" title="' + title + '"></span>';
|
|
}
|
|
},
|
|
{
|
|
"data": "nextRunDt",
|
|
"orderable": false,
|
|
"render": dataTableDateFromUnix
|
|
},
|
|
{
|
|
"data": "runNow",
|
|
"render": dataTableTickCrossColumn
|
|
},
|
|
{
|
|
"data": "lastRunDt",
|
|
"render": dataTableDateFromUnix
|
|
},
|
|
{
|
|
"data": "lastRunStatus",
|
|
"render": function (data, type, row) {
|
|
if (type !== "display")
|
|
return data;
|
|
|
|
var icon = "";
|
|
if (data === 4)
|
|
icon = "fa-check";
|
|
else
|
|
icon = "fa-times";
|
|
|
|
return '<span class="fa ' + icon + '" title="' +
|
|
((row.lastRunMessage === null) ? "" : row.lastRunMessage) + '"></span>';
|
|
}
|
|
},
|
|
{
|
|
"data": "lastRunDuration",
|
|
"render": function (data, type, row) {
|
|
if (type !== "display")
|
|
return data;
|
|
|
|
return (data === null) ? 0 : moment().startOf("day").seconds(data).format("H:mm:ss");
|
|
}
|
|
},
|
|
{
|
|
"orderable": false,
|
|
responsivePriority: 1,
|
|
"data": dataTableButtonsColumn
|
|
}
|
|
]
|
|
});
|
|
|
|
table.on('draw', dataTableDraw);
|
|
table.on('processing.dt', dataTableProcessing);
|
|
dataTableAddButtons(table, $('#tasks_wrapper').find('.dataTables_buttons'));
|
|
|
|
$("#refreshGrid").click(function () {
|
|
table.ajax.reload();
|
|
});
|
|
</script>
|
|
{% endblock %}
|