Add admin job list and manual exec to admin
This commit is contained in:
parent
3a4c475488
commit
fc04e2dace
|
@ -5,9 +5,9 @@ namespace App\Console;
|
|||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
|
||||
use App\Jobs\NotifyUsersManualModeOn;
|
||||
use App\Jobs\RemoveOldIpAddressesFromLogs;
|
||||
use App\Jobs\ResetAvailabilityMinutes;
|
||||
use App\Jobs\NotifyUsersManualModeOnJob;
|
||||
use App\Jobs\RemoveOldIpAddressesFromLogsJob;
|
||||
use App\Jobs\ResetAvailabilityMinutesJob;
|
||||
use App\Jobs\UpdateAvailabilityWithSchedulesJob;
|
||||
|
||||
class Kernel extends ConsoleKernel
|
||||
|
@ -17,13 +17,13 @@ class Kernel extends ConsoleKernel
|
|||
*/
|
||||
protected function schedule(Schedule $schedule): void
|
||||
{
|
||||
$schedule->job(new NotifyUsersManualModeOn)
|
||||
$schedule->job(new NotifyUsersManualModeOnJob)
|
||||
->dailyAt('7:00');
|
||||
//->sentryMonitor();
|
||||
$schedule->job(new RemoveOldIpAddressesFromLogs)
|
||||
$schedule->job(new RemoveOldIpAddressesFromLogsJob)
|
||||
->dailyAt('0:30');
|
||||
//->sentryMonitor();
|
||||
$schedule->job(new ResetAvailabilityMinutes)
|
||||
$schedule->job(new ResetAvailabilityMinutesJob)
|
||||
->monthlyOn(1, '0:00');
|
||||
//->sentryMonitor();
|
||||
$schedule->job(new UpdateAvailabilityWithSchedulesJob)
|
||||
|
|
|
@ -94,6 +94,43 @@ class AdminController extends Controller
|
|||
]);
|
||||
}
|
||||
|
||||
public function getJobsList() {
|
||||
if(!request()->user()->hasPermission("admin-maintenance-read")) abort(401);
|
||||
|
||||
$jobPath = app_path('Jobs');
|
||||
$jobs = [];
|
||||
|
||||
$files = scandir($jobPath);
|
||||
foreach ($files as $file) {
|
||||
if (pathinfo($file, PATHINFO_EXTENSION) == 'php') {
|
||||
$jobs[] = pathinfo($file, PATHINFO_FILENAME);
|
||||
}
|
||||
}
|
||||
|
||||
return response()->json($jobs);
|
||||
}
|
||||
|
||||
public function runJob(Request $request) {
|
||||
if(!request()->user()->hasPermission("admin-maintenance-update")) abort(401);
|
||||
|
||||
$request->validate([
|
||||
'job' => 'required|string'
|
||||
]);
|
||||
|
||||
Artisan::call('schedule:test', ['--name' => "App\\Jobs\\".$request->input('job')]);
|
||||
$output = Artisan::output();
|
||||
|
||||
if(str_contains($output, 'No matching scheduled command found.')) {
|
||||
return response()->json([
|
||||
'message' => 'Job not found'
|
||||
], 404);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Job ran successfully'
|
||||
]);
|
||||
}
|
||||
|
||||
public function getMaintenanceMode() {
|
||||
if(!request()->user()->hasPermission("admin-maintenance-read")) abort(401);
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ use DefStudio\Telegraph\Keyboard\Button;
|
|||
use DefStudio\Telegraph\Keyboard\Keyboard;
|
||||
use DefStudio\Telegraph\Facades\Telegraph;
|
||||
|
||||
class NotifyUsersManualModeOn implements ShouldQueue
|
||||
class NotifyUsersManualModeOnJob implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
|
@ -10,7 +10,7 @@ use Illuminate\Queue\SerializesModels;
|
|||
use App\Models\Log;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class RemoveOldIpAddressesFromLogs implements ShouldQueue
|
||||
class RemoveOldIpAddressesFromLogsJob implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
|
@ -11,7 +11,7 @@ use Illuminate\Queue\SerializesModels;
|
|||
use App\Models\User;
|
||||
use App\Models\AvailabilityMinutesArchive;
|
||||
|
||||
class ResetAvailabilityMinutes implements ShouldQueue
|
||||
class ResetAvailabilityMinutesJob implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
|
@ -99,6 +99,9 @@ Route::middleware('auth:sanctum')->group( function () {
|
|||
Route::post('/admin/runMigrations', [AdminController::class, 'runMigrations']);
|
||||
Route::post('/admin/runSeeding', [AdminController::class, 'runSeeding']);
|
||||
|
||||
Route::get('/admin/jobs', [AdminController::class, 'getJobsList']);
|
||||
Route::post('/admin/runJob', [AdminController::class, 'runJob']);
|
||||
|
||||
Route::get('/admin/maintenanceMode', [AdminController::class, 'getMaintenanceMode']);
|
||||
Route::post('/admin/maintenanceMode', [AdminController::class, 'updateMaintenanceMode']);
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<div class="row">
|
||||
<div class="col-md-6 right-border">
|
||||
<div class="row">
|
||||
<h4>Database:</h4>
|
||||
<h4>{{ 'admin.database'|translate|ftitlecase }}:</h4>
|
||||
|
||||
<div class="table-responsive ms-3 pe-5">
|
||||
<table class="table table-striped table-bordered">
|
||||
|
@ -66,8 +66,6 @@
|
|||
<button type="button" class="btn btn-lg btn-danger" (click)="runSeeding()">{{ 'admin.run_seeding'|translate|ftitlecase }}</button>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="mb-2 ms-3 ps-5 pe-5" *ngIf="db && db.tables">
|
||||
<button type="button" class="btn btn-primary" (click)="isTableListCollaped = !isTableListCollaped"
|
||||
[attr.aria-expanded]="!isTableListCollaped" aria-controls="collapseBasic">
|
||||
|
@ -94,6 +92,30 @@
|
|||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="row">
|
||||
<h4>{{ 'admin.operations'|translate|ftitlecase }}:</h4>
|
||||
|
||||
<div class="table-responsive ms-3 pe-5">
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ 'name'|translate|ftitlecase }}</th>
|
||||
<th>{{ 'admin.manual_execution'|translate|ftitlecase }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let job of jobs">
|
||||
<td>{{ job }}</td>
|
||||
<td (click)="runJob(job)" class="pointer text-center"
|
||||
[ngClass]="{'text-bg-danger': ultraDangerousJobs.includes(job), 'text-bg-warning': dangerousJobs.includes(job)}">
|
||||
<i class="fas fa-play"></i> {{ 'admin.run'|translate|ftitlecase }}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="row">
|
||||
|
|
|
@ -12,6 +12,10 @@
|
|||
animation: blink 2s linear infinite;
|
||||
}
|
||||
|
||||
.pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.right-border {
|
||||
border-right: #0000004a 1px solid
|
||||
}
|
|
@ -12,6 +12,15 @@ export class AdminMaintenanceComponent implements OnInit {
|
|||
public db: any | undefined = undefined;
|
||||
public isTableListCollaped = true;
|
||||
|
||||
public jobs: string[] = [];
|
||||
//Hard-coded list of jobs that should not be run manually
|
||||
public dangerousJobs: string[] = [
|
||||
"NotifyUsersManualModeOnJob"
|
||||
];
|
||||
public ultraDangerousJobs: string[] = [
|
||||
"ResetAvailabilityMinutesJob"
|
||||
];
|
||||
|
||||
public isMaintenanceModeActive = false;
|
||||
|
||||
public telegramBotInfo: any | undefined = undefined;
|
||||
|
@ -40,6 +49,19 @@ export class AdminMaintenanceComponent implements OnInit {
|
|||
});
|
||||
}
|
||||
|
||||
getJobs() {
|
||||
this.api.get('admin/jobs').then((res: any) => {
|
||||
this.jobs = res;
|
||||
console.log(this.jobs);
|
||||
}).catch((err: any) => {
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: this.translateService.instant('error_title'),
|
||||
text: err.message
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
getMaintenanceMode() {
|
||||
this.api.get('admin/maintenanceMode').then((res: any) => {
|
||||
this.isMaintenanceModeActive = res.enabled;
|
||||
|
@ -68,6 +90,7 @@ export class AdminMaintenanceComponent implements OnInit {
|
|||
|
||||
ngOnInit(): void {
|
||||
this.getDB();
|
||||
this.getJobs();
|
||||
this.getMaintenanceMode();
|
||||
this.getTelegramBotDebugInfo();
|
||||
}
|
||||
|
@ -118,6 +141,35 @@ export class AdminMaintenanceComponent implements OnInit {
|
|||
});
|
||||
}
|
||||
|
||||
runJob(job: string) {
|
||||
//Require confirmation before proceeding
|
||||
Swal.fire({
|
||||
title: this.translateService.instant('admin.run_confirm_title'),
|
||||
text: this.translateService.instant('admin.run_confirm_text'),
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: this.translateService.instant('yes'),
|
||||
cancelButtonText: this.translateService.instant('no')
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
this.api.post('admin/runJob', { job }).then((res: any) => {
|
||||
Swal.fire({
|
||||
icon: 'success',
|
||||
title: this.translateService.instant('success_title'),
|
||||
text: this.translateService.instant('admin.run_success')
|
||||
});
|
||||
this.getJobs();
|
||||
}).catch((err: any) => {
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: this.translateService.instant('error_title'),
|
||||
text: err.error.message
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
updateMaintenanceMode(enabled: boolean) {
|
||||
this.api.post('admin/maintenanceMode', { enabled }).then((res: any) => {
|
||||
this.isMaintenanceModeActive = enabled;
|
||||
|
|
|
@ -46,7 +46,12 @@
|
|||
"telegram_webhook_set": "Set Telegram Webhook",
|
||||
"telegram_webhook_set_success": "Telegram Webhook set successfully",
|
||||
"telegram_webhook_unset": "Unset Telegram Webhook",
|
||||
"telegram_webhook_unset_success": "Telegram Webhook unset successfully"
|
||||
"telegram_webhook_unset_success": "Telegram Webhook unset successfully",
|
||||
"manual_execution": "manual execution",
|
||||
"run": "run",
|
||||
"run_confirm_title": "Are you sure you want to run this command?",
|
||||
"run_confirm_text": "This action cannot be undone.",
|
||||
"run_success": "Command executed successfully"
|
||||
},
|
||||
"table": {
|
||||
"yes_remove": "Yes, remove",
|
||||
|
|
|
@ -46,7 +46,12 @@
|
|||
"telegram_webhook_set": "Imposta Webhook Telegram",
|
||||
"telegram_webhook_set_success": "Webhook Telegram impostato con successo",
|
||||
"telegram_webhook_unset": "Rimuovi Webhook Telegram",
|
||||
"telegram_webhook_unset_success": "Webhook Telegram rimosso con successo"
|
||||
"telegram_webhook_unset_success": "Webhook Telegram rimosso con successo",
|
||||
"manual_execution": "esecuzione manuale",
|
||||
"run": "esegui",
|
||||
"run_confirm_title": "Sei sicuro di voler eseguire questo comando?",
|
||||
"run_confirm_text": "Questa operazione non potrà essere annullata.",
|
||||
"run_success": "Comando eseguito con successo"
|
||||
},
|
||||
"table": {
|
||||
"yes_remove": "Si, rimuovi",
|
||||
|
|
Loading…
Reference in New Issue