Added log pages in cp

This commit is contained in:
Pinga 2023-11-13 13:31:49 +02:00
parent 07b69a4e2b
commit 3d639c7268
8 changed files with 303 additions and 15 deletions

View file

@ -11,8 +11,16 @@ class LogsController extends Controller
{ {
public function view(Request $request, Response $response) public function view(Request $request, Response $response)
{ {
$logModel = new RegistryTransaction($this->container->get('db')); return view($response,'admin/logs/index.twig');
$logs = $logModel->getAllRegistryTransaction(); }
return view($response,'admin/logs/index.twig', compact('logs'));
public function poll(Request $request, Response $response)
{
return view($response,'admin/logs/poll.twig');
}
public function log(Request $request, Response $response)
{
return view($response,'admin/logs/log.twig');
} }
} }

View file

@ -0,0 +1,65 @@
{% extends "layouts/app.twig" %}
{% block title %}{{ __('System Log') }}{% endblock %}
{% block content %}
<div class="page-wrapper">
<!-- Page header -->
<div class="page-header d-print-none">
<div class="container-xl">
<div class="row g-2 align-items-center">
<div class="col">
<!-- Page pre-title -->
<div class="page-pretitle">
{{ __('Overview') }}
</div>
<h2 class="page-title">
{{ __('System Log') }}
</h2>
</div>
</div>
</div>
</div>
<!-- Page body -->
<div class="page-body">
<div class="container-xl">
<div class="col-12">
<div class="card">
<div class="card-body border-bottom py-3">
<div class="d-flex">
<div class="text-secondary">
<button class="btn btn-info btn-icon" onclick="downloadCSV()"><svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M10 15a1 1 0 0 0 1 1h2a1 1 0 0 0 1 -1v-2a1 1 0 0 0 -1 -1h-2a1 1 0 0 1 -1 -1v-2a1 1 0 0 1 1 -1h2a1 1 0 0 1 1 1"></path><path d="M17 8l2 8l2 -8"></path><path d="M7 10a2 2 0 1 0 -4 0v4a2 2 0 1 0 4 0"></path></svg></button>
<button class="btn btn-info btn-icon" onclick="downloadJSON()"><svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M20 16v-8l3 8v-8"></path><path d="M15 8a2 2 0 0 1 2 2v4a2 2 0 1 1 -4 0v-4a2 2 0 0 1 2 -2z"></path><path d="M1 8h3v6.5a1.5 1.5 0 0 1 -3 0v-.5"></path><path d="M7 15a1 1 0 0 0 1 1h1a1 1 0 0 0 1 -1v-2a1 1 0 0 0 -1 -1h-1a1 1 0 0 1 -1 -1v-2a1 1 0 0 1 1 -1h1a1 1 0 0 1 1 1"></path></svg></button>
<button class="btn btn-green btn-icon" onclick="downloadXLSX()"><svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M14 3v4a1 1 0 0 0 1 1h4"></path><path d="M5 12v-7a2 2 0 0 1 2 -2h7l5 5v4"></path><path d="M4 15l4 6"></path><path d="M4 21l4 -6"></path><path d="M17 20.25c0 .414 .336 .75 .75 .75h1.25a1 1 0 0 0 1 -1v-1a1 1 0 0 0 -1 -1h-1a1 1 0 0 1 -1 -1v-1a1 1 0 0 1 1 -1h1.25a.75 .75 0 0 1 .75 .75"></path><path d="M11 15v6h3"></path></svg></button>
<button class="btn btn-red btn-icon" onclick="downloadPDF()"><svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M10 8v8h2a2 2 0 0 0 2 -2v-4a2 2 0 0 0 -2 -2h-2z"></path><path d="M3 12h2a2 2 0 1 0 0 -4h-2v8"></path><path d="M17 12h3"></path><path d="M21 8h-4v8"></path></svg></button>
</div>
<div class="ms-auto text-secondary">
Search:
<div class="ms-2 d-inline-block">
<input id="search-input" type="text" class="form-control" aria-label="Search logs">
</div>
</div>
</div>
</div>
<div class="table-responsive">
<div id="logsTable"></div>
</div>
</div>
</div>
</div>
</div>
<footer class="footer footer-transparent d-print-none">
<div class="container-xl">
<div class="col-12 col-lg-auto mt-3 mt-lg-0">
<ul class="list-inline list-inline-dots mb-0">
<li class="list-inline-item">
Copyright &copy; 2023
<a href="https://namingo.org" target="_blank" class="link-secondary">Namingo</a>.
</li>
</ul>
</div>
</div>
</div>
</footer>
</div>
{% endblock %}

View file

