Rebuild logs view
This commit is contained in:
parent
64dc16e4d9
commit
e947e788f9
|
@ -39,6 +39,10 @@ $route->get('/design', 'DesignController@index');
|
|||
$route->addGroup(
|
||||
'/admin',
|
||||
function (RouteCollector $route) {
|
||||
// Log
|
||||
$route->get('/logs', 'Admin\\LogsController@index');
|
||||
$route->post('/logs', 'Admin\\LogsController@index');
|
||||
|
||||
// Schedule
|
||||
$route->addGroup(
|
||||
'/schedule',
|
||||
|
@ -48,6 +52,8 @@ $route->addGroup(
|
|||
$route->post('/import', 'Admin\\Schedule\\ImportSchedule@importSchedule');
|
||||
}
|
||||
);
|
||||
|
||||
// News
|
||||
$route->addGroup(
|
||||
'/news',
|
||||
function (RouteCollector $route) {
|
||||
|
|
|
@ -68,7 +68,6 @@ $includeFiles = [
|
|||
__DIR__ . '/../includes/pages/admin_arrive.php',
|
||||
__DIR__ . '/../includes/pages/admin_free.php',
|
||||
__DIR__ . '/../includes/pages/admin_groups.php',
|
||||
__DIR__ . '/../includes/pages/admin_log.php',
|
||||
__DIR__ . '/../includes/pages/admin_questions.php',
|
||||
__DIR__ . '/../includes/pages/admin_rooms.php',
|
||||
__DIR__ . '/../includes/pages/admin_shifts.php',
|
||||
|
|
|
@ -102,12 +102,14 @@ function admin_free()
|
|||
form([
|
||||
div('row', [
|
||||
div('col-md-12 form-inline', [
|
||||
div('inline-form-spacing', [
|
||||
form_text('search', __('Search'), $search),
|
||||
form_select('angeltype', __('Angeltype'), $angel_types, $angelType),
|
||||
form_submit('submit', __('Search'))
|
||||
]),
|
||||
]),
|
||||
]),
|
||||
]),
|
||||
table([
|
||||
'name' => __('Nick'),
|
||||
'shift_state' => __('Next shift'),
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Engelsystem\Models\LogEntry;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
function admin_log_title()
|
||||
{
|
||||
return __('Log');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
function admin_log()
|
||||
{
|
||||
$filter = '';
|
||||
if (request()->has('keyword')) {
|
||||
$filter = strip_request_item('keyword');
|
||||
}
|
||||
|
||||
$log_entries = LogEntry::filter($filter);
|
||||
|
||||
$entries = [];
|
||||
foreach ($log_entries as $entry) {
|
||||
$data = $entry->toArray();
|
||||
$data['message'] = nl2br(htmlspecialchars($data['message']));
|
||||
$data['created_at'] = date_format($entry->created_at, 'd.m.Y H:i');
|
||||
$entries[] = $data;
|
||||
}
|
||||
|
||||
return page_with_title(admin_log_title(), [
|
||||
msg(),
|
||||
form([
|
||||
form_text('keyword', __('Search'), $filter),
|
||||
form_submit(__('Search'), 'Go')
|
||||
]),
|
||||
table([
|
||||
'created_at' => 'Time',
|
||||
'level' => 'Type',
|
||||
'message' => 'Log Entry'
|
||||
], $entries)
|
||||
]);
|
||||
}
|
|
@ -108,6 +108,8 @@ function make_navigation()
|
|||
|
||||
$admin_menu = [];
|
||||
$admin_pages = [
|
||||
// path => name
|
||||
// path => [name, permission]
|
||||
'admin_arrive' => 'Arrived angels',
|
||||
'admin_active' => 'Active angels',
|
||||
'admin_user' => 'All Angels',
|
||||
|
@ -118,7 +120,7 @@ function make_navigation()
|
|||
'admin_rooms' => 'Rooms',
|
||||
'admin_groups' => 'Grouprights',
|
||||
'admin/schedule' => ['schedule.import', 'schedule.import'],
|
||||
'admin_log' => 'Log',
|
||||
'admin/logs' => ['log.log', 'admin_log'],
|
||||
'admin_event_config' => 'Event config',
|
||||
];
|
||||
|
||||
|
|
|
@ -248,6 +248,10 @@ h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 {
|
|||
overflow-x: inherit;
|
||||
}
|
||||
|
||||
.inline-form-spacing {
|
||||
margin-bottom: @form-group-margin-bottom;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
|
|
|
@ -986,8 +986,6 @@ msgstr "Alle Schichten anzeigen"
|
|||
|
||||
#: includes/pages/admin_active.php:307 includes/pages/admin_arrive.php:178
|
||||
#: includes/pages/admin_arrive.php:179 includes/pages/admin_free.php:105
|
||||
#: includes/pages/admin_free.php:107 includes/pages/admin_log.php:36
|
||||
#: includes/pages/admin_log.php:37
|
||||
msgid "Search"
|
||||
msgstr "Suche"
|
||||
|
||||
|
@ -1294,10 +1292,6 @@ msgstr "Zu löschende Schichten"
|
|||
msgid "It's done!"
|
||||
msgstr "Erledigt!"
|
||||
|
||||
#: includes/pages/admin_log.php:10 includes/sys_menu.php:121
|
||||
msgid "Log"
|
||||
msgstr "Log"
|
||||
|
||||
#: includes/pages/user_messages.php:121
|
||||
msgid "Message"
|
||||
msgstr "Nachricht"
|
||||
|
@ -2866,3 +2860,18 @@ msgstr "Treffen"
|
|||
|
||||
msgid "news.edit.message"
|
||||
msgstr "Nachricht"
|
||||
|
||||
msgid "form.search"
|
||||
msgstr "Suchen"
|
||||
|
||||
msgid "log.log"
|
||||
msgstr "Logs"
|
||||
|
||||
msgid "log.time"
|
||||
msgstr "Zeit"
|
||||
|
||||
msgid "log.level"
|
||||
msgstr "Level"
|
||||
|
||||
msgid "log.message"
|
||||
msgstr "Nachricht"
|
||||
|
|
|
@ -144,3 +144,18 @@ msgstr "Meeting"
|
|||
|
||||
msgid "news.edit.message"
|
||||
msgstr "Message"
|
||||
|
||||
msgid "form.search"
|
||||
msgstr "Search"
|
||||
|
||||
msgid "log.log"
|
||||
msgstr "Logs"
|
||||
|
||||
msgid "log.time"
|
||||
msgstr "Time"
|
||||
|
||||
msgid "log.level"
|
||||
msgstr "Level"
|
||||
|
||||
msgid "log.message"
|
||||
msgstr "Message"
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
{% extends 'layouts/app.twig' %}
|
||||
{% import 'macros/base.twig' as m %}
|
||||
{% import 'macros/form.twig' as f %}
|
||||
|
||||
{% set title %}{% block title %}{{ __('log.log') }}{% endblock %}{% endset %}
|
||||
|
||||
{% block content %}
|
||||
<div class="col-md-12">
|
||||
<h1>{{ block('title') }}</h1>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="inline-form-spacing">
|
||||
<form method="POST" action="{{ url('/admin/logs') }}" class="form-inline">
|
||||
{{ csrf() }}
|
||||
|
||||
{{ f.input('search', __('form.search'), 'text', {'value': search, 'hide_label': true}) }}
|
||||
|
||||
{{ f.submit(__('form.search')) }}
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<table class="table table-striped">
|
||||
<tr>
|
||||
<th>{{ __('log.time') }}</th>
|
||||
<th>{{ __('log.level') }}</th>
|
||||
<th>{{ __('log.message') }}</th>
|
||||
</tr>
|
||||
{% for entry in entries %}
|
||||
{%- set type = 'default' %}
|
||||
{%- if entry.level in ['notice', 'info'] %}
|
||||
{%- set type = 'info' %}
|
||||
{%- endif %}
|
||||
{%- if entry.level in ['error', 'warning'] %}
|
||||
{%- set type = 'warning' %}
|
||||
{%- endif %}
|
||||
{%- if entry.level in ['emergency', 'alert', 'critical'] %}
|
||||
{%- set type = 'danger' %}
|
||||
{%- endif %}
|
||||
|
||||
{%- set td_type = '' %}
|
||||
{%- if type in ['warning', 'danger'] %}
|
||||
{%- set td_type = type %}
|
||||
{%- endif %}
|
||||
|
||||
<tr>
|
||||
<td class="{{ td_type }}">{{ entry.created_at.format(__('Y-m-d H:i')) }}</td>
|
||||
<td class="{{ td_type }}">
|
||||
<span class="label label-{{ type }}">{{ entry.level|capitalize }}</span>
|
||||
</td>
|
||||
<td>{{ entry.message|nl2br }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -1,11 +1,11 @@
|
|||
{% macro input(name, label, type, opt) %}
|
||||
<div class="form-group">
|
||||
{% if label -%}
|
||||
<label for="{{ name }}">{{ label }}</label>
|
||||
<label for="{{ name }}"{% if opt.hide_label|default(false) %} class="sr-only"{% endif %}>{{ label }}</label>
|
||||
{%- endif %}
|
||||
<input type="{{ type|default('text') }}" class="form-control"
|
||||
id="{{ name }}" name="{{ name }}"
|
||||
value="{{ opt.value|default('') }}"
|
||||
value="{{ opt.value|default('')|escape('html_attr') }}"
|
||||
{%- if opt.required|default(false) %}
|
||||
required
|
||||
{%- endif -%}
|
||||
|
@ -59,7 +59,7 @@
|
|||
{%- endmacro %}
|
||||
|
||||
{% macro hidden(name, value) %}
|
||||
<input type="hidden" id="{{ name }}" name="{{ name }}" value="{{ value }}">
|
||||
<input type="hidden" id="{{ name }}" name="{{ name }}" value="{{ value|escape('html_attr') }}">
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro button(label, opt) %}
|
||||
|
|
|
@ -101,6 +101,9 @@
|
|||
<div class="col-md-2">
|
||||
{{ f.input('form-input-text', 'Text', 'text', {'value': 'Value'}) }}
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
{{ f.input('form-input-text-hidden-label', 'Hidden label', 'text', {'value': 'Hidden label', 'hide_label': true}) }}
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
{{ f.input('form-input-text-disabled', 'Disabled', 'text', {'disabled': true, 'value': 'Value'}) }}
|
||||
</div>
|
||||
|
@ -113,11 +116,11 @@
|
|||
<div class="col-md-2">
|
||||
{{ f.input('form-input-number', 'Number', 'number', {'value': 42}) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-2">
|
||||
{{ f.textarea('form-input-textarea', 'Textarea', {'rows': 2, 'value': lipsum}) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-2">
|
||||
{{ f.select('form-input-select', {'lorem': 'Ipsum', 'dolor': 'Sit'}, 'Select', 'dolor') }}
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
namespace Engelsystem\Controllers\Admin;
|
||||
|
||||
use Engelsystem\Controllers\BaseController;
|
||||
use Engelsystem\Http\Request;
|
||||
use Engelsystem\Http\Response;
|
||||
use Engelsystem\Models\LogEntry;
|
||||
|
||||
class LogsController extends BaseController
|
||||
{
|
||||
/** @var LogEntry */
|
||||
protected $log;
|
||||
|
||||
/** @var Response */
|
||||
protected $response;
|
||||
|
||||
/** @var array */
|
||||
protected $permissions = [
|
||||
'admin_log',
|
||||
];
|
||||
|
||||
/**
|
||||
* @param LogEntry $log
|
||||
* @param Response $response
|
||||
*/
|
||||
public function __construct(LogEntry $log, Response $response)
|
||||
{
|
||||
$this->log = $log;
|
||||
$this->response = $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
public function index(Request $request): Response
|
||||
{
|
||||
$search = $request->input('search');
|
||||
$entries = $this->log->filter($search);
|
||||
|
||||
return $this->response->withView(
|
||||
'admin/log.twig',
|
||||
['entries' => $entries, 'search' => $search]
|
||||
);
|
||||
}
|
||||
}
|
|
@ -188,10 +188,6 @@ class LegacyMiddleware implements MiddlewareInterface
|
|||
$title = admin_shifts_title();
|
||||
$content = admin_shifts();
|
||||
return [$title, $content];
|
||||
case 'admin_log':
|
||||
$title = admin_log_title();
|
||||
$content = admin_log();
|
||||
return [$title, $content];
|
||||
}
|
||||
|
||||
throw_redirect(page_link_to('login'));
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
|
||||
namespace Engelsystem\Test\Unit\Controllers\Admin;
|
||||
|
||||
use Engelsystem\Controllers\Admin\LogsController;
|
||||
use Engelsystem\Http\Request;
|
||||
use Engelsystem\Http\Response;
|
||||
use Engelsystem\Models\LogEntry;
|
||||
use Engelsystem\Test\Unit\HasDatabase;
|
||||
use Engelsystem\Test\Unit\TestCase;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Psr\Log\LogLevel;
|
||||
|
||||
class LogsControllerTest extends TestCase
|
||||
{
|
||||
use HasDatabase;
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Controllers\Admin\LogsController::index
|
||||
* @covers \Engelsystem\Controllers\Admin\LogsController::__construct
|
||||
*/
|
||||
public function testIndex()
|
||||
{
|
||||
$log = new LogEntry();
|
||||
$alert = $log->create(['level' => LogLevel::ALERT, 'message' => 'Alert test']);
|
||||
$alert = $log->find($alert)->first();
|
||||
$error = $log->create(['level' => LogLevel::ERROR, 'message' => 'Error test']);
|
||||
$error = $log->find($error)->first();
|
||||
|
||||
$response = $this->createMock(Response::class);
|
||||
$response->expects($this->exactly(2))
|
||||
->method('withView')
|
||||
->withConsecutive(
|
||||
['admin/log.twig', ['entries' => new Collection([$error, $alert]), 'search' => null]],
|
||||
['admin/log.twig', ['entries' => new Collection([$error]), 'search' => 'error']]
|
||||
)
|
||||
->willReturn($response);
|
||||
|
||||
$request = Request::create('/');
|
||||
|
||||
$controller = new LogsController($log, $response);
|
||||
$controller->index($request);
|
||||
|
||||
$request->request->set('search', 'error');
|
||||
$controller->index($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the DB
|
||||
*/
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->initDatabase();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue