Move system debugger to Vue component.
This commit is contained in:
parent
63e3bf84a1
commit
dffb6b39f9
|
@ -0,0 +1,278 @@
|
|||
<template>
|
||||
<h2 class="outside-card-header mb-1">
|
||||
{{ $gettext('System Debugger') }}
|
||||
</h2>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<section
|
||||
class="card mb-3"
|
||||
aria-labelledby="hdr_clear_cache"
|
||||
>
|
||||
<div class="card-header bg-primary-dark">
|
||||
<h2
|
||||
id="hdr_clear_cache"
|
||||
class="card-title"
|
||||
>
|
||||
{{ $gettext('Clear Cache') }}
|
||||
</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p>
|
||||
{{ $gettext('Clearing the application cache may log you out of your session.') }}
|
||||
</p>
|
||||
|
||||
<div class="buttons">
|
||||
<a
|
||||
class="btn btn-sm btn-primary"
|
||||
role="button"
|
||||
:href="clearCacheUrl"
|
||||
>
|
||||
{{ $gettext('Clear Cache') }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<section
|
||||
class="card mb-3"
|
||||
aria-labelledby="hdr_clear_queues"
|
||||
>
|
||||
<div class="card-header bg-primary-dark">
|
||||
<h2
|
||||
id="hdr_clear_queues"
|
||||
class="card-title"
|
||||
>
|
||||
{{ $gettext('Clear All Message Queues') }}
|
||||
</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p>
|
||||
{{ $gettext('This will clear any pending unprocessed messages in all message queues.') }}
|
||||
</p>
|
||||
<div class="buttons">
|
||||
<a
|
||||
class="btn btn-sm btn-primary"
|
||||
role="button"
|
||||
:href="clearQueuesUrl"
|
||||
>
|
||||
{{ $gettext('Clear All Message Queues') }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section
|
||||
class="card mb-3"
|
||||
aria-labelledby="hdr_sync_tasks"
|
||||
>
|
||||
<div class="card-header bg-primary-dark">
|
||||
<h2
|
||||
id="hdr_sync_tasks"
|
||||
class="card-title"
|
||||
>
|
||||
{{ $gettext('Synchronization Tasks') }}
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<data-table
|
||||
ref="$datatable"
|
||||
:fields="syncTaskFields"
|
||||
:items="syncTasks"
|
||||
:show-toolbar="false"
|
||||
>
|
||||
<template #cell(name)="row">
|
||||
<h5>{{ row.item.task }}</h5>
|
||||
{{ row.item.pattern }}
|
||||
</template>
|
||||
<template #cell(actions)="row">
|
||||
<a
|
||||
class="btn btn-sm btn-primary"
|
||||
role="button"
|
||||
:href="row.item.url"
|
||||
>
|
||||
{{ $gettext('Run Task') }}
|
||||
</a>
|
||||
</template>
|
||||
</data-table>
|
||||
</section>
|
||||
|
||||
<section
|
||||
class="card mb-3"
|
||||
aria-labelledby="hdr_message_queues"
|
||||
>
|
||||
<div class="card-header bg-primary-dark">
|
||||
<h2
|
||||
id="hdr_message_queues"
|
||||
class="card-title"
|
||||
>
|
||||
{{ $gettext('Message Queues') }}
|
||||
</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div
|
||||
v-for="row in queueTotals"
|
||||
:key="row.name"
|
||||
class="col"
|
||||
>
|
||||
<h5 class="mb-0">
|
||||
{{ row.name }}
|
||||
</h5>
|
||||
|
||||
<p>
|
||||
{{
|
||||
$gettext(
|
||||
'%{messages} queued messages',
|
||||
{messages: row.count}
|
||||
)
|
||||
}}
|
||||
</p>
|
||||
|
||||
<div class="buttons">
|
||||
<a
|
||||
class="btn btn-sm btn-primary"
|
||||
role="button"
|
||||
:href="row.url"
|
||||
>
|
||||
{{ $gettext('Clear Queue') }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section
|
||||
class="card"
|
||||
aria-labelledby="hdr_station_debugging"
|
||||
>
|
||||
<div class="card-header bg-primary-dark">
|
||||
<h2
|
||||
id="hdr_station_debugging"
|
||||
class="card-title"
|
||||
>
|
||||
{{ $gettext('Station-Specific Debugging') }}
|
||||
</h2>
|
||||
</div>
|
||||
<b-tabs
|
||||
pills
|
||||
card
|
||||
>
|
||||
<b-tab
|
||||
v-for="station in stations"
|
||||
:key="station.id"
|
||||
:title="station.name"
|
||||
>
|
||||
<h3>{{ station.name }}</h3>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<h5>{{ $gettext('AutoDJ Queue') }}</h5>
|
||||
|
||||
<div class="buttons">
|
||||
<a
|
||||
class="btn btn-sm btn-primary"
|
||||
role="button"
|
||||
:href="station.clearQueueUrl"
|
||||
>
|
||||
{{ $gettext('Clear Queue') }}
|
||||
</a>
|
||||
<a
|
||||
class="btn btn-sm btn-primary"
|
||||
role="button"
|
||||
:href="station.getNextSongUrl"
|
||||
>
|
||||
{{ $gettext('Get Next Song') }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<h5>{{ $gettext('Get Now Playing') }}</h5>
|
||||
|
||||
<div class="buttons">
|
||||
<a
|
||||
class="btn btn-sm btn-primary"
|
||||
role="button"
|
||||
:href="station.getNowPlayingUrl"
|
||||
>
|
||||
{{ $gettext('Run Task') }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</b-tab>
|
||||
</b-tabs>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {ref} from "vue";
|
||||
import useHasDatatable from "~/functions/useHasDatatable";
|
||||
import DataTable from "~/components/Common/DataTable.vue";
|
||||
import {DateTime} from "luxon";
|
||||
import {useAzuraCast} from "~/vendor/azuracast";
|
||||
import {useTranslate} from "~/vendor/gettext";
|
||||
|
||||
const props = defineProps({
|
||||
clearCacheUrl: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
clearQueuesUrl: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
syncTasks: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
queueTotals: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
stations: {
|
||||
type: Array,
|
||||
required: true
|
||||
}
|
||||
});
|
||||
|
||||
const {$gettext} = useTranslate();
|
||||
const {timeConfig} = useAzuraCast();
|
||||
|
||||
const syncTaskFields = [
|
||||
{key: 'name', isRowHeader: true, label: $gettext('Task Name'), sortable: true},
|
||||
{
|
||||
key: 'time',
|
||||
label: $gettext('Last Run'),
|
||||
formatter: (value) => {
|
||||
if (value === 0) {
|
||||
return $gettext('Not Run');
|
||||
}
|
||||
|
||||
return DateTime.fromSeconds(value).toRelative({
|
||||
...timeConfig
|
||||
});
|
||||
},
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
key: 'nextRun',
|
||||
label: $gettext('Next Run'),
|
||||
formatter: (value) => {
|
||||
return DateTime.fromSeconds(value).toRelative({
|
||||
...timeConfig
|
||||
});
|
||||
},
|
||||
sortable: true
|
||||
},
|
||||
{key: 'actions', label: $gettext('Actions')}
|
||||
];
|
||||
|
||||
const $datatable = ref(); // Template Ref
|
||||
useHasDatatable($datatable);
|
||||
|
||||
</script>
|
|
@ -0,0 +1,5 @@
|
|||
import initBase from '~/base.js';
|
||||
|
||||
import AdminDebug from '~/components/Admin/Debug.vue';
|
||||
|
||||
export default initBase(AdminDebug);
|
|
@ -14,6 +14,7 @@ module.exports = {
|
|||
AdminBackups: '~/pages/Admin/Backups.js',
|
||||
AdminBranding: '~/pages/Admin/Branding.js',
|
||||
AdminCustomFields: '~/pages/Admin/CustomFields.js',
|
||||
AdminDebug: '~/pages/Admin/Debug.js',
|
||||
AdminGeoLite: '~/pages/Admin/GeoLite.js',
|
||||
AdminIndex: '~/pages/Admin/Index.js',
|
||||
AdminLogs: '~/pages/Admin/Logs.js',
|
||||
|
|
|
@ -32,12 +32,21 @@ final class IndexAction
|
|||
ServerRequest $request,
|
||||
Response $response
|
||||
): ResponseInterface {
|
||||
$router = $request->getRouter();
|
||||
|
||||
$queueTotals = [];
|
||||
foreach (QueueNames::cases() as $queue) {
|
||||
$queueTotals[$queue->value] = $this->queueManager->getQueueCount($queue);
|
||||
$queueTotals[] = [
|
||||
'name' => $queue->value,
|
||||
'count' => $this->queueManager->getQueueCount($queue),
|
||||
'url' => $router->named(
|
||||
'admin:debug:clear-queue',
|
||||
['queue' => $queue->value]
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
$syncTimes = [];
|
||||
$syncTasks = [];
|
||||
$now = CarbonImmutable::now(new DateTimeZone('UTC'));
|
||||
$syncTasksEvent = new GetSyncTasks();
|
||||
$this->dispatcher->dispatch($syncTasksEvent);
|
||||
|
@ -48,20 +57,49 @@ final class IndexAction
|
|||
|
||||
$cronExpression = new CronExpression($pattern);
|
||||
|
||||
$syncTimes[$task] = [
|
||||
$syncTasks[] = [
|
||||
'task' => $task,
|
||||
'pattern' => $pattern,
|
||||
'time' => $this->cache->get($cacheKey, 0),
|
||||
'nextRun' => $cronExpression->getNextRunDate($now)->getTimestamp(),
|
||||
'url' => $router->named(
|
||||
'admin:debug:sync',
|
||||
['task' => rawurlencode($task)]
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
return $request->getView()->renderToResponse(
|
||||
$response,
|
||||
'admin/debug/index',
|
||||
[
|
||||
'queue_totals' => $queueTotals,
|
||||
'sync_times' => $syncTimes,
|
||||
'stations' => $this->stationRepo->fetchArray(),
|
||||
$stations = [];
|
||||
foreach ($this->stationRepo->fetchArray() as $station) {
|
||||
$stations[] = [
|
||||
'id' => $station['id'],
|
||||
'name' => $station['name'],
|
||||
'clearQueueUrl' => $router->named(
|
||||
'admin:debug:clear-station-queue',
|
||||
['station_id' => $station['id']]
|
||||
),
|
||||
'getNextSongUrl' => $router->named(
|
||||
'admin:debug:nextsong',
|
||||
['station_id' => $station['id']]
|
||||
),
|
||||
'getNowPlayingUrl' => $router->named(
|
||||
'admin:debug:nowplaying',
|
||||
['station_id' => $station['id']]
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
return $request->getView()->renderVuePage(
|
||||
response: $response,
|
||||
component: 'Vue_AdminDebug',
|
||||
id: 'admin-debug',
|
||||
title: __('System Debugger'),
|
||||
props: [
|
||||
'clearCacheUrl' => $router->named('admin:debug:clear-cache'),
|
||||
'clearQueuesUrl' => $router->named('admin:debug:clear-queue'),
|
||||
'syncTasks' => $syncTasks,
|
||||
'queueTotals' => $queueTotals,
|
||||
'stations' => $stations,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,222 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @var App\View\GlobalSections $sections
|
||||
* @var App\Http\RouterInterface $router
|
||||
* @var array $stations
|
||||
* @var array $sync_times
|
||||
* @var array $queue_totals
|
||||
*/
|
||||
|
||||
$this->layout('main', [
|
||||
'title' => __('System Debugger'),
|
||||
'manual' => true,
|
||||
]);
|
||||
|
||||
$sections->appendStart('bodyjs');
|
||||
?>
|
||||
<script src="<?= $this->assetUrl('dist/lib/luxon/luxon.min.js') ?>"></script>
|
||||
|
||||
<script>
|
||||
jQuery(function ($) {
|
||||
$('time[data-duration]').each(function () {
|
||||
$(this).text(luxon.DateTime.fromSeconds($(this).data('duration')).toRelative());
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
$sections->end();
|
||||
?>
|
||||
|
||||
<h2 class="outside-card-header mb-1"><?= __('System Debugger') ?></h2>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="card mb-3">
|
||||
<div class="card-header bg-primary-dark">
|
||||
<h2 class="card-title"><?= __('Clear Cache') ?></h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p><?= __('Clearing the application cache may log you out of your session.') ?></p>
|
||||
<div class="buttons">
|
||||
<a class="btn btn-sm btn-primary" role="button"
|
||||
href="<?= $router->named('admin:debug:clear-cache') ?>">
|
||||
<?= __('Clear Cache') ?>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="card mb-3">
|
||||
<div class="card-header bg-primary-dark">
|
||||
<h2 class="card-title"><?= __('Clear All Message Queues') ?></h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p><?= __('This will clear any pending unprocessed messages in all message queues.') ?></p>
|
||||
<div class="buttons">
|
||||
<a class="btn btn-sm btn-primary" role="button"
|
||||
href="<?= $router->named('admin:debug:clear-queue') ?>">
|
||||
<?= __('Clear All Message Queues') ?>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card mb-3">
|
||||
<div class="card-header bg-primary-dark">
|
||||
<h2 class="card-title"><?= __('Synchronization Tasks') ?></h2>
|
||||
</div>
|
||||
<table class="table">
|
||||
<colgroup>
|
||||
<col width="40%">
|
||||
<col width="20%">
|
||||
<col width="20%">
|
||||
<col width="20%">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?= __('Task Name') ?></th>
|
||||
<th><?= __('Last Run') ?></th>
|
||||
<th><?= __('Next Run') ?></th>
|
||||
<th><?= __('Actions') ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<?php
|
||||
foreach ($sync_times as $task => $taskInfo): ?>
|
||||
<tr>
|
||||
<td>
|
||||
<big><?= $task ?></big><br>
|
||||
<?= $taskInfo['pattern'] ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php
|
||||
if (0 === $taskInfo['time']): ?>
|
||||
<?= __('Not Run') ?>
|
||||
<?php
|
||||
else: ?>
|
||||
<time <?php
|
||||
if ($taskInfo['time'] < time() - (60 * 60 * 3)): ?>class="text-danger"<?php
|
||||
endif; ?> data-duration="<?= $taskInfo['time'] ?>"></time>
|
||||
<?php
|
||||
endif; ?>
|
||||
</td>
|
||||
<td>
|
||||
<time data-duration="<?= $taskInfo['nextRun'] ?>"></time>
|
||||
</td>
|
||||
<td>
|
||||
<div class="buttons">
|
||||
<a class="btn btn-sm btn-primary" role="button" href="<?= $router->named(
|
||||
'admin:debug:sync',
|
||||
['task' => rawurlencode($task)]
|
||||
) ?>">
|
||||
<?= __('Run Task') ?>
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
endforeach; ?>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="card mb-3">
|
||||
<div class="card-header bg-primary-dark">
|
||||
<h2 class="card-title"><?= __('Message Queues') ?></h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<?php
|
||||
foreach ($queue_totals as $queueType => $queueTotal): ?>
|
||||
<div class="col">
|
||||
<h5 class="mb-0"><?= $queueType ?></h5>
|
||||
<p><?= sprintf(__('%d queued messages'), $queueTotal) ?></p>
|
||||
|
||||
<div class="buttons">
|
||||
<a class="btn btn-sm btn-primary" role="button" href="<?= $router->named(
|
||||
'admin:debug:clear-queue',
|
||||
['queue' => $queueType]
|
||||
) ?>">
|
||||
<?= __('Clear Queue') ?>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header bg-primary-dark">
|
||||
<h2 class="card-title"><?=__('Station-Specific Debugging')?></h2>
|
||||
</div>
|
||||
<div class="card-body pb-0">
|
||||
<ul class="nav nav-pills nav-pills-scrollable card-header-pills">
|
||||
<?php foreach ($stations as $station): ?>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" role="tab" data-toggle="tab" aria-expanded="true" aria-controls="debug_station_<?=$station['id']?>" href="#debug_station_<?=$station['id']?>"><?=$this->e($station['name'])?></a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="tab-content">
|
||||
<?php foreach ($stations as $station): ?>
|
||||
<div class="card-body card-padding-sm tab-pane" id="debug_station_<?= $station['id'] ?>">
|
||||
<h3><?= $station['name'] ?></h3>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<h5><?= __('AutoDJ Queue') ?></h5>
|
||||
|
||||
<div class="buttons">
|
||||
<a class="btn btn-sm btn-primary" role="button" href="<?= $router->named(
|
||||
'admin:debug:clear-station-queue',
|
||||
['station_id' => $station['id']]
|
||||
) ?>">
|
||||
<?= __('Clear Queue') ?>
|
||||
</a>
|
||||
<a class="btn btn-sm btn-primary" role="button" href="<?= $router->named(
|
||||
'admin:debug:nextsong',
|
||||
['station_id' => $station['id']]
|
||||
) ?>">
|
||||
<?= __('Get Next Song') ?>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<h5><?= __('Get Now Playing') ?></h5>
|
||||
|
||||
<div class="buttons">
|
||||
<a class="btn btn-sm btn-primary" role="button" href="<?= $router->named(
|
||||
'admin:debug:nowplaying',
|
||||
['station_id' => $station['id']]
|
||||
) ?>">
|
||||
<?= __('Run Task') ?>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
if ($station['backend_type'] === App\Radio\Enums\BackendAdapters::Liquidsoap->value): ?>
|
||||
<div class="col-md-4">
|
||||
<h5><?= __('Send Liquidsoap Telnet Command') ?></h5>
|
||||
|
||||
<form class="form" method="POST" action="<?= $router->named(
|
||||
'admin:debug:telnet',
|
||||
['station_id' => $station['id']]
|
||||
) ?>">
|
||||
<div class="form-group">
|
||||
<label for="<?= $station['id'] ?>_command"><?= __('Command') ?>:</label>
|
||||
<input id="<?= $station['id'] ?>_command" name="command" class="form-control"
|
||||
type="text">
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary"><?= __('Execute Command') ?></button>
|
||||
</form>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
|
@ -1,31 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @var \App\Assets $assets
|
||||
*/
|
||||
|
||||
$this->layout('main', [
|
||||
'title' => __('Run Synchronization Task'),
|
||||
'manual' => true,
|
||||
]);
|
||||
?>
|
||||
|
||||
<div class="card mb-3">
|
||||
<div class="card-header bg-primary-dark">
|
||||
<h3 class="card-title"><?=__('Run Synchronization Task')?></h3>
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<a class="btn btn-outline-primary" href="<?=$router->fromHere('admin:debug:index')?>">
|
||||
<i class="material-icons" aria-hidden="true">arrow_back</i>
|
||||
<?=__('Debug Home')?>
|
||||
</a>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="card-text">
|
||||
<?=__('The synchronization task is running in the background. The log below will update automatically.')?>
|
||||
</p>
|
||||
|
||||
<?=$this->fetch('partials/log_inline', [
|
||||
'url' => (string)$router->fromHere('admin:debug:log', ['path' => $outputLog]),
|
||||
])?>
|
||||
</div>
|
||||
</div>
|
Loading…
Reference in New Issue