@ -0,0 +1,65 @@
{% extends "layouts/app.twig" %}
{% block title %}{{ __('Message Queue') }}{% endblock %}
{% block content %}
<div class="page-wrapper">
<!-- Page header -->
<div class="page-header d-print-none">
<div class="container-xl">
<div class="row g-2 align-items-center">
<div class="col">
<!-- Page pre-title -->
<div class="page-pretitle">
{{ __('Overview') }}
</div>
<h2 class="page-title">
{{ __('Message Queue') }}
</h2>
</div>
</div>
</div>
</div>
<!-- Page body -->
<div class="page-body">
<div class="container-xl">
<div class="col-12">
<div class="card">
<div class="card-body border-bottom py-3">
<div class="d-flex">
<div class="text-secondary">
<button class="btn btn-info btn-icon" onclick="downloadCSV()"><svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M10 15a1 1 0 0 0 1 1h2a1 1 0 0 0 1 -1v-2a1 1 0 0 0 -1 -1h-2a1 1 0 0 1 -1 -1v-2a1 1 0 0 1 1 -1h2a1 1 0 0 1 1 1"></path><path d="M17 8l2 8l2 -8"></path><path d="M7 10a2 2 0 1 0 -4 0v4a2 2 0 1 0 4 0"></path></svg></button>
<button class="btn btn-info btn-icon" onclick="downloadJSON()"><svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M20 16v-8l3 8v-8"></path><path d="M15 8a2 2 0 0 1 2 2v4a2 2 0 1 1 -4 0v-4a2 2 0 0 1 2 -2z"></path><path d="M1 8h3v6.5a1.5 1.5 0 0 1 -3 0v-.5"></path><path d="M7 15a1 1 0 0 0 1 1h1a1 1 0 0 0 1 -1v-2a1 1 0 0 0 -1 -1h-1a1 1 0 0 1 -1 -1v-2a1 1 0 0 1 1 -1h1a1 1 0 0 1 1 1"></path></svg></button>
<button class="btn btn-green btn-icon" onclick="downloadXLSX()"><svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M14 3v4a1 1 0 0 0 1 1h4"></path><path d="M5 12v-7a2 2 0 0 1 2 -2h7l5 5v4"></path><path d="M4 15l4 6"></path><path d="M4 21l4 -6"></path><path d="M17 20.25c0 .414 .336 .75 .75 .75h1.25a1 1 0 0 0 1 -1v-1a1 1 0 0 0 -1 -1h-1a1 1 0 0 1 -1 -1v-1a1 1 0 0 1 1 -1h1.25a.75 .75 0 0 1 .75 .75"></path><path d="M11 15v6h3"></path></svg></button>
<button class="btn btn-red btn-icon" onclick="downloadPDF()"><svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M10 8v8h2a2 2 0 0 0 2 -2v-4a2 2 0 0 0 -2 -2h-2z"></path><path d="M3 12h2a2 2 0 1 0 0 -4h-2v8"></path><path d="M17 12h3"></path><path d="M21 8h-4v8"></path></svg></button>
</div>
<div class="ms-auto text-secondary">
Search:
<div class="ms-2 d-inline-block">
<input id="search-input" type="text" class="form-control" aria-label="Search queue">
</div>
</div>
</div>
</div>
<div class="table-responsive">
<div id="pollTable"></div>
</div>
</div>
</div>
</div>
</div>
<footer class="footer footer-transparent d-print-none">
<div class="container-xl">
<div class="col-12 col-lg-auto mt-3 mt-lg-0">
<ul class="list-inline list-inline-dots mb-0">
<li class="list-inline-item">
Copyright &copy; 2023
<a href="https://namingo.org" target="_blank" class="link-secondary">Namingo</a>.
</li>
</ul>
</div>
</div>
</div>
</footer>
</div>
{% endblock %}

View file

@ -6,7 +6,7 @@
<meta http-equiv="X-UA-Compatible" content="ie=edge"/> <meta http-equiv="X-UA-Compatible" content="ie=edge"/>
<title>{% block title %}{% endblock %} | Namingo</title> <title>{% block title %}{% endblock %} | Namingo</title>
<!-- CSS files --> <!-- CSS files -->
{% if route_is('domains') or route_is('contacts') or route_is('hosts') or route_is('epphistory') or route_is('registrars') or route_is('transactions') or route_is('overview') or route_is('reports') or route_is('transfers') or route_is('users') or route_is('support') %} {% if route_is('domains') or route_is('contacts') or route_is('hosts') or route_is('epphistory') or route_is('registrars') or route_is('transactions') or route_is('overview') or route_is('reports') or route_is('transfers') or route_is('users') or route_is('support') or route_is('poll') or route_is('log') %}
{% include 'partials/css-tables.twig' %} {% include 'partials/css-tables.twig' %}
{% else %} {% else %}
{% include 'partials/css.twig' %} {% include 'partials/css.twig' %}
@ -229,7 +229,7 @@
</a> </a>
</div> </div>
</li> </li>
<li {{ is_current_url('epphistory') ? 'class="nav-item dropdown active"' : 'class="nav-item dropdown"' }}> <li {{ is_current_url('epphistory') or is_current_url('poll') or is_current_url('log') ? 'class="nav-item dropdown active"' : 'class="nav-item dropdown"' }}>
<a class="nav-link dropdown-toggle" href="#" data-bs-toggle="dropdown" data-bs-auto-close="outside" role="button" aria-expanded="false"> <a class="nav-link dropdown-toggle" href="#" data-bs-toggle="dropdown" data-bs-auto-close="outside" role="button" aria-expanded="false">
<span class="nav-link-icon d-md-none d-lg-inline-block"><svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-activity" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M3 12h4l3 8l4 -16l3 8h4"></path></svg> <span class="nav-link-icon d-md-none d-lg-inline-block"><svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-activity" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M3 12h4l3 8l4 -16l3 8h4"></path></svg>
</span> </span>
@ -238,19 +238,13 @@
</span> </span>
</a> </a>
<div class="dropdown-menu"> <div class="dropdown-menu">
<a class="dropdown-item" href="#"> <a class="dropdown-item" href="{{route('poll')}}">
{{ __('Message Queue') }} {{ __('Message Queue') }}
</a> </a>
<a class="dropdown-item" href="{{route('epphistory')}}"> <a class="dropdown-item" href="{{route('epphistory')}}">
{{ __('EPP History') }} {{ __('EPP History') }}
</a> </a>
<a class="dropdown-item" href="#"> <a class="dropdown-item" href="{{route('log')}}">
{{ __('Audit History') }}
</a>
<a class="dropdown-item" href="#">
{{ __('Backup History') }}
</a>
<a class="dropdown-item" href="#">
{{ __('System Log') }} {{ __('System Log') }}
</a> </a>
</div> </div>
@ -415,6 +409,10 @@
{% include 'partials/js-users.twig' %} {% include 'partials/js-users.twig' %}
{% elseif route_is('support') %} {% elseif route_is('support') %}
{% include 'partials/js-support.twig' %} {% include 'partials/js-support.twig' %}
{% elseif route_is('poll') %}
{% include 'partials/js-poll.twig' %}
{% elseif route_is('log') %}
{% include 'partials/js-log.twig' %}
{% else %} {% else %}
{% include 'partials/js.twig' %} {% include 'partials/js.twig' %}
{% endif %} {% endif %}

View file

@ -0,0 +1,73 @@
<script src="/assets/js/tabulator.min.js" defer></script>
<script src="/assets/js/tabler.min.js" defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf-autotable/3.6.0/jspdf.plugin.autotable.min.js"></script>
<script>
var table;
document.addEventListener("DOMContentLoaded", function(){
table = new Tabulator("#logsTable", {
ajaxURL:"/api/records/error_log?join=registrar", // Set the URL for your JSON data
ajaxConfig:"GET",
pagination:"local",
paginationSize:10,
ajaxResponse:function(url, params, response){
return response.records;
},
layout:"fitDataFill",
responsiveLayout: "collapse",
responsiveLayoutCollapseStartOpen:false,
resizableColumns:false,
initialSort:[
{column:"date", dir:"desc"}, // sorting by the "cldate" field in descending order
],
columns:[
{formatter:"responsiveCollapse", width:30, minWidth:30, hozAlign:"center", resizable:false, headerSort:false, responsive:0},
{title:"Registrar", field:"registrar_id.name", headerSort:true, responsive:0},
{title:"Date", field:"date", headerSort:true, responsive:0},
{title:"Log", field:"log", headerSort:true, responsive:2},
],
placeholder:function(){
return this.getHeaderFilters().length ? "No Matching Data" : "No Data"; //set placeholder based on if there are currently any header filters
}
});
var searchInput = document.getElementById("search-input");
searchInput.addEventListener("input", function () {
var term = searchInput.value.toLowerCase();
if (term) { // Only apply the filter when there's a term to search for
table.setFilter(function (data) {
// Check if any of the fields contain the search term
return (
String(data.registrar_id.name).toLowerCase().includes(term) ||
String(data.date).toLowerCase().includes(term) ||
String(data.log).toLowerCase().includes(term)
);
});
} else {
table.clearFilter(); // Clear the filter when the search box is emptied
}
});
});
function downloadCSV() {
table.download("csv", "data.csv");
}
function downloadJSON() {
table.download("json", "data.json");
}
function downloadXLSX() {
table.download("xlsx", "data.xlsx", {sheetName:"My Logs"});
}
function downloadPDF() {
table.download("pdf", "data.pdf", {
orientation:"portrait",
title:"My Logs",
jsPDF:{unit:"mm", format:"a4", orientation:"p"}
});
}
</script>

View file

@ -72,13 +72,13 @@
} }
function downloadXLSX() { function downloadXLSX() {
table.download("xlsx", "data.xlsx", {sheetName:"My Contacts"}); table.download("xlsx", "data.xlsx", {sheetName:"My EPP Log"});
} }
function downloadPDF() { function downloadPDF() {
table.download("pdf", "data.pdf", { table.download("pdf", "data.pdf", {
orientation:"portrait", orientation:"portrait",
title:"My Contacts", title:"My EPP Log",
jsPDF:{unit:"mm", format:"a4", orientation:"p"} jsPDF:{unit:"mm", format:"a4", orientation:"p"}
}); });
} }

View file

@ -0,0 +1,77 @@
<script src="/assets/js/tabulator.min.js" defer></script>
<script src="/assets/js/tabler.min.js" defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf-autotable/3.6.0/jspdf.plugin.autotable.min.js"></script>
<script>
var table;
document.addEventListener("DOMContentLoaded", function(){
table = new Tabulator("#pollTable", {
ajaxURL:"/api/records/poll?join=registrar", // Set the URL for your JSON data
ajaxConfig:"GET",
pagination:"local",
paginationSize:10,
ajaxResponse:function(url, params, response){
return response.records;
},
layout:"fitDataFill",
responsiveLayout: "collapse",
responsiveLayoutCollapseStartOpen:false,
resizableColumns:false,
initialSort:[
{column:"qdate", dir:"desc"}, // sorting by the "cldate" field in descending order
],
columns:[
{formatter:"responsiveCollapse", width:30, minWidth:30, hozAlign:"center", resizable:false, headerSort:false, responsive:0},
{title:"Registrar", field:"registrar_id.name", headerSort:true, responsive:2},
{title:"Date", field:"qdate", headerSort:true, responsive:0},
{title:"Message", field:"msg", headerSort:true, responsive:0},
{title:"Message Type", field:"msg_type", headerSort:true, responsive:0},
{title:"Object", field:"obj_name_or_id", headerSort:true, responsive:2},
],
placeholder:function(){
return this.getHeaderFilters().length ? "No Matching Data" : "No Data"; //set placeholder based on if there are currently any header filters
}
});
var searchInput = document.getElementById("search-input");
searchInput.addEventListener("input", function () {
var term = searchInput.value.toLowerCase();
if (term) { // Only apply the filter when there's a term to search for
table.setFilter(function (data) {
// Check if any of the fields contain the search term
return (
String(data.registrar_id.name).toLowerCase().includes(term) ||
String(data.qdate).toLowerCase().includes(term) ||
String(data.msg).toLowerCase().includes(term) ||
String(data.msg_type).toLowerCase().includes(term) ||
String(data.obj_name_or_id).toLowerCase().includes(term)
);
});
} else {
table.clearFilter(); // Clear the filter when the search box is emptied
}
});
});
function downloadCSV() {
table.download("csv", "data.csv");
}
function downloadJSON() {
table.download("json", "data.json");
}
function downloadXLSX() {
table.download("xlsx", "data.xlsx", {sheetName:"My Contacts"});
}
function downloadPDF() {
table.download("pdf", "data.pdf", {
orientation:"portrait",
title:"My Contacts",
jsPDF:{unit:"mm", format:"a4", orientation:"p"}
});
}
</script>

View file

@ -59,6 +59,8 @@ $app->group('', function ($route) {
$route->get('/users', UsersController::class .':view')->setName('users'); $route->get('/users', UsersController::class .':view')->setName('users');
$route->get('/epphistory', LogsController::class .':view')->setName('epphistory'); $route->get('/epphistory', LogsController::class .':view')->setName('epphistory');
$route->get('/poll', LogsController::class .':poll')->setName('poll');
$route->get('/log', LogsController::class .':log')->setName('log');
$route->get('/reports', ReportsController::class .':view')->setName('reports'); $route->get('/reports', ReportsController::class .':view')->setName('reports');
$route->get('/pricing', FinancialsController::class .':pricing')->setName('pricing'); $route->get('/pricing', FinancialsController::class .':pricing')->setName('pricing');